The . point is quite valid and cured by a /s. Here is my take which first gets the file type sig then does the deed. As you can see for GIF, and BMP the size info is a set number of bytes from the SOF. This is set down in the spec so there is no reason this should not be very reliable. Similarly the PNG spec has the 'IHDR' sequence denoting the start of the header. In all the PNGs I have seen this sequence is 12 bytes from the SOF but as this does not appear formally in the spec just grabbing the first IHDR seems pretty reasonable to me.
With JPEG the SOFn sig \xFF\xC0 is followed 3 bytes later (2 for length, 1 for precison) by the size info. 0xFF is the SOF marker and 0xC0 is the (n) baseline marker. This 2 byte sequence should not appear in the header so that should not be a problem. A ?real problem is the ability to embed a thumbnail so you have 2 SOFn sections (one is the thumbnail, the next the image) - with this simplistic approach you will get the first dimension (possibly the thumbnail size not the main image size). Other than that caveat I don't see why this should not be a reliable approach given that all the format specs are set down.
#!/usr/bin/perl -w use strict; sub image_size { return unless $_[0]; my ($width, $height, $sig); if ( $_[0] =~ m/^GIF8..(....)/s ) { $sig = 'GIF'; # found GIF signature ($width, $height) = unpack( "SS", $1 ); } elsif ( $_[0] =~ m/^^\xFF\xD8.{4}JFIF/s ) { $sig = 'JPEG'; # found JPG signature ($height,$width) = unpack( "nn", $1 ) if $_[0] =~ /\xFF\xC0... +(....)/s; } elsif ( $_[0] =~ /^\x89PNG\x0d\x0a\x1a\x0a/ ) { $sig = 'PNG'; # found PNG signature ($width, $height) = unpack( "NN", $1 ) if $_[0] =~ /IHDR(.{8}) +/s; } elsif ( $_[0] =~ /BM.{16}(.{8})/s ) { $sig = 'BMP'; # found bitmap sig ($width, $height) = unpack( "LL", $1); } return $width, $height, $sig; } sub get_file { open FILE, $_[0] or die $!; binmode FILE; local $/; my $data = <FILE>; close FILE; return $data; } for my $img ( qw( c:/sample.bmp c:/sample.jpg c:/sample.gif c:/sample. +png) ) { my $data = get_file($img); my @res = image_size($data); print "$img $res[2] width $res[0] height $res[1]\n"; } __END__ c:/sample.bmp BMP width 512 height 384 c:/sample.jpg JPEG width 100 height 149 c:/sample.gif GIF width 110 height 58 c:/sample.png PNG width 256 height 192
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
In reply to Re: Re: Image size in pure perl
by tachyon
in thread Image size in pure perl
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |