KTX File Format Specification22nd December 2018
© 2013-2018 The Khronos Group Inc. All Rights Reserved. See license. AbstractKTX is a format for storing textures for OpenGL® and OpenGL® ES applications. It is distinguished by the simplicity of the loader required to instantiate a GL texture object from the file contents. Status of this documentThis is the approved final specification. Table of contentsFile StructureByte[12] identifier UInt32 endianness UInt32 glType UInt32 glTypeSize UInt32 glFormat Uint32 glInternalFormat Uint32 glBaseInternalFormat UInt32 pixelWidth UInt32 pixelHeight UInt32 pixelDepth UInt32 numberOfArrayElements UInt32 numberOfFaces UInt32 numberOfMipmapLevels UInt32 bytesOfKeyValueData for each keyValuePair that fits in bytesOfKeyValueData UInt32 keyAndValueByteSize Byte keyAndValue[keyAndValueByteSize] Byte valuePadding[3 - ((keyAndValueByteSize + 3) % 4)] end for each mipmap_level in numberOfMipmapLevels1 UInt32 imageSize; for each array_element in numberOfArrayElements2 for each face in numberOfFaces3 for each z_slice in pixelDepth2 for each row or row_of_blocks in pixelHeight2 for each pixel or block_of_pixels in pixelWidth Byte data[format-specific-number-of-bytes]4 end end end Byte cubePadding[0-3] end end Byte mipPadding[0-3] end
Field DescriptionsidentifierThe file identifier is a unique set of bytes that will differentiate the file from other types of files. It consists of 12 bytes, as follows: Byte[12] FileIdentifier = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A } This can also be expressed using C-style character definitions as: Byte[12] FileIdentifier = { '«', 'K', 'T', 'X', ' ', '1', '1', '»', '\r', '\n', '\x1A', '\n' } The rationale behind the choice values in the identifier is based on the rationale for the identifier in the PNG specification. This identifier both identifies the file as a KTX file and provides for immediate detection of common file-transfer problems.
endiannessendianness contains the number 0x04030201 written as a 32 bit integer. If the file is little endian then this is represented as the bytes 0x01 0x02 0x03 0x04. If the file is big endian then this is represented as the bytes 0x04 0x03 0x02 0x01. When reading endianness as a 32 bit integer produces the value 0x04030201 then the endianness of the file matches the the endianness of the program that is reading the file and no conversion is necessary. When reading endianness as a 32 bit integer produces the value 0x01020304 then the endianness of the file is opposite the endianness of the program that is reading the file, and in that case the program reading the file must endian convert all header bytes and, if glTypeSize > 1, all texture data to the endianness of the program (i.e. a little endian program must convert from big endian, and a big endian program must convert to little endian). glTypeFor compressed textures, glType must equal 0. For uncompressed textures,
glType specifies the glTypeSizeglTypeSize specifies the data type size that should be used when endianness conversion is required for the texture data stored in the file. If glType is not 0, this should be the size in bytes corresponding to glType. For texture data which does not depend on platform endianness, including compressed texture data, glTypeSize must equal 1. glFormatFor compressed textures, glFormat must equal 0. For uncompressed textures,
glFormat specifies the glInternalFormat For compressed textures, glInternalFormat must equal the compressed internal format,
usually one of the values from table 8.14 of the OpenGL 4.4 specification. For
uncompressed textures, glInternalFormat specifies the glBaseInternalFormat For both compressed and uncompressed textures, glBaseInternalFormat specifies
the base internal format of the texture, usually one of the values from
table 8.11 of the OpenGL 4.4 specification (RGB, RGBA, ALPHA, etc.). For uncompressed
textures, this value will be the same as glFormat and is used as the pixelWidth, pixelHeight, pixelDepthThe size of the texture image for level 0, in pixels. No rounding to block sizes should be applied for block compressed textures. For 1D textures pixelHeight and pixelDepth must be 0. For 2D and cube textures pixelDepth must be 0. numberOfArrayElementsnumberOfArrayElements specifies the number of array elements. If the texture is not an array texture, numberOfArrayElements must equal 0. numberOfFacesnumberOfFaces specifies the number of cubemap faces. For cubemaps and cubemap arrays this should be 6. For non cubemaps this should be 1. Cube map faces are stored in the order: +X, -X, +Y, -Y, +Z, -Z. Due to GL_OES_compressed_paletted_texture not defining the interaction between cubemaps and its GL_PALETTE* formats, if `glInternalFormat` is one of its GL_PALETTE* format, numberOfFaces must be 1 numberOfMipmapLevelsnumberOfMipmapLevels must equal 1 for non-mipmapped textures. For mipmapped textures, it equals the number of mipmaps. Mipmaps are stored in order from largest size to smallest size. The first mipmap level is always level 0. A KTX file does not need to contain a complete mipmap pyramid. If numberOfMipmapLevels equals 0, it indicates that a full mipmap pyramid should be generated from level 0 at load time (this is usually not allowed for compressed formats). For the GL_PALETTE* formats, this equals the number of mipmaps and is passed as the levels, parameter when uploading to OpenGL {,ES}. However all levels are packed into a single block of data along with the palette so numberOfMipmapLevels is considered to be 1 in the for loop over the data. Individual mipmaps are not identifiable. bytesOfKeyValueDataAn arbitrary number of key/value pairs may follow the header. This can be used to encode any arbitrary data. The bytesOfKeyValueData field indicates the total number of bytes of key/value data including all keyAndValueByteSize fields, all keyAndValue fields, and all valuePadding fields. The file offset of the first imageSize field is located at the file offset of the bytesOfKeyValueData field plus the value of the bytesOfKeyValueData field plus 4. keyAndValueByteSizekeyAndValueByteSize is the number of bytes of combined key and value data in one key/value pair following the header. This includes the size of the key, the NUL byte terminating the key, and all the bytes of data in the value. If the value is a UTF-8 string it should be NUL terminated and the keyAndValueByteSize should include the NUL character (but code that reads KTX files must not assume that value fields are NUL terminated). keyAndValueByteSize does not include the bytes in valuePadding. keyAndValuekeyAndValue contains 2 separate sections. First it contains a key encoded in UTF-8 without a byte order mark (BOM). The key must be terminated by a NUL character (a single 0x00 byte). Keys that begin with the 3 ascii characters 'KTX' or 'ktx' are reserved and must not be used except as described by this spec (this version of the KTX spec defines a single key). Immediately following the NUL character that terminates the key is the Value data. The Value data may consist of any arbitrary data bytes. Any byte value is allowed. It is encouraged that the value be a NUL terminated UTF-8 string but this is not required. UTF-8 strings must not contain BOMs. If the Value data is binary, it is a sequence of bytes rather than of words. It is up to the vendor defining the key to specify how those bytes are to be interpreted (including the endianness of any encoded numbers). If the Value data is a string of bytes then the NUL termination should be included in the keyAndValueByteSize byte count (but programs that read KTX files must not rely on this). valuePaddingvaluePadding contains between 0 and 3 bytes of value imageSizeFor most textures imageSize is the number of bytes of pixel data in the current LOD level. This includes all array layers, all z slices, all faces, all rows (or rows of blocks) and all pixels (or blocks) in each row for the mipmap level. It does not include any bytes in mipPadding. The exception is non-array cubemap textures (any texture where numberOfFaces is 6 and numberOfArrayElements is 0). For these textures imageSize is the number of bytes in each face of the texture for the current LOD level, not including bytes in cubePadding or mipPadding. cubePadding For non-array cubemap textures (any texture where numberOfFaces
is 6 and numberOfArrayElements is 0) cubePadding contains between
0 and 3 bytes of value This is empty in the non-array cubemap case as well. The requirement of GL_UNPACK_ALIGNMENT = 4 means the size of uncompressed textures will always be a multiple of 4 bytes. All known compressed formats, that are usable for cubemaps, have block sizes that are a multiple of 4 bytes. The field is still shown in case a compressed format emerges with a block size that is not a multiple of 4 bytes. mipPaddingBetween 0 and 3 bytes of value This is empty for all known texture formats for the reasons given in cubePadding and is retained for the same reason. General commentsThe unpack alignment is 4. I.e. uncompressed pixel data is packed according to the rules described in section 8.4.4.1 of the OpenGL 4.4 specification for a GL_UNPACK_ALIGNMENT of 4. Values listed in tables referred to in the OpenGL 4.4 specification may be supplemented by extensions. The references are given as examples and do not imply that all of those texture types can be loaded in OpenGL ES or earlier versions of OpenGL. Texture data in a KTX file are arranged so that the first pixel in the data stream for each face and/or array element is closest to the origin of the texture coordinate system. In OpenGL that origin is conventionally described as being at the lower left, but this convention is not shared by all image file formats and content creation tools, so there is abundant room for confusion. The desired texture axis orientation is often predetermined by, e.g. a content creation tool's or existing application's use of the image. Therefore it is strongly recommended that tools for generating KTX files clearly describe their behaviour, and provide an option to specify the texture axis origin and orientation relative to the logical orientation of the source image. At minimum they should provide a choice between top-left and bottom-left as origin for 2D source images, with the positive S axis pointing right. Where possible, the preferred default is to use the logical upper-left corner of the image as the texture origin. Note that this is contrary to the standard interpretation of GL texture coordinates. However, the majority of texture compression tools use this convention. As an aid to writing image manipulation tools and viewers, the logical orientation of the data in a KTX file may be indicated in the file's key/value metadata. Note that this metadata affects only the logical interpretation of the data, has no effect on the mapping from pixels in the file byte stream to texture coordinates. The recommended key to use is: It is recommended that viewing and editing tools support at least the following values:
where
Although other orientations can be represented, it is recommended that tools that create KTX files use only the values listed above as other values may not be widely supported by other tools. An example KTX file:// HEADER 0xAB, 0x4B, 0x54, 0x58, // first four bytes of Byte[12] identifier 0x20, 0x31, 0x31, 0xBB, // next four bytes of Byte[12] identifier 0x0D, 0x0A, 0x1A, 0x0A, // final four bytes of Byte[12] identifier 0x04, 0x03, 0x02, 0x01, // Byte[4] endianess (Big endian in this case) 0x00, 0x00, 0x00, 0x00, // UInt32 glType = 0 0x00, 0x00, 0x00, 0x01, // UInt32 glTypeSize = 1 0x00, 0x00, 0x00, 0x00, // UInt32 glFormat = 0 0x00, 0x00, 0x8D, 0x64, // UInt32 glInternalFormat = GL_ETC1_RGB8_OES 0x00, 0x00, 0x19, 0x07, // UInt32 glBaseInternalFormat = GL_RGB 0x00, 0x00, 0x00, 0x20, // UInt32 pixelWidth = 32 0x00, 0x00, 0x00, 0x20, // UInt32 pixelHeight = 32 0x00, 0x00, 0x00, 0x00, // UInt32 pixelDepth = 0 0x00, 0x00, 0x00, 0x00, // UInt32 numberOfArrayElements = 0 0x00, 0x00, 0x00, 0x01, // UInt32 numberOfFaces = 1 0x00, 0x00, 0x00, 0x01, // UInt32 numberOfMipmapLevels = 1 0x00, 0x00, 0x00, 0x10, // UInt32 bytesOfKeyValueData = 16 // METADATA 0x00, 0x00, 0x00, 0x0A, // UInt32 keyAndValueByteSize = 10 0x61, 0x70, 0x69, 0x00, // UTF8 key: 'api\0' 0x67, 0x6C, 0x65, 0x73, // UTF8 v: 'gles2\0' 0x32, 0x00, 0x00, 0x00, // Byte[2] valuePadding (2 bytes) // TEXTURE DATA 0x00, 0x00, 0x02, 0x00, // UInt32 imageSize = 512 bytes 0xD8, 0xD8, 0xD8, 0xDA, // Byte[512] ETC compressed texture data... ... IANA Mime-Type Registration InformationPermission is expressly granted to IANA to copy this section as necessary for managing the MIME types registry. Type name: Image Subtype name: ktx Required parameters: none Optional parameters: none Encoding considerations: binary Security considerations:
Interoperability considerations:
Published specification: Applications that use this media type :
Additional information:
Person & email address to contact for further information: Mark Callow (callow_mark at hicorp.co.jp) Intended usage: COMMON Restrictions on usage: none Authors: Mark Callow, Georg Kolling, Jacob Ström Change controller: The Khronos Group, the industry consortium responsible for standards such as OpenGL, OpenGL ES, WebGL and OpenCL. ReferencesNormative references
This reference is not intended to imply that values in file header fields are limited to those in the referenced tables. New values may be introduced at any time by OpenGL {,ES} extensions or new versions. Other referencesAcknowledgementsThis specification was produced by the Khronos OpenGL® ES Working Group. Special thanks to: Acorn Pooley (NVIDIA), Bruce Merry (ARM). Revision History
|