LazPaint LZP Format

From Lazarus wiki
Revision as of 00:01, 17 March 2015 by Circular (talk | contribs) (→‎ZStream: concat)
Jump to navigationJump to search

LZP File format specification

The default encoding for numbers is little endian. So the hexadecimal number $12345678 would be stored as the sequence of bytes 78 56 34 12.

Pascal convention is used in this document for hexadecimal numbers, so for example $10 means 16.

Global structure

The file is composed of:

- file header

- thumbnail (optional)

- flat image

- layer structure (optional)


Note: some old formats do not have a header and start directly with the flat image. Image readers may discard those files. However for your information, in this case, images are always stored with ZStream compression and the size of the image is deduced from the size of the flat image.

File header

 TLazPaintImageHeader = packed record
   magic: packed array[0..7] of char;
   zero1, headerSize: DWord;
   width, height, nbLayers, previewOffset: DWord;
   zero2, compressionMode, reserved1, layersOffset: DWord;
 end;

magic contains the string 'LazPaint'.

zero1 and zero2 must be equal to 0.

headerSize contains the size of this header. An image reader must read this to know which fields are available. It must be greater or equal to $30.

width and height are the dimension of the canvas. There is no real limitation for these numbers however it is recommended to keep it under or equal to 8192.

nbLayers is the number of layers. The minimum is 1. There is no real limitation however it is recommended to keep it under or equal to 99.

previewOffset is the address (from the beginning of the file) of the flattened image.

compressionMode contains flags indicating the compression and the presence of a thumbnail.

The low order byte indicates the compression of the image. It is the value (compressionMode and $ff):

- $01 indicates ZStream compression

- $02 indicates RLE compression

The following flags can be defined:

- $100 indicates that there is thumbnail in PNG format; check with (compressionMode and $100) <> 0

If there is a thumbnail, it is directly after the header. The reader should read headerSize to have the correct location.

reserved1 is reserved for future use and is equal to 0 in current version.

layersOffset is the address (from the beginning of the file) of the layer structure. If it is equal to 0, it means that the image is flat and that there is no layer description.

Thumbnail

Currently, it is a PNG file embedded directly after the header. It is only provided as a way to facilitate quick preview. Its presence is optional.

There is no real limitation but the recommended size for the thumbnail is 128 along the largest dimension. The other dimension may be smaller if the image is not a square.

Images

This applies for both the flat image and for the images in the layer structure.

There are two possible compressions. Both are lossless i.e. there is no loss of quality.

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.

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)