/*
 * @(#)JFIFSegments.txt  1.0  2008-10-14
 *
 * Copyright (c) 2008 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.
 */

/**
 * This file contains the description of some
 * well known segments of the JPEG File Interchange Format (JFIF)
 * as published in
 *   Pennebaker, W., Mitchell, J. (1993).
 *   JPEG Still Image Data Compression Standard.
 *   Chapmann & Hall, New York.
 *   ISBN 0-442-01272-1
 *
 *
 * @author Werner Randelshofer, Hausmatt 10, CH-6405 Immensee, Switzerland
 * @version 1.0 2008-10-14 Created. 
 */

/* ============================================
 *
 * Segments
 *
 * ============================================
 */
magic data "0";
description data "Entropy-encoded data", "Entropy-encoded data.";
magic junk "ffffffff";
description junk "Junk", "Junk data.";

magic SOF0 "ffc0";
description SOF0 "SOF0 Start of Frame", "Marks the start of nondifferential Huffman-coding frames with baseline DCT.";
magic SOF1 "ffc1";
description SOF "SOF1 Start of Frame", "Marks the start of nondifferential Huffman-coding frames with extended sequential DCT.";
magic SOF2 "ffc2";
description SOF2 "SOF2 Start of Frame", "Marks the start of nondifferential Huffman-coding frames with progressive DCT.";
magic SOF3 "ffc3";
description SOF3 "SOF3 Start of Frame", "Marks the start of nondifferential Huffman-coding frames with lossless (sequential) data.";

magic SOF5 "ffc5";
description SOF5 "SOF5 Start of Frame", "Marks the start of differential Huffman-coding frames with differential sequential DCT.";
magic SOF6 "ffc6";
description SOF6 "SOF6 Start of Frame", "Marks the start of differential Huffman-coding frames with differential progressive DCT.";
magic SOF7 "ffc7";
description SOF7 "SOF7 Start of Frame", "Marks the start of differential Huffman-coding frames with differential lossless data.";

magic SOF9 "ffc9";
description SOF9 "SOF9 Start of Frame", "Marks the start of nondifferential Arithmetic-coding frames with extended sequential DCT.";
magic SOF10 "ffca";
description SOF10 "SOF10 Start of Frame", "Marks the start of nondifferential Arithmetic-coding frames with progressive DCT.";
magic SOF11 "ffcb";
description SOF11 "SOF11 Start of Frame", "Marks the start of nondifferential Arithmetic-coding frames with lossless (sequential) data.";

magic SOF13 "ffcd";
description SOF "SOF13 Start of Frame", "Marks the start of differential Arithmetic-coding frames with differential sequential DCT.";
magic SOF14 "ffce";
description SOF "SOF14 Start of Frame", "Marks the start of differential Arithmetic-coding frames with differential progressive DCT.";
magic SOF15 "ffcf";
description SOF "SOF15 Start of Frame", "Marks the start of differential Arithmetic-coding frames with differential lossless DCT.";

magic APP0 "ffe0";
description APP0 "APP0 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP1 "ffe1";
description APP1 "APP1 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP2 "ffe2";
description APP2 "APP2 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP3 "ffe3";
description APP3 "APP3 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP4 "ffe4";
description APP4 "APP4 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP5 "ffe5";
description APP5 "APP5 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP6 "ffe6";
description APP6 "APP6 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP7 "ffe7";
description APP7 "APP7 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP8 "ffe8";
description APP8 "APP8 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP9 "ffe9";
description APP9 "APP9 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP10 "ffea";
description APP10 "APP10 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP11 "ffeb";
description APP11 "APP11 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP12 "ffec";
description APP12 "APP12 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP13 "ffed";
description APP13 "APP13 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP14 "ffee";
description APP14 "APP14 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";
magic APP15 "ffef";
description APP15 "APP15 Reserved for application use", "This segment may be defined differently for different applications. The JPEG DIS states that APP-segments should be removed when data is transferred between application environments, but this is not mandatory. If two applications require conflicting usage of an APP-segment, checking of the data may be needed.";

magic JPG0 "fff0";
description JPG0 "JPG0 Reserved for JPEG extensions", "";
magic JPG1 "fff1";
description JPG1 "JPG1 Reserved for JPEG extensions", "";
magic JPG2 "fff2";
description JPG2 "JPG2 Reserved for JPEG extensions", "";
magic JPG3 "fff3";
description JPG3 "JPG3 Reserved for JPEG extensions", "";
magic JPG4 "fff4";
description JPG4 "JPG4 Reserved for JPEG extensions", "";
magic JPG5 "fff5";
description JPG5 "JPG5 Reserved for JPEG extensions", "";
magic JPG6 "fff6";
description JPG6 "JPG6 Reserved for JPEG extensions", "";
magic JPG7 "fff7";
description JPG7 "JPG7 Reserved for JPEG extensions", "";
magic JPG8 "fff8";
description JPG8 "JPG8 Reserved for JPEG extensions", "";
magic JPG9 "fff9";
description JPG9 "JPG9 Reserved for JPEG extensions", "";
magic JPG10 "fffa";
description JPG10 "JPG10 Reserved for JPEG extensions", "";
magic JPG11 "fffb";
description JPG11 "JPG11 Reserved for JPEG extensions", "";
magic JPG12 "fffc";
description JPG12 "JPG12 Reserved for JPEG extensions", "";
magic JPG13 "fffd";

