libktx Reference 4.3.2
Libraries and tools to create and read KTX image texture files.
Loading...
Searching...
No Matches
libktx Reference

libktx is a small library of functions for creating and reading KTX (Khronos TeXture) files, version 1 and 2 and instantiating OpenGL® and OpenGL® ES textures and Vulkan images from them. KTX version 2 files can contain images supercompressed with zstd or zlib. They can also contain images in the Basis Universal formats. libktx can deflate and inflate zstd and zlib compressed images, can encode and transcode the Basis Universal formats and can encode ASTC formats.

For information about the KTX format see the formal specification.

Authors
Mark Callow, Edgewise Consulting, formerly at HI Corporation
Mátyás Császár and Daniel Rákos, RasterGrid
Wasim Abbas, Arm
Andreas Atteneder, Independent
Georg Kolling, Imagination Technology
Jacob Ström, Ericsson AB

API Version
v4.0

Date
Fri Dec 22 22:46:49 2023 +0900

Usage Overview

The following ktxTexture examples work for both KTX and KTX2 textures. The texture type is determined from the file contents.

Reading a KTX file for non-GL and non-Vulkan Use

#include <ktx.h>
ktxTexture* texture;
ktx_size_t offset;
ktx_uint8_t* image;
ktx_uint32_t level, layer, faceSlice;
result = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
&texture);
// Retrieve information about the texture from fields in the ktxTexture
// such as:
ktx_uint32 numLevels = texture->numLevels;
ktx_uint32 baseWidth = texture->baseWidth;
ktx_bool_t isArray = texture->isArray;
// Retrieve a pointer to the image for a specific mip level, array layer
// & face or depth slice.
level = 1; layer = 0; faceSlice = 3;
result = ktxTexture_GetImageOffset(texture, level, layer, faceSlice, &offset);
image = ktxTexture_GetData(texture) + offset;
// ...
// Do something with the texture image.
// ...
Declares the public functions and structures of the KTX API.
#define ktxTexture_Destroy(This)
Helper for calling the Destroy virtual method of a ktxTexture.
Definition: ktx.h:530
@ KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT
Definition: ktx.h:775
#define KTX_error_code
For backward compatibility.
Definition: ktx.h:198
#define ktxTexture_GetImageOffset(This, level, layer, faceSlice, pOffset)
Helper for calling the GetImageOffset virtual method of a ktxTexture.
Definition: ktx.h:538
Base class representing a texture.
Definition: ktx.h:287
ktx_uint32_t baseWidth
Width of the texture's base level.
Definition: ktx.h:288
ktx_uint32_t numLevels
Number of mip levels in the texture.
Definition: ktx.h:288
ktx_bool_t isArray
Definition: ktx.h:288

Creating a GL texture object from a KTX file.

#include <ktx.h>
ktxTexture* kTexture;
ktx_size_t offset;
ktx_uint8_t* image;
ktx_uint32_t level, layer, faceSlice;
GLuint texture = 0;
GLenum target, glerror;
result = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
KTX_TEXTURE_CREATE_NO_FLAGS,
&kTexture);
glGenTextures(1, &texture); // Optional. GLUpload can generate a texture.
result = ktxTexture_GLUpload(kTexture, &texture, &target, &glerror);
// ...
// GL rendering using the texture
// ...

Creating a Vulkan image object from a KTX file.

