SPUG: pack and unpack

Richard Wood wildwood_players at yahoo.com
Wed Aug 27 13:47:39 CDT 2003


I thought I would try this again without the reference
to graphics which I hope is why only one person
responded.  I am familiar with and use both
ImageMagick and GIMP.  That is not what I need. 
Surely there are many pack/unpack experts out there in
SPUG-land.

I am trying to process (read and interpret) binary
files.  These files can be big-endian or
little-endian, based on a header record. The files I
am reading are big-endian.

The format of the records that I am trying to read
are:

 12 - 8-bit bytes (line feeds introduced for clarity)

|--------|--------|
| 2-byte tag      |

|--------|--------|
| 2-byte type     |

|--------|--------|--------|--------|
| 4-byte count                      |

|--------|--------|--------|--------|
| 4-byte value or offset            |

I read in 12 bytes, check the "type" then try to
convert the "value" to something I can use like ascii
characters or numbers.  I am not having much luck with
the ascii.  I have never used pack or unpack before
and I clearly need help.

If the "type" is ASCII and the "count" is less than 4,
the last 4 bytes should be ascii characters, otherwise
it is an offset into the file.  I read the 12 bytes
into $buffer like this:

    seek(TIF, $offset, 0) or die "Seek $i: $!\n";
    read(TIF, $buffer, 12);

Now that I have 12 bytes of binary data in my buffer,
can someone give me a couple of examples on how
to get meaningful data out of the value field?

I am able to get the tag, type, count values using an
unpack to separate the bytes then another unpack to
convert to decimal but I suspect that is not the most
efficient method.  I am not sure how to get meaningful
data out of the ascii.

($tagB, $typeB, $countB, $val1B, $val2B, $val3B,
$val4B) = unpack "B16B16B32B8B8B8B8", $buffer;
$tagC = bin2dec($tagB);
$typeC = bin2dec($typeB);
$countC = bin2dec($countB);

sub bin2dec {
    return unpack("N", pack("B32", substr("0" x 32 .
shift, -32)));
}

Details of the expected data:

The tag is a number that corresponds to a tag name,
things like:

256 = ImageWidth
257 = ImageLength
259 = Compression
306 = DateTime
270 = ImageDescription

The type is a number that describes the what is
contained in the value field:

1 = BYTE	8-bit unsigned integer
2 = ASCII	8-bit byte that contains a 7-bit ASCII code;
the last byte is NUL (binary zero)
3 = SHORT	16-bit unsigned integer
4 = LONG	32-bit unsigned integer
5 = RATIONAL	Two LONGs: first represents numerator,
second denominator
6 = SBYTE	8-bit unsigned integer
7 = UNDEFINED	8-bit byte that may contain anything
depending upon the tag
8 = SSHORT	16-bit signed integer
9 = SLONG	16-bit signed integer
10 = SRATIONAL	Two SLONGs: first represents numerator,
second denominator
11 = FLOAT	Single precision (4-byte) IEEE format
12 = DOUBLE	Double precision (8-byte) IEEE format

Regards,

Rich Wood


=====
Richard O. Wood
Wildwood IT Consultants, Inc.
wildwood_players at yahoo.com
425.281.1914 mobile
206.544.9885 desk

__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com



More information about the spug-list mailing list