magic COM "fffe";
description COM "COM Comment", "The comment marker segment is intended for text fields. It may not contain information that could affect decoding. JPEG has not specified the character set to be used in this segment.";

magic DAC "ffcc";
description DAC "DAC Define arithmetic conditioning table(s)", "This segment defines one or more tables of parameters for the conditioning of the probability estimates used in the arithmetic coding procedures.";
magic DHP "ffde";
description DHP "DHP Define hierarchical progression", "This segment defines the dimensions, components and relative sampling of the final image of the hierarchical progression. It must precede the first frame of the progression.";
magic DHT "ffc4";
description DHT "DHT Define Huffman table(s)", "Defines one or more Huffman tables.";
magic DNL "ffdc";
description DNL "DNL Define number of lines", "Defines or redefines the number of lines of the image after the first scan.";
magic DQT "ffdb";
description DQT "DQT Define quantization table(s)", "Defines one or more quantization tables for DCT-based algorithms.";
magic DRI "ffdd";
description DRI "DRI Define restart interval", "Sets or resets the restart interval.";

magic EOI "ffd9";
description EOI "EOI End of Image Marker", "This marker segment terminates the JPEG compressed data stream.";

magic EXP "ffdf";
description EXP "EXP Expand reference image(s)", "This segment signals the expansion of the spatial resolution of the reference data needed by the hierarchical differential frame that follows.";

magic RST0 "ffd0";
description RST0 "RST0 Restart with modulo 8 counter 0", "The restart marker is appended to the compressed data between restart intervals. This marker segment provides a byte-aligned code that can be located by scanning the compressed data.";
magic RST1 "ffd1";
description RST1 "RST1 Restart with modulo 8 counter 1", "The restart marker is appended to the compressed data between restart intervals. This marker segment provides a byte-aligned code that can be located by scanning the compressed data.";
magic RST2 "ffd2";
description RST2 "RST2 Restart with modulo 8 counter 2", "The restart marker is appended to the compressed data between restart intervals. This marker segment provides a byte-aligned code that can be located by scanning the compressed data.";
magic RST3 "ffd3";
description RST3 "RST3 Restart with modulo 8 counter 3", "The restart marker is appended to the compressed data between restart intervals. This marker segment provides a byte-aligned code that can be located by scanning the compressed data.";
magic RST4 "ffd4";
description RST4 "RST4 Restart with modulo 8 counter 4", "The restart marker is appended to the compressed data between restart intervals. This marker segment provides a byte-aligned code that can be located by scanning the compressed data.";
magic RST5 "ffd5";
description RST5 "RST5 Restart with modulo 8 counter 5", "The restart marker is appended to the compressed data between restart intervals. This marker segment provides a byte-aligned code that can be located by scanning the compressed data.";
magic RST6 "ffd6";
description RST6 "RST6 Restart with modulo 8 counter 6", "The restart marker is appended to the compressed data between restart intervals. This marker segment provides a byte-aligned code that can be located by scanning the compressed data.";
magic RST7 "ffd7";
description RST7 "RST7 Restart with modulo 8 counter 7", "The restart marker is appended to the compressed data between restart intervals. This marker segment provides a byte-aligned code that can be located by scanning the compressed data.";


magic SOI "ffd8";
description SOI "SOI Start of Image Marker", "This marker begins the compressed data stream.";
magic SOS "ffda";
description SOS "SOS Start of Scan", "This marker begins a scan header. The scan header is always followed immediately by entropy-coded data for the scan.";

magic TEM "ff01";
description TEM "TEM Temporary Private Use Marker", "This maker is for temporary private use in arithmetic coding";

// ------------------
// SOF Start of frame
// ------------------
typedef struct { 
    ubyte   componentIdentifier;
    uint4   horizontalSamplingFactor;
    uint4   verticalSamplingFactor;
    ubyte   quantizationTableDestinationSelector;
} SOFFrameComponent;

typedef struct { 
    ubyte   samplePrecision;
    ushort  numberOfLines;
    ushort  numberOfSamplesPerLine;
    ubyte   numberOfComponentsInFrame;
    SOFFrameComponent[numberOfComponentsInFrame] frameComponent;
} SOF0;

typedef SOF0 SOF1;
typedef SOF0 SOF2;
typedef SOF0 SOF3;

typedef SOF0 SOF5;
typedef SOF0 SOF6;
typedef SOF0 SOF7;

typedef SOF0 SOF9;
typedef SOF0 SOF10;
typedef SOF0 SOF11;
typedef SOF0 SOF13;
typedef SOF0 SOF14;
typedef SOF0 SOF15;

// ------------------
// SOS Scan Header
// ------------------
typedef struct { 
    ubyte   scanComponentSelector;
    uint4   dcEntropyCodingTableSelector;
    uint4   acEntropyCodingTableSelector;
} SOSScanComponentSpec;