#include <vulkan/vulkan.h>
#include <ktxvulkan.h>
ktxTexture* kTexture;
ktx_size_t offset;
ktx_uint8_t* image;
ktx_uint32_t level, layer, faceSlice;
// Set up Vulkan physical device (gpu), logical device (device), queue
// and command pool. Save the handles to these in a struct called vkctx.
// ktx VulkanDeviceInfo is used to pass these with the expectation that
// apps are likely to upload a large number of textures.
ktxVulkanDeviceInfo_Construct(&vdi, vkctx.gpu, vkctx.device,
vkctx.queue, vkctx.commandPool, nullptr);
ktxresult = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
KTX_TEXTURE_CREATE_NO_FLAGS,
&kTexture);
ktxresult = ktxTexture_VkUploadEx(kTexture, &vdi, &texture,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
ktxVulkanDeviceInfo_Destruct(&vdi);
// ...
// Vulkan rendering using the texture
// ...
// When done using the image in Vulkan...
ktxVulkanTexture_Destruct(&texture, vkctx.device, nullptr);
Struct for passing information about the Vulkan device on which to create images to the texture image...
Definition: ktxvulkan.h:188
Struct for returning information about the Vulkan texture image created by the ktxTexture_VkUpload* f...
Definition: ktxvulkan.h:108

Extracting Metadata

Once a ktxTexture object has been created, metadata can be easily found and extracted. The following can be added to any of the above.

char* pValue;
uint32_t valueLen;
if (KTX_SUCCESS == ktxHashList_FindValue(&kTexture->kvDataHead,
&valueLen, (void**)&pValue))
{
char s, t;
if (sscanf(pValue, KTX_ORIENTATION2_FMT, &s, &t) == 2) {
...
}
}
@ KTX_SUCCESS
Definition: ktx.h:170
#define KTX_ORIENTATION_KEY
Key string for standard orientation metadata.
Definition: ktx.h:124
#define KTX_ORIENTATION2_FMT
Standard KTX 1 format for 2D orientation value.
Definition: ktx.h:149
ktxHashList kvDataHead
Head of the hash list of metadata.
Definition: ktx.h:288

Writing a KTX or KTX2 file

#include <ktx.h>
#include <vkformat_enum.h>
ktxTexture2* texture; // For KTX2
//ktxTexture1* texture; // For KTX
ktx_uint32_t level, layer, faceSlice;
FILE* src;
ktx_size_t srcSize;
createInfo.glInternalformat = GL_RGB8; // Ignored if creating a ktxTexture2.
createInfo.vkFormat = VK_FORMAT_R8G8B8_UNORM; // Ignored if creating a ktxTexture1.
createInfo.baseWidth = 2048;
createInfo.baseHeight = 1024;
createInfo.baseDepth = 16;
createInfo.numDimensions = 3.
// Note: it is not necessary to provide a full mipmap pyramid.
createInfo.numLevels = log2(createInfo.baseWidth) + 1
createInfo.numLayers = 1;
createInfo.numFaces = 1;
createInfo.isArray = KTX_FALSE;
createInfo.generateMipmaps = KTX_FALSE;
// Call ktxTexture1_Create to create a KTX texture.
result = ktxTexture2_Create(&createInfo,
&texture);
src = // Open a stdio FILE* on the baseLevel image, slice 0.
srcSize = // Query size of the file.
level = 0;
layer = 0;
faceSlice = 0;
level, layer, faceSlice,
src, srcSize);
// Repeat for the other 15 slices of the base level and all other levels
// up to createInfo.numLevels.
ktxTexture_WriteToNamedFile(ktxTexture(texture), "mytex3d.ktx");
#define ktxTexture_SetImageFromMemory(This, level, layer, faceSlice, src, srcSize)
Helper for calling the SetImageFromMemory virtual method of a ktxTexture.
Definition: ktx.h:598
@ KTX_TEXTURE_CREATE_ALLOC_STORAGE
Definition: ktx.h:763
#define ktxTexture_WriteToNamedFile(This, dstname)
Helper for calling the WriteToNamedfile virtual method of a ktxTexture.
Definition: ktx.h:628
#define ktxTexture(t)
Helper for casting ktxTexture1 and ktxTexture2 to ktxTexture.
Definition: ktx.h:716
Class representing a KTX version 2 format texture.
Definition: ktx.h:699
Structure for passing texture information to ktxTexture1_Create() and ktxTexture2_Create().
Definition: ktx.h:728
ktx_uint32_t glInternalformat
Definition: ktx.h:729
ktx_uint32_t numFaces
Definition: ktx.h:745
ktx_uint32_t numDimensions
Definition: ktx.h:740
ktx_uint32_t baseWidth
Definition: ktx.h:737
ktx_uint32_t baseDepth
Definition: ktx.h:739
ktx_uint32_t numLevels
Definition: ktx.h:742
ktx_bool_t isArray
Definition: ktx.h:746
ktx_bool_t generateMipmaps
Definition: ktx.h:749
ktx_uint32_t vkFormat
Definition: ktx.h:732
ktx_uint32_t numLayers
Definition: ktx.h:744
ktx_uint32_t baseHeight
Definition: ktx.h:738

