sub _getJpegDimensions { my $path = shift; # read first 100kb - this should be enough to get the SOF section. open my $fh, '<', $path; read $fh, my $data, 102400; close $fh; my @chars = split("", $data); my @asciis = map { ord() } @chars; # convert all chars to ascii values # jpg images start with xff xd8, so check this first and remove if found if ((shift @asciis == 0xff) and (shift @asciis == 0xd8)) { # loop through each section until the SOF section is found while(@asciis) { my $val = shift @asciis; # check if $val is possibly the start of a marker (all markers are 0xffXX) if ( $val != 0xff ) { next; } else { $val = shift @asciis; # Start of frame marker is usually 0xffc0 # check for c0 to c3 to include extended sequential, progressive and lossless markers if (($val >= 0xc0) and ($val <= 0xc3)) { # SOF block is [0xffc0][ushort length][uchar precision][ushort x][ushort y] # [0xffc0][ 2 Bytes ][ 1 Byte ][2 Bytes ][2 Bytes ] # note that x is height, y is width my $width = ($asciis[5] * 256) + $asciis[6]; # convert the 2 byte ushort into a decimal number my $height = ($asciis[3] * 256) + $asciis[4]; return ($width, $height); } else { # if this isnt an SOF section, skip the rest # section length is immediately after marker # section length includes marker, hence why 2 is subtracted my $section_length = shift @asciis; if ($section_length - 2 > 0) { splice @asciis, 0, $section_length - 2; } } } } } else { return (0,0); } }