LazPaint LZP Format Single Image
This description applies for both the flat image and for the images in the layer structure of LZP file format.
There are two possible compressions. Both are lossless i.e. there is no loss of quality.
If a file is saved in this format without any header, it uses ZStream compression.
ZStream
The image has a defined width and height. There is a rectangular area for its content. Pixels that are outside of this area are transparent (all channels equal to zero).
The content is compressed in any number of chunks. The uncompressed data must then be concatenated regardless of where scanlines start or end.
The header of the ZStream image is as follows:
Offset Size Content ------ ---- ---------------------------- 0 4 Width 4 4 Height 8 4 Length of the caption (N) 12 N Caption (UTF8 encoded) 12+N 4 Left bound of the content 16+N 4 Top bound of the content 20+N 4 Right bound of the content 24+N 4 Bottom bound of the content 28+N 4 Line order (0: top to bottom, 1: bottom to top) 32+N 4 Number of chunks
The content contains the lines in the rectangular area, following the specified line order. Each line contains all pixels in BGRA 32-bit format, i.e. 1 byte for each channel and the order of the channels being blue, green, red, alpha.
The chunks follow directly the header. Here is the structure for one chunk:
Offset Size Content ------ ---- ---------------------------- 0 4 Size of the compressed data in the chunk (M) 4 M Compressed data using ZStream (without ZStream header)
RLE
The header of the RLE image is as follows:
Offset Size Content ------ ---- ---------------------------- 0 4 Width 4 4 Height 8 4 Length of the caption (N) 12 N Caption (UTF8 encoded) 12+N 1 Plane flags
The following plane flags are defined:
- $01: the green channel is a copy of the red channel
- $02: the blue channel is a copy of the red channel
- $04: the blue channel is a copy of the green channel
- $08: there is no alpha channel (the image is opaque)
- $16: there is an RGB palette
There is then a variable number of RLE streams.
RLE stream
The structure of one RLE stream is as follows:
Offset Size Content ------ ---- ---------------------------- 0 4 Size of the compressed data (P) 4 P Compressed data
The data is a series of unpacking instructions. Each element of the instruction is a one byte value.
Special instructions:
Sequence Meaning -------------------------- --------------------------------------------------------------- $C1 Reserved (the reader must stop and say the format is not supported) $C2 Reserved (the reader must stop and say the format is not supported) $E0 Ends of stream $E1 Reserved (the reader must stop and say the format is not supported) $FF The reader must ignore and continue to read
Big repetitions instructions:
Sequence Meaning -------------------------- --------------------------------------------------------------- $00 Hi Lo Val Repeats (Hi*256 + Lo) times the value Val $80 Val Repeats the value Val the same number of times that in the previous $00 instruction $40 Count Val Repeats (Count+64) times the value Val $C0 Val Repeats the value Val the same number of times that in the previous $40 instruction
Small repetitions:
Sequence Meaning -------------------------- --------------------------------------------------------------- $01..$3f Val Repeats Val, the number of times being the value of the instruction ($01..$3f) $40+n (n = 1..31) Uncompress n group of packed repetition (see below) $60+n (n = 1..16) Repeats (n+1) times the value 0 $70+n (n = 1..16) Repeats (n+1) times the value 255
Dump:
Sequence Meaning -------------------------- --------------------------------------------------------------- $81 Count The next (Count+64) bytes are copied as they are $80+n (n = 2..63) The next n bytes are copied as they are $C0+n Val (n = 3..15) The next (n-1)/2 bytes must be unpacked to yield n uncompressed bytes (see below)