Modifying a KTX file

#include <ktx.h>
ktxTexture* texture;
ktx_size_t offset;
ktx_uint8_t* image;
ktx_uint32_t level, layer, faceSlice;
result = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
&texture);
// The file is closed after all the data has been read.
// It is the responsibilty of the application to make sure its
// modifications are valid.
texture->generateMipmaps = KTX_TRUE;
ktxTexture_WriteToNamedFile(texture, "mytex3d.ktx");
ktx_bool_t generateMipmaps
Definition: ktx.h:288

Writing a Basis-compressed Universal Texture

Basis compression supports two universal texture formats: BasisLZ/ETC1S and UASTC. The latter gives higher quality at a larger file size. Textures can be compressed to either format using ktxTexture2_CompressBasisEx as shown in this example.

#include <ktx.h>
#include <vkformat_enum.h>
ktxTexture2* texture;
ktx_uint32_t level, layer, faceSlice;
FILE* src;
ktx_size_t srcSize;
ktxBasisParams params = {0};
params.structSize = sizeof(params);
createInfo.glInternalformat = 0; //Ignored as we'll create a KTX2 texture.
createInfo.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
createInfo.baseWidth = 2048;
createInfo.baseHeight = 1024;
createInfo.baseDepth = 16;
createInfo.numDimensions = 3.
// Note: it is not necessary to provide a full mipmap pyramid.
createInfo.numLevels = log2(createInfo.baseWidth) + 1
createInfo.numLayers = 1;
createInfo.numFaces = 1;
createInfo.isArray = KTX_FALSE;
createInfo.generateMipmaps = KTX_FALSE;
result = ktxTexture2_Create(&createInfo,
&texture);
src = // Open the file for the baseLevel image, slice 0 and
// read it into memory.
srcSize = // Query size of the file.
level = 0;
layer = 0;
faceSlice = 0;
level, layer, faceSlice,
src, srcSize);
// Repeat for the other 15 slices of the base level and all other levels
// up to createInfo.numLevels.
// For BasisLZ/ETC1S
params.compressionLevel = KTX_ETC1S_DEFAULT_COMPRESSION_LEVEL;
// For UASTC
params.uastc = KTX_TRUE;
// Set other BasisLZ/ETC1S or UASTC params to change default quality settings.
result = ktxtexture2_CompressBasisEx(texture, &params);
ktxTexture_WriteToNamedFile(ktxTexture(texture), "mytex3d.ktx2");
Structure for passing extended parameters to ktxTexture2_CompressBasisEx().
Definition: ktx.h:1279
ktx_uint32_t compressionLevel
Definition: ktx.h:1298
ktx_uint32_t structSize
Definition: ktx.h:1280
ktx_bool_t uastc
Definition: ktx.h:1284

There is a shortcut that can be used when compressing to BasisLZ/ETC1S. Remove the declaration and initialization of params in the previous example and replace ktxtexture2_CompressBasisEx with

// Quality range is 1 - 255. 0 gets the default quality, currently 128.
// The qualityLevel field in ktxBasisParams is set from this.
int quality = 0;
result = ktxTexture2_CompressBasis(texture, quality);

Transcoding a BasisLZ/ETC1S or UASTC-compressed Texture

