Skip to contents

A very simplistic lossless routine to (un)pack repetitive bitmap data. Often used in InterLeaved BitMap (ILBM) images in IFF containers (IFFChunk()).

Usage

packBitmap(x)

unPackBitmap(x)

Arguments

x

raw data, usually representing a (packed) bitmap.

Value

Returns packed or unpacked raw data, depending on whether packBitmap or unPackBitmap was called.

Details

InterLeaved BitMap (ILBM) images on the Amiga often use a packing algorithm referred to as `ByteRun1'. This routine was introduced first on the Macintosh where it was called PackBits. It is a form of run-length encoding and is very simple: when a specific byte is repeated in a bitmap, it is replaced by a (signed negative) byte telling how many times the following byte should be repeated. When a series of bytes are not repetitive, it is preceded by a (signed positive) byte telling how long the non repetitive part is.

Not very complicated, but for most images some bytes can be shaved off the file. This was very useful when everything had to be stored on 880 kilobyte floppy disks with little CPU time to spare. Note that the file size can also increase for (noisy) images.

This packing routine will pack the entire bitmap (x) at once. The IFF file format requires packing of bitmap data per scanline. This is done automatically by the rasterToIFF() function, which calls this packing routine per scanline.

Author

Pepijn de Vries

Examples

## generate some random raw data:
dat.rnd <- as.raw(sample.int(10, 100, TRUE))

## try to pack it:
pack.rnd <- packBitmap(dat.rnd)

## due to the random nature of the source data
## the data could not be packed efficiently.
## The length of the packed data is close to
## the length of the original data:
length(pack.rnd) - length(dat.rnd)
#> [1] 1

## Now generate similar data but sort it
## to generate more repetitive data:
dat.srt  <- as.raw(sort(sample.int(10, 100, TRUE)))
pack.srt <- packBitmap(dat.srt)

## This time the packing routing is more successful:
length(pack.srt) - length(dat.srt)
#> [1] -80

## The original data can always be obtained
## from the packed data:
all(dat.rnd == unPackBitmap(pack.rnd))
#> [1] TRUE
all(dat.srt == unPackBitmap(pack.srt))
#> [1] TRUE