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