79
|
0 |
3 |
if (not eval {
do {
local $SIG{'__DIE__'};
my $boxes = &read_heif($source, qr/\A(?:ftyp|meta)\z/);
my $ftyp = $boxes->{'ftyp'};
&die_for_info("no ftyp box") unless defined $ftyp;
&die_for_info("malformed ftyp box") unless length $ftyp >= 8 and not length $ftyp & 3;
&die_for_info("major brand is not \"avif\"") unless substr($ftyp, 0, 4) eq "avif";
$info->replace_info(0, "file_media_type", "image/avif");
$info->replace_info(0, "file_ext", "avif");
my $mboxes;
{
my $meta = $boxes->{'meta'};
&die_for_info("no meta box") unless defined $meta;
my $metafh = &io_string($meta);
&die_for_info("malformed meta box") unless &read_block($metafh, 1) eq "\0";
&read_block($metafh, 3);
$mboxes = &read_heif($metafh, qr/\A(?:hdlr|iprp)\z/);
};
{
my $hdlr = $mboxes->{'hdlr'};
&die_for_info("no hdlr box") unless defined $hdlr;
my $hdlrfh = &io_string($hdlr);
&die_for_info("malformed hdlr box") unless &read_block($hdlrfh, 1) eq "\0";
&read_block($hdlrfh, 3);
&die_for_info("non-zero pre-defined value") unless unpack("N", &read_block($hdlrfh, 4)) == 0;
&die_for_info("handler type is not \"pict\"") unless &read_block($hdlrfh, 4) eq "pict";
&read_block($hdlrfh, 12);
&read_nulterm($hdlrfh);
};
my $pboxes;
{
my $iprp = $mboxes->{'iprp'};
&die_for_info("no iprp box") unless defined $iprp;
my $iprpfh = &io_string($iprp);
$pboxes = &read_heif($iprpfh, qr/\Aipco\z/);
};
my $cboxes;
{
my $ipco = $pboxes->{'ipco'};
&die_for_info("no ipco box") unless defined $ipco;
my $ipcofh = &io_string($ipco);
$cboxes = &read_heif($ipcofh, qr/\A(?:irot|clap|ispe|pixi|colr|pasp)\z/);
};
my $rot = 0;
if (defined(my $irot = $cboxes->{'irot'})) {
&die_for_info("malformed irot box") unless length $irot >= 1;
my($angle) = unpack("C", $irot);
&die_for_info("malformed irot box") if $angle & -4;
$rot = 1 if $angle & 1;
};
if (defined(my $clap = $cboxes->{'clap'})) {
&die_for_info("malformed clap box") unless length $clap >= 32;
my($width_num, $width_den, $height_num, $height_den) = unpack("NNNN", $clap);
&die_for_info("malformed clap box") unless $width_den != 0 and $height_den != 0;
my $width = int $width_num / $width_den;
my $height = int $height_num / $height_den;
($width, $height) = ($height, $width) if $rot;
$info->replace_info(0, "width", $width);
$info->replace_info(0, "height", $height);
}
elsif (defined(my $ispe = $cboxes->{'ispe'})) {
&die_for_info("malformed ispe box") unless length $ispe >= 12;
my($ver, undef, $width, $height) = unpack("Ca3NN", $ispe);
&die_for_info("malformed ispe box") unless $ver == 0;
($width, $height) = ($height, $width) if $rot;
$info->replace_info(0, "width", $width);
$info->replace_info(0, "height", $height);
};
if (defined(my $pixi = $cboxes->{'pixi'})) {
&die_for_info("malformed pixi box") unless length $pixi >= 5;
my($ver, undef, $planes) = unpack("Ca3C", $pixi);
&die_for_info("malformed pixi box") unless $ver == 0;
&die_for_info("malformed pixi box") unless length $pixi >= 5 + $planes;
$info->replace_info(0, "SamplesPerPixel", $planes);
$info->replace_info(0, "BitsPerSample", [map({unpack "C", substr($pixi, 5 + $_, 1);} 0 .. $planes - 1)]);
};
if (defined(my $colr = $cboxes->{'colr'})) {
&die_for_info("malformed colr box") unless length $colr >= 4;
my $type = substr($colr, 0, 4);
if ($type eq "nclx") {
&die_for_info("malformed colr box") unless length $colr >= 11;
my($prim) = unpack("n", substr($colr, 4, 2));
if (defined(my $ctype = $primaries_type[$prim])) {
$info->replace_info(0, "color_type", $ctype);
};
};
};
if (defined(my $pasp = $cboxes->{'pasp'})) {
&die_for_info("malformed pasp box") unless length $pasp >= 8;
my($hspc, $vspc) = unpack("NN", $pasp);
$info->replace_info(0, "resolution", "$vspc/$hspc");
};
1
}
}) |