SPUG: pack and unpack of binary raster graphic files
Richard Wood
wildwood_players at yahoo.com
Fri Aug 22 11:02:06 CDT 2003
I hope this email is readable, I wrote it in notepad
then pasted it in.
I am trying to process (read and interpret) TIFF
(raster graphics) files which are binary.
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
|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|
| 2-byte tag | 2-byte type | 4-byte count
| 4-byte value or offset |
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
I read in 12 bytes, check the "type" then try to
convert it 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, 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)));
}
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