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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.