Skip to content

Instantly share code, notes, and snippets.

@kkkrackpot
Created November 29, 2016 11:31
Show Gist options
  • Select an option

  • Save kkkrackpot/292062e13111f7506135351821a575cc to your computer and use it in GitHub Desktop.

Select an option

Save kkkrackpot/292062e13111f7506135351821a575cc to your computer and use it in GitHub Desktop.
3dlut file specification
________________________________________________________________________________
3DL2 file format specification
http://forum.doom9.org/showthread.php?p=1525672#post1525672
________________________________________________________________________________
enum {PAGE_SIZE = 16384};
struct H3DLUT2
{
byte signature[4]; // file signature; must be: “3DL2” as encoded using the ASCII standard (0x33444C32)
int fileVersion; // file format version number (currently 2)
byte programName[32]; // name of the program that created the file
long programVersion; // version number of the program that created the file
int inputBitDepth[3]; // input bit depth per component (Y,Cb,Cr or B,G,R)
int inputColorEncoding; // input color encoding standard (0 = BGR, 1 = YCbCr)
int inputValueRange; // value range for the input (0 = Full range (0-255), 1 = Limited (16-235)) [up to v1]
int outputBitDepth; // output bit depth for all components (valid values are 8, 16, 32 and 64)
int outputColorEncoding; // output color encoding standard (0 = BGR, 1 = YCbCr, 2 = XYZ)
int outputValueRange; // value range for the output
int parametersFileOffset; // number of bytes between the beginning of the file and array 'parametersData'
int parametersSize; // size in bytes of the array 'parametersData'
int lutFileOffset; // number of bytes between the beginning of the file and array lutData
int lutCompressionMethod; // type of compression used if any (0 = none, 1 = LZO, ...)
int lutCompressedSize; // size in bytes of the array 'lutData' inside the file, whether compressed or not
PRIMARIES inputColorSpace; // Input color space - this section is strictly optional,
// a value of 0 for all means “disabled/unknown”
PRIMARIES outputColorSpace; // Output color space - the same rules apply as for input color space.
// In addition, if the output is XYZ, this section is to be set to 0 for all values
// This header is followed by the byte array 'parametersData', of length 'parametersSize',
// and by the array 'lutDataxx', of length 'lutCompressedSize'.
};
struct PRIMARIES
{
double primaryRedx; // The x and y refer here to the coordinates on the CIE xy chromaticity diagram,
double primaryRedy; // Y is assumed to be 1.0 for these primaries
double primaryGreenx;
double primaryGreeny;
double primaryBluex;
double primaryBluey;
double primaryWhitex;
double primaryWhitey;
};
byte parametersData[1];
union LUTDATA
{
byte lutData8[1];
ushort lutData16[1];
float lutData32[1];
double lutData64[1];
};
// The array 'parametersData' starts 'parametersFileOffset' bytes after the beginning of the file.
// The array 'lutDataxx' starts 'lutFileOffset' bytes after the beginning of the file.
// When creating a 3DLUT2 file, 'lutDataxx' should be positioned on a 16384 byte boundary.
//
// parametersData - byte array with size 'parametersSize' that contains an exact copy of the
// input file with the commands and settings used for creating the 3DLUT2 file
//
// lutDataxx - array with size lutSizeUncompressed that contains the 3D LUTs output values.
// The type used depends on the outputBitDepth field:
// - unsigned byte, if outputBitDepth = 8
// - unsigned short, if outputBitDepth = 16
// - float, if outputBitDepth = 32
// - double, if outputBitDepth = 64
//
// The value ranges are assumed to be as follows:
// Full range (integers): 0 to (2∧depth)−1, for example 0–255 and 0–65535
// Full range (floats): 0 to 1
// Limited range (integers): 16–235, left/right shifted to the correct bit depth, eg. 4096–60160)
// Limited range (floats): (16÷255)≈0.06275 to (235÷255)≈0.92157.
//
// For XYZ output:
// XYZ must be appropriately normalized so that the luminosity of white = the range limit.
// eg. for limited range 8-bit output, the luminosity of white would be 235. If the value range is full range,
// this would mean that the values are essentially capped to 255. As such, using limited range for XYZ is
// preferable for integer output. It is strongly recommended that one uses full range floats for XYZ however,
// where the luminosity of white would be normalized to 1.0
//
// The offset inside the array is calculated as:
// offset = (A + B << (inputBitDepth[0]) + C << (inputBitDepth[1]+inputBitDepth[0])) × 3
//
// The output order inside the array is:
// A = lutDataxx[offset]; B = lutDataxx[offset+1]; C = lutDataxx[offset+2]
//
// A, B and C refer to the respective channels of the used encoding (eg. B, G, R or Y', Cb, Cr)
//
// The lutUncompressedSize of the array is calculated as:
// lutDim = 3 × 2∧inputBitDepth[0] × 2∧inputBitDepth[1] × 2∧inputBitDepth[2] × outputBitDepth÷8
//
// This specification assumes:
// byte = 1 byte; short = 2 byte; int = 4 byte; long = 8 byte; // integers
// float = 4 byte; double = 8 byte; // floating point numbers
//
// << is used to denote an arithmetic left shift operator. Where strict/large inequality is wanted, ≪ is used.
________________________________________________________________________________
3DLUT file format specification
https://sourceforge.net/projects/thr3dlut/
________________________________________________________________________________
enum {PAGE_SIZE = 16384};
struct H3DLUT
{
char signature[4]; // file signature; must be: '3DLT'
long fileVersion; // file format version number (currently "1")
char programName[32]; // name of the program that created the file
long long programVersion; // version number of the program that created the file
long inputBitDepth[3]; // input bit depth per component (Y,Cb,Cr or R,G,B)
long inputColorEncoding; // input color encoding standard
long outputBitDepth; // output bit depth for all components (valid values are 8, 16 and 32)
long outputColorEncoding; // output color encoding standard
long parametersFileOffset; // number of bytes between the beginning of the file and array parametersData
long parametersSize; // size in bytes of the array parametersData
long lutFileOffset; // number of bytes between the beginning of the file and array lutData
long lutCompressionMethod; // type of compression used if any (0 = none, ...)
long lutCompressedSize; // size in bytes of the array lutData inside the file, whether compressed or not
long lutUncompressedSize; // true size in bytes of the array lutData when in memory for usage (outside the file)
// This header is followed by the char array 'parametersData', of length 'parametersSize',
// and by the array 'lutDataxx', of length 'lutCompressedSize'.
};
char parametersData[1];
union LUTDATA
{
unsigned char lutData8[1];
unsigned short lutData16[1];
float lutData32[1];
};
// The array 'parametersData' starts 'parametersFileOffset' bytes after the beginning of the file.
// The array 'lutDataxx' starts 'lutFileOffset' bytes after the beginning of the file.
// When creating a 3DLUT file, 'lutDataxx' should be positioned on a 16384 byte boundary.
//
// parametersData - char array with size parametersSize that contains an exact copy of the
// input file with the commands and settings used for creating the 3DLUT file
// lutDataxx - array with size lutSizeUncompressed that contains the 3D LUTs output values.
// The type used depends on the 'outputBitDepth' field:
// - unsigned char, if outputBitDepth = 8
// - unsigned short, if outputBitDepth = 16
// - float, if outputBitDepth = 32
// The offset inside the array is calculated as:
// offset = (cr<<(inputBitDepth[1]+inputBitDepth[0])+cb<<(inputBitDepth[0])+y)*3 // YCbCr input
// offset = ( r<<(inputBitDepth[1]+inputBitDepth[0])+ g<<(inputBitDepth[0])+b)*3 // RGB input
// The output order inside the array is:
// Y = lutDataxx(offset); Cb = lutDataxx(offset+1); Cr = lutDataxx(offset+2) // YCbCr output
// B = lutDataxx(offset); G = lutDataxx(offset+1); R = lutDataxx(offset+2) // RGB output
// The 'lutUncompressedSize' of the array is calculated as:
// lutDim = 3*(2^inputBitDepth[0]*2^inputBitDepth[1]*2^inputBitDepth[2])
// lutUncompressedSize = lutDim*outputBitDepth/8
// This specification assumes: char = 1 byte; short = 2 byte; float = 4 byte; long = 4 byte; long long = 8 byte
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment