The Planar RGB codec is used to compress frames in MOV files. It is a simple codec that stores frames in RGB format (24 bit or paletted), in planar format (first all red samples, then the green ones and finally the blue), using an RLE algorithm. Each chunk of data encodes a single frame.

The format allows encoding of lines shorter than image width and can do a partial update of the frame. Please note that none of my samples use this trick, and all frames in the file are key frames. I don't know if the original QT decoder would accept short lines; the codec was probably designed to be intra only.

Contents

Data Format

Frames are rendered from left to right, top to bottom. The number of planes in the image depends on the colorspace:

RGB8 has one plane containing palette indices

RGB24 has 3 planes

RGB32 has 4 (the 4th plane is probalby alpha channel)

If the image format is RGB8, the palette is stored in the ImageDescription atom in the encapsulating QuickTime video trak's stsd atom.

Frame Structure

Every compressed frame can be split in two sections: The line lengths and the pixel data. All line lengths are grouped at the beginning of the compressed frame, one set for each plane. The compressed pixel data follows them.

The first set is for red plane (or palette indexes if format is RGB8). If colorspace is RGB24 or RGB32, there is a second set used for green pixels, and a third set for blue pixels. For RGB32 data, there is a fourth set used for the 4th plane of data (probably an alpha channel).

Line Lengths

Each line length is a 2-byte value that represents the size of the compressed data for that line. The values are stored from top to bottom, starting with top line. The size of each line length set is 2*image_height bytes. Sets are stored in the same order as planes.

So, line lengths for blue plane for RGB32 format starts after 2*(2*image_height) bytes from the beginning of the compressed frame. The compressed pixel data, stored after line lengths, starts at offset
4*(2*image_height) into the compressed frame.

Line Decompression

To decompress each line, follow this simple algorithm:

repeat until all compressed data for this line is decoded
get a byte, and call it counter
if counter is <= 127
copy counter bytes from compressed data to output plane
else
get a byte, and call it value
store value into output plane for (257 - counter) times

Frame Decompression

Follow this algorithm:

build compressed data pointer
for each plane
build line length set pointer
for each line
get compressed line length
decompress line

Then, if needed, the decoder can reassemble the planes to build a standard packed-data RGB frame.

Final Notes

I never encountered a file coded in RGB32 colorspace, so this data format is not verified. The format allows you to encode lines shorter than image width. In that case, the decoder should keep values from previous frame for non-coded pixel. Please note that I didn't check if short lines really exist in encoded files.