#include <ktx.h>
ktxTexture2* texture;
result = ktxTexture_CreateFromNamedFile("mytex3d_basis.ktx2",
KTX_TEXTURE_CREATE_NO_FLAGS,
(ktxTexture**)&kTexture);
// or
//result = ktxTexture2_CreateFromNamedFile("mytex3d_basis.ktx2",
// KTX_TEXTURE_CREATE_NO_FLAGS,
// &kTexture);
if (ktxTexture2_NeedsTranscoding(texture)) {
// Using VkGetPhysicalDeviceFeatures or GL_COMPRESSED_TEXTURE_FORMATS or
// extension queries, determine what compressed texture formats are
// supported and pick a format. For example
vk::PhysicalDeviceFeatures deviceFeatures;
vkctx.gpu.getFeatures(&deviceFeatures);
khr_df_model_e colorModel = ktxTexture2_GetColorModel_e(texture);
if (colorModel == KHR_DF_MODEL_UASTC
&& deviceFeatures.textureCompressionASTC_LDR) {
} else if (colorModel == KHR_DF_MODEL_ETC1S
&& deviceFeatures.textureCompressionETC2) {
} else if (deviceFeatures.textureCompressionASTC_LDR) {
} else if (deviceFeatures.textureCompressionETC2)
else if (deviceFeatures.textureCompressionBC)
else {
message << "Vulkan implementation does not support any available transcode target.";
throw std::runtime_error(message.str());
}
result = ktxTexture2_TranscodeBasis(texture, tf, 0);
// Then use VkUpload or GLUpload to create a texture object on the GPU.
}
@ KHR_DF_MODEL_UASTC
Definition: khr_df.h:317
@ KHR_DF_MODEL_ETC1S
Definition: khr_df.h:310
enum _khr_df_model_e khr_df_model_e
Model in which the color coordinate space is defined. There is no requirement that a color format use...
#define ktx_texture_transcode_fmt_e
Definition: ktx.h:1726
@ KTX_TTF_ASTC_4x4_RGBA
Definition: ktx.h:1490
@ KTX_TTF_BC3_RGBA
Definition: ktx.h:1462
@ KTX_TTF_ETC2_RGBA
Definition: ktx.h:1452
@ KTX_TTF_ETC
Definition: ktx.h:1534

Writing an ASTC-Compressed Texture

#include <ktx.h>
#include <vkformat_enum.h>
ktxTexture2* texture;
ktx_uint32_t level, layer, faceSlice;
FILE* src;
ktx_size_t srcSize;
ktxAstcParams params = {0};
params.structSize = sizeof(params);
createInfo.glInternalformat = 0; //Ignored as we'll create a KTX2 texture.
createInfo.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
createInfo.baseWidth = 2048;
createInfo.baseHeight = 1024;
createInfo.baseDepth = 16;
createInfo.numDimensions = 3.
// Note: it is not necessary to provide a full mipmap pyramid.
createInfo.numLevels = log2(createInfo.baseWidth) + 1
createInfo.numLayers = 1;
createInfo.numFaces = 1;
createInfo.isArray = KTX_FALSE;
createInfo.generateMipmaps = KTX_FALSE;
result = ktxTexture2_Create(&createInfo,
&texture);
src = // Open the file for the baseLevel image, slice 0 and
// read it into memory.
srcSize = // Query size of the file.
level = 0;
layer = 0;
faceSlice = 0;
level, layer, faceSlice,
src, srcSize);
// Repeat for the other 15 slices of the base level and all other levels
// up to createInfo.numLevels.
params.threadCount = 1;
params.blockDimension = KTX_PACK_ASTC_BLOCK_DIMENSION_6x6;
params.mode = KTX_PACK_ASTC_ENCODER_MODE_LDR;
result = ktxtexture2_CompressAstcEx(texture, &params);
ktxTexture_WriteToNamedFile(ktxTexture(texture), "mytex3d.ktx2");
@ KTX_PACK_ASTC_QUALITY_LEVEL_MEDIUM
Definition: ktx.h:1137
Structure for passing extended parameters to ktxTexture_CompressAstc.
Definition: ktx.h:1206
ktx_uint32_t threadCount
Definition: ktx.h:1217
ktx_uint32_t structSize
Definition: ktx.h:1207
ktx_uint32_t blockDimension
Definition: ktx.h:1222
ktx_uint32_t mode
Definition: ktx.h:1227
ktx_uint32_t qualityLevel
Definition: ktx.h:1231

There is a shortcut that can be used when the only params field you want to modify is the qualityLevel. Remove the declaration and initialization of params in the previous example and replace ktxtexture2_CompressAstcEx with

// Quality range is 0 - 100. 0 is fastest/lowest. 100 is slowest/highest.
result = ktxTexture2_CompressAstc(texture, quality);