/*
 * @(#)PNGChunks.txt  1.0  2010-06-25
 *
 * Copyright (c) 2010 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */

/**
 * Portable Network Graphics Specification (Second Edition)
 * http://www.libpng.org/pub/png/spec/iso/index-noobject.html
 */

// *******
// bKGD
// ********
magic bKGD "bKGD";
description bKGD "Background colour",
    "The bKGD chunk specifies a default background colour to present the image"
    +" against."
    +"<br><br>If there is any other preferred background, either user-specified or"
    +" part of a larger page (as in a browser), the bKGD chunk should be"
    +" ignored."
    +"<br><br>For colour type 3 (indexed-colour), the value is the palette index of"
    +" the colour to be used as background. For colour types 0 and 4"
    +" (greyscale, greyscale with alpha), the value is the grey level to be"
    +" used as background in the range 0 to (2^bitdepth)-1. For colour types 2"
    +" and 6 (truecolour, truecolour with alpha), the values are the colour to"
    +" be used as background, given as RGB samples in the range 0 to"
    +" (2^bitdepth)-1. In each case, for consistency, two bytes per sample are"
    +" used regardless of the image bit depth. If the image bit depth is less"
    +" than 16, the least significant bits are used and the others are 0.";



// *******
// cHRM
// ********
magic cHRM "cHRM";
description cHRM "Primary chromaticities and white point", 
    "The cHRM chunk may be used to specify the 1931 CIE x,y chromaticities of"
    +" the red, green, and blue display primaries used in the image, and the"
    +" referenced white point."
    +"<br><br>Each value is encoded as a four-byte PNG unsigned integer,"
    +" representing the x or y value times 100000. A value of 0.3127 would be"
    +" stored as the integer 31270.";

typedef struct {
    uint whitePointX;
    uint whitePointY;
    uint redX;
    uint redY;
    uint greenX;
    uint greenY;
    uint blueX;
    uint blueY;
} cHRM;

// *******
// gAMA
// ********
magic gAMA "gAMA";
description gAMA "Image gamma", 
    "The gAMA chunk specifies the relationship between the image samples and"
    +" the desired display output intensity."
    +"<br><br>The value is encoded as a four-byte PNG unsigned integer,"
    +" representing gamma times 100000. A gamma of 1/2.2 would be stored as the"
    +" integer 45455.";

typedef struct {
    uint imageGamma;
} gAMA;

// *******
// hIST
// ********
magic hIST "hIST";
description hIST "Image histogram",
    "The hIST chunk gives the approximate usage frequency of each colour in the"
    +" palette."
    +"<br><br>A histogram chunk can appear only when a PLTE chunk appears. If a"
    +" viewer is unable to provide all the colours listed in the palette, the"
    +" histogram may help it decide how to choose a subset of the colours for"
    +" display.";

typedef struct {
    ushort frequency[];
} hIST;

// *******
// iCCP
// ********
magic iCCP "iCCP";
description iCCP "Embedded ICC profile", "If the iCCP chunk is present, the image samples conform to the colour space represented by the embedded ICC profile as defined by the International Color Consortium. The colour space of the ICC profile shall be an RGB colour space for colour images (PNG colour types 2, 3, and 6), or a greyscale colour space for greyscale images (PNG colour types 0 and 4). A PNG encoder that writes the iCCP chunk is encouraged to also write gAMA and cHRM chunks that approximate the ICC profile, to provide compatibility with applications that do not use the iCCP chunk. When the iCCP chunk is present, PNG decoders that recognize it and are capable of colour management shall ignore the gAMA and cHRM chunks and use the iCCP chunk instead and interpret it. PNG decoders that are used in an environment that is incapable of full-fledged colour management should use the gAMA and cHRM chunks if present.";

enum {
    zlibWithDeflate=0
} iCCPCompressionMethod;


typedef struct {
    cstring profileName;
    ubyte enum iCCPCompressionMethod compressionMethod;
    ubyte[] compressedProfile;
} iCCP;

// *******
// IDAT
// ********
magic IDAT "IDAT";
description IDAT "Image data", 
    "The IDAT chunk contains the actual image data which is the output stream"
    +" of the compression algorithm."
    +"<br><br>There may be multiple IDAT chunks; if so, they shall appear"
    +" consecutively with no other intervening chunks. The compressed"
    +" datastream is then the concatenation of the contents of the data fields"
    +" of all IDAT chunks.";

// typedef intentionally left out.

// *******
// IEND
// ********
magic IEND "IEND";
description IEND "Image trailer", 
    "The IEND chunk marks the end of the PNG datastream. The chunk's data field"
    +" is empty.";


// *******
// IHDR
// ********
magic IHDR "IHDR";
description IHDR "Image header",
    "The IHDR chunk shall be the first chunk in the PNG datastream.";

enum {
    greyscale=0,
    truecolour=2,
    indexedColour=3,
    greyscaleWithAlpha=4,
    truecolourWithAlpha=6
} IHDRColourType;

enum {
    deflate=0
} IHDRCompressionMethod;

enum {
    adaptive=0
} IHDRFilterMethod;

enum {
    noInterlace=0,
    adam7Interlace=1
} IHDRInterlaceMethod;

