Difference between revisions of "LazPaint LZP Format"
(→File header: formatting) |
(→Global structure: formatting) |
||
Line 9: | Line 9: | ||
The file is composed of: | The file is composed of: | ||
− | - | + | Offset Content |
− | + | ------ -------------------- | |
− | + | 0 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. | 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. |
Revision as of 02:22, 17 March 2015
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:
Offset Content ------ -------------------- 0 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
Offset Size Name Content ------ ---- ------------------ ------------------------ 0 8 magic Always contains the string 'LazPaint' 8 4 zero1 Contains the number 0 12 4 headerSize Size of this header 16 4 width Width of the image canvas 20 4 height Height of the image canvas 24 4 nbLayers Number of layers 28 4 previewOffset Offset (from the beginning of the file) of the flattened image 32 4 zero2 Contains the number 0 36 4 compressionMode Contains flags indicating the compression and the presence of a thumbnail 40 4 reserved1 Reserved for future use. Set to 0. 44 4 layersOffset Offset (from the beginning of the file) of the layer structure
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 48.
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.
layersOffset can be 0, in which case the image is flat and that there is no layer description.
Compression
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.
Thumbnail
Its presence is optional and determined by the flag $100 of compressionMode.
Currently, it is a PNG file embedded directly after the header. It is provided as a way to facilitate quick preview.
PNG format is widespread so it is easy to implement a browser that would display the thumbnail. To do so, check that the header contains magic and that the flag for the thumbnail is set in compressionMode. Then jump to the end of the header using headerSize. Then read the PNG file.
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. Of course if the image is smaller than 128 then the thumbnail will be smaller than 128.
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)
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)