From 5c1676dfe6d2f3c837a5e074117b45613fd29a72 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:30:19 +0200 Subject: Adding upstream version 2.10.34. Signed-off-by: Daniel Baumann --- devel-docs/xcf.txt | 1607 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1607 insertions(+) create mode 100644 devel-docs/xcf.txt (limited to 'devel-docs/xcf.txt') diff --git a/devel-docs/xcf.txt b/devel-docs/xcf.txt new file mode 100644 index 0000000..945c30c --- /dev/null +++ b/devel-docs/xcf.txt @@ -0,0 +1,1607 @@ +==================================== +DOCUMENTATION OF THE XCF FILE FORMAT +==================================== + +Introduction +------------ + +This document describes the native image file format of GIMP. + +Note that the XCF format is a "living" format which follows closely the +GIMP software and evolves together. The ultimate reference for the +format is therefore its code, even though we will try to update this +documentation regularly, to make life simpler to ourselves as well as +third-party XCF-reader's developers. + +The code for reading and writing XCF is found in: app/xcf/ + + +License +------- + +Copyright Henning Makholm , 2006-07-11 +Copyright various GIMP developers (see git log), 2009-2019 + +This is free documentation; you can modify and/or redistribute +it according to the terms of the GNU General Public License +as published by the Free Software Foundation, either version +2 of the license, or (at your option) any later version. + + +Table of contents +----------------- + +Documentation of the XCF file format + License + Table of contents + Audience + Scope + Status + Version history + +1. Basic concepts + XCF file + Basic data types + Canvas + Color + Pixel data: Tiles + Pixel data: Levels of detail hierarchy + Channels + Layers + Layer masks + Properties + Parasites + Selections + Floating selection + Tattoos + +2. General properties + +3. The Image structure + Header + Image properties + +4. The Channel structure + Channel properties + +5. The Layer structure + Layer properties + +6. The Hierarchy structure + Levels + +7. Tile data organization + Uncompressed tile data + RLE compressed tile data + +8. Miscellaneous + The name XCF + + +Audience +-------- + +Audience of this document are developers of GIMP and other software that +reads and writes XCF files. + + +Scope +----- + +The XCF format is designed to store the whole state of GIMP that is specific to +one image (i.e., not the cut buffer, tool options, key bindings, etc.) and +is not undo data. This makes the full collection of data stored in an XCF file +rather heterogeneous and tied to the internals of GIMP. + +Use of the XCF format by third-party software is recommended only as a +way to get data into and out of GIMP for which it would be impossible or +inconvenient to use a more standard interchange format. Authors of +third-party XCF-creating software in particular should take care to +write files that are as indistinguishable as possible from ones saved by +GIMP. The GIMP developers take care to make each version of GIMP able to +read XCF files produced by older GIMP versions, but they make no special +efforts to allow reading of XCF files created by other software. + +Interchanging image data with other applications is not the goal of the +XCF format. Other formats may be more appropriate. For this use case +GIMP opens and exports common images formats, like JPEG, PNG and PSD, +though they may all miss various features of XCF. +OpenRaster (ORA) in particular is meant to be a generic interchange +format between software, with as few feature loss as possible, though +its standardization is still quite slow. + +For the stated reasons and clarification GIMP _saves_ XCF files, +but _exports_ to other image formats. + +Beware that CinePaint's native file format is called XCF, too. While it is +derived from the format described here, both formats differ in many details +and are _not_ mutually compatible. +This document does not describe the CinePaint XCF format. +For more information on that see: +https://web.archive.org/web/20161024115140/http://www.cinepaint.org/more/docs/xcf.html + + +Status +------ + +This specification is an official condensation and extrapolation of +the XCF-writing and -reading code in version 2.10.14 of GIMP, and +earlier versions. Yet we remind that the ultimate reference is the +loading and saving code of the XCF format. + +Some of the normative statements made below are enforced by the XCF +code in GIMP; others are just the authors' informed guess about +"best practices" that would be likely to maximize interoperability +with future versions of GIMP. + +This document is complete, relatively to GIMP 2.10 features stored in +the XCF format, though if you discover any errors or missing features, +we would be thankful if you could report it as a bug: +https://gitlab.gnome.org/GNOME/gimp/issues + + +Version history +--------------- +This section lists the changes between file format versions in bigger terms. +Details are denoted in the text. + +Version 0: +Since GIMP 0.99.16, released on 1997-12-15. +The initial file format. Everything that is not listed in the following versions +is part of this. + +Version 1: +Since GIMP 0.99.16, released on 1997-12-15. +Adds color maps. Chapter 3 "The image structure" describes the PROP_COLOR_MAP +property. + +Version 2: +Since GIMP 1.3.10, released on 2002-11-07. +Adds layer modes "Soft light", "Grain extract", "Grain merge" and painting +mode "Color Erase". In chapter 5 "The layer structure" the description of +the property PROP_MODE contains the new layer modes. +Improves path handling in GIMP 1.3.21, released on 5.10.2003. +Chapter 1 "Basic concepts" describes the path handling in general and +chapter 2 "General concepts" introduces the PROP_VECTORS property. + +Version 3: +Since GIMP 2.7.1, released on 2010-06-29. +Adds layer groups. The chapter 5 "The layer structure" describes the new +properties PROP_GROUP_ITEM, PROP_GROUP_ITEM_FLAGS and PROP_ITEM_PATH. + +Version 4 to 13: +Since GIMP 2.10.0, released on 2018-04-27. +Adds many layer modes, layer group masks, high-bit depth (precisions +other than 8-bit gamma), zlib compression and 64-bit offsets for XCF +files bigger than 4GB. + + +1. BASIC CONCEPTS +================= + +It is recommended that a software developer who wants to take full +advantage of the XCF format be deeply familiar with GIMP at least +as a user. The following high-level overview is meant to help those +non-users who just need to extract pixel data from an XCF file get up +to speed. + + +XCF file +-------- + +An XCF file is a sequence of bytes. In general an XCF file describes a stack of +layers and channels on a canvas. +It contains a series of data structures, the order of which is in general not +significant. The exception to this is that the main image structure must come at +the very beginning of the file, and that the tile data blocks for each drawable +must follow each other directly. + +References _between_ structures in the XCF file take the form of +"pointers" that count the number of bytes between the beginning +of the XCF file and the beginning of the target structure. +Pointers used to be 32-bit data. Since the maximum address of a layer, +channel, hierarchy or tile set was 2^32 - 1, i.e. at 4 GB, the maximum +size for XCF images before GIMP 2.10.0 was quite limited. +Now pointers can be 64-bit, allowing files big enough for any image +produced by current technology. See the chapter "Basic data types" for +description of the POINTER type. + +Each structure is designed to be written and read sequentially; many +contain items of variable length and the concept of an offset _within_ +a data structure is not often relevant. + + +Basic data types +---------------- + +A WORD is a 32-bit integer stored as 4 bytes in big-endian order, i.e. with +the most significant byte first. The word is not necessarily aligned to an +offset within the XCF file that is a multiple of 4. +Depending on the context the word can be unsigned or (2's complement) signed. +UINT32 denotes unsigned words and INT32 denotes signed words in this document. + +A FLOAT is stored as a 32-bit IEEE 754 single-precision floating-point number +in big-endian order. + +A STRING is stored as follows: + + uint32 n+1 Number of bytes that follow, including the zero byte + byte[n] ... String data in Unicode, encoded using UTF-8 + byte 0 Zero marks the end of the string. + +Exception: the empty string is stored simply as an uint32 with the +value 0. + +A POINTER is stored as a 32-bit integer (4 bytes) in big-endian order +for XCF up to 10, and 64-bit (8 bytes), still big-endian, for XCF 11 +and over, allowing higher than 4GB XCF files since GIMP 2.10.0. + +Canvas +------ + +A canvas is an abstract rectangular viewport for the layers and channels. +The image header stores the canvas' dimensions. + + +Color +----- + +RGB: +Three intensity values for red, green, and blue additive color +components, each on a scale from 0 to 255. The exact color space +is not specified. GIMP displays image data directly on PC +display hardware without any software correction, so in most +cases the intensity values should be considered nonlinear samples +that map to physical light intensities using a power function +with an exponent ("gamma") of about 2.5. (This is how PC hardware +commonly treat bit values in the video buffer, which incidentally +also has the property of making each 1/255th step about equally +perceptible to the human eye when the monitor is correctly +adjusted). +Beware, however, that GIMP's compositing algorithms (as described +in the document compositing.txt) implicitly treat the intensities +as _linear_ samples. The XCF file format currently has no support +for storing the intended gamma of the samples. + +TODO: Are the statements about color space, gamma and layer modes still valid? + +Grayscale: +One intensity value on a scale from 0 (black) to 255 (white). +Gamma considerations as for RGB. + +Indexed: +An 8-bit index into a color map that is shared between all +layers. The color map maps each index to an RGB triple which is +interpreted as in the RGB model. + + +Pixel data: Tiles +----------------- + +Basically pixels are organized in a grid of "tiles", each +with a width and height of up to 64 pixels. The only tiles that have a +width less than 64 are those in the rightmost column, and the only +tiles that have a height less than 64 are those in the bottommost row. +Thus, a layer measuring 200 x 150 pixels will be divided into 12 +tiles: + + +-----------------+-----------------+------------------+-----------------+ + | Tile 0: 64 x 64 | Tile 1: 64 x 64 | Tile 2: 64 x 64 | Tile 3: 8 x 64 | + +-----------------+-----------------+------------------+-----------------+ + | Tile 4: 64 x 64 | Tile 5: 64 x 64 | Tile 6: 64 x 64 | Tile 7: 8 x 64 | + +-----------------+-----------------+------------------+-----------------+ + | Tile 8: 64 x 22 | Tile 9: 64 x 22 | Tile 10: 64 x 22 | Tile 11: 8 x 22 | + +-----------------+-----------------+------------------+-----------------+ + +As can be seen from this example, the tiles appear in the XCF file in +row-major, top-to-bottom, left-to-right order. The dimensions of the +individual tiles are not stored explicitly in the XCF file, but must +be computed by the reader. + +The tiles that are pointed to by a single level structure must be +contiguous in the XCF file, because GIMP's XCF reader uses the +difference between two subsequent tile pointers to judge the amount of +memory it needs to allocate for internal data structures. + + +Pixel data: Levels of detail hierarchy +-------------------------------------- + +The tiles themselves are organized in levels of detail. These levels +build a hierarchy. + +Only the first level structure is used by GIMP's XCF reader, +except that the reader checks that a terminating zero for the +level-pointer list can be found. GIMP's XCF writer creates a +series of dummy level structures (with NULL-pointers to the tiles), each +declaring a height and width half of the previous one (rounded down), +until the height and with are both less than 64. Thus, for a layer of +200 x 150 pixels, this series of levels will be saved: + + A level of 200 x 150 pixels with 12 tiles: the actually used one + A level of 100 x 75 pixels with no tiles + A level of 50 x 37 pixels with no tiles + +Third-party XCF writers should probably mimic this entire structure; +robust XCF readers should have no reason to even read past the pointer +to the first level structure. + +TODO: The XCF file holds (for unclear historical reasons) +a level-of-detail hierarchy, but we only use the +lowest hierarchy level of it and other XCF consumers +are told to do the same. This looks like a mipmap. Would +using it to save an image pyramid or the thumbnail +for the File dialogs get us some benefits? + + +Channel +------- + +A channel is a named object that contains a single byte of information +for each pixel in the canvas area. Channels have a variety of use as +intermediate objects during editing; they are not meant to be rendered +directly when the final image is displayed or exported to layer-less +formats. A major use of channels is as a store for saved selections. + +A channel can be edited as if it was a grayscale layer with the same +dimensions as the canvas. When it is shown in the GIMP editor UI +together with other layers, it is used as if it was the _inverse_ +alpha channel of a layer with the same color information in all +pixels; this color can be stored in the XCF file as a property of the +channel. This "mask" representation is generally thought of as an UI +feature rather than an intrinsic semantics of a channel. + +Though the channel data structure in the XCF file contains a height +and width field, these must always be the same as the canvas width and +height. +TODO: does this apply to any channel or only to selections? + + +Layer +----- + +A layer is a named rectangular area of pixels which has a definite +position with respect to the canvas. It may extend beyond the canvas or +(more commonly) only cover some of it. Each pixel of the layer has a color +which is specified in one of three ways as described in the "Color" section. + +All layers in an image must use the same color model. +Exception: if the "floating selection" (see below) belongs to a channel or +layer mask, it will be represented as grayscale pixels with alpha independently +of the image's overall color model. + +Each pixel of a layer also has an alpha component which specifies the +opacity of the pixel on a linear scale from 0 (denoting an alpha of +0.0, or completely transparent) to 255 (denoting an alpha of 1.0, or +completely opaque). The color values do not use "premultiplied alpha" +storage. The color information for pixels with alpha 0 _may_ be +meaningful; GIMP preserves it when parts of a layer are erased and +provides (obscure) ways of recovering it in its user interface. + +The bottommost layer _only_ in an image may not contain alpha +information; in this case all pixels in the layer have an alpha value +of 255. (Even if the bottommost layer does not cover the entire +canvas, it is the only layer that can be without an explicit alpha +channel). + +In images that use the indexed color model, GIMP does not support +partial transparency and interprets alpha values from 0 to 127 as +fully transparent and values from 128 to 255 as fully opaque. This +behavior _may_ change in future versions of GIMP. +TODO: has already changed? + +Layers have certain other properties such as a visibility flag, +a global opacity (which is multiplied with individual pixel alphas) +a layer group flag and various editing state flags. + + +Layer mask +---------- + +The layer mask can be attached to a layer (since GIMP 2.10.0, layer +group can also have a layer mask). +Actually it is represented as a channel structure in the XCF file. +It is referred to from its parent layer and not listed in the master list +of channels. +Its dimensions and placement coincide with those of its parent layer. + +Unless disabled by the PROP_APPLY_MASK property, the layer mask +functions as an extra alpha channel for the layer, in that for each +pixel the layer's alpha byte and the layer mask byte are multiplied to +find the extent to which the layer blankets the background. Thus a +layer mask can make parts of the layer more transparent, but never +more opaque. + + +Properties +---------- + +Properties are an extension mechanism to attribute the image, channels +and layers. Some are attributes for general use, such as PROP_END, +others are specific to the image, a channel or a layer. + +Technically properties are implemented as variable-length series of +variable-length PROPERTY records which have the following general format + + uint32 type Numerical type identifier + uint32 plength Payload length in bytes (but BEWARE! see below) + byte[n] ... Payload - interpretation depends on the type + +The authoritative source for property type numbers is the file +app/xcf/xcf-private.h in the GIMP sources. Only GIMP itself should define +new property types. + +The number of properties in a property list is not stored explicitly; +the last property in the list is identified by having type 0; it must +have length 0. + +XCF readers must skip and ignore property records of unrecognized +type, and the length word is there to support such skipping. However, +GIMP's own XCF reader will _ignore_ the length word of most +properties that it _does_ recognize, and instead reads the amount of +payload it knows this property to have. This means that a property +record is not itself extensible: one cannot piggyback extra data onto +an existing property record by increasing its length. Also, some +historical versions of GIMP actually stored the wrong length for +some properties, so there are XCF files with misleading property +length information in circulation. For maximal compatibility, an XCF +reader should endeavor to know the native lengths of as many +properties as possible and fall back to the length word only for truly +unknown property types. + +There is not supposed to be more than one instance of each property in +a property list, but some versions of GIMP will erroneously emit +duplicate properties. An XCF reader that meets a duplicated property +should let the content of the later instance take precedence, except +for properties that contain lists of subitems, in which the lists +should generally be concatenated. An XCF writer should never +deliberately duplicate properties within a single property list. + + +Parasites +--------- + +Parasites provide a second level of extensibility. +A parasite is analogous to a property, but is identified by a string +rather than a number. This makes a larger namespace available for +parasites. GIMP plug-ins can access the parasites of an image +component through the API and can define their own parasite +names which will be ignored by other plug-ins. + +A list of known parasites and their data formats can be found in the +file devel-doc/parasites.txt of the GIMP source tree. + +The PROP_PARASITE property stores the parasites of the image, layers +and channels and the PROP_VECTORS property those of the paths. + +The number of parasites there is not directly encoded; the list ends when +the total length of the parasite data read equals the property payload length. + +GIMP's XCF reader checks that the combined size of all parasites +in the property precisely equals the length word, so it is safe for +a reader to use the length word to skip the property without parsing +the individual parasites. + +The parasite content may be binary, but often a textual encoding is +chosen in order to spare the writing and reading code of having to deal +with byte ordering. + +There can only be one parasite with a given name attached to +each element of the image. Some versions of GIMP will +erroneously write some parasites twice in the same property list; +XCF readers must be prepared to gracefully ignore all but the +last instance of a parasite name in each property list. + +TODO: How shall parasite readers handle lists in duplicate parasites? + +Selection +--------- + +If the current selection in the editor is nonempty, then GIMP stores it +as a channel in the XCF file. Pixels with a value of 255 belong to the +selection; pixels with a value of 0 don't, and pixels with intermediate +values are partially selected. + + +Floating selection +------------------ + +A floating selection is a selection, that is attached to a particular +layer, channel or layer mask. + +Technically it is handled as a layer with alpha. + +If a floating selection exists, it must always be the first layer in +the layer list, but it is not rendered at that position in the layer stack. +Instead it is logically attached to another layer, or a channel or layer mask, +and the content of the floating selection is combined with ("anchored to") +that drawable before it is used to render the visible image. + +The floating selection must not have a layer mask of its own, but if +an ordinary (not floating) selection also exists, it will be used as +a layer mask for the floating selection. + +If a floating selection exists, it must also be the active layer. + +Because the floating selection is modal and ephemeral, users rarely +save XCF files containing a floating selection. It may be acceptable +for third-party XCF consumers to ignore the floating selection or +explicitly refuse to process it. + + +Tattoos +------- + +A tattoo is a unique and permanent identifier attached to a drawable or path +that can be used to uniquely identify it within an image even between sessions. + +The tattoo of the image, a layer or channel is stored in the PROP_TATTOO +property, a tattoo for a path in the PROP_VECTORS property. + +The PROP_TATTOO property of the entire image stores a "high-water +mark" for the entire image; it is greater than OR EQUAL TO any +tattoo for an element of the image. It allows efficient generation +of new unused tattoo values and also prevents old tattoo numbers +from being reused within a single image, lest plug-ins that use +the tattoos for bookkeeping get confused. + +An XCF file must either provide tattoo values for all its elements +or for none of them. GIMP will invent fresh tattoos when it +reads in tattoo-less elements, but it does not attempt to keep them +different from ones specified explicitly in the file. +TODO: can this cause confusion and hard-to-find errors? If so, fix. + + +Text +---- + +GIMP stores text in plain layers with parasites for the text and formatting +and PROP_TEXT_LAYER_FLAGS for flags. + + +Vector paths +------------ + +GIMP stores vector paths as properties of the image. +If all paths are continuous sequences of Bezier strokes, then GIMP uses +the PROP_PATHS property, otherwise PROP_VECTORS. PROP_PATHS is for old +files from GIMP up to version 1.2. + + +2. GENERAL PROPERTIES +===================== + +This chapter describes the formats of the defined property records that +can appear in more than one context in an XCF file. + +PROP_COLOR_TAG (since GIMP 2.10.0, commit 4f9095798d0) + uint32 34 Type identification + uint32 4 Four bytes of payload + uint32 tag Color tag of the layer; one of + 0: None + 1: Blue + 2: Green + 3: Yellow + 4: Orange + 5: Brown + 6: Red + 7: Violet + 8: Gray + + PROP_COLOR_TAG can be assigned to layers, channels and paths. They are + only organisational properties and have no consequence on render. + +PROP_END + uint32 0 Type identification + uint32 0 PROP_END has no payload. + + The PROP_END pseudo-property marks the end of any property list. + +PROP_FLOAT_OPACITY (essential, since GIMP 2.10.0, commit a2ad257711a) + uint32 33 Type identification + uint32 4 Four bytes of payload + float opacity Opacity on a scale from 0.0 (fully transparent) to + 1.0 (fully opaque) + + PROP_FLOAT_OPACITY records the overall opacity setting for the layer + or channel. Since GIMP 2.10.0, it always appears in the property list + of layers and channels after PROP_OPACITY, which saves the same value, + yet with integer precision. This way, new readers can overwrite the + 8-bit value with proper precision whereas older readers can simply + skip PROP_FLOAT_OPACITY if unknown. + +PROP_LINKED (editing state) + uint32 9 Type identification + uint32 4 Four bytes of payload + uint32 linked 1 if the layer is linked; 0 if not + + PROP_LINKED controls the behavior of Transform tools with a layer, + channel or path. If a Transform tool is used to transform one of them + all other linked elements will be transformed the same way. + It appears in the property list for layers, channels and paths. + +PROP_LOCK_CONTENT (since version 3, editing state) + uint32 28 Type identification + uint32 4 Four bytes of payload + uint32 locked 1 if the content is locked; 0 if not + + PROP_LOCK_CONTENT specifies whether the layer, channel or path is locked, + i.e. cannot be edited. + +PROP_LOCK_POSITION (since GIMP 2.10.0, commit d4933b30526, editing state) + uint32 32 Type identification + uint32 4 Four bytes of payload + uint32 locked 1 if the position is locked; 0 if not + + PROP_LOCK_POSITION specifies whether the layer, channel or path's + position is locked, i.e. cannot be transformed (translation, etc.). + +PROP_OPACITY (essential) + uint32 6 Type identification + uint32 4 Four bytes of payload + uint32 opacity Opacity on a scale from 0 (fully transparent) to + 255 (fully opaque) + + PROP_OPACITY records the overall opacity setting for the layer or channel. + It appears in the property list of layers and channels. + + Note that though GIMP's user interface displays the opacity as a percentage, + it is actually stored on a 0-255 scale. Also note that this opacity value + is stored as a 32-bit quantity even though it has been scaled to + fit exactly in a single byte. + + When reading old XCF files that lack this property, full opacity + should be assumed. + + While this property continues to be stored for compatibility, the new + property PROP_FLOAT_OPACITY since GIMP 2.10.0 must override the value + of PROP_OPACITY with float precision. + +PROP_PARASITES + uint32 21 Type identification + uint32 plength Total length of the following payload data in bytes + ,----------------- Repeat for each parasite: + | string name Name of the parasite + | uint32 flags Flags of the parasite + | uint32 pplength Length of the payload data in bytes + | byte[n] ... Parasite-specific payload + `-- + + PROP_PARASITES stores parasites. It can contain multiple parasite records. + See "Basic concepts" and the file parasites.txt for more information about + parasites. + This property can appear in any property list. + +PROP_TATTOO (internal GIMP state) + uint32 20 Type identification + uint32 4 Four bytes of payload + uint32 tattoo Nonzero unsigned integer identifier + + PROP_TATTOO is an unique identifier for the denoted image, channel or layer. + It appears in the property list of layers, channels, and the image. + +PROP_VISIBLE (essential) + uint32 8 Type identification + uint32 4 Four bytes of payload + uint32 visible 1 if the layer/channel is visible; 0 if not + + PROP_VISIBLE specifies the visibility of a layer or channel. + It appears in the property list for layers and channels. + For the visibility of a path see the PROP_VECTORS property. + + When reading old XCF files that lack this property, assume that + layers are visible and channels are not. + + +3. THE IMAGE STRUCTURE +====================== + +Header +------ + +The image structure always starts at offset 0 in the XCF file. + + byte[9] "gimp xcf " File type identification + byte[4] version XCF version + "file": version 0 + "v001": version 1 + "v002": version 2 + "v003": version 3 + byte 0 Zero marks the end of the version tag. + uint32 width Width of canvas + uint32 height Height of canvas + uint32 base_type Color mode of the image; one of + 0: RGB color + 1: Grayscale + 2: Indexed color + (see enum GimpImageBaseType + in libgimpbase/gimpbaseenums.h) + uint32 precision Image precision; this field is only present for + XCF 4 or over (since GIMP 2.10.0). Its value for + XCF 7 or over is one of: + 100: 8-bit linear integer + 150: 8-bit gamma integer + 200: 16-bit linear integer + 250: 16-bit gamma integer + 300: 32-bit linear integer + 350: 32-bit gamma integer + 500: 16-bit linear floating point + 550: 16-bit gamma floating point + 600: 32-bit linear floating point + 650: 32-bit gamma floating point + 700: 64-bit linear floating point + 750: 64-bit gamma floating point + For XCF 4 (which was a development version, hence + this format should not be found often and may be + ignored by readers), its value may be one of: + 0: 8-bit gamma integer + 1: 16-bit gamma integer + 2: 32-bit linear integer + 3: 16-bit linear floating point + 4: 32-bit linear floating point + For XCF 5 or 6 (which were development versions, + hence these formats may be ignored by readers), + its value may be one of: + 100: 8-bit linear integer + 150: 8-bit gamma integer + 200: 16-bit linear integer + 250: 16-bit gamma integer + 300: 32-bit linear integer + 350: 32-bit gamma integer + 400: 16-bit linear floating point + 450: 16-bit gamma floating point + 500: 32-bit linear floating point + 550: 32-bit gamma floating point + NOTE: XCF 3 or older's precision was always + "8-bit gamma integer". + property-list Image properties + ,----------------- Repeat once for each layer, topmost layer first: + | pointer lptr Pointer to the layer structure. + `-- + pointer 0 Zero marks the end of the array of layer pointers. + ,------------------ Repeat once for each channel, in no particular order: + | pointer cptr Pointer to the channel structure. + `-- + pointer 0 Zero marks the end of the array of channel pointers. + +The last 4 characters of the initial 13-character identification string are +a version indicator. The version will be higher than 3 if the correct +reconstruction of pixel data from the file requires that the reader +understands features not described in this specification. On the other +hand, optional extra information that can be safely ignored will not +cause the version to increase. + +GIMP's XCF writer dynamically selects the lowest version that will +allow the image to be represented. Third-party XCF writers should do +likewise. + +Version numbers from v100 upwards have been used by CinePaint, which +originated as a 16-bit fork of GIMP, see "Scope". + + +Image properties +---------------- + +The following properties are found only in the property list of the +image structure. Additionally the list can also contain the properties +PROP_END, PROP_PARASITES and PROP_TATTOO, defined in chapter 2. + +PROP_COLORMAP (essential) + uint32 1 Type identification + uint32 3*n+4 Payload length in bytes + uint32 n Number of colors in the color map (should be <256) + ,------------ Repeat n times: + | byte r Red component of a color map color + | byte g Green component of a color map color + | byte b Blue component of a color map color + `-- + + PROP_COLORMAP stores the color map. + It appears in all indexed images. + + The property will be ignored if it is encountered in an RGB or grayscale + image. The current GIMP will not write a color map with RGB or + grayscale images, but some older ones occasionally did, and readers + should be prepared to gracefully ignore it in those cases. + + Note that in contrast to the palette data model of, for example, the + PNG format, an XCF color map does not contain alpha components, and + there is no color map entry for "transparent"; the alpha channel of + layers that have one is always represented separately. + + The structure here is that of since XCF version 1. Comments in the + GIMP source code indicate that XCF version 0 could not store indexed + images in a sane way; contemporary GIMP versions will complain and + reinterpret the pixel data as a grayscale image if they meet a + version-0 indexed image. + + Beware that the payload length of the PROP_COLORMAP in particular + cannot be trusted: some historic releases of GIMP erroneously + wrote n+4 instead of 3*n+4 into the length word (but still actually + followed it by 3*n+4 bytes of payload). + +PROP_COMPRESSION (essential) + uint32 17 Type identification + uint32 1 One byte of payload + byte comp Compression indicator; one of + 0: No compression + 1: RLE encoding + 2: zlib compression + 3: (Never used, but reserved for some fractal compression) + + PROP_COMPRESSION defines the encoding of pixels in tile data blocks in the + entire XCF file. See chapter 7 for details. + + Note that unlike most other properties whose payload is always a + small integer, PROP_COMPRESSION does _not_ pad the value to a full + 32-bit integer. + + Contemporary GIMP versions always write files with comp=1. It is unknown to + the author of this document whether versions that wrote completely + uncompressed (comp=0) files ever existed. + +PROP_GUIDES (editing state) + uint32 18 Type identification + uint32 5*n Five bytes of payload per guide + ,--------------- Repeat n times: + | int32 coord Guide coordinate + | byte o Guide orientation; one of + | 1: The guide is horizontal, and coord is a y coordinate + | 2: The guide is vertical, and coord is an x coordinate + (see enum XcfOrientationType in /app/xcf/xcf-private.h) + `-- + + PROP_GUIDES stores the horizontal or vertical positions of guides. + It appears if any guides have been defined. + + Some old XCF files define guides with negative coordinates; those + should be ignored by readers. + +PROP_PATHS + uint32 23 Type identification + uint32 plength Total length of the following payload in bytes + uint32 aindex Index of the active path + uint32 n Number of paths that follow + path_1 + path_2 + ... + path_n + + PROP_PATHS stores the paths. + + Each path has one of three formats + + Format 1: Format 2: Format 3: + string string string name Name of the path + uint32 uint32 uint32 linked 1 if the path is linked; + 0 if not + byte byte byte state 4 if closed; 2 otherwise + (for GIMP 1.2 compatibility) + uint32 uint32 uint32 closed 1 if path is closed; + 0 otherwise + uint32 uint32 uint32 np Number of points + uint32=1 uint32=2 uint32=3 version Version indicator + uint32 uint32 dummy Ignored; always set to 1 + uint32 tattoo 0 if none, or see PROP_TATTOO + ,---------- ,---------- ,------------------ Repeat for np points: + | int32 | int32 | int32 type Type of point; one of + | | | 0: Anchor + | | | 1: Bezier control point + | | | (for GIMP 1.2 compatibility) + | int32 | float | float x X coordinate + | int32 | float | float y Y coordinate + `-- `-- `-- + + This format is used to save path data if all paths in the image are + continuous sequences of Bezier strokes. Otherwise GIMP stores the paths in + PROP_VECTORS. + + Note: the attribute 'linked' was formerly erroneously called 'locked' + (but meant 'linked' anyway). + + A closed path is a path which has the last and the first point connected, + for instance a triangle. + + GIMP's XCF reader _does not_ check that the total size of all path + specifications in the property precisely equals the plength word. + Note that this is different to PROP_VECTORS. + + TODO: Clarify: PROP_PATHS cannot represent parasites for paths, but the + XCF writer does not check whether all paths are parasite-less when + choosing which property to use, so path parasites may be lost upon + saving). Is this by design or a bug? + + There may be paths that declare a length of 0 points; these should + be ignored. + +PROP_RESOLUTION (not editing state, but not _really_ essential either) + uint32 19 Type identification + uint32 8 Eight bytes of payload + float hres Horizontal resolution in pixels per inch (ppi) + float vres Vertical resolution in pixels per inch (ppi) + + PROP_RESOLUTION gives the intended physical size of the image's pixels. + + Note that for many images, such as graphics created for the web, the + creator does not really have an intended resolution in mind but + intends the image to be shown at whatever the natural resolution of + the viewer's monitor is. Similarly, photographs commonly do not have + a well-defined target size and are intended to be scaled to fit the + available space instead. Therefore readers should not interpret the + information in this property too rigidly; GIMP writes it to XCF + files unconditionally, even if the user has not explicitly chosen a + resolution. + +PROP_SAMPLE_POINTS + uint32 17 Type identification + uint32 plength Total length of the following payload in bytes + ,---------------- Repeat for each sample point: + | uint32 x X coordinate + | uint32 y Y coordinate + `-- + +PROP_UNIT (editing state) + uint32 22 Type identification + uint32 4 Four bytes of payload + uint32 uid Unit identifier; one of + 1: Inches (25.4 mm) + 2: Millimeters (1 mm) + 3: Points (127/360 mm) + 4: Picas (127/30 mm) + + PROP_UNIT specifies the units used to specify resolution in the Scale Image + and Print Size dialogs. Note that this is used only in the user interface; + the PROP_RESOLUTION property is always stored in ppi. + + To specify non-standard units use PROP_USER_UNIT. + +PROP_USER_UNIT (editing state) + uint32 24 Type identification + uint32 plength Total length of the following payload in bytes + float factor 1 inch divided by the length of the unit + uint32 digits Number of decimal digits used with the unit + string id An identifier for the unit + string symbol Short symbol for the unit + string abbrev Abbreviation for the unit + string sname Unit name in singular form + string pname Unit name in plural form + + PROP_USER_UNIT allows the use of units that are not on the standard list. + It is an alternative to PROP_UNIT. + TODO: How is this related to the unitrc file? + +PROP_VECTORS + uint32 25 Type identification + uint32 plength Total length of the following payload in bytes + uint32 1 Version tag; so far always 1 + uint32 aindex Index of the active path + uint32 n Number of paths that follow + ,---------------------- Repeat n times: + | string name Name of the path + | uint32 tattoo Tattoo of the path (see PROP_TATTOO), or 0 + | uint32 visible 1 if path is visible, 0 if not + | uint32 linked 1 if path is linked, 0 if not + | uint32 m Number of parasites for the path + | uint32 k Number of strokes in the first path + | ,-------------------- Repeat m times: + | | parasite ... In same format as in PROP_PARASITES. + | `-- + | ,-------------------- Repeat k times: + | | uint32 1 The stroke is a Bezier stroke + | | uint32 closed 1 if path is closed; 0 otherwise + | | uint32 nf Number of floats given for each point; + | | must be >= 2 and <= 6. + | | uint32 np Number of control points for this stroke + | | ,------------------ Repeat np times: + | | | uint32 type Type of the first point; one of + | | | 0: Anchor + | | | 1: Bezier control point + | | | float x X coordinate + | | | float y Y coordinate + | | | float pressure Only if nf >= 3; otherwise defaults to 1.0 + | | | float xtilt Only if nf >= 4; otherwise defaults to 0.5 + | | | float ytilt Only if nf >= 5; otherwise defaults to 0.5 + | | | float wheel Only if nf == 6; otherwise defaults to 0.5 + | | `-- + | `-- + `-- + + PROP_VECTORS stores the paths. + + It appears if all paths are continuous sequences of Bezier strokes; + otherwise PROP_PATHS is used. + + GIMP's XCF reader checks that the total size of all path + specifications in the property precisely equals the plength word, so + it is safe for a reader to use the plength word to skip the property + without parsing the individual parasites. (Note that this is _not_ + the case for PROP_PATHS). + + +4. THE CHANNEL STRUCTURE +======================== + +Channel structures are pointed to from layer structures (in case of +layer masks) or from the master image structure (for all other +channels). + + uint32 width Width of the channel + uint32 height Height of the channel + string name Name of the channel + property-list Channel properties + pointer hptr Pointer to the hierarchy structure with the pixels. + +The width and height of the channel must be the same as those of its +parent structure (the layer in the case of layer masks; the canvas for +all other channels). + + +Channel properties +------------------ + +The following properties are found only in the property list of +channel structures. Additionally the list can also contain the +properties: PROP_COLOR_TAG, PROP_END, PROP_FLOAT_OPACITY, PROP_LINKED, +PROP_LOCK_CONTENT, PROP_LOCK_POSITION, PROP_OPACITY, PROP_PARASITES, +PROP_TATTOO and PROP_VISIBLE, defined in chapter 2. + +PROP_ACTIVE_CHANNEL (editing state) + uint32 3 Type identification + uint32 0 PROP_ACTIVE_CHANNEL has no payload + + The presence of PROP_ACTIVE_CHANNEL indicates that the channel is the + currently active channel. + It appears in the property list of the currently active channel. + Only zero or one channel must have this property at any time. + +PROP_COLOR + uint32 16 Type identification + uint32 3 Three bytes of payload + byte r Red component of color + byte g Green component of color + byte b Blue component of color + + PROP_COLOR gives the color of the screen that is used to represent the channel + when it is visible in the UI. + (The alpha of the screen is given as the channel's PROP_OPACITY). + TODO: What exactly does "screen" mean here? + + While this property continues to be stored for compatibility, the new + property PROP_FLOAT_COLOR since GIMP 2.10.0 must override the value + of PROP_COLOR with float precision. + +PROP_FLOAT_COLOR (since GIMP 2.10.0, essential, commit 10360c9e130) + uint32 38 Type identification + uint32 12 Twelve bytes of payload + float r Red component of color + float g Green component of color + float b Blue component of color + + PROP_FLOAT_COLOR gives the color of the screen that is used to + represent the channel when it is visible in the UI. Each component is + in the range 0.0 to 1.0. + PROP_FLOAT_COLOR stores the same property as PROP_COLOR with float + precision. Since GIMP 2.10.0, it always appears in the property list + of channels after PROP_COLOR. This way, new readers can overwrite the + 8-bit value with proper precision whereas older readers can simply + skip PROP_FLOAT_COLOR if unknown. + +PROP_SELECTION (editing state?) + uint32 4 Type identification + uint32 0 PROP_SELECTION has no payload + + PROP_SELECTION appears in the property list of the channel structure that + represents the selection mask. + +PROP_SHOW_MASKED (editing state) + uint32 14 Type identification + uint32 4 Four bytes of payload + uint32 masked 1 if the channel is shown as a mask, 0 if not + + PROP_SHOW_MASKED specifies whether a channel is shown as a mask. + + +5. THE LAYER STRUCTURE +====================== + +Layer structures are pointed to from a list of layer pointers in the +master image structure. + + uint32 width Width of the layer + uint32 height Height of the layer + uint32 type Color mode of the layer: one of + 0: RGB color without alpha + 1: RGB color with alpha + 2: Grayscale without alpha + 3: Grayscale with alpha + 4: Indexed without alpha + 5: Indexed with alpha + (see enum GimpImageType in libgimpbase/gimpbaseenums.h) + string name Name of the layer + property-list Layer properties + pointer hptr Pointer to the hierarchy structure with the pixels + pointer mptr Pointer to the layer mask (a channel structure), or 0 + +The color mode of a layer must match that of the entire image. +All layers except the bottommost one _must_ have an alpha channel. The bottom +layer _can_ have an alpha channel. +TODO: Check whether the redundant color mode storage potentially causes errors. +Wouldn't a alpha bit/flag be sufficient? + +Exception: If the layer is a floating selection and is attached to a channel or +layer mask, then its color mode must be 3 (grayscale with alpha). + + +Layer properties +---------------- + +The following properties are found only in the property list of layer +structures. Additionally the list can also contain the properties: +PROP_COLOR_TAG, PROP_END, PROP_FLOAT_OPACITY, PROP_LINKED, +PROP_LOCK_CONTENT, PROP_LOCK_POSITION, PROP_OPACITY, PROP_PARASITES, +PROP_TATTOO and PROP_VISIBLE, defined in chapter 2. + +PROP_ACTIVE_LAYER (editing state) + uint32 2 Type identification + uint32 0 PROP_ACTIVE_LAYER has no payload + + The presence of PROP_ACTIVE_LAYER indicates that the channel is the + currently active layer. + Only zero or one layer must have this property at any time. + +PROP_APPLY_MASK (essential) + uint32 11 Type identification + uint32 4 Four bytes of payload + uint32 apply 1 if the layer mask should be applied, 0 if not + + PROP_APPLY_MASK specifies whether the layer mask shall be applied + to the layer. + If the property does not appear for a layer which has a layer mask, + it defaults to true. + + Robust readers should force this to false if the layer has no layer + mask. Writers should never save this as true unless the layer has a + layer mask. + +PROP_COMPOSITE_MODE (since GIMP 2.10.0, essential, commit 8634b5cbc31) + uint32 35 Type identification + uint32 4 Four bytes of payload + int32 mode Composite mode of the layer; one of: + 1: Union + 2: Clip to backdrop + 3: Clip to layer + 4: Intersection + See below for meaning of negative values. + + PROP_COMPOSITE_MODE records the composite mode, for layers only. A + negative value means that the composite mode was left to "Auto", + rather than explicitly set, while we still store the mapping of "Auto" + at the time of saving the XCF, by inverting it. For instance if "mode" + is -2, it means that "Auto" was set, which corresponds to "Clip to + backdrop" for this specific layer mode. + The reason for this is that we must always keep the expected output, + even if we were to change the mapping of "Auto" in the future. + + Note: as you may guess, "Auto" maps to different actual composite + modes, depending on PROP_MODE. This system makes so you don't have to + know this mapping. A XCF reader may just use the absolute value of + PROP_COMPOSITE_MODE. + +PROP_COMPOSITE_SPACE (since GIMP 2.10.0, essential, commit 8634b5cbc31) + uint32 36 Type identification + uint32 4 Four bytes of payload + int32 space Composite space of the layer; one of: + 1: RGB (linear) + 2: RGB (perceptual) + 3: LAB + See below for meaning of negative values. + + PROP_COMPOSITE_SPACE records the composite mode, for layers only. A + negative value means that the composite space was left to "Auto", + rather than explicitly set, while we still store the mapping of "Auto" + at the time of saving the XCF, by inverting it. For instance if "space" + is -3, it means that "Auto" was set, which corresponds to "LAB" + composite space for this specific layer mode. + The reason for this is that we must always keep the expected output, + even if we were to change the mapping of "Auto" in the future. + + Note: as you may guess, "Auto" maps to different actual composite + spaces, depending on PROP_MODE. This system makes so you don't have to + know this mapping. A XCF reader may just use the absolute value of + PROP_COMPOSITE_SPACE. + +PROP_BLEND_SPACE (since GIMP 2.10.0, essential, commit 8634b5cbc31) + uint32 36 Type identification + uint32 4 Four bytes of payload + int32 space Composite space of the layer; one of: + 1: RGB (linear) + 2: RGB (perceptual) + 3: LAB + See below for meaning of negative values. + + PROP_BLEND_SPACE records the blend mode, for layers only. A negative + value means that the composite space was left to "Auto", rather than + explicitly set, while we still store the mapping of "Auto" at the time + of saving the XCF, by inverting it. For instance if "space" is -3, it + means that "Auto" was set, which corresponds to "LAB" composite space + for this specific layer mode. + The reason for this is that we must always keep the expected output, + even if we were to change the mapping of "Auto" in the future. + + Note: as you may guess, "Auto" maps to different actual blend spaces, + depending on PROP_MODE. This system makes so you don't have to know + this mapping. A XCF reader may just use the absolute value of + PROP_BLEND_SPACE. + +PROP_EDIT_MASK (editing state) + uint32 12 Type identification + uint32 4 Four bytes of payload + uint32 editing 1 if the layer mask is currently being edited, 0 if not + + PROP_EDIT_MASK specifies whether the layer mask is currently being edited. + If the property does not appear for a layer which has a layer mask, + it defaults to false. + + Robust readers should force this to false if the layer has no layer + mask. Writers should never save this as true unless the layer has a + layer mask. + +PROP_FLOATING_SELECTION (essential) + uint32 5 Type identification + uint32 4 Four bytes of payload + pointer ptr Pointer to the layer or channel the floating selection is + attached to + + PROP_FLOATING_SELECTION indicates that the layer is the floating selection + and specifies the pointer to the layer, channel and layer mask it is attached + to. + It appears in the property list for the layer that is the floating selection. + Only zero or one layer must have this property at any time. + +PROP_GROUP_ITEM (since version 3) + uint32 29 Type identification + uint32 0 PROP_GROUP_ITEM has no payload + + PROP_GROUP_ITEM indicates that the layer is a layer group. + It appears in the property list if the layer is a layer group. + +PROP_ITEM_PATH (since version 3) + uint32 30 Type identification + uint32 plength Total length of the following payload in bytes + item-path List of pointers, represented as uint32 values + +TODO: The code reads that it is a list of pointers, represented as uint32 +integers and somehow in the context of layers. What this is for and what +do the property values mean? + +PROP_GROUP_ITEM_FLAGS (since version 3) + uint32 31 Type identification + uint32 4 Four bytes of payload + uint32 flags Flags for the layer, or'ed together from the following set: + 0x00000001 Layer group is expanded. + (see enum XcfGroupItemFlagsType in app/xcf/xcf-private.h) + + PROP_GROUP_ITEM_FLAGS specifies flags for the layer group. + It appears in the property list if the layer is a layer group. + +PROP_LOCK_ALPHA (editing state) +(called PROP_PRESERVE_TRANSPARENCY in GIMP before 2.3) + uint32 10 Type identification + uint32 4 Four bytes of payload + uint32 lock_alpha 1 if alpha is locked; 0 if not + + PROP_LOCK_ALPHA prevents all drawing tools in GIMP from increasing the alpha + of any pixel in the layer. Decreasing the alpha is possible. + +PROP_MODE (essential) + uint32 7 Type identification + uint32 4 Four bytes of payload + unit32 mode Layer mode; one of + * Since "ancient times": + + 0: Normal (legacy) + 1: Dissolve (legacy) [random dithering to discrete alpha) + 2: Behind (legacy) [not selectable in the GIMP UI] + 3: Multiply (legacy) + 4: Screen (legacy) + 5: Old broken Overlay + 6: Difference (legacy) + 7: Addition (legacy) + 8: Subtract (legacy) + 9: Darken only (legacy) + 10: Lighten only (legacy) + 11: Hue (HSV) (legacy) + 12: Saturation (HSV) (legacy) + 13: Color (HSL) (legacy) + 14: Value (HSV) (legacy) + 15: Divide (legacy) + 16: Dodge (legacy) + 17: Burn (legacy) + 18: Hard Light (legacy) + + * Since XCF 2 (GIMP 2.8) + 19: Soft light (legacy) + 20: Grain extract (legacy) + 21: Grain merge (legacy) + 22: Color erase (legacy) + + * Since XCF 9 (GIMP 2.10.0) + 23: Overlay + 24: Hue (LCH) + 25: Chroma (LCH) + 26: Color (LCH) + 27: Lightness (LCH) + + * Since XCF 10 (GIMP 2.10.0) + 28: Normal + 29: Behind + 30: Multiply + 31: Screen + 32: Difference + 33: Addition + 34: Subtract + 35: Darken only + 36: Lighten only + 37: Hue (HSV) + 38: Saturation (HSV) + 39: Color (HSL) + 40: Value (HSV) + 41: Divide + 42: Dodge + 43: Burn + 44: Hard light + 45: Soft light + 46: Grain extract + 47: Grain merge + 48: Vivid light + 49: Pin light + 50: Linear light + 51: Hard mix + 52: Exclusion + 53: Linear burn + 54: Luma/Luminance darken only + 55: Luma/Luminance lighten only + 56: Luminance + 57: Color erase + 58: Erase + 59: Merge + 60: Split + 61: Pass through + + PROP_MODE specifies the layer mode. + + When reading old XCF files that lack this property, assume mode==0. + The effects of the various layer modes are defined in the document + compositing.txt. + + Beware that GIMP ignores all other layer modes than Normal and + Dissolve for the bottommost visible layer of the image. If a mode>=3 has + been specified for this layer it will interpreted as mode==0 (Normal) for + display and flattening purposes. This effect happens for one layer + only: even if the bottommost visible layer covers only some (or + none) of the canvas, it will be the only layer to have its mode + forced to Normal. + + Implementation note: all layer modes are implemented as GEGL + operations. The list can be found at: + app/operations/layer-modes/gimp-layer-modes.c + The "op_name" value in particular gives the operation name allowing + reader developers to search for this string. For instance, the + "Normal" layer mode is implemented as the "gimp:normal" GEGL operation + whose implementation can be found at: + app/operations/layer-modes/gimpoperationnormal.c + +NOTE: The layer modes 'Old broken Overlay' and 'Soft light (legacy)' are identical. + +PROP_OFFSETS (essential) + uint32 15 Type identification + uint32 8 Eight bytes of payload + int32 xoffset Horizontal offset + int32 yoffset Vertical offset + + PROP_OFFSETS gives the coordinates of the upper left corner of the layer + relative to the upper left corner of the canvas. + The coordinates can be negative; this corresponds to a layer that + extends to the left of or above the canvas boundary. + + When reading old XCF files that lack this property, assume (0,0). + +PROP_SHOW_MASK (editing state) + uint32 13 Type identification + uint32 4 Four bytes of payload + uint32 visible 1 if the layer mask is visible, 0 if not + + PROP_SHOW_MASK specifies whether the layer mask is visible. + If the property does not appear for a layer which has a layer mask, + it defaults to false. + + Robust readers should force this to false if the layer has no layer + mask. Writers should never save this as true unless the layer has a + layer mask. + +PROP_TEXT_LAYER_FLAGS + uint32 26 Type identification + uint32 4 Four bytes of payload + uint32 flags Flags, or'ed together from the following set: + 0x00000001 Do _not_ change the layer name if the text + content is changed + 0x00000002 The pixel data has been painted to or otherwise + modified since the text was rendered. + (see the anonymous enum in app/text/gimptextlayer-xcf.c) + + PROP_TEXT_LAYER_FLAGS specifies the text layer behavior by flags. + It appears in property lists for text layers. + The actual text (and other parameters such as font and color) is a + parasite rather than a property. + + +6. THE HIERARCHY STRUCTURE +========================== + +A hierarchy contains data for a rectangular array of pixels. +It appears in a context: each layer and channel has a pointer to its hierarchy. + + uint32 width Width of the pixel array + uint32 height Height of the pixel array + uint32 bpp Number of bytes per pixel given + 3: RGB color without alpha + 4: RGB color with alpha + 1: Grayscale without alpha + 2: Grayscale with alpha + 1: Indexed without alpha + 2: Indexed with alpha + + pointer lptr Pointer to the "level" structure + ,-------- ------ Repeat zero or more times + | pointer dlevel Pointer to an unused level structure (dummy level) + `-- + pointer 0 Zero marks the end of the list of level pointers. + +The width, height and bpp values are for consistency checking; their +correct values can always be inferred from the context, and are +checked when GIMP reads the XCF file. + + +Levels +------ + +The level structure for the first level is laid out as follows: + + uint32 width Width of the pixel array + uint32 height Height of the pixel array + ,----------------- Repeat for each of the ceil(width/64)*ceil(height/64) tiles + | pointer tptr Pointer to tile data + `-- + pointer 0 Zero marks the end of the array of tile pointers. + +Due to oversight, in the level structures for the aforementioned +dummy levels, the "pointer" fields are "uint32" instead. + +The width and height must be the same as the ones recorded in the +hierarchy structure (except for the dummy levels). + +Ceil(x) is the smallest integer not smaller than x. + + +7. TILE DATA ORGANIZATION +========================= + +The format of the data blocks pointed to by the tile pointers in the +level structure of hierarchy differs according to the value of the +PROP_COMPRESSION property of the main image structure. Current +GIMP versions use RLE compression by default, and zlib compression +optionally. Readers should nevertheless be prepared to meet the +older uncompressed format. + +Both formats assume the width, height and byte depth of the tile are +known from the context (namely, they are stored explicitly in the +hierarchy structure for regular tiles). Both encodings store a linear sequence +of width*height pixels, extracted from the tile in row-major, +top-to-bottom, left-to-right order (the same as the reading direction +of multi-line English text). + +In color modes with alpha information, the alpha value is the last of +the 2 or 4 bytes for each pixel. In RGB color modes, the 3 (first) +bytes for each pixel is the red intensity, the green intensity, and +the blue intensity, in that order. + +Tile data, as other data in XCF format, is big-endian. In particular it +means that pixel values are stored as big-endian when the precision is +over 8-bit per channel. + +Warning: a bug during development was having pixel data saved in the +host byte order before version 12, which means that any XCF file from +version 7 to 11 may be broken when saved then loaded on machines with +different byte orders (and we cannot know for sure which byte order was +used for storage for these XCF versions, though little-endian may be a +safe assumption, considering most end-user processors are little-endian +nowadays). The stable GIMP 2.10.0 always outputs in big-endian and would +only use XCF version 7 to 11 when precision is 8-bit. Therefore if a XCF +reader tries to load a XCF 7 to 11 using over 8-bit precision, this XCF +was created with a development version of GIMP (therefore unsupported) +and byte-order is unspecified. + +Uncompressed tile data +---------------------- + +In the uncompressed format the file first contains all the bytes for +the first pixel, then all the bytes for the second pixel, and so on. + +zlib compressed tile data +------------------------ + +In the zlib compressed format, each tile is compressed as-is (pixel +after pixel) with zlib. + +RLE compressed tile data +------------------------ + +In the Run-Length Encoded format, each tile consists of a run-length +encoded stream of the first byte of each pixel, then a stream of the +second byte of each pixel, and so forth. In each of the streams, +multiple occurrences of the same byte value are represented in +compressed form. The representation of a stream is a series of +operations; the first byte of each operation determines the format and +meaning of the operation (opcode): + + byte n For 0 <= n <= 126: a short run of identical bytes + byte v Repeat this value n+1 times +or + byte 127 A long run of identical bytes + byte p + byte q + byte v Repeat this value p*256 + q times +or + byte 128 A long run of different bytes + byte p + byte q + byte[p*256+q] data Copy these verbatim to the output stream +or + byte n For 129 <= n <= 255: a short run of different bytes + byte[256-n] data Copy these verbatim to the output stream + +The end of the stream for "the first byte of all pixels" (and the +following similar streams) must occur at the end of one of these +operations; it is not permitted to have one operation span the +boundary between streams. + +The RLE encoding can cause degenerated encodings in which the original +data stream may double in size (or grow to arbitrarily large sizes if +(128,0,0) operations are inserted). Such encodings must be avoided, as +GIMP's XCF reader expects that the size of an encoded tile is +never more than 24 KB, which is only 1.5 times the unencoded size of a +64x64 RGBA tile. + +A simple way for an XCF creator to avoid overflow is + a) never using opcode 0 (but instead opcode 255) + b) using opcodes 127 and 128 only for lengths larger than 127 + c) never emitting two "different bytes" opcodes next to each other + in the encoding of a single stream. + +TODO: If each tile has a maximum of 64 pixels (resulting in a maximum of 64 +bytes for each color in this tile), do values>64 and long runs apply at all? + + +8. MISCELLANEOUS +================ + + +The name XCF +------------ + +The name XCF honors GIMP's origin at the eXperimental Computing +Facility of the University of California at Berkeley. + +TODO: Integrate this document into the API doc. + +TODO: Some properties are denoted with "essential", +"editing state", "not editing state, but not really +essential either". What did the original author Henning Makholm mean? + +TODO: What will happen with the format after the GEGL +port? AFAIK the ORA format will play a big role in +the GEGL context (correct me if I'm wrong). +Will XCF be dropped then or will ORA then be yet +another import/export format like PSD etc.? + + -- cgit v1.2.3