| // BSD clause 2 license see full LICENSE text at end of file |
| #pragma once |
| #ifndef TINY_KTX_TINYKTX_H |
| #define TINY_KTX_TINYKTX_H |
| |
| #ifndef TINYKTX_HAVE_UINTXX_T |
| #include <stdint.h> // for uint32_t and int64_t |
| #endif |
| #ifndef TINYKTX_HAVE_BOOL |
| #include <stdbool.h> // for bool |
| #endif |
| #ifndef TINYKTX_HAVE_SIZE_T |
| #include <stddef.h> // for size_t |
| #endif |
| #ifndef TINYKTX_HAVE_MEMCPY |
| #include <string.h> // for memcpy |
| #endif |
| |
| // if you don't want the helper format function or already have GL defines |
| // comment these two lines out |
| //#define TINYKTX_WANT_TINYKTX_FORMAT 0 |
| //#define TINYKTX_WANT_FAKE_GL_DEFINES 0 |
| |
| |
| #ifndef TINYKTX_WANT_TINYKTX_FORMAT |
| #define TINYKTX_WANT_TINYKTX_FORMAT 1 |
| #define TINYKTX_WANT_FAKE_GL_DEFINES 1 |
| #endif |
| |
| #ifndef TINYKTX_WANT_FAKE_GL_DEFINES |
| #define TINYKTX_WANT_FAKE_GL_DEFINES 1 |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #define TINYKTX_MAX_MIPMAPLEVELS 16 |
| |
| typedef struct TinyKtx_Context *TinyKtx_ContextHandle; |
| |
| typedef void *(*TinyKtx_AllocFunc)(void *user, size_t size); |
| typedef void (*TinyKtx_FreeFunc)(void *user, void *memory); |
| typedef size_t (*TinyKtx_ReadFunc)(void *user, void *buffer, size_t byteCount); |
| typedef bool (*TinyKtx_SeekFunc)(void *user, int64_t offset); |
| typedef int64_t (*TinyKtx_TellFunc)(void *user); |
| typedef void (*TinyKtx_ErrorFunc)(void *user, char const *msg); |
| |
| typedef struct TinyKtx_Callbacks { |
| TinyKtx_ErrorFunc error; |
| TinyKtx_AllocFunc alloc; |
| TinyKtx_FreeFunc free; |
| TinyKtx_ReadFunc read; |
| TinyKtx_SeekFunc seek; |
| TinyKtx_TellFunc tell; |
| } TinyKtx_Callbacks; |
| |
| TinyKtx_ContextHandle TinyKtx_CreateContext(TinyKtx_Callbacks const *callbacks, void *user); |
| void TinyKtx_DestroyContext(TinyKtx_ContextHandle handle); |
| |
| // reset like you reuse the context for another file (saves an alloc/free cycle) |
| void TinyKtx_Reset(TinyKtx_ContextHandle handle); |
| |
| // call this to read the header file should already be at the start of the KTX data |
| bool TinyKtx_ReadHeader(TinyKtx_ContextHandle handle); |
| |
| // this is slow linear search. TODO add iterator style reading of key value pairs |
| bool TinyKtx_GetValue(TinyKtx_ContextHandle handle, char const *key, void const **value); |
| |
| bool TinyKtx_Is1D(TinyKtx_ContextHandle handle); |
| bool TinyKtx_Is2D(TinyKtx_ContextHandle handle); |
| bool TinyKtx_Is3D(TinyKtx_ContextHandle handle); |
| bool TinyKtx_IsCubemap(TinyKtx_ContextHandle handle); |
| bool TinyKtx_IsArray(TinyKtx_ContextHandle handle); |
| |
| bool TinyKtx_Dimensions(TinyKtx_ContextHandle handle, uint32_t* width, uint32_t* height, uint32_t* depth, uint32_t* slices); |
| uint32_t TinyKtx_Width(TinyKtx_ContextHandle handle); |
| uint32_t TinyKtx_Height(TinyKtx_ContextHandle handle); |
| uint32_t TinyKtx_Depth(TinyKtx_ContextHandle handle); |
| uint32_t TinyKtx_ArraySlices(TinyKtx_ContextHandle handle); |
| |
| bool TinyKtx_GetFormatGL(TinyKtx_ContextHandle handle, uint32_t *glformat, uint32_t *gltype, uint32_t *glinternalformat, uint32_t* typesize, uint32_t* glbaseinternalformat); |
| |
| bool TinyKtx_NeedsGenerationOfMipmaps(TinyKtx_ContextHandle handle); |
| bool TinyKtx_NeedsEndianCorrecting(TinyKtx_ContextHandle handle); |
| |
| uint32_t TinyKtx_NumberOfMipmaps(TinyKtx_ContextHandle handle); |
| uint32_t TinyKtx_ImageSize(TinyKtx_ContextHandle handle, uint32_t mipmaplevel); |
| |
| // data return by ImageRawData is owned by the context. Don't free it! |
| void const *TinyKtx_ImageRawData(TinyKtx_ContextHandle handle, uint32_t mipmaplevel); |
| |
| typedef void (*TinyKtx_WriteFunc)(void *user, void const *buffer, size_t byteCount); |
| |
| typedef struct TinyKtx_WriteCallbacks { |
| TinyKtx_ErrorFunc error; |
| TinyKtx_AllocFunc alloc; |
| TinyKtx_FreeFunc free; |
| TinyKtx_WriteFunc write; |
| } TinyKtx_WriteCallbacks; |
| |
| |
| bool TinyKtx_WriteImageGL(TinyKtx_WriteCallbacks const *callbacks, |
| void *user, |
| uint32_t width, |
| uint32_t height, |
| uint32_t depth, |
| uint32_t slices, |
| uint32_t mipmaplevels, |
| uint32_t format, |
| uint32_t internalFormat, |
| uint32_t baseFormat, |
| uint32_t type, |
| uint32_t typeSize, |
| bool cubemap, |
| uint32_t const *mipmapsizes, |
| void const **mipmaps); |
| |
| #if TINYKTX_WANT_TINYKTX_FORMAT != 0 |
| // ktx is based on GL (slightly confusing imho) texture format system |
| // there is format, internal format, type etc. |
| |
| // we try and expose a more dx12/vulkan/metal style of format |
| // but obviously still need to GL data so bare with me. |
| // a TinyKTX_Format is the equivilent to GL/KTX Format and Type |
| // the API doesn't expose the actual values (which come from GL itself) |
| // but provide an API call to crack them back into the actual GL values). |
| |
| // this may look very similar to Vulkan/Dx12 format (its not but related) |
| // these are even more closely related to my gfx_imageformat library... |
| |
| typedef enum TinyKtx_Format { |
| TKTX_UNDEFINED = 0, |
| TKTX_R4G4_UNORM_PACK8, |
| TKTX_R4G4B4A4_UNORM_PACK16, |
| TKTX_B4G4R4A4_UNORM_PACK16, |
| TKTX_R5G6B5_UNORM_PACK16, |
| TKTX_B5G6R5_UNORM_PACK16, |
| TKTX_R5G5B5A1_UNORM_PACK16, |
| TKTX_B5G5R5A1_UNORM_PACK16, |
| TKTX_A1R5G5B5_UNORM_PACK16, |
| |
| TKTX_R8_UNORM, |
| TKTX_R8_SNORM, |
| TKTX_R8_UINT, |
| TKTX_R8_SINT, |
| TKTX_R8_SRGB, |
| |
| TKTX_R8G8_UNORM, |
| TKTX_R8G8_SNORM, |
| TKTX_R8G8_UINT, |
| TKTX_R8G8_SINT, |
| TKTX_R8G8_SRGB, |
| |
| TKTX_R8G8B8_UNORM, |
| TKTX_R8G8B8_SNORM, |
| TKTX_R8G8B8_UINT, |
| TKTX_R8G8B8_SINT, |
| TKTX_R8G8B8_SRGB, |
| TKTX_B8G8R8_UNORM, |
| TKTX_B8G8R8_SNORM, |
| TKTX_B8G8R8_UINT, |
| TKTX_B8G8R8_SINT, |
| TKTX_B8G8R8_SRGB, |
| |
| TKTX_R8G8B8A8_UNORM, |
| TKTX_R8G8B8A8_SNORM, |
| TKTX_R8G8B8A8_UINT, |
| TKTX_R8G8B8A8_SINT, |
| TKTX_R8G8B8A8_SRGB, |
| TKTX_B8G8R8A8_UNORM, |
| TKTX_B8G8R8A8_SNORM, |
| TKTX_B8G8R8A8_UINT, |
| TKTX_B8G8R8A8_SINT, |
| TKTX_B8G8R8A8_SRGB, |
| |
| TKTX_A8B8G8R8_UNORM_PACK32, |
| TKTX_A8B8G8R8_SNORM_PACK32, |
| TKTX_A8B8G8R8_UINT_PACK32, |
| TKTX_A8B8G8R8_SINT_PACK32, |
| TKTX_A8B8G8R8_SRGB_PACK32, |
| |
| TKTX_E5B9G9R9_UFLOAT_PACK32, |
| TKTX_A2R10G10B10_UNORM_PACK32, |
| TKTX_A2R10G10B10_UINT_PACK32, |
| TKTX_A2B10G10R10_UNORM_PACK32, |
| TKTX_A2B10G10R10_UINT_PACK32, |
| TKTX_B10G11R11_UFLOAT_PACK32, |
| |
| TKTX_R16_UNORM, |
| TKTX_R16_SNORM, |
| TKTX_R16_UINT, |
| TKTX_R16_SINT, |
| TKTX_R16_SFLOAT, |
| TKTX_R16G16_UNORM, |
| TKTX_R16G16_SNORM, |
| TKTX_R16G16_UINT, |
| TKTX_R16G16_SINT, |
| TKTX_R16G16_SFLOAT, |
| TKTX_R16G16B16_UNORM, |
| TKTX_R16G16B16_SNORM, |
| TKTX_R16G16B16_UINT, |
| TKTX_R16G16B16_SINT, |
| TKTX_R16G16B16_SFLOAT, |
| TKTX_R16G16B16A16_UNORM, |
| TKTX_R16G16B16A16_SNORM, |
| TKTX_R16G16B16A16_UINT, |
| TKTX_R16G16B16A16_SINT, |
| TKTX_R16G16B16A16_SFLOAT, |
| TKTX_R32_UINT, |
| TKTX_R32_SINT, |
| TKTX_R32_SFLOAT, |
| TKTX_R32G32_UINT, |
| TKTX_R32G32_SINT, |
| TKTX_R32G32_SFLOAT, |
| TKTX_R32G32B32_UINT, |
| TKTX_R32G32B32_SINT, |
| TKTX_R32G32B32_SFLOAT, |
| TKTX_R32G32B32A32_UINT, |
| TKTX_R32G32B32A32_SINT, |
| TKTX_R32G32B32A32_SFLOAT, |
| |
| TKTX_BC1_RGB_UNORM_BLOCK, |
| TKTX_BC1_RGB_SRGB_BLOCK, |
| TKTX_BC1_RGBA_UNORM_BLOCK, |
| TKTX_BC1_RGBA_SRGB_BLOCK, |
| TKTX_BC2_UNORM_BLOCK, |
| TKTX_BC2_SRGB_BLOCK, |
| TKTX_BC3_UNORM_BLOCK, |
| TKTX_BC3_SRGB_BLOCK, |
| TKTX_BC4_UNORM_BLOCK, |
| TKTX_BC4_SNORM_BLOCK, |
| TKTX_BC5_UNORM_BLOCK, |
| TKTX_BC5_SNORM_BLOCK, |
| TKTX_BC6H_UFLOAT_BLOCK, |
| TKTX_BC6H_SFLOAT_BLOCK, |
| TKTX_BC7_UNORM_BLOCK, |
| TKTX_BC7_SRGB_BLOCK, |
| |
| TKTX_ETC2_R8G8B8_UNORM_BLOCK, |
| TKTX_ETC2_R8G8B8A1_UNORM_BLOCK, |
| TKTX_ETC2_R8G8B8A8_UNORM_BLOCK, |
| TKTX_ETC2_R8G8B8_SRGB_BLOCK, |
| TKTX_ETC2_R8G8B8A1_SRGB_BLOCK, |
| TKTX_ETC2_R8G8B8A8_SRGB_BLOCK, |
| TKTX_EAC_R11_UNORM_BLOCK, |
| TKTX_EAC_R11G11_UNORM_BLOCK, |
| TKTX_EAC_R11_SNORM_BLOCK, |
| TKTX_EAC_R11G11_SNORM_BLOCK, |
| |
| TKTX_PVR_2BPP_BLOCK, |
| TKTX_PVR_2BPPA_BLOCK, |
| TKTX_PVR_4BPP_BLOCK, |
| TKTX_PVR_4BPPA_BLOCK, |
| TKTX_PVR_2BPP_SRGB_BLOCK, |
| TKTX_PVR_2BPPA_SRGB_BLOCK, |
| TKTX_PVR_4BPP_SRGB_BLOCK, |
| TKTX_PVR_4BPPA_SRGB_BLOCK, |
| |
| TKTX_ASTC_4x4_UNORM_BLOCK, |
| TKTX_ASTC_4x4_SRGB_BLOCK, |
| TKTX_ASTC_5x4_UNORM_BLOCK, |
| TKTX_ASTC_5x4_SRGB_BLOCK, |
| TKTX_ASTC_5x5_UNORM_BLOCK, |
| TKTX_ASTC_5x5_SRGB_BLOCK, |
| TKTX_ASTC_6x5_UNORM_BLOCK, |
| TKTX_ASTC_6x5_SRGB_BLOCK, |
| TKTX_ASTC_6x6_UNORM_BLOCK, |
| TKTX_ASTC_6x6_SRGB_BLOCK, |
| TKTX_ASTC_8x5_UNORM_BLOCK, |
| TKTX_ASTC_8x5_SRGB_BLOCK, |
| TKTX_ASTC_8x6_UNORM_BLOCK, |
| TKTX_ASTC_8x6_SRGB_BLOCK, |
| TKTX_ASTC_8x8_UNORM_BLOCK, |
| TKTX_ASTC_8x8_SRGB_BLOCK, |
| TKTX_ASTC_10x5_UNORM_BLOCK, |
| TKTX_ASTC_10x5_SRGB_BLOCK, |
| TKTX_ASTC_10x6_UNORM_BLOCK, |
| TKTX_ASTC_10x6_SRGB_BLOCK, |
| TKTX_ASTC_10x8_UNORM_BLOCK, |
| TKTX_ASTC_10x8_SRGB_BLOCK, |
| TKTX_ASTC_10x10_UNORM_BLOCK, |
| TKTX_ASTC_10x10_SRGB_BLOCK, |
| TKTX_ASTC_12x10_UNORM_BLOCK, |
| TKTX_ASTC_12x10_SRGB_BLOCK, |
| TKTX_ASTC_12x12_UNORM_BLOCK, |
| TKTX_ASTC_12x12_SRGB_BLOCK, |
| |
| } TinyKtx_Format; |
| |
| TinyKtx_Format TinyKtx_GetFormat(TinyKtx_ContextHandle handle); |
| bool TinyKtx_CrackFormatToGL(TinyKtx_Format format, uint32_t *glformat, uint32_t *gltype, uint32_t *glinternalformat, uint32_t* typesize); |
| bool TinyKtx_WriteImage(TinyKtx_WriteCallbacks const *callbacks, |
| void *user, |
| uint32_t width, |
| uint32_t height, |
| uint32_t depth, |
| uint32_t slices, |
| uint32_t mipmaplevels, |
| TinyKtx_Format format, |
| bool cubemap, |
| uint32_t const *mipmapsizes, |
| void const **mipmaps); |
| #endif |
| |
| #if TINYKTX_WANT_FAKE_GL_DEFINES != 0 |
| // GL types |
| #define TINYKTX_GL_TYPE_COMPRESSED 0x0 |
| #define TINYKTX_GL_TYPE_BYTE 0x1400 |
| #define TINYKTX_GL_TYPE_UNSIGNED_BYTE 0x1401 |
| #define TINYKTX_GL_TYPE_SHORT 0x1402 |
| #define TINYKTX_GL_TYPE_UNSIGNED_SHORT 0x1403 |
| #define TINYKTX_GL_TYPE_INT 0x1404 |
| #define TINYKTX_GL_TYPE_UNSIGNED_INT 0x1405 |
| #define TINYKTX_GL_TYPE_FLOAT 0x1406 |
| #define TINYKTX_GL_TYPE_DOUBLE 0x140A |
| #define TINYKTX_GL_TYPE_HALF_FLOAT 0x140B |
| #define TINYKTX_GL_TYPE_UNSIGNED_BYTE_3_3_2 0x8032 |
| #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_4_4_4_4 0x8033 |
| #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_5_5_1 0x8034 |
| #define TINYKTX_GL_TYPE_UNSIGNED_INT_8_8_8_8 0x8035 |
| #define TINYKTX_GL_TYPE_UNSIGNED_INT_10_10_10_2 0x8036 |
| #define TINYKTX_GL_TYPE_UNSIGNED_BYTE_2_3_3_REV 0x8362 |
| #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_6_5 0x8363 |
| #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_6_5_REV 0x8364 |
| #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 |
| #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 |
| #define TINYKTX_GL_TYPE_UNSIGNED_INT_8_8_8_8_REV 0x8367 |
| #define TINYKTX_GL_TYPE_UNSIGNED_INT_2_10_10_10_REV 0x8368 |
| #define TINYKTX_GL_TYPE_UNSIGNED_INT_24_8 0x84FA |
| #define TINYKTX_GL_TYPE_UNSIGNED_INT_5_9_9_9_REV 0x8C3E |
| #define TINYKTX_GL_TYPE_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B |
| #define TINYKTX_GL_TYPE_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD |
| |
| // formats |
| #define TINYKTX_GL_FORMAT_RED 0x1903 |
| #define TINYKTX_GL_FORMAT_GREEN 0x1904 |
| #define TINYKTX_GL_FORMAT_BLUE 0x1905 |
| #define TINYKTX_GL_FORMAT_ALPHA 0x1906 |
| #define TINYKTX_GL_FORMAT_RGB 0x1907 |
| #define TINYKTX_GL_FORMAT_RGBA 0x1908 |
| #define TINYKTX_GL_FORMAT_LUMINANCE 0x1909 |
| #define TINYKTX_GL_FORMAT_LUMINANCE_ALPHA 0x190A |
| #define TINYKTX_GL_FORMAT_ABGR 0x8000 |
| #define TINYKTX_GL_FORMAT_INTENSITY 0x8049 |
| #define TINYKTX_GL_FORMAT_BGR 0x80E0 |
| #define TINYKTX_GL_FORMAT_BGRA 0x80E1 |
| #define TINYKTX_GL_FORMAT_RG 0x8227 |
| #define TINYKTX_GL_FORMAT_RG_INTEGER 0x8228 |
| #define TINYKTX_GL_FORMAT_SRGB 0x8C40 |
| #define TINYKTX_GL_FORMAT_SRGB_ALPHA 0x8C42 |
| #define TINYKTX_GL_FORMAT_SLUMINANCE_ALPHA 0x8C44 |
| #define TINYKTX_GL_FORMAT_SLUMINANCE 0x8C46 |
| #define TINYKTX_GL_FORMAT_RED_INTEGER 0x8D94 |
| #define TINYKTX_GL_FORMAT_GREEN_INTEGER 0x8D95 |
| #define TINYKTX_GL_FORMAT_BLUE_INTEGER 0x8D96 |
| #define TINYKTX_GL_FORMAT_ALPHA_INTEGER 0x8D97 |
| #define TINYKTX_GL_FORMAT_RGB_INTEGER 0x8D98 |
| #define TINYKTX_GL_FORMAT_RGBA_INTEGER 0x8D99 |
| #define TINYKTX_GL_FORMAT_BGR_INTEGER 0x8D9A |
| #define TINYKTX_GL_FORMAT_BGRA_INTEGER 0x8D9B |
| #define TINYKTX_GL_FORMAT_RED_SNORM 0x8F90 |
| #define TINYKTX_GL_FORMAT_RG_SNORM 0x8F91 |
| #define TINYKTX_GL_FORMAT_RGB_SNORM 0x8F92 |
| #define TINYKTX_GL_FORMAT_RGBA_SNORM 0x8F93 |
| |
| #define TINYKTX_GL_INTFORMAT_ALPHA4 0x803B |
| #define TINYKTX_GL_INTFORMAT_ALPHA8 0x803C |
| #define TINYKTX_GL_INTFORMAT_ALPHA12 0x803D |
| #define TINYKTX_GL_INTFORMAT_ALPHA16 0x803E |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE4 0x803F |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE8 0x8040 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE12 0x8041 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE16 0x8042 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE4_ALPHA4 0x8043 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE6_ALPHA2 0x8044 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE8_ALPHA8 0x8045 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE12_ALPHA4 0x8046 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE12_ALPHA12 0x8047 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE16_ALPHA16 0x8048 |
| #define TINYKTX_GL_INTFORMAT_INTENSITY4 0x804A |
| #define TINYKTX_GL_INTFORMAT_INTENSITY8 0x804B |
| #define TINYKTX_GL_INTFORMAT_INTENSITY12 0x804C |
| #define TINYKTX_GL_INTFORMAT_INTENSITY16 0x804D |
| #define TINYKTX_GL_INTFORMAT_RGB2 0x804E |
| #define TINYKTX_GL_INTFORMAT_RGB4 0x804F |
| #define TINYKTX_GL_INTFORMAT_RGB5 0x8050 |
| #define TINYKTX_GL_INTFORMAT_RGB8 0x8051 |
| #define TINYKTX_GL_INTFORMAT_RGB10 0x8052 |
| #define TINYKTX_GL_INTFORMAT_RGB12 0x8053 |
| #define TINYKTX_GL_INTFORMAT_RGB16 0x8054 |
| #define TINYKTX_GL_INTFORMAT_RGBA2 0x8055 |
| #define TINYKTX_GL_INTFORMAT_RGBA4 0x8056 |
| #define TINYKTX_GL_INTFORMAT_RGB5_A1 0x8057 |
| #define TINYKTX_GL_INTFORMAT_RGBA8 0x8058 |
| #define TINYKTX_GL_INTFORMAT_RGB10_A2 0x8059 |
| #define TINYKTX_GL_INTFORMAT_RGBA12 0x805A |
| #define TINYKTX_GL_INTFORMAT_RGBA16 0x805B |
| #define TINYKTX_GL_INTFORMAT_R8 0x8229 |
| #define TINYKTX_GL_INTFORMAT_R16 0x822A |
| #define TINYKTX_GL_INTFORMAT_RG8 0x822B |
| #define TINYKTX_GL_INTFORMAT_RG16 0x822C |
| #define TINYKTX_GL_INTFORMAT_R16F 0x822D |
| #define TINYKTX_GL_INTFORMAT_R32F 0x822E |
| #define TINYKTX_GL_INTFORMAT_RG16F 0x822F |
| #define TINYKTX_GL_INTFORMAT_RG32F 0x8230 |
| #define TINYKTX_GL_INTFORMAT_R8I 0x8231 |
| #define TINYKTX_GL_INTFORMAT_R8UI 0x8232 |
| #define TINYKTX_GL_INTFORMAT_R16I 0x8233 |
| #define TINYKTX_GL_INTFORMAT_R16UI 0x8234 |
| #define TINYKTX_GL_INTFORMAT_R32I 0x8235 |
| #define TINYKTX_GL_INTFORMAT_R32UI 0x8236 |
| #define TINYKTX_GL_INTFORMAT_RG8I 0x8237 |
| #define TINYKTX_GL_INTFORMAT_RG8UI 0x8238 |
| #define TINYKTX_GL_INTFORMAT_RG16I 0x8239 |
| #define TINYKTX_GL_INTFORMAT_RG16UI 0x823A |
| #define TINYKTX_GL_INTFORMAT_RG32I 0x823B |
| #define TINYKTX_GL_INTFORMAT_RG32UI 0x823C |
| #define TINYKTX_GL_INTFORMAT_RGBA32F 0x8814 |
| #define TINYKTX_GL_INTFORMAT_RGB32F 0x8815 |
| #define TINYKTX_GL_INTFORMAT_RGBA16F 0x881A |
| #define TINYKTX_GL_INTFORMAT_RGB16F 0x881B |
| #define TINYKTX_GL_INTFORMAT_R11F_G11F_B10F 0x8C3A |
| #define TINYKTX_GL_INTFORMAT_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B |
| #define TINYKTX_GL_INTFORMAT_RGB9_E5 0x8C3D |
| #define TINYKTX_GL_INTFORMAT_SRGB8 0x8C41 |
| #define TINYKTX_GL_INTFORMAT_SRGB8_ALPHA8 0x8C43 |
| #define TINYKTX_GL_INTFORMAT_SLUMINANCE8_ALPHA8 0x8C45 |
| #define TINYKTX_GL_INTFORMAT_SLUMINANCE8 0x8C47 |
| #define TINYKTX_GL_INTFORMAT_RGB565 0x8D62 |
| #define TINYKTX_GL_INTFORMAT_RGBA32UI 0x8D70 |
| #define TINYKTX_GL_INTFORMAT_RGB32UI 0x8D71 |
| #define TINYKTX_GL_INTFORMAT_RGBA16UI 0x8D76 |
| #define TINYKTX_GL_INTFORMAT_RGB16UI 0x8D77 |
| #define TINYKTX_GL_INTFORMAT_RGBA8UI 0x8D7C |
| #define TINYKTX_GL_INTFORMAT_RGB8UI 0x8D7D |
| #define TINYKTX_GL_INTFORMAT_RGBA32I 0x8D82 |
| #define TINYKTX_GL_INTFORMAT_RGB32I 0x8D83 |
| #define TINYKTX_GL_INTFORMAT_RGBA16I 0x8D88 |
| #define TINYKTX_GL_INTFORMAT_RGB16I 0x8D89 |
| #define TINYKTX_GL_INTFORMAT_RGBA8I 0x8D8E |
| #define TINYKTX_GL_INTFORMAT_RGB8I 0x8D8F |
| #define TINYKTX_GL_INTFORMAT_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD |
| #define TINYKTX_GL_INTFORMAT_R8_SNORM 0x8F94 |
| #define TINYKTX_GL_INTFORMAT_RG8_SNORM 0x8F95 |
| #define TINYKTX_GL_INTFORMAT_RGB8_SNORM 0x8F96 |
| #define TINYKTX_GL_INTFORMAT_RGBA8_SNORM 0x8F97 |
| #define TINYKTX_GL_INTFORMAT_R16_SNORM 0x8F98 |
| #define TINYKTX_GL_INTFORMAT_RG16_SNORM 0x8F99 |
| #define TINYKTX_GL_INTFORMAT_RGB16_SNORM 0x8F9A |
| #define TINYKTX_GL_INTFORMAT_RGBA16_SNORM 0x8F9B |
| #define TINYKTX_GL_INTFORMAT_ALPHA8_SNORM 0x9014 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE8_SNORM 0x9015 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE8_ALPHA8_SNORM 0x9016 |
| #define TINYKTX_GL_INTFORMAT_INTENSITY8_SNORM 0x9017 |
| #define TINYKTX_GL_INTFORMAT_ALPHA16_SNORM 0x9018 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE16_SNORM 0x9019 |
| #define TINYKTX_GL_INTFORMAT_LUMINANCE16_ALPHA16_SNORM 0x901A |
| #define TINYKTX_GL_INTFORMAT_INTENSITY16_SNORM 0x901B |
| |
| #define TINYKTX_GL_PALETTE4_RGB8_OES 0x8B90 |
| #define TINYKTX_GL_PALETTE4_RGBA8_OES 0x8B91 |
| #define TINYKTX_GL_PALETTE4_R5_G6_B5_OES 0x8B92 |
| #define TINYKTX_GL_PALETTE4_RGBA4_OES 0x8B93 |
| #define TINYKTX_GL_PALETTE4_RGB5_A1_OES 0x8B94 |
| #define TINYKTX_GL_PALETTE8_RGB8_OES 0x8B95 |
| #define TINYKTX_GL_PALETTE8_RGBA8_OES 0x8B96 |
| #define TINYKTX_GL_PALETTE8_R5_G6_B5_OES 0x8B97 |
| #define TINYKTX_GL_PALETTE8_RGBA4_OES 0x8B98 |
| #define TINYKTX_GL_PALETTE8_RGB5_A1_OES 0x8B99 |
| |
| // compressed formats |
| |
| #define TINYKTX_GL_COMPRESSED_RGB_S3TC_DXT1 0x83F0 |
| #define TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT1 0x83F1 |
| #define TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT3 0x83F2 |
| #define TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT5 0x83F3 |
| #define TINYKTX_GL_COMPRESSED_3DC_X_AMD 0x87F9 |
| #define TINYKTX_GL_COMPRESSED_3DC_XY_AMD 0x87FA |
| #define TINYKTX_GL_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA 0x87EE |
| #define TINYKTX_GL_COMPRESSED_SRGB_PVRTC_2BPPV1 0x8A54 |
| #define TINYKTX_GL_COMPRESSED_SRGB_PVRTC_4BPPV1 0x8A55 |
| #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1 0x8A56 |
| #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1 0x8A57 |
| #define TINYKTX_GL_COMPRESSED_RGB_PVRTC_4BPPV1 0x8C00 |
| #define TINYKTX_GL_COMPRESSED_RGB_PVRTC_2BPPV1 0x8C01 |
| #define TINYKTX_GL_COMPRESSED_RGBA_PVRTC_4BPPV1 0x8C02 |
| #define TINYKTX_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 0x8C03 |
| #define TINYKTX_GL_COMPRESSED_SRGB_S3TC_DXT1 0x8C4C |
| #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1 0x8C4D |
| #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3 0x8C4E |
| #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5 0x8C4F |
| #define TINYKTX_GL_COMPRESSED_LUMINANCE_LATC1 0x8C70 |
| #define TINYKTX_GL_COMPRESSED_SIGNED_LUMINANCE_LATC1 0x8C71 |
| #define TINYKTX_GL_COMPRESSED_LUMINANCE_ALPHA_LATC2 0x8C72 |
| #define TINYKTX_GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2 0x8C73 |
| #define TINYKTX_GL_COMPRESSED_ATC_RGB 0x8C92 |
| #define TINYKTX_GL_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA 0x8C93 |
| #define TINYKTX_GL_COMPRESSED_RED_RGTC1 0x8DBB |
| #define TINYKTX_GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC |
| #define TINYKTX_GL_COMPRESSED_RED_GREEN_RGTC2 0x8DBD |
| #define TINYKTX_GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2 0x8DBE |
| #define TINYKTX_GL_COMPRESSED_ETC1_RGB8_OES 0x8D64 |
| #define TINYKTX_GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C |
| #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D |
| #define TINYKTX_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E |
| #define TINYKTX_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F |
| #define TINYKTX_GL_COMPRESSED_R11_EAC 0x9270 |
| #define TINYKTX_GL_COMPRESSED_SIGNED_R11_EAC 0x9271 |
| #define TINYKTX_GL_COMPRESSED_RG11_EAC 0x9272 |
| #define TINYKTX_GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 |
| #define TINYKTX_GL_COMPRESSED_RGB8_ETC2 0x9274 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ETC2 0x9275 |
| #define TINYKTX_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 |
| #define TINYKTX_GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 |
| #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2 0x93F0 |
| #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2 0x93F1 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_4x4 0x93B0 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_5x4 0x93B1 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_5x5 0x93B2 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_6x5 0x93B3 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_6x6 0x93B4 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x5 0x93B5 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x6 0x93B6 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x8 0x93B7 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x5 0x93B8 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x6 0x93B9 |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x8 0x93BA |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x10 0x93BB |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_12x10 0x93BC |
| #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_12x12 0x93BD |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 0x93D0 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 0x93D1 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 0x93D2 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 0x93D3 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 0x93D4 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 0x93D5 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 0x93D6 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 0x93D7 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 0x93D8 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 0x93D9 |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 0x93DA |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 0x93DB |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 0x93DC |
| #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 0x93DD |
| |
| #endif |
| |
| #ifdef TINYKTX_IMPLEMENTATION |
| |
| typedef struct TinyKtx_Header { |
| uint8_t identifier[12]; |
| uint32_t endianness; |
| uint32_t glType; |
| uint32_t glTypeSize; |
| uint32_t glFormat; |
| uint32_t glInternalFormat; |
| uint32_t glBaseInternalFormat; |
| uint32_t pixelWidth; |
| uint32_t pixelHeight; |
| uint32_t pixelDepth; |
| uint32_t numberOfArrayElements; |
| uint32_t numberOfFaces; |
| uint32_t numberOfMipmapLevels; |
| uint32_t bytesOfKeyValueData; |
| |
| } TinyKtx_Header; |
| |
| typedef struct TinyKtx_KeyValuePair { |
| uint32_t size; |
| } TinyKtx_KeyValuePair; // followed by at least size bytes (aligned to 4) |
| |
| |
| typedef struct TinyKtx_Context { |
| TinyKtx_Callbacks callbacks; |
| void *user; |
| uint64_t headerPos; |
| uint64_t firstImagePos; |
| |
| TinyKtx_Header header; |
| TinyKtx_KeyValuePair const *keyData; |
| bool headerValid; |
| bool sameEndian; |
| |
| uint32_t mipMapSizes[TINYKTX_MAX_MIPMAPLEVELS]; |
| uint8_t const *mipmaps[TINYKTX_MAX_MIPMAPLEVELS]; |
| |
| } TinyKtx_Context; |
| |
| static uint8_t TinyKtx_fileIdentifier[12] = { |
| 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A |
| }; |
| static void TinyKtx_NullErrorFunc(void *user, char const *msg) {} |
| |
| TinyKtx_ContextHandle TinyKtx_CreateContext(TinyKtx_Callbacks const *callbacks, void *user) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) callbacks->alloc(user, sizeof(TinyKtx_Context)); |
| if (ctx == NULL) |
| return NULL; |
| |
| memset(ctx, 0, sizeof(TinyKtx_Context)); |
| memcpy(&ctx->callbacks, callbacks, sizeof(TinyKtx_Callbacks)); |
| ctx->user = user; |
| if (ctx->callbacks.error == NULL) { |
| ctx->callbacks.error = &TinyKtx_NullErrorFunc; |
| } |
| |
| if (ctx->callbacks.read == NULL) { |
| ctx->callbacks.error(user, "TinyKtx must have read callback"); |
| return NULL; |
| } |
| if (ctx->callbacks.alloc == NULL) { |
| ctx->callbacks.error(user, "TinyKtx must have alloc callback"); |
| return NULL; |
| } |
| if (ctx->callbacks.free == NULL) { |
| ctx->callbacks.error(user, "TinyKtx must have free callback"); |
| return NULL; |
| } |
| if (ctx->callbacks.seek == NULL) { |
| ctx->callbacks.error(user, "TinyKtx must have seek callback"); |
| return NULL; |
| } |
| if (ctx->callbacks.tell == NULL) { |
| ctx->callbacks.error(user, "TinyKtx must have tell callback"); |
| return NULL; |
| } |
| |
| TinyKtx_Reset(ctx); |
| |
| return ctx; |
| } |
| |
| void TinyKtx_DestroyContext(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return; |
| TinyKtx_Reset(handle); |
| ctx->callbacks.free(ctx->user, ctx); |
| } |
| |
| void TinyKtx_Reset(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return; |
| |
| // backup user provided callbacks and data |
| TinyKtx_Callbacks callbacks; |
| memcpy(&callbacks, &ctx->callbacks, sizeof(TinyKtx_Callbacks)); |
| void *user = ctx->user; |
| |
| // free memory of sub data |
| if (ctx->keyData != NULL) { |
| ctx->callbacks.free(ctx->user, (void *) ctx->keyData); |
| } |
| for (int i = 0; i < TINYKTX_MAX_MIPMAPLEVELS; ++i) { |
| if (ctx->mipmaps[i] != NULL) { |
| ctx->callbacks.free(ctx->user, (void *) ctx->mipmaps[i]); |
| } |
| } |
| |
| // reset to default state |
| memset(ctx, 0, sizeof(TinyKtx_Context)); |
| memcpy(&ctx->callbacks, &callbacks, sizeof(TinyKtx_Callbacks)); |
| ctx->user = user; |
| |
| } |
| |
| bool TinyKtx_ReadHeader(TinyKtx_ContextHandle handle) { |
| |
| static uint32_t const sameEndianDecider = 0x04030201; |
| static uint32_t const differentEndianDecider = 0x01020304; |
| |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| |
| ctx->headerPos = ctx->callbacks.tell(ctx->user); |
| ctx->callbacks.read(ctx->user, &ctx->header, sizeof(TinyKtx_Header)); |
| |
| if (memcmp(&ctx->header.identifier, TinyKtx_fileIdentifier, 12) != 0) { |
| ctx->callbacks.error(ctx->user, "Not a KTX file or corrupted as identified isn't valid"); |
| return false; |
| } |
| |
| if (ctx->header.endianness == sameEndianDecider) { |
| ctx->sameEndian = true; |
| } else if (ctx->header.endianness == differentEndianDecider) { |
| ctx->sameEndian = false; |
| } else { |
| // corrupt or mid endian? |
| ctx->callbacks.error(ctx->user, "Endian Error"); |
| return false; |
| } |
| |
| if (ctx->header.numberOfFaces != 1 && ctx->header.numberOfFaces != 6) { |
| ctx->callbacks.error(ctx->user, "no. of Faces must be 1 or 6"); |
| return false; |
| } |
| |
| ctx->keyData = (TinyKtx_KeyValuePair const *) ctx->callbacks.alloc(ctx->user, ctx->header.bytesOfKeyValueData); |
| ctx->callbacks.read(ctx->user, (void *) ctx->keyData, ctx->header.bytesOfKeyValueData); |
| |
| ctx->firstImagePos = ctx->callbacks.tell(ctx->user); |
| |
| ctx->headerValid = true; |
| return true; |
| } |
| bool TinyKtx_GetValue(TinyKtx_ContextHandle handle, char const *key, void const **value) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| if (ctx->keyData == NULL) { |
| ctx->callbacks.error(ctx->user, "No key value data in this KTX"); |
| return false; |
| } |
| |
| TinyKtx_KeyValuePair const *curKey = ctx->keyData; |
| while (((uint8_t *) curKey - (uint8_t *) ctx->keyData) < ctx->header.bytesOfKeyValueData) { |
| char const *kvp = (char const *) curKey; |
| |
| if (strcmp(kvp, key) == 0) { |
| size_t sl = strlen(kvp); |
| *value = (void const *) (kvp + sl); |
| return true; |
| } |
| curKey = curKey + ((curKey->size + 3u) & ~3u); |
| } |
| return false; |
| } |
| |
| bool TinyKtx_Is1D(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| return (ctx->header.pixelHeight == 1 && ctx->header.pixelDepth == 1); |
| } |
| bool TinyKtx_Is2D(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| return (ctx->header.pixelHeight != 1 && ctx->header.pixelDepth == 1); |
| } |
| bool TinyKtx_Is3D(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| return (ctx->header.pixelHeight != 1 && ctx->header.pixelDepth != 1); |
| } |
| |
| bool TinyKtx_IsCubemap(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| return (ctx->header.numberOfFaces == 6); |
| } |
| bool TinyKtx_IsArray(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| return (ctx->header.numberOfArrayElements > 1); |
| } |
| bool TinyKtx_Dimensions(TinyKtx_ContextHandle handle, |
| uint32_t *width, |
| uint32_t *height, |
| uint32_t *depth, |
| uint32_t *slices) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| if (width) |
| *width = ctx->header.pixelWidth; |
| if (height) |
| *height = ctx->header.pixelWidth; |
| if (depth) |
| *depth = ctx->header.pixelDepth; |
| if (slices) |
| *slices = ctx->header.numberOfArrayElements; |
| |
| return true; |
| } |
| |
| uint32_t TinyKtx_Width(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return 0; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return 0; |
| } |
| |
| return ctx->header.pixelWidth; |
| } |
| |
| uint32_t TinyKtx_Height(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return 0; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return 0; |
| } |
| |
| return ctx->header.pixelHeight; |
| } |
| |
| uint32_t TinyKtx_Depth(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return 0; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return 0; |
| } |
| |
| return ctx->header.pixelDepth; |
| } |
| |
| uint32_t TinyKtx_ArraySlices(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return 0; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return 0; |
| } |
| |
| return ctx->header.numberOfArrayElements; |
| } |
| |
| uint32_t TinyKtx_NumberOfMipmaps(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return 0; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return 0; |
| } |
| |
| return ctx->header.numberOfMipmapLevels ? ctx->header.numberOfMipmapLevels : 1; |
| } |
| |
| bool TinyKtx_NeedsGenerationOfMipmaps(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| return ctx->header.numberOfMipmapLevels == 0; |
| } |
| |
| bool TinyKtx_NeedsEndianCorrecting(TinyKtx_ContextHandle handle) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| return ctx->sameEndian == false; |
| } |
| |
| bool TinyKtx_GetFormatGL(TinyKtx_ContextHandle handle, uint32_t *glformat, uint32_t *gltype, uint32_t *glinternalformat, uint32_t* typesize, uint32_t* glbaseinternalformat) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return false; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return false; |
| } |
| |
| *glformat = ctx->header.glFormat; |
| *gltype = ctx->header.glType; |
| *glinternalformat = ctx->header.glInternalFormat; |
| *glbaseinternalformat = ctx->header.glBaseInternalFormat; |
| *typesize = ctx->header.glBaseInternalFormat; |
| |
| return true; |
| } |
| |
| bool TinyKtx_WriteImageGL(TinyKtx_WriteCallbacks const *callbacks, |
| void *user, |
| uint32_t width, |
| uint32_t height, |
| uint32_t depth, |
| uint32_t slices, |
| uint32_t mipmaplevels, |
| uint32_t format, |
| uint32_t internalFormat, |
| uint32_t baseFormat, |
| uint32_t type, |
| uint32_t typeSize, |
| bool cubemap, |
| uint32_t const *mipmapsizes, |
| void const **mipmaps) { |
| |
| TinyKtx_Header header; |
| memcpy(header.identifier, TinyKtx_fileIdentifier, 12); |
| header.endianness = 0x04030201; |
| header.glFormat = format; |
| header.glInternalFormat = internalFormat; |
| header.glBaseInternalFormat = baseFormat; |
| header.glType = type; |
| header.glTypeSize = typeSize; |
| header.pixelWidth = width; |
| header.pixelHeight = height; |
| header.pixelDepth = depth; |
| header.numberOfArrayElements = slices; |
| header.numberOfFaces = cubemap ? 6 : 1; |
| header.numberOfMipmapLevels = mipmaplevels; |
| // TODO keyvalue pair data |
| header.bytesOfKeyValueData = 0; |
| callbacks->write(user, &header, sizeof(TinyKtx_Header)); |
| |
| static uint8_t const padding[4] = {0, 0, 0, 0}; |
| |
| // TODO this might be wrong for non array cubemaps with < 4 bytes per pixel... |
| // cubemap padding needs factoring in. |
| for (uint32_t i = 0u; i < mipmaplevels; ++i) { |
| callbacks->write(user, mipmapsizes + i, sizeof(uint32_t)); |
| callbacks->write(user, mipmaps[i], mipmapsizes[i]); |
| callbacks->write(user, padding, ((mipmapsizes[i] + 3u) & ~3u) - mipmapsizes[i]); |
| } |
| |
| return true; |
| } |
| |
| static uint32_t imageSize(TinyKtx_ContextHandle handle, uint32_t mipmaplevel, bool seekLast) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return 0; |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return 0; |
| } |
| if (mipmaplevel >= ctx->header.numberOfMipmapLevels) { |
| ctx->callbacks.error(ctx->user, "Invalid mipmap level"); |
| return 0; |
| } |
| if (mipmaplevel >= TINYKTX_MAX_MIPMAPLEVELS) { |
| ctx->callbacks.error(ctx->user, "Invalid mipmap level"); |
| return 0; |
| } |
| if (!seekLast && ctx->mipMapSizes[mipmaplevel] != 0) |
| return ctx->mipMapSizes[mipmaplevel]; |
| |
| uint64_t currentOffset = ctx->firstImagePos; |
| for (uint32_t i = 0; i <= mipmaplevel; ++i) { |
| uint32_t size; |
| // if we have already read this mipmaps size use it |
| if (ctx->mipMapSizes[i] != 0) { |
| size = ctx->mipMapSizes[i]; |
| if (seekLast && i == mipmaplevel) { |
| ctx->callbacks.seek(ctx->user, currentOffset + sizeof(uint32_t)); |
| } |
| } else { |
| // otherwise seek and read it |
| ctx->callbacks.seek(ctx->user, currentOffset); |
| size_t readchk = ctx->callbacks.read(ctx->user, &size, sizeof(uint32_t)); |
| if(readchk != 4) { |
| ctx->callbacks.error(ctx->user, "Reading image size error"); |
| return 0; |
| } |
| |
| if (ctx->header.numberOfFaces == 6 && ctx->header.numberOfArrayElements == 0) { |
| size = ((size + 3u) & ~3u) * 6; // face padding and 6 faces |
| } |
| |
| ctx->mipMapSizes[i] = size; |
| } |
| currentOffset += (size + sizeof(uint32_t) + 3u) & ~3u; // size + mip padding |
| } |
| |
| return ctx->mipMapSizes[mipmaplevel]; |
| } |
| |
| uint32_t TinyKtx_ImageSize(TinyKtx_ContextHandle handle, uint32_t mipmaplevel) { |
| return imageSize(handle, mipmaplevel, false); |
| } |
| |
| void const *TinyKtx_ImageRawData(TinyKtx_ContextHandle handle, uint32_t mipmaplevel) { |
| TinyKtx_Context *ctx = (TinyKtx_Context *) handle; |
| if (ctx == NULL) |
| return NULL; |
| |
| if (ctx->headerValid == false) { |
| ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid"); |
| return NULL; |
| } |
| |
| if (mipmaplevel >= ctx->header.numberOfMipmapLevels) { |
| ctx->callbacks.error(ctx->user, "Invalid mipmap level"); |
| return NULL; |
| } |
| |
| if (mipmaplevel >= TINYKTX_MAX_MIPMAPLEVELS) { |
| ctx->callbacks.error(ctx->user, "Invalid mipmap level"); |
| return NULL; |
| } |
| |
| if (ctx->mipmaps[mipmaplevel] != NULL) |
| return ctx->mipmaps[mipmaplevel]; |
| |
| uint32_t size = imageSize(handle, mipmaplevel, true); |
| if (size == 0) |
| return NULL; |
| |
| ctx->mipmaps[mipmaplevel] = (uint8_t const*) ctx->callbacks.alloc(ctx->user, size); |
| if (ctx->mipmaps[mipmaplevel]) { |
| ctx->callbacks.read(ctx->user, (void *) ctx->mipmaps[mipmaplevel], size); |
| } |
| |
| return ctx->mipmaps[mipmaplevel]; |
| } |
| |
| #if TINYKTX_WANT_TINYKTX_FORMAT != 0 |
| |
| #define FT(fmt, type, intfmt, size) *glformat = TINYKTX_GL_FORMAT_##fmt; \ |
| *gltype = TINYKTX_GL_TYPE_##type; \ |
| *glinternalformat = TINYKTX_GL_INTFORMAT_##intfmt; \ |
| *typesize = size; \ |
| return true; |
| #define FTC(fmt, intfmt) *glformat = TINYKTX_GL_FORMAT_##fmt; \ |
| *gltype = TINYKTX_GL_TYPE_COMPRESSED; \ |
| *glinternalformat = TINYKTX_GL_COMPRESSED_##intfmt; \ |
| *typesize = 1; \ |
| return true; |
| |
| bool TinyKtx_CrackFormatToGL(TinyKtx_Format format, |
| uint32_t *glformat, |
| uint32_t *gltype, |
| uint32_t *glinternalformat, |
| uint32_t *typesize) { |
| switch (format) { |
| case TKTX_R4G4_UNORM_PACK8: break; |
| case TKTX_R4G4B4A4_UNORM_PACK16: FT(RGBA, UNSIGNED_SHORT_4_4_4_4, RGBA4, 1) |
| case TKTX_B4G4R4A4_UNORM_PACK16: FT(BGRA, UNSIGNED_SHORT_4_4_4_4_REV, RGBA4, 1) |
| case TKTX_R5G6B5_UNORM_PACK16: FT(RGB, UNSIGNED_SHORT_5_6_5, RGB565, 1) |
| case TKTX_B5G6R5_UNORM_PACK16: FT(BGR, UNSIGNED_SHORT_5_6_5_REV, RGB565, 1) |
| case TKTX_R5G5B5A1_UNORM_PACK16: FT(RGBA, UNSIGNED_SHORT_5_5_5_1, RGB5_A1, 1) |
| case TKTX_A1R5G5B5_UNORM_PACK16: FT(RGBA, UNSIGNED_SHORT_1_5_5_5_REV, RGB5_A1, 1) |
| case TKTX_B5G5R5A1_UNORM_PACK16: FT(BGRA, UNSIGNED_SHORT_5_5_5_1, RGB5_A1, 1) |
| |
| case TKTX_A2R10G10B10_UNORM_PACK32: FT(BGRA, UNSIGNED_INT_2_10_10_10_REV, RGB10_A2, 1) |
| case TKTX_A2R10G10B10_UINT_PACK32: FT(BGRA_INTEGER, UNSIGNED_INT_2_10_10_10_REV, RGB10_A2, 1) |
| case TKTX_A2B10G10R10_UNORM_PACK32: FT(RGBA, UNSIGNED_INT_2_10_10_10_REV, RGB10_A2, 1) |
| case TKTX_A2B10G10R10_UINT_PACK32: FT(RGBA_INTEGER, UNSIGNED_INT_2_10_10_10_REV, RGB10_A2, 1) |
| |
| case TKTX_R8_UNORM: FT(RED, UNSIGNED_BYTE, R8, 1) |
| case TKTX_R8_SNORM: FT(RED, BYTE, R8_SNORM, 1) |
| case TKTX_R8_UINT: FT(RED_INTEGER, UNSIGNED_BYTE, R8UI, 1) |
| case TKTX_R8_SINT: FT(RED_INTEGER, BYTE, R8I, 1) |
| case TKTX_R8_SRGB: FT(SLUMINANCE, UNSIGNED_BYTE, SRGB8, 1) |
| |
| case TKTX_R8G8_UNORM: FT(RG, UNSIGNED_BYTE, RG8, 1) |
| case TKTX_R8G8_SNORM: FT(RG, BYTE, RG8_SNORM, 1) |
| case TKTX_R8G8_UINT: FT(RG_INTEGER, UNSIGNED_BYTE, RG8UI, 1) |
| case TKTX_R8G8_SINT: FT(RG_INTEGER, BYTE, RG8I, 1) |
| case TKTX_R8G8_SRGB: FT(SLUMINANCE_ALPHA, UNSIGNED_BYTE, SRGB8, 1) |
| |
| case TKTX_R8G8B8_UNORM: FT(RGB, UNSIGNED_BYTE, RGB8, 1) |
| case TKTX_R8G8B8_SNORM: FT(RGB, BYTE, RGB8_SNORM, 1) |
| case TKTX_R8G8B8_UINT: FT(RGB_INTEGER, UNSIGNED_BYTE, RGB8UI, 1) |
| case TKTX_R8G8B8_SINT: FT(RGB_INTEGER, BYTE, RGB8I, 1) |
| case TKTX_R8G8B8_SRGB: FT(SRGB, UNSIGNED_BYTE, SRGB8, 1) |
| |
| case TKTX_B8G8R8_UNORM: FT(BGR, UNSIGNED_BYTE, RGB8, 1) |
| case TKTX_B8G8R8_SNORM: FT(BGR, BYTE, RGB8_SNORM, 1) |
| case TKTX_B8G8R8_UINT: FT(BGR_INTEGER, UNSIGNED_BYTE, RGB8UI, 1) |
| case TKTX_B8G8R8_SINT: FT(BGR_INTEGER, BYTE, RGB8I, 1) |
| case TKTX_B8G8R8_SRGB: FT(BGR, UNSIGNED_BYTE, SRGB8, 1) |
| |
| case TKTX_R8G8B8A8_UNORM:FT(RGBA, UNSIGNED_BYTE, RGBA8, 1) |
| case TKTX_R8G8B8A8_SNORM:FT(RGBA, BYTE, RGBA8_SNORM, 1) |
| case TKTX_R8G8B8A8_UINT: FT(RGBA_INTEGER, UNSIGNED_BYTE, RGBA8UI, 1) |
| case TKTX_R8G8B8A8_SINT: FT(RGBA_INTEGER, BYTE, RGBA8I, 1) |
| case TKTX_R8G8B8A8_SRGB: FT(SRGB_ALPHA, UNSIGNED_BYTE, SRGB8, 1) |
| |
| case TKTX_B8G8R8A8_UNORM: FT(BGRA, UNSIGNED_BYTE, RGBA8, 1) |
| case TKTX_B8G8R8A8_SNORM: FT(BGRA, BYTE, RGBA8_SNORM, 1) |
| case TKTX_B8G8R8A8_UINT: FT(BGRA_INTEGER, UNSIGNED_BYTE, RGBA8UI, 1) |
| case TKTX_B8G8R8A8_SINT: FT(BGRA_INTEGER, BYTE, RGBA8I, 1) |
| case TKTX_B8G8R8A8_SRGB: FT(BGRA, UNSIGNED_BYTE, SRGB8, 1) |
| |
| case TKTX_E5B9G9R9_UFLOAT_PACK32: FT(BGR, UNSIGNED_INT_5_9_9_9_REV, RGB9_E5, 1); |
| case TKTX_A8B8G8R8_UNORM_PACK32: FT(ABGR, UNSIGNED_BYTE, RGBA8, 1) |
| case TKTX_A8B8G8R8_SNORM_PACK32: FT(ABGR, BYTE, RGBA8, 1) |
| case TKTX_A8B8G8R8_UINT_PACK32: FT(ABGR, UNSIGNED_BYTE, RGBA8UI, 1) |
| case TKTX_A8B8G8R8_SINT_PACK32: FT(ABGR, BYTE, RGBA8I, 1) |
| case TKTX_A8B8G8R8_SRGB_PACK32: FT(ABGR, UNSIGNED_BYTE, SRGB8, 1) |
| case TKTX_B10G11R11_UFLOAT_PACK32: FT(BGR, UNSIGNED_INT_10F_11F_11F_REV, R11F_G11F_B10F, 1) |
| |
| case TKTX_R16_UNORM: FT(RED, UNSIGNED_SHORT, R16, 2) |
| case TKTX_R16_SNORM: FT(RED, SHORT, R16_SNORM, 2) |
| case TKTX_R16_UINT: FT(RED_INTEGER, UNSIGNED_SHORT, R16UI, 2) |
| case TKTX_R16_SINT: FT(RED_INTEGER, SHORT, R16I, 2) |
| case TKTX_R16_SFLOAT:FT(RED, HALF_FLOAT, R16F, 2) |
| |
| case TKTX_R16G16_UNORM: FT(RG, UNSIGNED_SHORT, RG16, 2) |
| case TKTX_R16G16_SNORM: FT(RG, SHORT, RG16_SNORM, 2) |
| case TKTX_R16G16_UINT: FT(RG_INTEGER, UNSIGNED_SHORT, RG16UI, 2) |
| case TKTX_R16G16_SINT: FT(RG_INTEGER, SHORT, RG16I, 2) |
| case TKTX_R16G16_SFLOAT:FT(RG, HALF_FLOAT, RG16F, 2) |
| |
| case TKTX_R16G16B16_UNORM: FT(RGB, UNSIGNED_SHORT, RGB16, 2) |
| case TKTX_R16G16B16_SNORM: FT(RGB, SHORT, RGB16_SNORM, 2) |
| case TKTX_R16G16B16_UINT: FT(RGB_INTEGER, UNSIGNED_SHORT, RGB16UI, 2) |
| case TKTX_R16G16B16_SINT: FT(RGB_INTEGER, SHORT, RGB16I, 2) |
| case TKTX_R16G16B16_SFLOAT: FT(RGB, HALF_FLOAT, RGB16F, 2) |
| |
| case TKTX_R16G16B16A16_UNORM: FT(RGBA, UNSIGNED_SHORT, RGBA16, 2) |
| case TKTX_R16G16B16A16_SNORM: FT(RGBA, SHORT, RGBA16_SNORM, 2) |
| case TKTX_R16G16B16A16_UINT: FT(RGBA_INTEGER, UNSIGNED_SHORT, RGBA16UI, 2) |
| case TKTX_R16G16B16A16_SINT: FT(RGBA_INTEGER, SHORT, RGBA16I, 2) |
| case TKTX_R16G16B16A16_SFLOAT:FT(RGBA, HALF_FLOAT, RGBA16F, 2) |
| |
| case TKTX_R32_UINT: FT(RED_INTEGER, UNSIGNED_INT, R32UI, 4) |
| case TKTX_R32_SINT: FT(RED_INTEGER, INT, R32I, 4) |
| case TKTX_R32_SFLOAT: FT(RED, FLOAT, R32F, 4) |
| |
| case TKTX_R32G32_UINT: FT(RG_INTEGER, UNSIGNED_INT, RG32UI, 4) |
| case TKTX_R32G32_SINT: FT(RG_INTEGER, INT, RG32I, 4) |
| case TKTX_R32G32_SFLOAT: FT(RG, FLOAT, RG32F, 4) |
| |
| case TKTX_R32G32B32_UINT: FT(RGB_INTEGER, UNSIGNED_INT, RGB32UI, 4) |
| case TKTX_R32G32B32_SINT: FT(RGB_INTEGER, INT, RGB32I, 4) |
| case TKTX_R32G32B32_SFLOAT: FT(RGB_INTEGER, FLOAT, RGB32F, 4) |
| |
| case TKTX_R32G32B32A32_UINT: FT(RGBA_INTEGER, UNSIGNED_INT, RGBA32UI, 4) |
| case TKTX_R32G32B32A32_SINT: FT(RGBA_INTEGER, INT, RGBA32I, 4) |
| case TKTX_R32G32B32A32_SFLOAT:FT(RGBA, FLOAT, RGBA32F, 4) |
| |
| case TKTX_BC1_RGB_UNORM_BLOCK: FTC(RGB, RGB_S3TC_DXT1) |
| case TKTX_BC1_RGB_SRGB_BLOCK: FTC(RGB, SRGB_S3TC_DXT1) |
| case TKTX_BC1_RGBA_UNORM_BLOCK: FTC(RGBA, RGBA_S3TC_DXT1) |
| case TKTX_BC1_RGBA_SRGB_BLOCK: FTC(RGBA, SRGB_ALPHA_S3TC_DXT1) |
| case TKTX_BC2_UNORM_BLOCK: FTC(RGBA, RGBA_S3TC_DXT3) |
| case TKTX_BC2_SRGB_BLOCK: FTC(RGBA, SRGB_ALPHA_S3TC_DXT3) |
| case TKTX_BC3_UNORM_BLOCK: FTC(RGBA, RGBA_S3TC_DXT5) |
| case TKTX_BC3_SRGB_BLOCK: FTC(RGBA, SRGB_ALPHA_S3TC_DXT5) |
| case TKTX_BC4_UNORM_BLOCK: FTC(RED, RED_RGTC1) |
| case TKTX_BC4_SNORM_BLOCK: FTC(RED, SIGNED_RED_RGTC1) |
| case TKTX_BC5_UNORM_BLOCK: FTC(RG, RED_GREEN_RGTC2) |
| case TKTX_BC5_SNORM_BLOCK: FTC(RG, SIGNED_RED_GREEN_RGTC2) |
| case TKTX_BC6H_UFLOAT_BLOCK: FTC(RGB, RGB_BPTC_UNSIGNED_FLOAT) |
| case TKTX_BC6H_SFLOAT_BLOCK: FTC(RGB, RGB_BPTC_SIGNED_FLOAT) |
| case TKTX_BC7_UNORM_BLOCK: FTC(RGBA, RGBA_BPTC_UNORM) |
| case TKTX_BC7_SRGB_BLOCK: FTC(RGBA, SRGB_ALPHA_BPTC_UNORM) |
| |
| case TKTX_ETC2_R8G8B8_UNORM_BLOCK: FTC(RGB, RGB8_ETC2) |
| case TKTX_ETC2_R8G8B8A1_UNORM_BLOCK: FTC(RGBA, RGB8_PUNCHTHROUGH_ALPHA1_ETC2) |
| case TKTX_ETC2_R8G8B8A8_UNORM_BLOCK: FTC(RGBA, RGBA8_ETC2_EAC) |
| case TKTX_ETC2_R8G8B8_SRGB_BLOCK: FTC(SRGB, SRGB8_ETC2) |
| case TKTX_ETC2_R8G8B8A1_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) |
| case TKTX_ETC2_R8G8B8A8_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ETC2_EAC) |
| case TKTX_EAC_R11_UNORM_BLOCK: FTC(RED, R11_EAC) |
| case TKTX_EAC_R11G11_UNORM_BLOCK: FTC(RG, RG11_EAC) |
| case TKTX_EAC_R11_SNORM_BLOCK: FTC(RED, SIGNED_R11_EAC) |
| case TKTX_EAC_R11G11_SNORM_BLOCK: FTC(RG, SIGNED_RG11_EAC) |
| |
| case TKTX_PVR_2BPP_BLOCK: FTC(RGB, RGB_PVRTC_2BPPV1) |
| case TKTX_PVR_2BPPA_BLOCK: FTC(RGBA, RGBA_PVRTC_2BPPV1); |
| case TKTX_PVR_4BPP_BLOCK: FTC(RGB, RGB_PVRTC_4BPPV1) |
| case TKTX_PVR_4BPPA_BLOCK: FTC(RGB, RGB_PVRTC_4BPPV1) |
| case TKTX_PVR_2BPP_SRGB_BLOCK: FTC(SRGB, SRGB_PVRTC_2BPPV1) |
| case TKTX_PVR_2BPPA_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB_ALPHA_PVRTC_2BPPV1); |
| case TKTX_PVR_4BPP_SRGB_BLOCK: FTC(SRGB, SRGB_PVRTC_2BPPV1) |
| case TKTX_PVR_4BPPA_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB_ALPHA_PVRTC_2BPPV1); |
| |
| case TKTX_ASTC_4x4_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_4x4) |
| case TKTX_ASTC_4x4_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_4x4) |
| case TKTX_ASTC_5x4_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_5x4) |
| case TKTX_ASTC_5x4_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_5x4) |
| case TKTX_ASTC_5x5_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_5x5) |
| case TKTX_ASTC_5x5_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_5x5) |
| case TKTX_ASTC_6x5_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_6x5) |
| case TKTX_ASTC_6x5_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_6x5) |
| case TKTX_ASTC_6x6_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_6x6) |
| case TKTX_ASTC_6x6_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_6x6) |
| case TKTX_ASTC_8x5_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_8x5) |
| case TKTX_ASTC_8x5_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_8x5) |
| case TKTX_ASTC_8x6_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_8x6) |
| case TKTX_ASTC_8x6_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_8x6) |
| case TKTX_ASTC_8x8_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_8x8) |
| case TKTX_ASTC_8x8_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_8x8) |
| case TKTX_ASTC_10x5_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_10x5) |
| case TKTX_ASTC_10x5_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_10x5) |
| case TKTX_ASTC_10x6_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_10x6) |
| case TKTX_ASTC_10x6_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_10x6) |
| case TKTX_ASTC_10x8_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_10x8); |
| case TKTX_ASTC_10x8_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_10x8) |
| case TKTX_ASTC_10x10_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_10x10) |
| case TKTX_ASTC_10x10_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_10x10) |
| case TKTX_ASTC_12x10_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_12x10) |
| case TKTX_ASTC_12x10_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_12x10) |
| case TKTX_ASTC_12x12_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_12x12) |
| case TKTX_ASTC_12x12_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_12x12) |
| |
| default:break; |
| } |
| return false; |
| } |
| #undef FT |
| #undef FTC |
| |
| TinyKtx_Format TinyKtx_CrackFormatFromGL(uint32_t const glformat, |
| uint32_t const gltype, |
| uint32_t const glinternalformat, |
| uint32_t const typesize) { |
| switch (glinternalformat) { |
| case TINYKTX_GL_COMPRESSED_RGB_S3TC_DXT1: return TKTX_BC1_RGB_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT1: return TKTX_BC1_RGBA_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT3: return TKTX_BC2_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT5: return TKTX_BC3_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_3DC_X_AMD: return TKTX_BC4_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_3DC_XY_AMD: return TKTX_BC5_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_PVRTC_2BPPV1: return TKTX_PVR_2BPP_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_PVRTC_4BPPV1: return TKTX_PVR_2BPPA_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1: return TKTX_PVR_2BPPA_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1: return TKTX_PVR_4BPPA_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGB_PVRTC_4BPPV1: return TKTX_PVR_4BPP_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGB_PVRTC_2BPPV1: return TKTX_PVR_2BPP_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_PVRTC_4BPPV1: return TKTX_PVR_4BPPA_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_PVRTC_2BPPV1: return TKTX_PVR_2BPPA_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_S3TC_DXT1: return TKTX_BC1_RGB_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1: return TKTX_BC1_RGBA_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3: return TKTX_BC2_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5: return TKTX_BC3_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_LUMINANCE_LATC1: return TKTX_BC4_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SIGNED_LUMINANCE_LATC1: return TKTX_BC4_SNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_LUMINANCE_ALPHA_LATC2: return TKTX_BC5_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2: return TKTX_BC5_SNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RED_RGTC1: return TKTX_BC4_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SIGNED_RED_RGTC1: return TKTX_BC4_SNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RED_GREEN_RGTC2: return TKTX_BC5_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2: return TKTX_BC5_SNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_ETC1_RGB8_OES: return TKTX_ETC2_R8G8B8_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_BPTC_UNORM: return TKTX_BC7_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: return TKTX_BC7_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: return TKTX_BC6H_SFLOAT_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: return TKTX_BC6H_UFLOAT_BLOCK; |
| case TINYKTX_GL_COMPRESSED_R11_EAC: return TKTX_EAC_R11_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SIGNED_R11_EAC: return TKTX_EAC_R11_SNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RG11_EAC: return TKTX_EAC_R11G11_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SIGNED_RG11_EAC: return TKTX_EAC_R11G11_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGB8_ETC2: return TKTX_ETC2_R8G8B8_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ETC2: return TKTX_ETC2_R8G8B8_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: return TKTX_ETC2_R8G8B8A1_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: return TKTX_ETC2_R8G8B8A1_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA8_ETC2_EAC: return TKTX_ETC2_R8G8B8A8_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: return TKTX_ETC2_R8G8B8A8_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_4x4: return TKTX_ASTC_4x4_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_5x4: return TKTX_ASTC_5x4_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_5x5: return TKTX_ASTC_5x5_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_6x5: return TKTX_ASTC_6x5_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_6x6: return TKTX_ASTC_6x6_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x5: return TKTX_ASTC_8x5_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x6: return TKTX_ASTC_8x6_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x8: return TKTX_ASTC_8x8_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x5: return TKTX_ASTC_10x5_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x6: return TKTX_ASTC_10x6_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x8: return TKTX_ASTC_10x8_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x10: return TKTX_ASTC_10x10_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_12x10: return TKTX_ASTC_12x10_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_RGBA_ASTC_12x12: return TKTX_ASTC_12x12_UNORM_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4: return TKTX_ASTC_4x4_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4: return TKTX_ASTC_5x4_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5: return TKTX_ASTC_5x5_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5: return TKTX_ASTC_6x5_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6: return TKTX_ASTC_6x6_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5: return TKTX_ASTC_8x5_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6: return TKTX_ASTC_8x6_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8: return TKTX_ASTC_8x8_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5: return TKTX_ASTC_10x5_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6: return TKTX_ASTC_10x6_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8: return TKTX_ASTC_10x8_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10: return TKTX_ASTC_10x10_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10: return TKTX_ASTC_12x10_SRGB_BLOCK; |
| case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12: return TKTX_ASTC_12x12_SRGB_BLOCK; |
| |
| // non compressed |
| case TINYKTX_GL_INTFORMAT_R8: return TKTX_R8_UNORM; |
| case TINYKTX_GL_INTFORMAT_RG8: return TKTX_R8G8_UNORM; |
| case TINYKTX_GL_INTFORMAT_RGB8: return TKTX_R8G8B8_UNORM; |
| case TINYKTX_GL_INTFORMAT_RGBA8: |
| if(glformat == TINYKTX_GL_FORMAT_RGBA) { |
| if(gltype == TINYKTX_GL_TYPE_UNSIGNED_BYTE) { |
| return TKTX_R8G8B8A8_UNORM; |
| } else if(gltype == TINYKTX_GL_TYPE_BYTE) { |
| return TKTX_R8G8B8A8_SNORM; |
| } |
| } else if(glformat == TINYKTX_GL_FORMAT_BGRA) { |
| if(gltype == TINYKTX_GL_TYPE_UNSIGNED_BYTE) { |
| return TKTX_B8G8R8A8_UNORM; |
| } else if(gltype == TINYKTX_GL_TYPE_BYTE) { |
| return TKTX_B8G8R8A8_SNORM; |
| } |
| } else if(glformat == TINYKTX_GL_FORMAT_ABGR) { |
| if(gltype == TINYKTX_GL_TYPE_UNSIGNED_BYTE) { |
| return TKTX_A8B8G8R8_UNORM_PACK32; |
| } else if(gltype == TINYKTX_GL_TYPE_BYTE) { |
| return TKTX_A8B8G8R8_SNORM_PACK32; |
| } |
| } |
| break; |
| case TINYKTX_GL_INTFORMAT_R8_SNORM: return TKTX_R8_SNORM; |
| case TINYKTX_GL_INTFORMAT_RG8_SNORM: return TKTX_R8G8_SNORM; |
| case TINYKTX_GL_INTFORMAT_RGB8_SNORM: return TKTX_R8G8B8_SNORM; |
| case TINYKTX_GL_INTFORMAT_RGBA8_SNORM: return TKTX_R8G8B8A8_SNORM; |
| |
| case TINYKTX_GL_INTFORMAT_R16: return TKTX_R16_UNORM; |
| case TINYKTX_GL_INTFORMAT_RG16: return TKTX_R16G16_UNORM; |
| case TINYKTX_GL_INTFORMAT_RGB16: return TKTX_R16G16B16_UNORM; |
| case TINYKTX_GL_INTFORMAT_RGBA16: return TKTX_R16G16B16A16_UNORM; |
| |
| case TINYKTX_GL_INTFORMAT_R16_SNORM:return TKTX_R16_SNORM; |
| case TINYKTX_GL_INTFORMAT_RG16_SNORM: return TKTX_R16G16_SNORM; |
| case TINYKTX_GL_INTFORMAT_RGB16_SNORM: return TKTX_R16G16B16_SNORM; |
| case TINYKTX_GL_INTFORMAT_RGBA16_SNORM: return TKTX_R16G16B16A16_SNORM; |
| |
| case TINYKTX_GL_INTFORMAT_R8I: return TKTX_R8_SINT; |
| case TINYKTX_GL_INTFORMAT_RG8I: return TKTX_R8G8_SINT; |
| case TINYKTX_GL_INTFORMAT_RGB8I:return TKTX_R8G8B8_SINT; |
| case TINYKTX_GL_INTFORMAT_RGBA8I: |
| if(glformat == TINYKTX_GL_FORMAT_RGBA || glformat == TINYKTX_GL_FORMAT_RGBA_INTEGER) { |
| return TKTX_R8G8B8A8_SINT; |
| } else if(glformat == TINYKTX_GL_FORMAT_BGRA || glformat == TINYKTX_GL_FORMAT_BGRA_INTEGER) { |
| return TKTX_B8G8R8A8_SINT; |
| } else if(glformat == TINYKTX_GL_FORMAT_ABGR) { |
| return TKTX_A8B8G8R8_SINT_PACK32; |
| } |
| break; |
| |
| case TINYKTX_GL_INTFORMAT_R16I: return TKTX_R16_SINT; |
| case TINYKTX_GL_INTFORMAT_RG16I: return TKTX_R16G16_SINT; |
| case TINYKTX_GL_INTFORMAT_RGB16I:return TKTX_R16G16B16_SINT; |
| case TINYKTX_GL_INTFORMAT_RGBA16I:return TKTX_R16G16B16A16_SINT; |
| |
| case TINYKTX_GL_INTFORMAT_R32I: return TKTX_R32_SINT; |
| case TINYKTX_GL_INTFORMAT_RG32I: return TKTX_R32G32_SINT; |
| case TINYKTX_GL_INTFORMAT_RGB32I: return TKTX_R32G32B32_SINT; |
| case TINYKTX_GL_INTFORMAT_RGBA32I:return TKTX_R32G32B32A32_SINT; |
| |
| case TINYKTX_GL_INTFORMAT_R8UI: return TKTX_R8_UINT; |
| case TINYKTX_GL_INTFORMAT_RG8UI: return TKTX_R8G8_UINT; |
| case TINYKTX_GL_INTFORMAT_RGB8UI: return TKTX_R8G8B8_UINT; |
| case TINYKTX_GL_INTFORMAT_RGBA8UI: |
| if(glformat == TINYKTX_GL_FORMAT_RGBA || glformat == TINYKTX_GL_FORMAT_RGBA_INTEGER) { |
| return TKTX_R8G8B8A8_UINT; |
| } else if(glformat == TINYKTX_GL_FORMAT_BGRA || glformat == TINYKTX_GL_FORMAT_BGRA_INTEGER) { |
| return TKTX_B8G8R8A8_UINT; |
| } else if(glformat == TINYKTX_GL_FORMAT_ABGR) { |
| return TKTX_A8B8G8R8_UINT_PACK32; |
| } |
| break; |
| |
| case TINYKTX_GL_INTFORMAT_R16UI: return TKTX_R16_UINT; |
| case TINYKTX_GL_INTFORMAT_RG16UI: return TKTX_R16G16_UINT; |
| case TINYKTX_GL_INTFORMAT_RGB16UI:return TKTX_R16G16B16_UINT; |
| case TINYKTX_GL_INTFORMAT_RGBA16UI: return TKTX_R16G16B16A16_UINT; |
| |
| case TINYKTX_GL_INTFORMAT_R32UI: return TKTX_R32_UINT; |
| case TINYKTX_GL_INTFORMAT_RG32UI: return TKTX_R32G32_UINT; |
| case TINYKTX_GL_INTFORMAT_RGB32UI: return TKTX_R32G32B32_UINT; |
| case TINYKTX_GL_INTFORMAT_RGBA32UI: return TKTX_R32G32B32A32_UINT; |
| |
| case TINYKTX_GL_INTFORMAT_R16F: return TKTX_R16_SFLOAT; |
| case TINYKTX_GL_INTFORMAT_RG16F: return TKTX_R16G16_SFLOAT; |
| case TINYKTX_GL_INTFORMAT_RGB16F: return TKTX_R16G16B16_SFLOAT; |
| case TINYKTX_GL_INTFORMAT_RGBA16F: return TKTX_R16G16B16A16_SFLOAT; |
| |
| case TINYKTX_GL_INTFORMAT_R32F: return TKTX_R32_SFLOAT; |
| case TINYKTX_GL_INTFORMAT_RG32F: return TKTX_R32G32_SFLOAT; |
| case TINYKTX_GL_INTFORMAT_RGB32F: return TKTX_R32G32B32_SFLOAT; |
| case TINYKTX_GL_INTFORMAT_RGBA32F: return TKTX_R32G32B32A32_SFLOAT; |
| |
| case TINYKTX_GL_INTFORMAT_R11F_G11F_B10F: return TKTX_B10G11R11_UFLOAT_PACK32; //?? |
| case TINYKTX_GL_INTFORMAT_UNSIGNED_INT_10F_11F_11F_REV: return TKTX_B10G11R11_UFLOAT_PACK32; //? |
| case TINYKTX_GL_INTFORMAT_RGB9_E5: return TKTX_E5B9G9R9_UFLOAT_PACK32; |
| case TINYKTX_GL_INTFORMAT_SLUMINANCE8_ALPHA8: return TKTX_R8G8_SRGB; |
| case TINYKTX_GL_INTFORMAT_SLUMINANCE8: return TKTX_R8_SRGB; |
| case TINYKTX_GL_INTFORMAT_RGB565: return TKTX_R5G6B5_UNORM_PACK16; |
| |
| case TINYKTX_GL_INTFORMAT_ALPHA8: return TKTX_R8_UNORM; |
| case TINYKTX_GL_INTFORMAT_ALPHA16: return TKTX_R16_UNORM; |
| case TINYKTX_GL_INTFORMAT_LUMINANCE8: return TKTX_R8_UNORM; |
| case TINYKTX_GL_INTFORMAT_LUMINANCE16: return TKTX_R16_UNORM; |
| case TINYKTX_GL_INTFORMAT_LUMINANCE8_ALPHA8: return TKTX_R8G8_UNORM; |
| case TINYKTX_GL_INTFORMAT_LUMINANCE16_ALPHA16: return TKTX_R16G16_UNORM; |
| case TINYKTX_GL_INTFORMAT_INTENSITY8: return TKTX_R8_UNORM; |
| case TINYKTX_GL_INTFORMAT_INTENSITY16: return TKTX_R16_UNORM; |
| |
| case TINYKTX_GL_INTFORMAT_ALPHA8_SNORM: return TKTX_R8_SNORM; |
| case TINYKTX_GL_INTFORMAT_LUMINANCE8_SNORM: return TKTX_R8_SNORM; |
| case TINYKTX_GL_INTFORMAT_LUMINANCE8_ALPHA8_SNORM: return TKTX_R8G8_SNORM; |
| case TINYKTX_GL_INTFORMAT_INTENSITY8_SNORM: return TKTX_R8_SNORM; |
| case TINYKTX_GL_INTFORMAT_ALPHA16_SNORM: return TKTX_R16_SNORM; |
| case TINYKTX_GL_INTFORMAT_LUMINANCE16_SNORM: return TKTX_R16_SNORM; |
| case TINYKTX_GL_INTFORMAT_LUMINANCE16_ALPHA16_SNORM: return TKTX_R16G16_SNORM; |
| case TINYKTX_GL_INTFORMAT_INTENSITY16_SNORM: return TKTX_R16_SNORM; |
| |
| case TINYKTX_GL_INTFORMAT_RGB5_A1: |
| if (gltype == TINYKTX_GL_TYPE_UNSIGNED_SHORT_1_5_5_5_REV) { |
| return TKTX_A1R5G5B5_UNORM_PACK16; |
| } else if (gltype == TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_5_5_1) { |
| return TKTX_R5G5B5A1_UNORM_PACK16; |
| } |
| break; |
| |
| case TINYKTX_GL_INTFORMAT_SRGB8: |
| case TINYKTX_GL_INTFORMAT_SRGB8_ALPHA8: |
| if (glformat == TINYKTX_GL_FORMAT_SLUMINANCE) { |
| return TKTX_R8_SRGB; |
| } else if (glformat == TINYKTX_GL_FORMAT_SLUMINANCE_ALPHA) { |
| return TKTX_R8G8_SRGB; |
| } else if (glformat == TINYKTX_GL_FORMAT_SRGB) { |
| return TKTX_R8G8B8_SRGB; |
| } else if (glformat == TINYKTX_GL_FORMAT_SRGB_ALPHA) { |
| return TKTX_R8G8B8A8_SRGB; |
| } else if (glformat == TINYKTX_GL_FORMAT_BGR) { |
| return TKTX_B8G8R8_SRGB; |
| } else if (glformat == TINYKTX_GL_FORMAT_BGRA) { |
| return TKTX_B8G8R8A8_SRGB; |
| } else if (glformat == TINYKTX_GL_FORMAT_ABGR) { |
| return TKTX_A8B8G8R8_SRGB_PACK32; |
| } |
| break; |
| case TINYKTX_GL_INTFORMAT_RGBA4: |
| if(glformat == TINYKTX_GL_FORMAT_RGBA) { |
| return TKTX_R4G4B4A4_UNORM_PACK16; |
| } else if(glformat == TINYKTX_GL_FORMAT_BGRA) { |
| return TKTX_B4G4R4A4_UNORM_PACK16; |
| } |
| break; |
| |
| case TINYKTX_GL_INTFORMAT_RGB10_A2: |
| if(glformat == TINYKTX_GL_FORMAT_BGRA) { |
| return TKTX_A2R10G10B10_UNORM_PACK32; |
| } else if(glformat == TINYKTX_GL_FORMAT_RGBA) { |
| return TKTX_A2B10G10R10_UNORM_PACK32; |
| } else if(glformat == TINYKTX_GL_FORMAT_BGRA_INTEGER) { |
| return TKTX_A2R10G10B10_UINT_PACK32; |
| } else if(glformat == TINYKTX_GL_FORMAT_RGBA_INTEGER) { |
| return TKTX_A2B10G10R10_UINT_PACK32; |
| } |
| break; |
| |
| // can't handle yet |
| case TINYKTX_GL_INTFORMAT_ALPHA4: |
| case TINYKTX_GL_INTFORMAT_ALPHA12: |
| case TINYKTX_GL_INTFORMAT_LUMINANCE4: |
| case TINYKTX_GL_INTFORMAT_LUMINANCE12: |
| case TINYKTX_GL_INTFORMAT_LUMINANCE4_ALPHA4: |
| case TINYKTX_GL_INTFORMAT_LUMINANCE6_ALPHA2: |
| case TINYKTX_GL_INTFORMAT_LUMINANCE12_ALPHA4: |
| case TINYKTX_GL_INTFORMAT_LUMINANCE12_ALPHA12: |
| case TINYKTX_GL_INTFORMAT_INTENSITY4: |
| case TINYKTX_GL_INTFORMAT_INTENSITY12: |
| case TINYKTX_GL_INTFORMAT_RGB2: |
| case TINYKTX_GL_INTFORMAT_RGB4: |
| case TINYKTX_GL_INTFORMAT_RGB5: |
| case TINYKTX_GL_INTFORMAT_RGB10: |
| case TINYKTX_GL_INTFORMAT_RGB12: |
| case TINYKTX_GL_INTFORMAT_RGBA2: |
| case TINYKTX_GL_INTFORMAT_RGBA12: |
| case TINYKTX_GL_INTFORMAT_FLOAT_32_UNSIGNED_INT_24_8_REV: |
| case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2: |
| case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2: |
| case TINYKTX_GL_COMPRESSED_ATC_RGB: |
| case TINYKTX_GL_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA: |
| case TINYKTX_GL_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA: |
| default: break; |
| } |
| return TKTX_UNDEFINED; |
| } |
| |
| TinyKtx_Format TinyKtx_GetFormat(TinyKtx_ContextHandle handle) { |
| uint32_t glformat; |
| uint32_t gltype; |
| uint32_t glinternalformat; |
| uint32_t typesize; |
| uint32_t glbaseinternalformat; |
| |
| if(TinyKtx_GetFormatGL(handle, &glformat, &gltype, &glinternalformat, &typesize, &glbaseinternalformat) == false) |
| return TKTX_UNDEFINED; |
| |
| return TinyKtx_CrackFormatFromGL(glformat, gltype, glinternalformat, typesize); |
| } |
| |
| bool TinyKtx_WriteImage(TinyKtx_WriteCallbacks const *callbacks, |
| void *user, |
| uint32_t width, |
| uint32_t height, |
| uint32_t depth, |
| uint32_t slices, |
| uint32_t mipmaplevels, |
| TinyKtx_Format format, |
| bool cubemap, |
| uint32_t const *mipmapsizes, |
| void const **mipmaps) { |
| uint32_t glformat; |
| uint32_t glinternalFormat; |
| uint32_t gltype; |
| uint32_t gltypeSize; |
| if (TinyKtx_CrackFormatToGL(format, &glformat, &gltype, &glinternalFormat, &gltypeSize) == false) |
| return false; |
| |
| return TinyKtx_WriteImageGL(callbacks, |
| user, |
| width, |
| height, |
| depth, |
| slices, |
| mipmaplevels, |
| glformat, |
| glinternalFormat, |
| glinternalFormat, //?? |
| gltype, |
| gltypeSize, |
| cubemap, |
| mipmapsizes, |
| mipmaps |
| ); |
| |
| } |
| #endif // end #if TINYKTX_WANT_TINYKTX_FORMAT != 0 |
| |
| #endif |
| |
| #ifdef __cplusplus |
| }; |
| #endif |
| |
| #endif // end header |
| /* |
| BSD 2-Clause License |
| |
| Copyright (c) 2019, DeanoC |
| All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are met: |
| |
| 1. Redistributions of source code must retain the above copyright notice, this |
| list of conditions and the following disclaimer. |
| |
| 2. Redistributions in binary form must reproduce the above copyright notice, |
| this list of conditions and the following disclaimer in the documentation |
| and/or other materials provided with the distribution. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |