Sign in Join
Wiki copytemporary

LazPaint LZP directory structure: what changed

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

OldNewLine
11The [[LazPaint LZP directory structure|directory structure]] contains additional information about the [[LazPaint LZP Format|layered image]], in particular originals used to render the layers. It can be discarded by raster editors as it contains essentially information necessary to render the layers from vector originals.
22
33### Global header
44
5-`Offset  Size  Content`\
6-`------  ----  -------------------------------------------------------`\
7-`0       16    Contains the string 'TMemDirectory' followed by the bytes 1A 00 00`\
8-`16      8     Root 64-bit offset R0`\
9-`24      8     Root 64-bit size S0`\
10-`R0      S0    Root entry`
5+```text
6+Offset Size Content
7+------ ---- -------------------------------------------------------
8+0 16 Contains the string 'TMemDirectory' followed by the bytes 1A 00 00
9+16 8 Root 64-bit offset R0
10+24 8 Root 64-bit size S0
11+R0 S0 Root entry
12+```
1113
1214The headers thus locates the root of the directory structure.
1315
1416### Directory
1517
1618The root directory and the subdirectory have the same format.
1719
18-`Offset  Size  Content`\
19-`------  ----  -------------------------------------------------------`\
20-`0       4     Number of entries in the directory`\
21-`4             First entry if any`
20+```text
21+Offset Size Content
22+------ ---- -------------------------------------------------------
23+0 4 Number of entries in the directory
24+4 First entry if any
25+```
2226
2327All entries are one after another.
2428
2529#### Entry
2630
2731An entry has a variable length depending on its content.
2832
29-`Offset  Size  Content`\
30-`------  ----  -------------------------------------------------------`\
31-`0       2     Flags of the entry`\
32-`2       2     Filename size in bytes FS`\
33-`4       8     Offset to the content (relative to the global header)`\
34-`12      8     Compressed size CS (optional)`\
35-`20      8     Uncompressed size UC (optional)`\
36-`?             Filename (not null terminated)`
33+```text
34+Offset Size Content
35+------ ---- -------------------------------------------------------
36+0 2 Flags of the entry
37+2 2 Filename size in bytes FS
38+4 8 Offset to the content (relative to the global header)
39+12 8 Compressed size CS (optional)
40+20 8 Uncompressed size UC (optional)
41+? Filename (not null terminated)
42+```
3743
3844Possible flags:
3945
4046- 1: the entry is a directory
4147- 2: the entry is compressed
4248- \$8000: the entry is small (content and name each 255 bytes or less)
4349
4450##### Small entry
4551
4652When the entry is small, the size fields are not supplied, so the entry header size without filename is 12 bytes. The content size is extracted from the filename size field. The content cannot be compressed.
4753
48-`CS = UC = FS shr 8`\
49-`FS = FS and 255`
54+```text
55+CS = UC = FS shr 8
56+FS = FS and 255
57+```
5058
5159The entry header can also be summarized as:
5260
53-`Offset  Size  Content`\
54-`------  ----  -------------------------------------------------------`\
55-`0       2     Flags of the entry`\
56-`2       1     Filename size in bytes FS`\
57-`3       1     Content size`\
58-`4       8     Offset to the content (relative to the global header)`\
59-`12      FS    Filename (not null terminated)`
61+```text
62+Offset Size Content
63+------ ---- -------------------------------------------------------
64+0 2 Flags of the entry
65+2 1 Filename size in bytes FS
66+3 1 Content size
67+4 8 Offset to the content (relative to the global header)
68+12 FS Filename (not null terminated)
69+```
6070
6171##### Non small entry
6272
6373When the entry is not small, the entry header size without filename is 28 bytes. The content can be compressed using the adequate flag.
6474
6575The filename is not null terminated and encoded as UTF8. Its size is supplied in bytes and not in characters.
6676
6777#### Entry content
6878
6979The entry content offset is relative to the start of the global header of the directory structure. If the flag directory flag is set, then it is to be interpreted as a directory like the root directory. Otherwise, it is to be interpreted as a file.
7080
7181The root is the path '/'. An entry in the root and called 'hello' has the path '/hello'.
7282
7383When directories are nested, the resulting path is concatenated with a '/' character as in Unix paths. For example, if there is a subdirectory called 'container' in the root directory and that it contains a file called 'readme.txt', then its path is '/container/readme.txt'.
7484
7585A file that does not contain '.' has thus no extension and is considered to be an attribute. An attribute is a value associated to the object that the directory represents, like a number or a list of numbers.
7686
7787If a file is not an attribute, it is similar to file that would be saved on a disk, like an image in PNG format.
7888
7989##### Attributes
8090
8191An attribute can have various types, but those are not saved explicitly. The reader needs to know what kind of value it expects from an attribute. Attributes are stored in ASCII unless specified.
8292
8393Here is the list of possible types:
8494
8595- integer: an optional sign and a sequence of digits forming a signed 32-bit integer.
8696- float: a single precision floating point number written using '.' decimal separator and that can have an exponent E.
8797- boolean: either 'true' or 'false'
8898- string: any sequence of characters (quotes are not added)
8999- color: can be a VGA or CSS color name, an RGB value with or without hashtag using one or two digit per channel with or without the alpha channel (example: red = \#f00 = ff0000ff), an RGB value expressed in CSS format (exemple: rgb(255,0,0) = rgba(100%,0,0,1))
90100- list of float: float values (or 'none' to specify undefined) separated by ','
91101- list of colors: color values separated by ','
92102- affine matrix: an affine matrix stored as binary so a sequence of 6 single precision floats (each 4 bytes in little endian) representing ux, uy, vx, vy, tx and tx
93103
94104Note:
95105
96106- a 2D coordinate is a list of 2 values (x and y), a 2D rectangle is a list of 4 values (left, top, right and bottom).
97107- the affine matrix is stored as binary to ensure exact equality when comparing matrices
98108
99109### Tree
100110
101111Here as an example of tree structure of a LazPaint file, with 3 layers and 2 originals.
102112
103113The first two layers has some registry entries, for example if layer1 is an effect generated for layer2.
104114
105115The second layer contains render backup, for example because it contains text that might not be rendered the same way on a different computer.
106116
107117There are two originals for example because layer2 is a vector layer and layer3 is a rotated image.
108118
109-`root`\
110-`  ├─ layers`\
111-`  │   ├─ layer1`\
112-`  │   │    └─ registry`\
113-`  │   ├─ layer2`\
114-`  │   │    ├─ registry`\
115-`  │   │    └─ render`\
116-`  │   └─ layer3`\
117-`  ├─ originals`\
118-`  │   ├─ {7F5D5954-8EAC-D992-6D0A-9CD24929EBEB}`\
119-`  │   │    ├─ shape1`\
120-`  │   │    ├─ shape2`\
121-`  │   │    └─ shape3`\
122-`  │   └─ {61BD152C-9F86-1325-B256-B50D877389E8}`\
123-`  └─ registry`
119+```text
120+root
121+ ├─ layers
122+ │ ├─ layer1
123+ │ │ └─ registry
124+ │ ├─ layer2
125+ │ │ ├─ registry
126+ │ │ └─ render
127+ │ └─ layer3
128+ ├─ originals
129+ │ ├─ {7F5D5954-8EAC-D992-6D0A-9CD24929EBEB}
130+ │ │ ├─ shape1
131+ │ │ ├─ shape2
132+ │ │ └─ shape3
133+ │ └─ {61BD152C-9F86-1325-B256-B50D877389E8}
134+ └─ registry
135+```
124136
125137#### Registry
126138
127139A registry is a series of attributes containing any kind of value. The identifier can only contain the following characters: 'A'..'Z','a'..'z','0'..'9','_','-'
128140
129141The registry at the root does not have predefined attributes. It can be used by scripts to store values like the last parameters used.
130142
131143#### Layers
132144
133145The layers represent the layer stack. The first layer is at the bottom and the last is on top.
134146
135147Each layer can have its own registry. The attribute 'guid' can define a Guid identifier for the layer, for example {5A8F1094-8386-E527-39E9-6F843771EDC6}. Script can also store values like the parameters of an effect.
136148
137149Each layer can have its own render directory. This directory contains at least a 'last-matrix' attribute containing the last affine matrix used to render the layer. If it is equal to the current affine matrix of the layer, then the render backup can be used to draw the layer. A part from that, each original is free to use the render directory as it wants.
138150
139151#### Originals
140152
141153The originals are graphical elements that can be transformed according to an affine matrix.
142154
143155Each original has a Guid and a directory named after its Guid.
144156
145157In each original directory, there is a 'class' attribute that identifies the type of original. The reader can know from this classname whether it can understand its structure. Apart from that, the content of the original directory is completely up to the class.
146158
147159The following classnames are defined in LazPaint:
148160
149161- image: a bitmap (PNG or JPEG)
150162- gradient: a gradient that fills the whole layer
151163- vector: a vectorial layer (containing vector objects of LazPaint)
152164- svg: an SVG file
153165
154166Using an image original is useful when an image is transformed as it allows to keep the original bitmap and thus avoid loss of information after multiple transformations.
155167
156168---
157169*From the Free Pascal wiki, page "LazPaint LZP directory structure", 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).*

Back to history