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