typedef struct {
    uint width;
    uint height;
    ubyte bitDepth;
    ubyte enum IHDRColourType colourType;
    ubyte enum IHDRCompressionMethod compressionMethod;
    ubyte enum IHDRFilterMethod filterMethod;
    ubyte enum IHDRInterlaceMethod interlaceMethod;
} IHDR;

// *******
// iTXt
// ********
magic iTXt "iTXt";
description iTXt "International textual data", "";

enum {
    uncompressed=0,
    compressed=1
} iTXtCompressionFlag;

enum {
    zlibWithDeflate=0
} iTXtCompressionMethod;

typedef struct {
    cstring keyword; /* ISO Latin-1 */
    ubyte enum iTXtCompressionFlag compressionFlag;
    ubyte enum iTXtCompressionMethod compressionMethod;
    cstring languageTag; /* ISO Latin-1 */
    utf8 translatedKeyword; /* UTF-8 */
    utf8 text; /* UTF-8 */
} iTXt;

// *******
// pHYs
// ********
magic pHYs "pHYs";
description pHYs "Physical pixel dimensions", 
    "The pHYs chunk specifies the intended pixel size or aspect ratio for"
    +" display of the image.";

enum {
    unknown=0,
    metre=1
} pHYsUnitSpecifier;

typedef struct {
    uint pixelsPerUnitXAxis;
    uint pixelsPerUnitYAxis;
    ubyte enum pHYsUnitSpecifier unitSpecifier;
} pHYs;

// *******
// PLTE
// ********
magic PLTE "PLTE";
description PLTE "Palette",
    "The PLTE chunk contains from 1 to 256 palette entries, each a three-byte series.";

typedef struct {
    uint8[3] rgb[];
} PLTE;


// *******
// sBIT
// ********
magic sBIT "sBIT";
description sBIT "Significant bits",
    "To simplify decoders, PNG specifies that only certain sample depths may be"
    +" used, and further specifies that sample values should be scaled to the"
    +" full range of possible values at the sample depth."
    +"<br><br>The sBIT chunk defines the original number of significant bits"
    +" (which can be less than or equal to the sample depth). This allows PNG"
    +" decoders to recover the original data losslessly even if the data had a"
    +" sample depth not directly supported by PNG.";

typedef struct {
    ubyte significantBits[];
} sBIT;

// *******
// sPLT
// ********
magic sPLT "sPLT";
description sPLT "Suggested palette",
    "Each palette entry is six bytes or ten bytes containing five unsigned"
    +" integers (red, blue, green, alpha, and frequency).";

typedef struct {
    cstring paletteName;
    ubyte sampleDepth;
    byte[] entries;
} sPLT;

// *******
// sRGB
// ********
magic sRGB "sRGB";
description sRGB "Standard RGB colour space", 
    "If the sRGB chunk is present, the image samples conform to the sRGB colour"
    +" space and should be displayed using the specified rendering intent"
    +" defined by the International Color Consortium."
    +"<br><br>It is recommended that a PNG encoder that writes the sRGB chunk"
    +" also write a gAMA chunk (and optionally a cHRM chunk) for compatibility"
    +" with decoders that do not use the sRGB chunk.";

enum {
    perceptual=0,
    relativeColorimetric=1,
    saturation=2,
    absoluteColorimetric=3
} sRGBRenderingIntent;

typedef struct {
    ubyte enum sRGBRenderingIntent renderingIntent;
} sRGB;

// *******
// tEXt
// ********
magic tEXt "tEXt";
description tEXt "Textual data",
    "Each tEXt chunk contains a keyword and a text string.";

typedef struct {
    cstring keyword; /* ISO Latin-1 */
    cstring text; /* ISO Latin-1 */
} tEXt;

// *******
// tIME
// ********
magic tIME "tIME";
description tIME "Image last-modification time",
    "The tIME chunk gives the time of the last image modification (not the time"
    +" of initial image creation).";

typedef struct {
    ushort year;
    ubyte month;
    ubyte day;
    ubyte hour;
    ubyte minute;
    ubyte second;
} tIME;

// *******
// tRNS
// ********
magic tRNS "tRNS";
description tRNS "Transparency",
    "The tRNS chunk specifies either alpha values that are associated with"
    +" palette entries (for indexed-colour images) or a single transparent"
    +" colour (for greyscale and truecolour images)."
    +"<br><br>For colour type 3 (indexed-colour), the tRNS chunk contains a"
    +" series of one-byte alpha values, corresponding to entries in the PLTE"
    +" chunk. Each entry indicates that pixels of the corresponding palette"
    +" index shall be treated as having the specified alpha value. Alpha values"
    +" have the same interpretation as in an 8-bit full alpha channel: 0 is"
    +" fully transparent, 255 is fully opaque, regardless of image bit depth."
    +"<br><br>For colour types 0 or 2 (grayscale or truecolour), two bytes per"
    +" sample are used regardless of the image bit depth.";


// *******
// zTXt
// ********
magic zTXt "zTXt";
description zTXt "Compressed textual data", 
    "The zTXt and tEXt chunks are semantically equivalent, but the zTXt chunk"
    +" is recommended for storing large blocks of text.";

enum {
    zlibWithDeflate=0
} zTXtCompressionMethod;


typedef struct {
    cstring keyword; /* ISO Latin-1 */
    ubyte enum zTXtCompressionMethod compressionMethod;
    byte[] compressedTextDatastream; /* ISO Latin-1 */
} zTXt;
