|This article does not cite any references (sources). (October 2011)|
Apple introduced the PackBits format with the release of MacPaint on the Macintosh computer. This compression scheme is one of the types of compression that can be used in TIFF-files. TGA-files also use this RLE compression scheme, but treats data stream as pixels instead of bytes.
A PackBits data stream consists of packets with a one-byte header followed by data. The header is a signed byte; the data can be signed, unsigned, or packed (such as MacPaint pixels).
In the following table, n is the value of the header byte as a signed integer.
|Header byte||Data following the header byte|
|0 to 127||(1 + n) literal bytes of data|
|-1 to -127||One byte of data, repeated (1 – n) times in the decompressed output|
|-128||No operation (skip and treat next byte as a header byte)|
Note that interpreting 0 as positive or negative makes no difference in the output. Runs of two bytes adjacent to non-runs are typically written as literal data. It should also be noted that there is no way based on the PackBits data to determine the end of the data stream; that is to say, one must already know the size of the compressed or uncompressed data before reading a PackBits data stream to know where it ends.
Apple Computer (see the external link) provides this short example of packed data:
FE AA 02 80 00 2A FD AA 03 80 00 2A 22 F7 AA
The following code, written in Microsoft VBA, unpacks the data:
Sub UnpackBitsDemo() Dim File As Variant Dim MyOutput As String Dim Count As Long Dim i As Long, j As Long File = "FE AA 02 80 00 2A FD AA 03 80 00 2A 22 F7 AA" File = Split(File, " ") For i = LBound(File) To UBound(File) Count = Application.WorksheetFunction.Hex2Dec(File(i)) Select Case Count Case Is >= 128 Count = 256 - Count 'Two's Complement For j = 0 To Count 'zero-based MyOutput = MyOutput & File(i + 1) & " " Next j i = i + 1 'Adjust the pointer Case Else For j = 0 To Count 'zero-based MyOutput = MyOutput & File(i + j + 1) & " " Next j i = i + j 'Adjust the pointer End Select Next i Debug.Print MyOutput 'AA AA AA 80 00 2A AA AA AA AA 80 00 2A 22 AA AA AA AA AA AA AA AA AA AA' End Sub