typedef struct { 
    ubyte   numberOfComponentsInScan;
    SOSScanComponentSpec[numberOfComponentsInScan] scanComponent;
    ubyte   startOfSpectralSelectionOrPredictorComponent;
    ubyte   endOfSpectralSelection;
    uint4   successiveApproximationBitPositionHigh;
    uint4   successiveApproximationBitPositionLowOrPointTransform;
    ubyte[]  data;
} SOS;

// ------------------
// APP Application data
// ------------------
/*
typedef struct {
    ubyte[] data;
} APP0;

typedef APP0 APP1;
typedef APP0 APP2;
typedef APP0 APP3;
typedef APP0 APP4;
typedef APP0 APP5;
typedef APP0 APP6;
typedef APP0 APP7;
typedef APP0 APP8;
typedef APP0 APP9;
typedef APP0 APP10;
typedef APP0 APP11;
typedef APP0 APP12;
typedef APP0 APP13;
typedef APP0 APP14;
typedef APP0 APP15;
*/
// ------------------
// COM Comment
// ------------------
typedef struct {
    charbyte[] text;
} COM;

// ------------------
// DAC 
// ------------------
enum {
    DC = 0,
    AC = 1
} DACTableClassEnum;
typedef struct {
    uint4 enum DACTableClassEnum tableClass;
    uint4   arithmeticCodingConditioningIdentifier;
    ubyte   conditioningTableValue;
} DACTable;
typedef struct {
    ushort  tableCount;
    DACTable[tableCount] table;
} DAC;

// ------------------
// DQT 
// ------------------
typedef struct {
    uint4   quantizationTableElementPrecision;
    uint4   quantizationTableIdentifier;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement0;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement1;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement2;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement3;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement4;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement5;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement6;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement7;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement8;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement9;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement10;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement11;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement12;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement13;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement14;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement15;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement16;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement17;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement18;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement19;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement20;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement21;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement22;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement23;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement24;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement25;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement26;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement27;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement28;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement29;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement30;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement31;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement32;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement33;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement34;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement35;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement36;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement37;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement38;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement39;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement40;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement41;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement42;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement43;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement44;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement45;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement46;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement47;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement48;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement49;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement50;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement51;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement52;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement53;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement54;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement55;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement56;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement57;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement58;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement59;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement60;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement61;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement62;
    ubyte[quantizationTableElementPrecision+1]   quantizationTableElement63;
} DQTTable;
typedef struct {
    DQTTable[] table;
} DQT;

// ------------------
// DHT 
// ------------------
enum {
    DC = 0,
    AC = 1
} DHTTableClassEnum;

typedef struct {
    uint4 enum DHTTableClassEnum tableClass;
    uint4 tableIdentifier;
    ubyte numberOfCodesOfLength1;
    ubyte numberOfCodesOfLength2;
    ubyte numberOfCodesOfLength3;
    ubyte numberOfCodesOfLength4;
    ubyte numberOfCodesOfLength5;
    ubyte numberOfCodesOfLength6;
    ubyte numberOfCodesOfLength7;
    ubyte numberOfCodesOfLength8;
    ubyte numberOfCodesOfLength9;
    ubyte numberOfCodesOfLength10;
    ubyte numberOfCodesOfLength11;
    ubyte numberOfCodesOfLength12;
    ubyte numberOfCodesOfLength13;
    ubyte numberOfCodesOfLength14;
    ubyte numberOfCodesOfLength15;
    ubyte numberOfCodesOfLength16;
    uint8[numberOfCodesOfLength1] valuesOfCodesOfLength1;
    uint8[numberOfCodesOfLength2] valuesOfCodesOfLength2;
    uint8[numberOfCodesOfLength3] valuesOfCodesOfLength3;
    uint8[numberOfCodesOfLength4] valuesOfCodesOfLength4;
    uint8[numberOfCodesOfLength5] valuesOfCodesOfLength5;
    uint8[numberOfCodesOfLength6] valuesOfCodesOfLength6;
    uint8[numberOfCodesOfLength7] valuesOfCodesOfLength7;
    uint8[numberOfCodesOfLength8] valuesOfCodesOfLength8;
    uint8[numberOfCodesOfLength9] valuesOfCodesOfLength9;
    uint8[numberOfCodesOfLength10] valuesOfCodesOfLength10;
    uint8[numberOfCodesOfLength11] valuesOfCodesOfLength11;
    uint8[numberOfCodesOfLength12] valuesOfCodesOfLength12;
    uint8[numberOfCodesOfLength13] valuesOfCodesOfLength13;
    uint8[numberOfCodesOfLength14] valuesOfCodesOfLength14;
    uint8[numberOfCodesOfLength15] valuesOfCodesOfLength15;
    uint8[numberOfCodesOfLength16] valuesOfCodesOfLength16;
} DHTTable;

typedef struct {
    DHTTable[] table;
} DHT;

// ------
// DRI
// ------
typedef struct {
    ushort restartInterval;
} DRI;
