Sign in Join
Wiki copytemporary

LazPaint LZP Format Single Image: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11This description applies for both the flat image and for the images in the layer structure of [[LazPaint LZP Format|LZP file format]].
22
33There are two possible compressions. Both are lossless i.e. there is no loss of quality.
44
55If a file is saved in this format without any header, it uses ZStream compression. But in general LazPaint uses RLE compression here.
66
77#### ZStream
88
99The 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).
1010
1111The content is compressed in any number of chunks. The uncompressed data must then be concatenated regardless of where scanlines start or end.
1212
1313The header of the ZStream image is as follows:
1414
15-`Offset  Size  Content`\
16-`------  ----  ----------------------------`\
17-`0       4     Width`\
18-`4       4     Height`\
19-`8       4     Length of the caption (N)`\
20-`12      N     Caption (UTF8 encoded)`\
21-`12+N    4     Left bound of the content`\
22-`16+N    4     Top bound of the content`\
23-`20+N    4     Right bound of the content`\
24-`24+N    4     Bottom bound of the content`\
25-`28+N    4     Line order (0: top to bottom, 1: bottom to top)`\
26-`32+N    4     Number of chunks`
15+```text
16+Offset Size Content
17+------ ---- ----------------------------
18+0 4 Width
19+4 4 Height
20+8 4 Length of the caption (N)
21+12 N Caption (UTF8 encoded)
22+12+N 4 Left bound of the content
23+16+N 4 Top bound of the content
24+20+N 4 Right bound of the content
25+24+N 4 Bottom bound of the content
26+28+N 4 Line order (0: top to bottom, 1: bottom to top)
27+32+N 4 Number of chunks
28+```
2729
2830The 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.
2931
3032The chunks follow directly the header. Here is the structure for one chunk:
3133
32-`Offset  Size  Content`\
33-`------  ----  ----------------------------`\
34-`0       4     Size of the compressed data in the chunk (M)`\
35-`4       M     Compressed data using ZStream (without ZStream header)`
34+```text
35+Offset Size Content
36+------ ---- ----------------------------
37+0 4 Size of the compressed data in the chunk (M)
38+4 M Compressed data using ZStream (without ZStream header)
39+```
3640
3741#### RLE
3842
3943The header of the RLE image is as follows:
4044
41-`Offset  Size  Content`\
42-`------  ----  ----------------------------`\
43-`0       4     Width`\
44-`4       4     Height`\
45-`8       4     Length of the caption (N)`\
46-`12      N     Caption (UTF8 encoded)`\
47-`12+N    1     Plane flags`
45+```text
46+Offset Size Content
47+------ ---- ----------------------------
48+0 4 Width
49+4 4 Height
50+8 4 Length of the caption (N)
51+12 N Caption (UTF8 encoded)
52+12+N 1 Plane flags
53+```
4854
4955The following plane flags are defined:
5056
5157\- \$01: the green channel is a copy of the red channel
5258
5359\- \$02: the blue channel is a copy of the red channel
5460
5561\- \$04: the blue channel is a copy of the green channel
5662
5763\- \$08: there is no alpha channel (the image is opaque)
5864
5965\- \$10: there is a palette and colors are expressed as indices in this palette
6066
6167There is then a variable number of RLE streams. The pixels are scanned from top to bottom and from left to right.
6268
6369##### Full RLE structure for empty images
6470
6571If the image is completely transparent, there are no stream for color channels.
6672
67-`Offset  Size  Content`\
68-`------  ----  -------------------------`\
69-`0       13+N  Header`\
70-`13+N    ?     Alpha channel stream`
73+```text
74+Offset Size Content
75+------ ---- -------------------------
76+0 13+N Header
77+13+N ? Alpha channel stream
78+```
7179
7280The uncompressed stream for the alpha channel contains one byte for each pixel of the canvas. 0 means the pixel is transparent and 255 means opaque. Because the image is empty, it contains only zeros.
7381
7482##### Full RLE structure for non paletted images
7583
76-`Offset  Size  Content`\
77-`------  ----  -------------------------`\
78-`0       13+N  Header`\
79-`13+N    ?     Alpha channel stream (optional)`\
80-`?       ?     Red channel stream`\
81-`?       ?     Green channel stream (optional)`\
82-`?       ?     Blue channel stream (optional)`
84+```text
85+Offset Size Content
86+------ ---- -------------------------
87+0 13+N Header
88+13+N ? Alpha channel stream (optional)
89+? ? Red channel stream
90+? ? Green channel stream (optional)
91+? ? Blue channel stream (optional)
92+```
8393
8494Alpha channel is not present if \$08 flag is used. Otherwise the uncompressed stream contains one byte for each pixel of the canvas. 0 means the pixel is transparent and 255 means opaque.
8595
8696The uncompressed stream for the red channel contains one byte for each **non-transparent** pixel.
8797
8898Green channel is not present if \$01 flag is used. Otherwise the uncompressed stream contains one byte for each **non-transparent** pixel.
8999
90100Blue channel is not present if \$02 or \$04 flag is used. Otherwise the uncompressed stream contains one byte for each **non-transparent** pixel.
91101
92102##### Full RLE structure for paletted images
93103
94-`Offset  Size  Content`\
95-`------  ----  -------------------------`\
96-`0       13+N  Header`\
97-`13+N    ?     Alpha channel stream (optional)`\
98-`?       ?     Red channel palette stream`\
99-`?       ?     Green channel palette stream (optional)`\
100-`?       ?     Blue channel palette stream (optional)`\
101-`?       ?     Indexed color stream`
104+```text
105+Offset Size Content
106+------ ---- -------------------------
107+0 13+N Header
108+13+N ? Alpha channel stream (optional)
109+? ? Red channel palette stream
110+? ? Green channel palette stream (optional)
111+? ? Blue channel palette stream (optional)
112+? ? Indexed color stream
113+```
102114
103115Alpha channel is not present if \$08 flag is used. Otherwise the uncompressed stream contains one byte for each pixel of the canvas. 0 means the pixel is transparent and 255 means opaque.
104116
105117Each channel palette stream contains a maximum of 256 uncompressed bytes. The streams may be shorter and in that case, the rest is padded with zeros. The position in the uncompressed stream is the color index.
106118
107119The uncompressed stream for the red channel contains one byte for each entry of the palette. It is padded with zeros to make 256 bytes.
108120
109121Green channel palette is not present if \$01 flag is used. Otherwise the stream contains the green values for the palette.
110122
111123Blue channel palette is not present if \$02 or \$04 flag is used. Otherwise the stream contains the blue values for the palette.
112124
113125The uncompressed indexed color stream contains one byte for each **non-transparent** pixel, that is the index into the palette.
114126
115127##### RLE stream
116128
117129The structure of one RLE stream is as follows:
118130
119-`Offset  Size  Content`\
120-`------  ----  ----------------------------`\
121-`0       4     Size of the compressed data (P)`\
122-`4       P     Compressed data`
131+```text
132+Offset Size Content
133+------ ---- ----------------------------
134+0 4 Size of the compressed data (P)
135+4 P Compressed data
136+```
123137
124138The data is a series of unpacking instructions. Each element of the instruction is a one byte value.
125139
126140Special instructions:
127141
128-`Sequence                    Meaning`\
129-`--------------------------  ---------------------------------------------------------------`\
130-`$C1                         Reserved (the reader must stop and say the format is not supported)`\
131-`$C2                         Reserved (the reader must stop and say the format is not supported)`\
132-`$E0                         Ends of stream`\
133-`$E1                         Reserved (the reader must stop and say the format is not supported)`\
134-`$FF                         The reader must ignore and continue to read`
142+```text
143+Sequence Meaning
144+-------------------------- ---------------------------------------------------------------
145+$C1 Reserved (the reader must stop and say the format is not supported)
146+$C2 Reserved (the reader must stop and say the format is not supported)
147+$E0 Ends of stream
148+$E1 Reserved (the reader must stop and say the format is not supported)
149+$FF The reader must ignore and continue to read
150+```
135151
136152Big repetitions instructions:
137153
138-`Sequence                    Meaning`\
139-`--------------------------  ---------------------------------------------------------------`\
140-`$00 `*`Hi`*` `*`Lo`*` `*`Val`*`               Repeats (`*`Hi`*`*256 + `*`Lo`*`) times the value `*`Val`*\
141-`$80 `*`Val`*`                     Repeats the value `*`Val`*` the same number of times that in the previous $00 instruction`\
142-`$40 `*`Count`*` `*`Val`*`               Repeats (`*`Count`*`+64) times the value `*`Val`*\
143-`$C0 `*`Val`*`                     Repeats the value `*`Val`*` the same number of times that in the previous $40 instruction`
154+```text
155+Sequence Meaning
156+-------------------------- ---------------------------------------------------------------
157+$00 Hi Lo Val Repeats (Hi*256 + Lo) times the value Val
158+$80 Val Repeats the value Val the same number of times that in the previous $00 instruction
159+$40 Count Val Repeats (Count+64) times the value Val
160+$C0 Val Repeats the value Val the same number of times that in the previous $40 instruction
161+```
144162
145163Small repetitions:
146164
147-`Sequence                    Meaning`\
148-`--------------------------  ---------------------------------------------------------------`\
149-`$01..$3f `*`Val`*`                Repeats `*`Val`*`, the number of times being the value of the instruction ($01..$3f)`\
150-`$40+n (`*`n`*` = 1..31)           Uncompress `*`n`*` group of packed repetition (see below)`\
151-`$60+`*`n`*` (`*`n`*` = 0..15)           Repeats (`*`n`*`+1) times the value 0`\
152-`$70+`*`n`*` (`*`n`*` = 0..15)           Repeats (`*`n`*`+1) times the value 255`
165+```text
166+Sequence Meaning
167+-------------------------- ---------------------------------------------------------------
168+$01..$3f Val Repeats Val, the number of times being the value of the instruction ($01..$3f)
169+$40+n (n = 1..31) Uncompress n group of packed repetition (see below)
170+$60+n (n = 0..15) Repeats (n+1) times the value 0
171+$70+n (n = 0..15) Repeats (n+1) times the value 255
172+```
153173
154174Dump:
155175
156-`Sequence                    Meaning`\
157-`--------------------------  ---------------------------------------------------------------`\
158-`$81 `*`Count`*`                   The next (`*`Count`*`+64) bytes are copied as they are`\
159-`$80+`*`n`*` (`*`n`*` = 2..63)           The next `*`n`*` bytes are copied as they are`\
160-`$C0+`*`n`*` `*`Val`*` (`*`n`*` = 3..31)       The next `*`(n-1)/2`*` bytes must be unpacked to yield `*`n`*` uncompressed bytes (see below)`\
161-`                            An initial value `*`Val`*` is provided and is put as it is in the uncompressed stream.`\
162-`$E0+`*`n`*` (`*`n`*` = 2..30)           The next `*`n/2`*` bytes must be unpacked to yield `*`n`*` uncompressed bytes (see below)`\
163-`                            The last unpacked value with instruction $C0 and $E0 is used as an implicit initial value.`\
164-`                            This initial value is however not put in the uncompressed stream. Its default value is $80`\
165-`                            in the case there is no previous unpacking instruction.`
176+```text
177+Sequence Meaning
178+-------------------------- ---------------------------------------------------------------
179+$81 Count The next (Count+64) bytes are copied as they are
180+$80+n (n = 2..63) The next n bytes are copied as they are
181+$C0+n Val (n = 3..31) The next (n-1)/2 bytes must be unpacked to yield n uncompressed bytes (see below)
182+ An initial value Val is provided and is put as it is in the uncompressed stream.
183+$E0+n (n = 2..30) The next n/2 bytes must be unpacked to yield n uncompressed bytes (see below)
184+ The last unpacked value with instruction $C0 and $E0 is used as an implicit initial value.
185+ This initial value is however not put in the uncompressed stream. Its default value is $80
186+ in the case there is no previous unpacking instruction.
187+```
166188
167189##### Simple instructions examples
168190
169-`07 FF 06 FE`
191+```text
192+07 FF 06 FE
193+```
170194
171195repeats 7 times the value \$FF then 6 times the value \$FE.
172196
173-`63 73`
197+```text
198+63 73
199+```
174200
175201repeat 4 times the value \$00 then 4 times the value \$FF.
176202
177-`00 01 00 23 E0`
203+```text
204+00 01 00 23 E0
205+```
178206
179207Stream containing \$100 times the value \$23. The \$E0 instruction indicates the end of the stream.
180208
181-`00 01 00 C0 80 FF 80 C0 80 FF`
209+```text
210+00 01 00 C0 80 FF 80 C0 80 FF
211+```
182212
183213Stream containing:
184214
185-`- $100 times the value $C0`\
186-`- $100 times the value $FF`\
187-`- $100 times the value $C0`\
188-`- $100 times the value $FF`\
189-`- the end of the stream instruction is missing`
215+``` pascal
216+- $100 times the value $C0
217+- $100 times the value $FF
218+- $100 times the value $C0
219+- $100 times the value $FF
220+- the end of the stream instruction is missing
221+```
190222
191-`40 03 FF C0 00`
223+```text
224+40 03 FF C0 00
225+```
192226
193227repeats 67 times the value \$FF, then 67 times the value \$00.
194228
195-`83 01 02 03`
229+```text
230+83 01 02 03
231+```
196232
197233writes 01 02 03 into the output stream (a total of 3 bytes).
198234
199-`81 03 01 02 03 04 ... 40 41 42 43`
235+```text
236+81 03 01 02 03 04 ... 40 41 42 43
237+```
200238
201239writes 01 02 03 04 ... 40 41 42 43 into the output stream (a total of 67 bytes).
202240
203241##### Packed repetitions
204242
205243The instructions \$41..\$5F (= \$40 + *n*) represent a group of *n* packed repetition. So the structure of one instruction is:
206244
207-`Instruction $40+`*`n`*` `\
208-`Packed repetition number 1`\
209-`Packed repetition number 2`\
210-`...`\
211-`Packed repetition number `*`n`*
245+```text
246+Instruction $40+n
247+Packed repetition number 1
248+Packed repetition number 2
249+...
250+Packed repetition number n
251+```
212252
213253One entry of packed repetition:
214254
215-`Offset  Size  Content`\
216-`-----   ----  -----------------`\
217-`0       1     Packed number P of repetitions to apply`\
218-`1       1     First byte to repeat N1 times`\
219-`2       1     2nd byte to repeat N2 times`\
220-`3       1     3rd byte to repeat N3 times`\
221-`4       1     4th byte to repeat N4 times`\
255+```text
256+Offset Size Content
257+----- ---- -----------------
258+0 1 Packed number P of repetitions to apply
259+1 1 First byte to repeat N1 times
260+2 1 2nd byte to repeat N2 times
261+3 1 3rd byte to repeat N3 times
262+4 1 4th byte to repeat N4 times
222263
223-`P = N1-1 + ((N2-1) `*`shl`*` 2) + ((N3-1) `*`shl`*` 4) + ((N4-1) `*`shl`*` 6)`
264+P = N1-1 + ((N2-1) shl 2) + ((N3-1) shl 4) + ((N4-1) shl 6)
265+```
224266
225267Example:
226268
227-`42 FF 01 02 03 04 55 01 02 03 04`\
269+```text
270+42 FF 01 02 03 04 55 01 02 03 04
228271
229-`is unpacked as`\
272+is unpacked as
230273
231-`01 01 01 01 02 02 02 02 03 03 03 03 04 04 04 04 01 01 02 02 03 03 04 04`
274+01 01 01 01 02 02 02 02 03 03 03 03 04 04 04 04 01 01 02 02 03 03 04 04
275+```
232276
233277##### Packed dumps
234278
235279In a packed dumps, it is the values themselves that are packed. To do that, an initial value is defined. By default it is \$80. Then each subsequent value is computed by adding an offset from -7 to +7. This offset is stored as a number between 1 and 15 (by adding 8 to it).
236280
237281For example:
238282
239-`20 22 25`\
283+```text
284+20 22 25
240285
241-`can be packed as`\
286+can be packed as
242287
243-`initial value $20, then offset +2, then offset +3`
288+initial value $20, then offset +2, then offset +3
289+```
244290
245291So it would be written in the compressed stream as:
246292
247-`C3 20 AB`
293+```text
294+C3 20 AB
295+```
248296
249297Where \$A = 10 = 2 + 8 is the first offset and \$B = 11 = 3 + 8 is the second offset.
250298
251299Another example:
252300
253-`00 01 02 03 04 05 ... 0E 0F (a total of 16 bytes)`\
301+```text
302+00 01 02 03 04 05 ... 0E 0F (a total of 16 bytes)
254303
255-`can be packed as`\
304+can be packed as
256305
257-`D0 00 99 99 99 99 99 99 99 90 (a total of 10 bytes)`
306+D0 00 99 99 99 99 99 99 99 90 (a total of 10 bytes)
307+```
258308
259309Note that the initial value may be omitted by using the instructions \$E2..\$FE.
260310
261311---
262312*From the Free Pascal wiki, page "LazPaint LZP Format Single Image", as it stood on 2020-12-04 after a change by Circular, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
263313Category: LazPaint

Back to history