in reply to Re: getting the dimensions of a picture (jpeg)
in thread getting the dimensions of a picture (jpeg)

As side notes:
#!/usr/bin/perl -w use strict;
Notice that nowadays (unless you have serious backward compatibility issues) it is recommended to
use warnings;
instead. Since when I made a similar remark somebody popped out asking why I thought the latter was a better alternative, I'll point out in advance that no, I'm not explaining it. perldoc warnings and perldoc perlrun give some clues about it.
my $jpg = shift or die "$!\n";
Huh?!? $! is meaningful only after a failure of a system call (well, "system library"). At this point it may be anything...
my $data = get_file($jpg); my @res = sizeJPG($data); print "$jpg width $res[0] height $res[1]\n";
Please, do not misunderstand me: I know that this is a minimal example, but why do you put the return values of your sub into an array only to later use its entries separately? I.e., wouldn't have
my $data = get_file($jpg); my ($h,$v) = sizeJPG($data); print "$jpg width $h height $v\n";
been clearer?

Also, in case the regex below is not matched, the return values will be undef, and this will issue a warning in the print statement above. And if you locally disable 'uninitialized' warnings, then you'll get an IMHO inconsistent output. You may want to treat this case in a different way...

sub sizeJPG { return unless $_[0]; my ( $width, $height ); ( $height, $width ) = unpack( "nn", $1 ) if $_[0] =~ /\xFF\xC0...(....)/; return ( $width, $height ); }
I like to do
local $_=shift;
if possible, but that's just a personal preference.

As a general remark you can also use the return value of the match operator, but indeed in this case it can be slightly awkward:

my ($width,$height)=unpack "nn", (/\xFF\xC0...(....)/)[0];
and it will also issue a warning if the regex is not matched. So a possibly better solution may be:
my ($width,$height)=unpack "nn", /\xFF\xC0...(....)/ ? $1 : ''; # or "\0" x 4, maybe?
Let's go on...
sub get_file { open FILE, $_[0] or die $!; binmode FILE; local $/; my $data = <FILE>; close FILE; return $data; }
Why not
sub get_file { local $/; open my $fh, '<:raw', shift or die $!; <$fh>; }
instead?

(But then I'd probably use a do block. In the meantime we continue to wait for Perl6's .slurp!!)

Replies are listed 'Best First'.
Re^3: getting the dimensions of a picture (jpeg)
by zentara (Cardinal) on Feb 17, 2005 at 13:37 UTC
    All good points. I was just in a hurry, and saw I had an old snippet which showed it. Last night I realized it could also probably be sped up too, since it prints on each pixel. It probably could be re-written to process chunks at a time, and even regexed chunks at a time. The only problem is making sure the chunk boundaries are on pixel boundaries, so you don't break up the pixel-triples.

    I'm not really a human, but I play one on earth. flash japh
Re^3: getting the dimensions of a picture (jpeg)
by squirrel448 (Initiate) on Jun 10, 2008 at 18:51 UTC
    I'm trying to play around with all this code you've posted but I can't seem to get past the original script's line 18-- "No such file or directory; it's also got a syntax error, "my $data = ;" crashes the script. Any way all these snippets can be squished together to make a usable script? Replacing that 'shift or die' thing at the top with 'picture.jpg' doesn't run as smoothly as I'd like it to :(