1 | # NOTE: Derived from lib/Image/Size.pm.
|
---|
2 | # Changes made here will be lost when autosplit is run again.
|
---|
3 | # See AutoSplit.pm.
|
---|
4 | package Image::Size;
|
---|
5 |
|
---|
6 | #line 979 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/tiffsize.al)"
|
---|
7 | # tiffsize: size a TIFF image
|
---|
8 | #
|
---|
9 | # Contributed by Cloyce Spradling <[email protected]>
|
---|
10 | sub tiffsize {
|
---|
11 | my $stream = shift;
|
---|
12 |
|
---|
13 | my ($x, $y, $id) = (undef, undef, "Unable to determine size of TIFF data");
|
---|
14 |
|
---|
15 | my $endian = 'n'; # Default to big-endian; I like it better
|
---|
16 | my $header = &$read_in($stream, 4);
|
---|
17 | $endian = 'v' if ($header =~ /II\x2a\x00/o); # little-endian
|
---|
18 |
|
---|
19 | # Set up an association between data types and their corresponding
|
---|
20 | # pack/unpack specification. Don't take any special pains to deal with
|
---|
21 | # signed numbers; treat them as unsigned because none of the image
|
---|
22 | # dimensions should ever be negative. (I hope.)
|
---|
23 | my @packspec = ( undef, # nothing (shouldn't happen)
|
---|
24 | 'C', # BYTE (8-bit unsigned integer)
|
---|
25 | undef, # ASCII
|
---|
26 | $endian, # SHORT (16-bit unsigned integer)
|
---|
27 | uc($endian), # LONG (32-bit unsigned integer)
|
---|
28 | undef, # RATIONAL
|
---|
29 | 'c', # SBYTE (8-bit signed integer)
|
---|
30 | undef, # UNDEFINED
|
---|
31 | $endian, # SSHORT (16-bit unsigned integer)
|
---|
32 | uc($endian), # SLONG (32-bit unsigned integer)
|
---|
33 | );
|
---|
34 |
|
---|
35 | my $offset = &$read_in($stream, 4, 4); # Get offset to IFD
|
---|
36 | $offset = unpack(uc($endian), $offset); # Fix it so we can use it
|
---|
37 |
|
---|
38 | my $ifd = &$read_in($stream, 2, $offset); # Get number of directory entries
|
---|
39 | my $num_dirent = unpack($endian, $ifd); # Make it useful
|
---|
40 | $offset += 2;
|
---|
41 | $num_dirent = $offset + ($num_dirent * 12); # Calc. maximum offset of IFD
|
---|
42 |
|
---|
43 | # Do all the work
|
---|
44 | $ifd = '';
|
---|
45 | my $tag = 0;
|
---|
46 | my $type = 0;
|
---|
47 | while (!defined($x) || !defined($y)) {
|
---|
48 | $ifd = &$read_in($stream, 12, $offset); # Get first directory entry
|
---|
49 | last if (($ifd eq '') || ($offset > $num_dirent));
|
---|
50 | $offset += 12;
|
---|
51 | $tag = unpack($endian, $ifd); # ...and decode its tag
|
---|
52 | $type = unpack($endian, substr($ifd, 2, 2)); # ...and the data type
|
---|
53 | # Check the type for sanity.
|
---|
54 | next if (($type > @packspec+0) || (!defined($packspec[$type])));
|
---|
55 | if ($tag == 0x0100) { # ImageWidth (x)
|
---|
56 | # Decode the value
|
---|
57 | $x = unpack($packspec[$type], substr($ifd, 8, 4));
|
---|
58 | } elsif ($tag == 0x0101) { # ImageLength (y)
|
---|
59 | # Decode the value
|
---|
60 | $y = unpack($packspec[$type], substr($ifd, 8, 4));
|
---|
61 | }
|
---|
62 | }
|
---|
63 |
|
---|
64 | # Decide if we were successful or not
|
---|
65 | if (defined($x) && defined($y)) {
|
---|
66 | $id = 'TIF';
|
---|
67 | } else {
|
---|
68 | $id = '';
|
---|
69 | $id = 'ImageWidth ' if (!defined($x));
|
---|
70 | if (!defined ($y)) {
|
---|
71 | $id .= 'and ' if ($id ne '');
|
---|
72 | $id .= 'ImageLength ';
|
---|
73 | }
|
---|
74 | $id .= 'tag(s) could not be found';
|
---|
75 | }
|
---|
76 |
|
---|
77 | ($x, $y, $id);
|
---|
78 | }
|
---|
79 |
|
---|
80 | # end of Image::Size::tiffsize
|
---|
81 | 1;
|
---|