Help with unpack

Help with unpack

am 10.10.2009 01:05:16 von Barry Brevik

I am writing an app which, at a certain point, needs to read a .PNG
graphics file.

The .PNG file is always small, so I read the whole file (binmode) into a
scalar, and this works well.

if ($gfilesize = -s $gfilespec)
{
$GRAPHFILE = "<$gfilespec";
if (open GRAPHFILE)
{
binmode GRAPHFILE;
read GRAPHFILE, $gbuffer, $gfilesize;
close GRAPHFILE;

The size of the file ($gfilesize) matches the size of the scalar
($gbuffer). This is good.

Then I proceed to paw through the buffer. The 1st 8 bytes of the file is
a signature, which I read and deal with. Then, the file is a series of
chunks where the 1st 4 bytes is a 32 bit number representing the size of
the chunk, and the 2nd 4 bytes is an ASCII "chunk name", such as "IHDR".

So, after the signature, the next 8 bytes look like this:

00 00 00 0d 49 48 44 52 . . . . I H D R

I am trying to decode this with the following:

$bufptr = 8;
($chunksize, $chunkname) = unpack "L a4", substr($gbuffer, $bufptr,
8);

Actually, I've tried every permutation of "unpack" template that I can
think of.

The problem is that the 2nd scalar ($chunkname) comes out fine as
"IHDR", but the first scalar comes out as "218103808" which is wrong as
you can see above, it should be "13".

I thought I was starting to understand unpack, but what am I doing
wrong??

Barry Brevik
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Re: Help with unpack

am 10.10.2009 01:16:01 von Michael Ellery

Have you tried reading it as BigEndian (using the N template)? It kinda
looks like BigEndian to me, but I get easily turned around by endianness...

-Mike

Barry Brevik wrote:
> I am writing an app which, at a certain point, needs to read a .PNG
> graphics file.
>
> The .PNG file is always small, so I read the whole file (binmode) into a
> scalar, and this works well.
>
> if ($gfilesize = -s $gfilespec)
> {
> $GRAPHFILE = "<$gfilespec";
> if (open GRAPHFILE)
> {
> binmode GRAPHFILE;
> read GRAPHFILE, $gbuffer, $gfilesize;
> close GRAPHFILE;
>
> The size of the file ($gfilesize) matches the size of the scalar
> ($gbuffer). This is good.
>
> Then I proceed to paw through the buffer. The 1st 8 bytes of the file is
> a signature, which I read and deal with. Then, the file is a series of
> chunks where the 1st 4 bytes is a 32 bit number representing the size of
> the chunk, and the 2nd 4 bytes is an ASCII "chunk name", such as "IHDR".
>
> So, after the signature, the next 8 bytes look like this:
>
> 00 00 00 0d 49 48 44 52 . . . . I H D R
>
> I am trying to decode this with the following:
>
> $bufptr = 8;
> ($chunksize, $chunkname) = unpack "L a4", substr($gbuffer, $bufptr,
> 8);
>
> Actually, I've tried every permutation of "unpack" template that I can
> think of.
>
> The problem is that the 2nd scalar ($chunkname) comes out fine as
> "IHDR", but the first scalar comes out as "218103808" which is wrong as
> you can see above, it should be "13".
>
> I thought I was starting to understand unpack, but what am I doing
> wrong??
>
> Barry Brevik
> _______________________________________________
> ActivePerl mailing list
> ActivePerl@listserv.ActiveState.com
> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
>

_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Re: Help with unpack

am 10.10.2009 01:59:03 von Bill Luebkert

Michael Ellery wrote:
> Have you tried reading it as BigEndian (using the N template)? It kinda
> looks like BigEndian to me, but I get easily turned around by endianness...

N is for Network byte order (big endian) and most PCs are little endian,
so you probably have him on the right track. He needs to reverse the bytes
in the unpack. "NA4" should hack it.

You can always get around it even when you don't have the N option, by
unpacking into a byte array and forming the longword yourself by
shifting and or'ing or multiplying and adding the bytes yourself.

>> So, after the signature, the next 8 bytes look like this:
>>
>> 00 00 00 0d 49 48 44 52 . . . . I H D R
>>
>> I am trying to decode this with the following:
>>
>> $bufptr = 8;
>> ($chunksize, $chunkname) = unpack "L a4", substr($gbuffer, $bufptr,
>> 8);
>>
>> Actually, I've tried every permutation of "unpack" template that I can
>> think of.
>>
>> The problem is that the 2nd scalar ($chunkname) comes out fine as
>> "IHDR", but the first scalar comes out as "218103808" which is wrong as
>> you can see above, it should be "13".
_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Re: Help with unpack

am 10.10.2009 02:15:50 von jwkenne

On Oct 9, 2009, at 7:16 PM, Michael Ellery wrote:
Have you tried reading it as BigEndian (using the N template)? It kinda
> looks like BigEndian to me, but I get easily turned around by =

> endianness...

That's the answer. 218103808 is decimal for hex 0x0d000000, which is =

what you get when you look at you interpret 0x0000000d as little- =

endian, instead of big-endian.

-- =

John W Kennedy
"The pathetic hope that the White House will turn a Caligula into a =

Marcus Aurelius is as na=EFve as the fear that ultimate power inevitably =

corrupts."
-- James D. Barber (1930-2004)



_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

RE: Help with unpack

am 12.10.2009 11:58:42 von Brian Raven

Barry Brevik <> wrote:
> I am writing an app which, at a certain point, needs to read a .PNG
> graphics file.

Your unpack question having been ably answered by others, I just thought
to ask whether you had considered using any of the existing modules that
understand png files, if it is image meta data that you are after? For
example Image::Info or Image::ExifTool.

HTH

--
Brian Raven
This e-mail may contain confidential and/or privileged information. If you are not the intended recipient or have received this e-mail in error, please advise the sender immediately by reply e-mail and delete this message and any attachments without retaining a copy.

Any unauthorised copying, disclosure or distribution of the material in this e-mail is strictly forbidden.

_______________________________________________
ActivePerl mailing list
ActivePerl@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs