├── .editorconfig
├── .gitignore
├── .idea
├── .gitignore
├── misc.xml
├── modules.xml
├── tiny_ktx.iml
└── vcs.xml
├── CMakeLists.txt
├── LICENSE
├── README.md
├── include
└── tiny_ktx
│ ├── tinyktx.h
│ └── tinyktx2.h
├── src
└── tinyktx.c
└── tests
├── runner.cpp
├── test_tinyktx.cpp
└── test_tinyktx_tinyimageformat.cpp
/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | root = true
3 |
4 | [*.{c,cpp,h,hpp}]
5 | indent_style = tab
6 | indent_size = 2
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Object files
5 | *.o
6 | *.ko
7 | *.obj
8 | *.elf
9 |
10 | # Linker output
11 | *.ilk
12 | *.map
13 | *.exp
14 |
15 | # Precompiled Headers
16 | *.gch
17 | *.pch
18 |
19 | # Libraries
20 | *.lib
21 | *.a
22 | *.la
23 | *.lo
24 |
25 | # Shared objects (inc. Windows DLLs)
26 | *.dll
27 | *.so
28 | *.so.*
29 | *.dylib
30 |
31 | # Executables
32 | *.exe
33 | *.out
34 | *.app
35 | *.i*86
36 | *.x86_64
37 | *.hex
38 |
39 | # Debug files
40 | *.dSYM/
41 | *.su
42 | *.idb
43 | *.pdb
44 |
45 | # Kernel Module Compile Results
46 | *.mod*
47 | *.cmd
48 | .tmp_versions/
49 | modules.order
50 | Module.symvers
51 | Mkfile.old
52 | dkms.conf
53 |
54 | # Project exclude paths
55 | /cmake-build-debug/
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/tiny_ktx.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.12.4)
2 | get_directory_property(hasParent PARENT_DIRECTORY)
3 | if(NOT hasParent)
4 | option(unittests "unittests" OFF)
5 | get_filename_component(_PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
6 | set_property(GLOBAL PROPERTY GLOBAL_FETCHDEPS_BASE ${_PARENT_DIR}/al2o3 )
7 | include(FetchContent)
8 | FetchContent_Declare( al2o3 GIT_REPOSITORY https://github.com/DeanoC/al2o3 GIT_TAG master )
9 | FetchContent_GetProperties(al2o3)
10 | if(NOT al2o3_POPULATED)
11 | FetchContent_Populate(al2o3)
12 | add_subdirectory(${al2o3_SOURCE_DIR} ${al2o3_BINARY_DIR})
13 | endif()
14 | INIT_AL2O3(${CMAKE_CURRENT_SOURCE_DIR})
15 | endif ()
16 |
17 | SET_MIN_VERSIONS()
18 | set(LibName tiny_ktx)
19 | project(${LibName})
20 |
21 | set(Interface
22 | tinyktx.h
23 | )
24 |
25 | set(Src
26 | tinyktx.c
27 | )
28 |
29 | set(Deps
30 | tiny_imageformat
31 | )
32 | ADD_LIB(${LibName} "${Interface}" "${Src}" "${Deps}")
33 |
34 | set( Tests
35 | runner.cpp
36 | test_tinyktx.cpp
37 | test_tinyktx_tinyimageformat.cpp
38 | )
39 | set( TestDeps
40 | al2o3_catch2
41 | al2o3_vfile
42 | al2o3_stb
43 | tiny_imageformat
44 | utils_simple_logmanager)
45 | ADD_LIB_TESTS(${LibName} "${Interface}" "${Tests}" "${TestDeps}")
46 |
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 DeanoC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tiny_ktx
2 | Small C based KTX texture loader (inspired by syoyo tiny libraries)
3 |
4 | KTX textures can handle
5 | * Almost any format of texture data
6 | * 1D, 2D, 3D and cubemaps textures
7 | * Texture arrays
8 | * Mipmaps
9 | * Key value pairs for custom data extensions
10 |
11 | Its an efficient open format for almost every realtime texture data you could want.
12 |
13 | ## What it does?
14 | * Loads Khronos KTX textures
15 | * Saves Khronos KTX textures
16 | * Optionally provide format in either native GL/KTX style or Vulkan/Dx12/Metal style
17 | * Optionally provides GL defines requires to read KTX files without GL
18 |
19 | tiny_ktx is a very low level API as such it only handles these parts, it doesn't process the data in any way
20 |
21 | ## Requirements
22 | None except a C compiler (TODO test which version 89 or 99)
23 |
24 | By default uses 4 std lib headers
25 | * stdint.h -for uint32_t and int64_t
26 | * stdbool.h - for bool
27 | * stddef.h - for size_t
28 | * string.h - for memcpy
29 |
30 | However if the types/functions are provided you can opt out
31 | of these being included via *TINYKTX_HAVE_UINTXX_T* etc.
32 |
33 | ## How to build
34 | * include tinyktx.h from include/tiny_ktx in your project
35 | * in 1 file in your project define *TINYKTX_IMPLEMENTATION* before tinyktx.h
36 |
37 | if using cmake and want a library version just add this using add_subdirectory
38 | and add tiny_ktx as a dependency
39 |
40 | ## Handling KTX format
41 | KTX file are based on OpenGL which has evolved a fairly complex pixel format system
42 |
43 | Whilst this may be useful if you are importing into a GL application for other its quite hard to convert.
44 |
45 | An optional part of TinyKtx (default is on) will convert these into a more Vulkan/Dx12/Metal format.
46 |
47 | Rather than the multiple uint32_t types KTX stores format in, TinyKtx provides a single large enum.
48 |
49 | *TinyKtx_GetFormatGL* will give you the format directly as stored in the KTX file
50 |
51 | *TinyKtx_GetFormat* will provide a single value converted from the KTX GL provided type.
52 |
53 | if TinyKtx_GetFormat can't convert it will return *TKTX_UNDEFINED*
54 |
55 | ## How to load a KTX
56 | Create a contex using *TinyKtx_CreateContext* passing in callbacks for
57 | * optional error report
58 | * alloc
59 | * free
60 | * read
61 | * seek
62 | * tell
63 |
64 | All are provides a void* user data argument for file handle etc.
65 |
66 | ```
67 | Read the header (TinyKtx_ReadHeader).
68 | A tell/read should be at the start of the KTX data
69 |
70 | Query the dimension, format etc. (TinyKtx_Width etc.)
71 |
72 | For each mipmap level in the file (TinyKtx_NumberOfMipmaps)
73 | get the mipmap size (TinyKtx_ImageSize)
74 | get the mipmap data (TinyKtx_ImageRawData)
75 | ```
76 | Load snippet
77 | ```c
78 | static void tinyktxCallbackError(void *user, char const *msg) {
79 | LOGERROR("Tiny_Ktx ERROR: %s", msg);
80 | }
81 | static void *tinyktxCallbackAlloc(void *user, size_t size) {
82 | return MEMORY_MALLOC(size);
83 | }
84 | static void tinyktxCallbackFree(void *user, void *data) {
85 | MEMORY_FREE(data);
86 | }
87 | static size_t tinyktxCallbackRead(void *user, void* data, size_t size) {
88 | auto handle = (VFile_Handle) user;
89 | return VFile_Read(handle, data, size);
90 | }
91 | static bool tinyktxCallbackSeek(void *user, int64_t offset) {
92 | auto handle = (VFile_Handle) user;
93 | return VFile_Seek(handle, offset, VFile_SD_Begin);
94 |
95 | }
96 | static int64_t tinyktxCallbackTell(void *user) {
97 | auto handle = (VFile_Handle) user;
98 | return VFile_Tell(handle);
99 | }
100 |
101 | AL2O3_EXTERN_C Image_ImageHeader const *Image_LoadKTX(VFile_Handle handle) {
102 | TinyKtx_Callbacks callbacks {
103 | &tinyktxCallbackError,
104 | &tinyktxCallbackAlloc,
105 | &tinyktxCallbackFree,
106 | tinyktxCallbackRead,
107 | &tinyktxCallbackSeek,
108 | &tinyktxCallbackTell
109 | };
110 |
111 | auto ctx = TinyKtx_CreateContext( &callbacks, handle);
112 | TinyKtx_ReadHeader(ctx);
113 | uint32_t w = TinyKtx_Width(ctx);
114 | uint32_t h = TinyKtx_Height(ctx);
115 | uint32_t d = TinyKtx_Depth(ctx);
116 | uint32_t s = TinyKtx_ArraySlices(ctx);
117 | ImageFormat fmt = ImageFormatToTinyKtxFormat(TinyKtx_GetFormat(ctx));
118 | if(fmt == ImageFormat_UNDEFINED) {
119 | TinyKtx_DestroyContext(ctx);
120 | return nullptr;
121 | }
122 |
123 | Image_ImageHeader const* topImage = nullptr;
124 | Image_ImageHeader const* prevImage = nullptr;
125 | for(auto i = 0u; i < TinyKtx_NumberOfMipmaps(ctx);++i) {
126 | auto image = Image_CreateNoClear(w, h, d, s, fmt);
127 | if(i == 0) topImage = image;
128 |
129 | if(Image_ByteCountOf(image) != TinyKtx_ImageSize(ctx, i)) {
130 | LOGERROR("KTX file %s mipmap %i size error", VFile_GetName(handle), i);
131 | Image_Destroy(topImage);
132 | TinyKtx_DestroyContext(ctx);
133 | return nullptr;
134 | }
135 | memcpy(Image_RawDataPtr(image), TinyKtx_ImageRawData(ctx, i), Image_ByteCountOf(image));
136 | if(prevImage) {
137 | auto p = (Image_ImageHeader *)prevImage;
138 | p->nextType = Image_NextType::Image_IT_MipMaps;
139 | p->nextImage = image;
140 | }
141 | if(w > 1) w = w / 2;
142 | if(h > 1) h = h / 2;
143 | if(d > 1) d = d / 2;
144 | prevImage = image;
145 | }
146 |
147 | TinyKtx_DestroyContext(ctx);
148 | return topImage;
149 | }
150 | ```
151 |
152 |
153 | ## How to save a KTX
154 | Saving doesn't need a context just a *TinyKtx_WriteCallbacks* with
155 | * error reporting
156 | * alloc (not currently used)
157 | * free (not currently used)
158 | * write
159 |
160 | ```
161 | A TinyKtx_WriteImage or TinyKtx_WriteImageGL are the only API entry point for saving a KTX file.
162 |
163 | Provide it with the format (in either style), dimensions and whether its a cube map or not
164 |
165 | Pass the number of mipmaps and arrays filled with the size of each mipmap image and a pointer to the data
166 | ```
167 | Save snippet
168 | ```c
169 | static void tinyktxCallbackError(void *user, char const *msg) {
170 | LOGERROR("Tiny_Ktx ERROR: %s", msg);
171 | }
172 |
173 | static void *tinyktxCallbackAlloc(void *user, size_t size) {
174 | return MEMORY_MALLOC(size);
175 | }
176 |
177 | static void tinyktxCallbackFree(void *user, void *data) {
178 | MEMORY_FREE(data);
179 | }
180 |
181 | static void tinyktxCallbackWrite(void *user, void const *data, size_t size) {
182 | auto handle = (VFile_Handle) user;
183 | VFile_Write(handle, data, size);
184 | }
185 | AL2O3_EXTERN_C bool Image_SaveKTX(Image_ImageHeader *image, VFile_Handle handle) {
186 | using namespace Image;
187 | TinyKtx_WriteCallbacks callback{
188 | &tinyktxCallbackError,
189 | &tinyktxCallbackAlloc,
190 | &tinyktxCallbackFree,
191 | &tinyktxCallbackWrite,
192 | };
193 |
194 | TinyKtx_Format fmt = ImageFormatToTinyKtxFormat(image->format);
195 | if(fmt == TKTX_UNDEFINED) return false;
196 |
197 | uint32_t numMipmaps = (image->nextType == Image_NextType::Image_IT_None) ? 1 : (uint32_t)Image_LinkedImageCountOf(image);
198 |
199 | uint32_t mipmapsizes[TINYKTX_MAX_MIPMAPLEVELS];
200 | void const* mipmaps[TINYKTX_MAX_MIPMAPLEVELS];
201 | memset(mipmapsizes, 0, sizeof(uint32_t)*TINYKTX_MAX_MIPMAPLEVELS);
202 | memset(mipmaps, 0, sizeof(void const*)*TINYKTX_MAX_MIPMAPLEVELS);
203 |
204 | for(size_t i = 0; i < numMipmaps; ++i) {
205 | mipmapsizes[i] = (uint32_t) Image_LinkedImageOf(image, i)->dataSize;
206 | mipmaps[i] = Image_RawDataPtr(Image_LinkedImageOf(image, i));
207 | }
208 |
209 | return TinyKtx_WriteImage(&callback,
210 | handle,
211 | image->width,
212 | image->height,
213 | image->depth,
214 | image->slices,
215 | numMipmaps,
216 | fmt,
217 | Image_IsCubemap(image),
218 | mipmapsizes,
219 | mipmaps );
220 | }
221 | ```
222 |
223 | ## Tests
224 | Testing is done using my Taylor scriptable content processor.
225 |
226 | [taylor_imagetest - script and data](https://github.com/DeanoC/taylor_imagetests)
227 |
228 | [taylor - app that runs the test script) ](https://github.com/DeanoC/taylor)
229 |
230 | ## TODO
231 | Lots of validation/tests
232 |
233 | Save key data pairs (currently will load them but doesn't write any)
234 |
235 | Handle endianness?
236 |
237 | ## Higher level
238 | tiny_ktx is the lowel level part of my gfx_imageio and gfx_image libraries.
239 |
240 | They handle conversion or data, reading and writing and load/save other format ast well
241 |
242 | taylor is a lua scripted content command line program that uses the above library for processing.
243 |
244 | If you want higher level of tiny_ktx or how tiny_ktx is used see the links below
245 |
246 | The snippets above are from gfx_imageio
247 |
248 | [gfx_imageio - higher level import/export image using tiny_ktx (and other formats)](https://github.com/DeanoC/gfx_imageio)
249 |
250 | [taylor - lua scripted image processer using gfx_imageio](https://github.com/DeanoC/taylor)
251 |
--------------------------------------------------------------------------------
/include/tiny_ktx/tinyktx.h:
--------------------------------------------------------------------------------
1 | // MIT license see full LICENSE text at end of file
2 | #pragma once
3 | #ifndef TINY_KTX_TINYKTX_H
4 | #define TINY_KTX_TINYKTX_H
5 |
6 | #ifndef TINYKTX_HAVE_UINTXX_T
7 | #include // for uint32_t and int64_t
8 | #endif
9 | #ifndef TINYKTX_HAVE_BOOL
10 | #include // for bool
11 | #endif
12 | #ifndef TINYKTX_HAVE_SIZE_T
13 | #include // for size_t
14 | #endif
15 | #ifndef TINYKTX_HAVE_MEMCPY
16 | #include // for memcpy
17 | #endif
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #define TINYKTX_MAX_MIPMAPLEVELS 16
24 |
25 | typedef struct TinyKtx_Context *TinyKtx_ContextHandle;
26 |
27 | typedef void *(*TinyKtx_AllocFunc)(void *user, size_t size);
28 | typedef void (*TinyKtx_FreeFunc)(void *user, void *memory);
29 | typedef size_t (*TinyKtx_ReadFunc)(void *user, void *buffer, size_t byteCount);
30 | typedef bool (*TinyKtx_SeekFunc)(void *user, int64_t offset);
31 | typedef int64_t (*TinyKtx_TellFunc)(void *user);
32 | typedef void (*TinyKtx_ErrorFunc)(void *user, char const *msg);
33 |
34 | typedef struct TinyKtx_Callbacks {
35 | TinyKtx_ErrorFunc errorFn;
36 | TinyKtx_AllocFunc allocFn;
37 | TinyKtx_FreeFunc freeFn;
38 | TinyKtx_ReadFunc readFn;
39 | TinyKtx_SeekFunc seekFn;
40 | TinyKtx_TellFunc tellFn;
41 | } TinyKtx_Callbacks;
42 |
43 | TinyKtx_ContextHandle TinyKtx_CreateContext(TinyKtx_Callbacks const *callbacks, void *user);
44 | void TinyKtx_DestroyContext(TinyKtx_ContextHandle handle);
45 |
46 | // reset lets you reuse the context for another file (saves an alloc/free cycle)
47 | void TinyKtx_Reset(TinyKtx_ContextHandle handle);
48 |
49 | // call this to read the header file should already be at the start of the KTX data
50 | bool TinyKtx_ReadHeader(TinyKtx_ContextHandle handle);
51 |
52 | // this is slow linear search. TODO add iterator style reading of key value pairs
53 | bool TinyKtx_GetValue(TinyKtx_ContextHandle handle, char const *key, void const **value);
54 |
55 | bool TinyKtx_Is1D(TinyKtx_ContextHandle handle);
56 | bool TinyKtx_Is2D(TinyKtx_ContextHandle handle);
57 | bool TinyKtx_Is3D(TinyKtx_ContextHandle handle);
58 | bool TinyKtx_IsCubemap(TinyKtx_ContextHandle handle);
59 | bool TinyKtx_IsArray(TinyKtx_ContextHandle handle);
60 |
61 | bool TinyKtx_Dimensions(TinyKtx_ContextHandle handle, uint32_t* width, uint32_t* height, uint32_t* depth, uint32_t* slices);
62 | uint32_t TinyKtx_Width(TinyKtx_ContextHandle handle);
63 | uint32_t TinyKtx_Height(TinyKtx_ContextHandle handle);
64 | uint32_t TinyKtx_Depth(TinyKtx_ContextHandle handle);
65 | uint32_t TinyKtx_ArraySlices(TinyKtx_ContextHandle handle);
66 |
67 | bool TinyKtx_GetFormatGL(TinyKtx_ContextHandle handle, uint32_t *glformat, uint32_t *gltype, uint32_t *glinternalformat, uint32_t* typesize, uint32_t* glbaseinternalformat);
68 |
69 | bool TinyKtx_NeedsGenerationOfMipmaps(TinyKtx_ContextHandle handle);
70 | bool TinyKtx_NeedsEndianCorrecting(TinyKtx_ContextHandle handle);
71 |
72 | uint32_t TinyKtx_NumberOfMipmaps(TinyKtx_ContextHandle handle);
73 | uint32_t TinyKtx_ImageSize(TinyKtx_ContextHandle handle, uint32_t mipmaplevel);
74 |
75 | bool TinyKtx_IsMipMapLevelUnpacked(TinyKtx_ContextHandle handle, uint32_t mipmaplevel);
76 | // this is required to read Unpacked data correctly
77 | uint32_t TinyKtx_UnpackedRowStride(TinyKtx_ContextHandle handle, uint32_t mipmaplevel);
78 |
79 | // data return by ImageRawData is owned by the context. Don't free it!
80 | void const *TinyKtx_ImageRawData(TinyKtx_ContextHandle handle, uint32_t mipmaplevel);
81 |
82 | typedef void (*TinyKtx_WriteFunc)(void *user, void const *buffer, size_t byteCount);
83 |
84 | typedef struct TinyKtx_WriteCallbacks {
85 | TinyKtx_ErrorFunc errorFn;
86 | TinyKtx_AllocFunc allocFn;
87 | TinyKtx_FreeFunc freeFn;
88 | TinyKtx_WriteFunc writeFn;
89 | } TinyKtx_WriteCallbacks;
90 |
91 |
92 | bool TinyKtx_WriteImageGL(TinyKtx_WriteCallbacks const *callbacks,
93 | void *user,
94 | uint32_t width,
95 | uint32_t height,
96 | uint32_t depth,
97 | uint32_t slices,
98 | uint32_t mipmaplevels,
99 | uint32_t format,
100 | uint32_t internalFormat,
101 | uint32_t baseFormat,
102 | uint32_t type,
103 | uint32_t typeSize,
104 | bool cubemap,
105 | uint32_t const *mipmapsizes,
106 | void const **mipmaps);
107 |
108 | // ktx v1 is based on GL (slightly confusing imho) texture format system
109 | // there is format, internal format, type etc.
110 |
111 | // we try and expose a more dx12/vulkan/metal style of format
112 | // but obviously still need to GL data so bare with me.
113 | // a TinyKTX_Format is the equivilent to GL/KTX Format and Type
114 | // the API doesn't expose the actual values (which come from GL itself)
115 | // but provide an API call to crack them back into the actual GL values).
116 |
117 | // Ktx v2 is based on VkFormat and also DFD, so we now base the
118 | // enumeration values of TinyKtx_Format on the Vkformat values where possible
119 |
120 | #ifndef TINYIMAGEFORMAT_VKFORMAT
121 | #define TINYIMAGEFORMAT_VKFORMAT
122 | typedef enum TinyImageFormat_VkFormat {
123 | TIF_VK_FORMAT_UNDEFINED = 0,
124 | TIF_VK_FORMAT_R4G4_UNORM_PACK8 = 1,
125 | TIF_VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
126 | TIF_VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
127 | TIF_VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
128 | TIF_VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
129 | TIF_VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
130 | TIF_VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
131 | TIF_VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
132 | TIF_VK_FORMAT_R8_UNORM = 9,
133 | TIF_VK_FORMAT_R8_SNORM = 10,
134 | TIF_VK_FORMAT_R8_USCALED = 11,
135 | TIF_VK_FORMAT_R8_SSCALED = 12,
136 | TIF_VK_FORMAT_R8_UINT = 13,
137 | TIF_VK_FORMAT_R8_SINT = 14,
138 | TIF_VK_FORMAT_R8_SRGB = 15,
139 | TIF_VK_FORMAT_R8G8_UNORM = 16,
140 | TIF_VK_FORMAT_R8G8_SNORM = 17,
141 | TIF_VK_FORMAT_R8G8_USCALED = 18,
142 | TIF_VK_FORMAT_R8G8_SSCALED = 19,
143 | TIF_VK_FORMAT_R8G8_UINT = 20,
144 | TIF_VK_FORMAT_R8G8_SINT = 21,
145 | TIF_VK_FORMAT_R8G8_SRGB = 22,
146 | TIF_VK_FORMAT_R8G8B8_UNORM = 23,
147 | TIF_VK_FORMAT_R8G8B8_SNORM = 24,
148 | TIF_VK_FORMAT_R8G8B8_USCALED = 25,
149 | TIF_VK_FORMAT_R8G8B8_SSCALED = 26,
150 | TIF_VK_FORMAT_R8G8B8_UINT = 27,
151 | TIF_VK_FORMAT_R8G8B8_SINT = 28,
152 | TIF_VK_FORMAT_R8G8B8_SRGB = 29,
153 | TIF_VK_FORMAT_B8G8R8_UNORM = 30,
154 | TIF_VK_FORMAT_B8G8R8_SNORM = 31,
155 | TIF_VK_FORMAT_B8G8R8_USCALED = 32,
156 | TIF_VK_FORMAT_B8G8R8_SSCALED = 33,
157 | TIF_VK_FORMAT_B8G8R8_UINT = 34,
158 | TIF_VK_FORMAT_B8G8R8_SINT = 35,
159 | TIF_VK_FORMAT_B8G8R8_SRGB = 36,
160 | TIF_VK_FORMAT_R8G8B8A8_UNORM = 37,
161 | TIF_VK_FORMAT_R8G8B8A8_SNORM = 38,
162 | TIF_VK_FORMAT_R8G8B8A8_USCALED = 39,
163 | TIF_VK_FORMAT_R8G8B8A8_SSCALED = 40,
164 | TIF_VK_FORMAT_R8G8B8A8_UINT = 41,
165 | TIF_VK_FORMAT_R8G8B8A8_SINT = 42,
166 | TIF_VK_FORMAT_R8G8B8A8_SRGB = 43,
167 | TIF_VK_FORMAT_B8G8R8A8_UNORM = 44,
168 | TIF_VK_FORMAT_B8G8R8A8_SNORM = 45,
169 | TIF_VK_FORMAT_B8G8R8A8_USCALED = 46,
170 | TIF_VK_FORMAT_B8G8R8A8_SSCALED = 47,
171 | TIF_VK_FORMAT_B8G8R8A8_UINT = 48,
172 | TIF_VK_FORMAT_B8G8R8A8_SINT = 49,
173 | TIF_VK_FORMAT_B8G8R8A8_SRGB = 50,
174 | TIF_VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
175 | TIF_VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
176 | TIF_VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
177 | TIF_VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
178 | TIF_VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
179 | TIF_VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
180 | TIF_VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
181 | TIF_VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
182 | TIF_VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
183 | TIF_VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
184 | TIF_VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
185 | TIF_VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
186 | TIF_VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
187 | TIF_VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
188 | TIF_VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
189 | TIF_VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
190 | TIF_VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
191 | TIF_VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
192 | TIF_VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
193 | TIF_VK_FORMAT_R16_UNORM = 70,
194 | TIF_VK_FORMAT_R16_SNORM = 71,
195 | TIF_VK_FORMAT_R16_USCALED = 72,
196 | TIF_VK_FORMAT_R16_SSCALED = 73,
197 | TIF_VK_FORMAT_R16_UINT = 74,
198 | TIF_VK_FORMAT_R16_SINT = 75,
199 | TIF_VK_FORMAT_R16_SFLOAT = 76,
200 | TIF_VK_FORMAT_R16G16_UNORM = 77,
201 | TIF_VK_FORMAT_R16G16_SNORM = 78,
202 | TIF_VK_FORMAT_R16G16_USCALED = 79,
203 | TIF_VK_FORMAT_R16G16_SSCALED = 80,
204 | TIF_VK_FORMAT_R16G16_UINT = 81,
205 | TIF_VK_FORMAT_R16G16_SINT = 82,
206 | TIF_VK_FORMAT_R16G16_SFLOAT = 83,
207 | TIF_VK_FORMAT_R16G16B16_UNORM = 84,
208 | TIF_VK_FORMAT_R16G16B16_SNORM = 85,
209 | TIF_VK_FORMAT_R16G16B16_USCALED = 86,
210 | TIF_VK_FORMAT_R16G16B16_SSCALED = 87,
211 | TIF_VK_FORMAT_R16G16B16_UINT = 88,
212 | TIF_VK_FORMAT_R16G16B16_SINT = 89,
213 | TIF_VK_FORMAT_R16G16B16_SFLOAT = 90,
214 | TIF_VK_FORMAT_R16G16B16A16_UNORM = 91,
215 | TIF_VK_FORMAT_R16G16B16A16_SNORM = 92,
216 | TIF_VK_FORMAT_R16G16B16A16_USCALED = 93,
217 | TIF_VK_FORMAT_R16G16B16A16_SSCALED = 94,
218 | TIF_VK_FORMAT_R16G16B16A16_UINT = 95,
219 | TIF_VK_FORMAT_R16G16B16A16_SINT = 96,
220 | TIF_VK_FORMAT_R16G16B16A16_SFLOAT = 97,
221 | TIF_VK_FORMAT_R32_UINT = 98,
222 | TIF_VK_FORMAT_R32_SINT = 99,
223 | TIF_VK_FORMAT_R32_SFLOAT = 100,
224 | TIF_VK_FORMAT_R32G32_UINT = 101,
225 | TIF_VK_FORMAT_R32G32_SINT = 102,
226 | TIF_VK_FORMAT_R32G32_SFLOAT = 103,
227 | TIF_VK_FORMAT_R32G32B32_UINT = 104,
228 | TIF_VK_FORMAT_R32G32B32_SINT = 105,
229 | TIF_VK_FORMAT_R32G32B32_SFLOAT = 106,
230 | TIF_VK_FORMAT_R32G32B32A32_UINT = 107,
231 | TIF_VK_FORMAT_R32G32B32A32_SINT = 108,
232 | TIF_VK_FORMAT_R32G32B32A32_SFLOAT = 109,
233 | TIF_VK_FORMAT_R64_UINT = 110,
234 | TIF_VK_FORMAT_R64_SINT = 111,
235 | TIF_VK_FORMAT_R64_SFLOAT = 112,
236 | TIF_VK_FORMAT_R64G64_UINT = 113,
237 | TIF_VK_FORMAT_R64G64_SINT = 114,
238 | TIF_VK_FORMAT_R64G64_SFLOAT = 115,
239 | TIF_VK_FORMAT_R64G64B64_UINT = 116,
240 | TIF_VK_FORMAT_R64G64B64_SINT = 117,
241 | TIF_VK_FORMAT_R64G64B64_SFLOAT = 118,
242 | TIF_VK_FORMAT_R64G64B64A64_UINT = 119,
243 | TIF_VK_FORMAT_R64G64B64A64_SINT = 120,
244 | TIF_VK_FORMAT_R64G64B64A64_SFLOAT = 121,
245 | TIF_VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
246 | TIF_VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
247 | TIF_VK_FORMAT_D16_UNORM = 124,
248 | TIF_VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
249 | TIF_VK_FORMAT_D32_SFLOAT = 126,
250 | TIF_VK_FORMAT_S8_UINT = 127,
251 | TIF_VK_FORMAT_D16_UNORM_S8_UINT = 128,
252 | TIF_VK_FORMAT_D24_UNORM_S8_UINT = 129,
253 | TIF_VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
254 | TIF_VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
255 | TIF_VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
256 | TIF_VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
257 | TIF_VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
258 | TIF_VK_FORMAT_BC2_UNORM_BLOCK = 135,
259 | TIF_VK_FORMAT_BC2_SRGB_BLOCK = 136,
260 | TIF_VK_FORMAT_BC3_UNORM_BLOCK = 137,
261 | TIF_VK_FORMAT_BC3_SRGB_BLOCK = 138,
262 | TIF_VK_FORMAT_BC4_UNORM_BLOCK = 139,
263 | TIF_VK_FORMAT_BC4_SNORM_BLOCK = 140,
264 | TIF_VK_FORMAT_BC5_UNORM_BLOCK = 141,
265 | TIF_VK_FORMAT_BC5_SNORM_BLOCK = 142,
266 | TIF_VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
267 | TIF_VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
268 | TIF_VK_FORMAT_BC7_UNORM_BLOCK = 145,
269 | TIF_VK_FORMAT_BC7_SRGB_BLOCK = 146,
270 | TIF_VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
271 | TIF_VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
272 | TIF_VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
273 | TIF_VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
274 | TIF_VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
275 | TIF_VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
276 | TIF_VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
277 | TIF_VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
278 | TIF_VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
279 | TIF_VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
280 | TIF_VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
281 | TIF_VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
282 | TIF_VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
283 | TIF_VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
284 | TIF_VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
285 | TIF_VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
286 | TIF_VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
287 | TIF_VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
288 | TIF_VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
289 | TIF_VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
290 | TIF_VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
291 | TIF_VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
292 | TIF_VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
293 | TIF_VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
294 | TIF_VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
295 | TIF_VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
296 | TIF_VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
297 | TIF_VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
298 | TIF_VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
299 | TIF_VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
300 | TIF_VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
301 | TIF_VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
302 | TIF_VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
303 | TIF_VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
304 | TIF_VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
305 | TIF_VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
306 | TIF_VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
307 | TIF_VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184,
308 |
309 | TIF_VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000,
310 | TIF_VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001,
311 | TIF_VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002,
312 | TIF_VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003,
313 | TIF_VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004,
314 | TIF_VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005,
315 | TIF_VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006,
316 | TIF_VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007,
317 | TIF_VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008,
318 | TIF_VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009,
319 | TIF_VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010,
320 | TIF_VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011,
321 | TIF_VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012,
322 | TIF_VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013,
323 | TIF_VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014,
324 | TIF_VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015,
325 | TIF_VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016,
326 | TIF_VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017,
327 | TIF_VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018,
328 | TIF_VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019,
329 | TIF_VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020,
330 | TIF_VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021,
331 | TIF_VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022,
332 | TIF_VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023,
333 | TIF_VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024,
334 | TIF_VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025,
335 | TIF_VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026,
336 | TIF_VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027,
337 | TIF_VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028,
338 | TIF_VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029,
339 | TIF_VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030,
340 | TIF_VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031,
341 | TIF_VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032,
342 | TIF_VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033,
343 | TIF_VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000,
344 | TIF_VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001,
345 | TIF_VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002,
346 | TIF_VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003,
347 | TIF_VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004,
348 | TIF_VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005,
349 | TIF_VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006,
350 | TIF_VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007,
351 | } TinyImageFormat_VkFormat;
352 | #endif // TINYIMAGEFORMAT_VKFORMAT
353 |
354 | #define TINYKTX_MEV(x) TKTX_##x = TIF_VK_FORMAT_##x
355 | typedef enum TinyKtx_Format {
356 | TINYKTX_MEV(UNDEFINED),
357 | TINYKTX_MEV(R4G4_UNORM_PACK8),
358 | TINYKTX_MEV(R4G4B4A4_UNORM_PACK16),
359 | TINYKTX_MEV(B4G4R4A4_UNORM_PACK16),
360 | TINYKTX_MEV(R5G6B5_UNORM_PACK16),
361 | TINYKTX_MEV(B5G6R5_UNORM_PACK16),
362 | TINYKTX_MEV(R5G5B5A1_UNORM_PACK16),
363 | TINYKTX_MEV(B5G5R5A1_UNORM_PACK16),
364 | TINYKTX_MEV(A1R5G5B5_UNORM_PACK16),
365 |
366 | TINYKTX_MEV(R8_UNORM),
367 | TINYKTX_MEV(R8_SNORM),
368 | TINYKTX_MEV(R8_UINT),
369 | TINYKTX_MEV(R8_SINT),
370 | TINYKTX_MEV(R8_SRGB),
371 |
372 | TINYKTX_MEV(R8G8_UNORM),
373 | TINYKTX_MEV(R8G8_SNORM),
374 | TINYKTX_MEV(R8G8_UINT),
375 | TINYKTX_MEV(R8G8_SINT),
376 | TINYKTX_MEV(R8G8_SRGB),
377 |
378 | TINYKTX_MEV(R8G8B8_UNORM),
379 | TINYKTX_MEV(R8G8B8_SNORM),
380 | TINYKTX_MEV(R8G8B8_UINT),
381 | TINYKTX_MEV(R8G8B8_SINT),
382 | TINYKTX_MEV(R8G8B8_SRGB),
383 | TINYKTX_MEV(B8G8R8_UNORM),
384 | TINYKTX_MEV(B8G8R8_SNORM),
385 | TINYKTX_MEV(B8G8R8_UINT),
386 | TINYKTX_MEV(B8G8R8_SINT),
387 | TINYKTX_MEV(B8G8R8_SRGB),
388 |
389 | TINYKTX_MEV(R8G8B8A8_UNORM),
390 | TINYKTX_MEV(R8G8B8A8_SNORM),
391 | TINYKTX_MEV(R8G8B8A8_UINT),
392 | TINYKTX_MEV(R8G8B8A8_SINT),
393 | TINYKTX_MEV(R8G8B8A8_SRGB),
394 | TINYKTX_MEV(B8G8R8A8_UNORM),
395 | TINYKTX_MEV(B8G8R8A8_SNORM),
396 | TINYKTX_MEV(B8G8R8A8_UINT),
397 | TINYKTX_MEV(B8G8R8A8_SINT),
398 | TINYKTX_MEV(B8G8R8A8_SRGB),
399 |
400 | TINYKTX_MEV(A8B8G8R8_UNORM_PACK32),
401 | TINYKTX_MEV(A8B8G8R8_SNORM_PACK32),
402 | TINYKTX_MEV(A8B8G8R8_UINT_PACK32),
403 | TINYKTX_MEV(A8B8G8R8_SINT_PACK32),
404 | TINYKTX_MEV(A8B8G8R8_SRGB_PACK32),
405 |
406 | TINYKTX_MEV(E5B9G9R9_UFLOAT_PACK32),
407 | TINYKTX_MEV(A2R10G10B10_UNORM_PACK32),
408 | TINYKTX_MEV(A2R10G10B10_UINT_PACK32),
409 | TINYKTX_MEV(A2B10G10R10_UNORM_PACK32),
410 | TINYKTX_MEV(A2B10G10R10_UINT_PACK32),
411 | TINYKTX_MEV(B10G11R11_UFLOAT_PACK32),
412 |
413 | TINYKTX_MEV(R16_UNORM),
414 | TINYKTX_MEV(R16_SNORM),
415 | TINYKTX_MEV(R16_UINT),
416 | TINYKTX_MEV(R16_SINT),
417 | TINYKTX_MEV(R16_SFLOAT),
418 | TINYKTX_MEV(R16G16_UNORM),
419 | TINYKTX_MEV(R16G16_SNORM),
420 | TINYKTX_MEV(R16G16_UINT),
421 | TINYKTX_MEV(R16G16_SINT),
422 | TINYKTX_MEV(R16G16_SFLOAT),
423 | TINYKTX_MEV(R16G16B16_UNORM),
424 | TINYKTX_MEV(R16G16B16_SNORM),
425 | TINYKTX_MEV(R16G16B16_UINT),
426 | TINYKTX_MEV(R16G16B16_SINT),
427 | TINYKTX_MEV(R16G16B16_SFLOAT),
428 | TINYKTX_MEV(R16G16B16A16_UNORM),
429 | TINYKTX_MEV(R16G16B16A16_SNORM),
430 | TINYKTX_MEV(R16G16B16A16_UINT),
431 | TINYKTX_MEV(R16G16B16A16_SINT),
432 | TINYKTX_MEV(R16G16B16A16_SFLOAT),
433 | TINYKTX_MEV(R32_UINT),
434 | TINYKTX_MEV(R32_SINT),
435 | TINYKTX_MEV(R32_SFLOAT),
436 | TINYKTX_MEV(R32G32_UINT),
437 | TINYKTX_MEV(R32G32_SINT),
438 | TINYKTX_MEV(R32G32_SFLOAT),
439 | TINYKTX_MEV(R32G32B32_UINT),
440 | TINYKTX_MEV(R32G32B32_SINT),
441 | TINYKTX_MEV(R32G32B32_SFLOAT),
442 | TINYKTX_MEV(R32G32B32A32_UINT),
443 | TINYKTX_MEV(R32G32B32A32_SINT),
444 | TINYKTX_MEV(R32G32B32A32_SFLOAT),
445 |
446 | TINYKTX_MEV(BC1_RGB_UNORM_BLOCK),
447 | TINYKTX_MEV(BC1_RGB_SRGB_BLOCK),
448 | TINYKTX_MEV(BC1_RGBA_UNORM_BLOCK),
449 | TINYKTX_MEV(BC1_RGBA_SRGB_BLOCK),
450 | TINYKTX_MEV(BC2_UNORM_BLOCK),
451 | TINYKTX_MEV(BC2_SRGB_BLOCK),
452 | TINYKTX_MEV(BC3_UNORM_BLOCK),
453 | TINYKTX_MEV(BC3_SRGB_BLOCK),
454 | TINYKTX_MEV(BC4_UNORM_BLOCK),
455 | TINYKTX_MEV(BC4_SNORM_BLOCK),
456 | TINYKTX_MEV(BC5_UNORM_BLOCK),
457 | TINYKTX_MEV(BC5_SNORM_BLOCK),
458 | TINYKTX_MEV(BC6H_UFLOAT_BLOCK),
459 | TINYKTX_MEV(BC6H_SFLOAT_BLOCK),
460 | TINYKTX_MEV(BC7_UNORM_BLOCK),
461 | TINYKTX_MEV(BC7_SRGB_BLOCK),
462 |
463 | TINYKTX_MEV(ETC2_R8G8B8_UNORM_BLOCK),
464 | TINYKTX_MEV(ETC2_R8G8B8A1_UNORM_BLOCK),
465 | TINYKTX_MEV(ETC2_R8G8B8A8_UNORM_BLOCK),
466 | TINYKTX_MEV(ETC2_R8G8B8_SRGB_BLOCK),
467 | TINYKTX_MEV(ETC2_R8G8B8A1_SRGB_BLOCK),
468 | TINYKTX_MEV(ETC2_R8G8B8A8_SRGB_BLOCK),
469 | TINYKTX_MEV(EAC_R11_UNORM_BLOCK),
470 | TINYKTX_MEV(EAC_R11G11_UNORM_BLOCK),
471 | TINYKTX_MEV(EAC_R11_SNORM_BLOCK),
472 | TINYKTX_MEV(EAC_R11G11_SNORM_BLOCK),
473 |
474 | TKTX_PVR_2BPP_UNORM_BLOCK = TIF_VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,
475 | TKTX_PVR_2BPPA_UNORM_BLOCK = TIF_VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG,
476 | TKTX_PVR_4BPP_UNORM_BLOCK = TIF_VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG,
477 | TKTX_PVR_4BPPA_UNORM_BLOCK = TIF_VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG,
478 | TKTX_PVR_2BPP_SRGB_BLOCK = TIF_VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,
479 | TKTX_PVR_2BPPA_SRGB_BLOCK = TIF_VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,
480 | TKTX_PVR_4BPP_SRGB_BLOCK = TIF_VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,
481 | TKTX_PVR_4BPPA_SRGB_BLOCK = TIF_VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG,
482 |
483 | TINYKTX_MEV(ASTC_4x4_UNORM_BLOCK),
484 | TINYKTX_MEV(ASTC_4x4_SRGB_BLOCK),
485 | TINYKTX_MEV(ASTC_5x4_UNORM_BLOCK),
486 | TINYKTX_MEV(ASTC_5x4_SRGB_BLOCK),
487 | TINYKTX_MEV(ASTC_5x5_UNORM_BLOCK),
488 | TINYKTX_MEV(ASTC_5x5_SRGB_BLOCK),
489 | TINYKTX_MEV(ASTC_6x5_UNORM_BLOCK),
490 | TINYKTX_MEV(ASTC_6x5_SRGB_BLOCK),
491 | TINYKTX_MEV(ASTC_6x6_UNORM_BLOCK),
492 | TINYKTX_MEV(ASTC_6x6_SRGB_BLOCK),
493 | TINYKTX_MEV(ASTC_8x5_UNORM_BLOCK),
494 | TINYKTX_MEV(ASTC_8x5_SRGB_BLOCK),
495 | TINYKTX_MEV(ASTC_8x6_UNORM_BLOCK),
496 | TINYKTX_MEV(ASTC_8x6_SRGB_BLOCK),
497 | TINYKTX_MEV(ASTC_8x8_UNORM_BLOCK),
498 | TINYKTX_MEV(ASTC_8x8_SRGB_BLOCK),
499 | TINYKTX_MEV(ASTC_10x5_UNORM_BLOCK),
500 | TINYKTX_MEV(ASTC_10x5_SRGB_BLOCK),
501 | TINYKTX_MEV(ASTC_10x6_UNORM_BLOCK),
502 | TINYKTX_MEV(ASTC_10x6_SRGB_BLOCK),
503 | TINYKTX_MEV(ASTC_10x8_UNORM_BLOCK),
504 | TINYKTX_MEV(ASTC_10x8_SRGB_BLOCK),
505 | TINYKTX_MEV(ASTC_10x10_UNORM_BLOCK),
506 | TINYKTX_MEV(ASTC_10x10_SRGB_BLOCK),
507 | TINYKTX_MEV(ASTC_12x10_UNORM_BLOCK),
508 | TINYKTX_MEV(ASTC_12x10_SRGB_BLOCK),
509 | TINYKTX_MEV(ASTC_12x12_UNORM_BLOCK),
510 | TINYKTX_MEV(ASTC_12x12_SRGB_BLOCK),
511 |
512 | } TinyKtx_Format;
513 | #undef TINYKTX_MEV
514 |
515 | // tiny_imageformat/format needs included before tinyktx.h for this functionality
516 | #ifdef TINYIMAGEFORMAT_BASE_H_
517 | TinyImageFormat TinyImageFormat_FromTinyKtxFormat(TinyKtx_Format format);
518 | TinyKtx_Format TinyImageFormat_ToTinyKtxFormat(TinyImageFormat format);
519 | #endif
520 |
521 | TinyKtx_Format TinyKtx_GetFormat(TinyKtx_ContextHandle handle);
522 | bool TinyKtx_CrackFormatToGL(TinyKtx_Format format, uint32_t *glformat, uint32_t *gltype, uint32_t *glinternalformat, uint32_t* typesize);
523 | bool TinyKtx_WriteImage(TinyKtx_WriteCallbacks const *callbacks,
524 | void *user,
525 | uint32_t width,
526 | uint32_t height,
527 | uint32_t depth,
528 | uint32_t slices,
529 | uint32_t mipmaplevels,
530 | TinyKtx_Format format,
531 | bool cubemap,
532 | uint32_t const *mipmapsizes,
533 | void const **mipmaps);
534 | // GL types
535 | #define TINYKTX_GL_TYPE_COMPRESSED 0x0
536 | #define TINYKTX_GL_TYPE_BYTE 0x1400
537 | #define TINYKTX_GL_TYPE_UNSIGNED_BYTE 0x1401
538 | #define TINYKTX_GL_TYPE_SHORT 0x1402
539 | #define TINYKTX_GL_TYPE_UNSIGNED_SHORT 0x1403
540 | #define TINYKTX_GL_TYPE_INT 0x1404
541 | #define TINYKTX_GL_TYPE_UNSIGNED_INT 0x1405
542 | #define TINYKTX_GL_TYPE_FLOAT 0x1406
543 | #define TINYKTX_GL_TYPE_DOUBLE 0x140A
544 | #define TINYKTX_GL_TYPE_HALF_FLOAT 0x140B
545 | #define TINYKTX_GL_TYPE_UNSIGNED_BYTE_3_3_2 0x8032
546 | #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_4_4_4_4 0x8033
547 | #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_5_5_1 0x8034
548 | #define TINYKTX_GL_TYPE_UNSIGNED_INT_8_8_8_8 0x8035
549 | #define TINYKTX_GL_TYPE_UNSIGNED_INT_10_10_10_2 0x8036
550 | #define TINYKTX_GL_TYPE_UNSIGNED_BYTE_2_3_3_REV 0x8362
551 | #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_6_5 0x8363
552 | #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_6_5_REV 0x8364
553 | #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
554 | #define TINYKTX_GL_TYPE_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
555 | #define TINYKTX_GL_TYPE_UNSIGNED_INT_8_8_8_8_REV 0x8367
556 | #define TINYKTX_GL_TYPE_UNSIGNED_INT_2_10_10_10_REV 0x8368
557 | #define TINYKTX_GL_TYPE_UNSIGNED_INT_24_8 0x84FA
558 | #define TINYKTX_GL_TYPE_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
559 | #define TINYKTX_GL_TYPE_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
560 | #define TINYKTX_GL_TYPE_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
561 |
562 | // formats
563 | #define TINYKTX_GL_FORMAT_RED 0x1903
564 | #define TINYKTX_GL_FORMAT_GREEN 0x1904
565 | #define TINYKTX_GL_FORMAT_BLUE 0x1905
566 | #define TINYKTX_GL_FORMAT_ALPHA 0x1906
567 | #define TINYKTX_GL_FORMAT_RGB 0x1907
568 | #define TINYKTX_GL_FORMAT_RGBA 0x1908
569 | #define TINYKTX_GL_FORMAT_LUMINANCE 0x1909
570 | #define TINYKTX_GL_FORMAT_LUMINANCE_ALPHA 0x190A
571 | #define TINYKTX_GL_FORMAT_ABGR 0x8000
572 | #define TINYKTX_GL_FORMAT_INTENSITY 0x8049
573 | #define TINYKTX_GL_FORMAT_BGR 0x80E0
574 | #define TINYKTX_GL_FORMAT_BGRA 0x80E1
575 | #define TINYKTX_GL_FORMAT_RG 0x8227
576 | #define TINYKTX_GL_FORMAT_RG_INTEGER 0x8228
577 | #define TINYKTX_GL_FORMAT_SRGB 0x8C40
578 | #define TINYKTX_GL_FORMAT_SRGB_ALPHA 0x8C42
579 | #define TINYKTX_GL_FORMAT_SLUMINANCE_ALPHA 0x8C44
580 | #define TINYKTX_GL_FORMAT_SLUMINANCE 0x8C46
581 | #define TINYKTX_GL_FORMAT_RED_INTEGER 0x8D94
582 | #define TINYKTX_GL_FORMAT_GREEN_INTEGER 0x8D95
583 | #define TINYKTX_GL_FORMAT_BLUE_INTEGER 0x8D96
584 | #define TINYKTX_GL_FORMAT_ALPHA_INTEGER 0x8D97
585 | #define TINYKTX_GL_FORMAT_RGB_INTEGER 0x8D98
586 | #define TINYKTX_GL_FORMAT_RGBA_INTEGER 0x8D99
587 | #define TINYKTX_GL_FORMAT_BGR_INTEGER 0x8D9A
588 | #define TINYKTX_GL_FORMAT_BGRA_INTEGER 0x8D9B
589 | #define TINYKTX_GL_FORMAT_RED_SNORM 0x8F90
590 | #define TINYKTX_GL_FORMAT_RG_SNORM 0x8F91
591 | #define TINYKTX_GL_FORMAT_RGB_SNORM 0x8F92
592 | #define TINYKTX_GL_FORMAT_RGBA_SNORM 0x8F93
593 |
594 | #define TINYKTX_GL_INTFORMAT_ALPHA4 0x803B
595 | #define TINYKTX_GL_INTFORMAT_ALPHA8 0x803C
596 | #define TINYKTX_GL_INTFORMAT_ALPHA12 0x803D
597 | #define TINYKTX_GL_INTFORMAT_ALPHA16 0x803E
598 | #define TINYKTX_GL_INTFORMAT_LUMINANCE4 0x803F
599 | #define TINYKTX_GL_INTFORMAT_LUMINANCE8 0x8040
600 | #define TINYKTX_GL_INTFORMAT_LUMINANCE12 0x8041
601 | #define TINYKTX_GL_INTFORMAT_LUMINANCE16 0x8042
602 | #define TINYKTX_GL_INTFORMAT_LUMINANCE4_ALPHA4 0x8043
603 | #define TINYKTX_GL_INTFORMAT_LUMINANCE6_ALPHA2 0x8044
604 | #define TINYKTX_GL_INTFORMAT_LUMINANCE8_ALPHA8 0x8045
605 | #define TINYKTX_GL_INTFORMAT_LUMINANCE12_ALPHA4 0x8046
606 | #define TINYKTX_GL_INTFORMAT_LUMINANCE12_ALPHA12 0x8047
607 | #define TINYKTX_GL_INTFORMAT_LUMINANCE16_ALPHA16 0x8048
608 | #define TINYKTX_GL_INTFORMAT_INTENSITY4 0x804A
609 | #define TINYKTX_GL_INTFORMAT_INTENSITY8 0x804B
610 | #define TINYKTX_GL_INTFORMAT_INTENSITY12 0x804C
611 | #define TINYKTX_GL_INTFORMAT_INTENSITY16 0x804D
612 | #define TINYKTX_GL_INTFORMAT_RGB2 0x804E
613 | #define TINYKTX_GL_INTFORMAT_RGB4 0x804F
614 | #define TINYKTX_GL_INTFORMAT_RGB5 0x8050
615 | #define TINYKTX_GL_INTFORMAT_RGB8 0x8051
616 | #define TINYKTX_GL_INTFORMAT_RGB10 0x8052
617 | #define TINYKTX_GL_INTFORMAT_RGB12 0x8053
618 | #define TINYKTX_GL_INTFORMAT_RGB16 0x8054
619 | #define TINYKTX_GL_INTFORMAT_RGBA2 0x8055
620 | #define TINYKTX_GL_INTFORMAT_RGBA4 0x8056
621 | #define TINYKTX_GL_INTFORMAT_RGB5_A1 0x8057
622 | #define TINYKTX_GL_INTFORMAT_RGBA8 0x8058
623 | #define TINYKTX_GL_INTFORMAT_RGB10_A2 0x8059
624 | #define TINYKTX_GL_INTFORMAT_RGBA12 0x805A
625 | #define TINYKTX_GL_INTFORMAT_RGBA16 0x805B
626 | #define TINYKTX_GL_INTFORMAT_R8 0x8229
627 | #define TINYKTX_GL_INTFORMAT_R16 0x822A
628 | #define TINYKTX_GL_INTFORMAT_RG8 0x822B
629 | #define TINYKTX_GL_INTFORMAT_RG16 0x822C
630 | #define TINYKTX_GL_INTFORMAT_R16F 0x822D
631 | #define TINYKTX_GL_INTFORMAT_R32F 0x822E
632 | #define TINYKTX_GL_INTFORMAT_RG16F 0x822F
633 | #define TINYKTX_GL_INTFORMAT_RG32F 0x8230
634 | #define TINYKTX_GL_INTFORMAT_R8I 0x8231
635 | #define TINYKTX_GL_INTFORMAT_R8UI 0x8232
636 | #define TINYKTX_GL_INTFORMAT_R16I 0x8233
637 | #define TINYKTX_GL_INTFORMAT_R16UI 0x8234
638 | #define TINYKTX_GL_INTFORMAT_R32I 0x8235
639 | #define TINYKTX_GL_INTFORMAT_R32UI 0x8236
640 | #define TINYKTX_GL_INTFORMAT_RG8I 0x8237
641 | #define TINYKTX_GL_INTFORMAT_RG8UI 0x8238
642 | #define TINYKTX_GL_INTFORMAT_RG16I 0x8239
643 | #define TINYKTX_GL_INTFORMAT_RG16UI 0x823A
644 | #define TINYKTX_GL_INTFORMAT_RG32I 0x823B
645 | #define TINYKTX_GL_INTFORMAT_RG32UI 0x823C
646 | #define TINYKTX_GL_INTFORMAT_RGBA32F 0x8814
647 | #define TINYKTX_GL_INTFORMAT_RGB32F 0x8815
648 | #define TINYKTX_GL_INTFORMAT_RGBA16F 0x881A
649 | #define TINYKTX_GL_INTFORMAT_RGB16F 0x881B
650 | #define TINYKTX_GL_INTFORMAT_R11F_G11F_B10F 0x8C3A
651 | #define TINYKTX_GL_INTFORMAT_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
652 | #define TINYKTX_GL_INTFORMAT_RGB9_E5 0x8C3D
653 | #define TINYKTX_GL_INTFORMAT_SRGB8 0x8C41
654 | #define TINYKTX_GL_INTFORMAT_SRGB8_ALPHA8 0x8C43
655 | #define TINYKTX_GL_INTFORMAT_SLUMINANCE8_ALPHA8 0x8C45
656 | #define TINYKTX_GL_INTFORMAT_SLUMINANCE8 0x8C47
657 | #define TINYKTX_GL_INTFORMAT_RGB565 0x8D62
658 | #define TINYKTX_GL_INTFORMAT_RGBA32UI 0x8D70
659 | #define TINYKTX_GL_INTFORMAT_RGB32UI 0x8D71
660 | #define TINYKTX_GL_INTFORMAT_RGBA16UI 0x8D76
661 | #define TINYKTX_GL_INTFORMAT_RGB16UI 0x8D77
662 | #define TINYKTX_GL_INTFORMAT_RGBA8UI 0x8D7C
663 | #define TINYKTX_GL_INTFORMAT_RGB8UI 0x8D7D
664 | #define TINYKTX_GL_INTFORMAT_RGBA32I 0x8D82
665 | #define TINYKTX_GL_INTFORMAT_RGB32I 0x8D83
666 | #define TINYKTX_GL_INTFORMAT_RGBA16I 0x8D88
667 | #define TINYKTX_GL_INTFORMAT_RGB16I 0x8D89
668 | #define TINYKTX_GL_INTFORMAT_RGBA8I 0x8D8E
669 | #define TINYKTX_GL_INTFORMAT_RGB8I 0x8D8F
670 | #define TINYKTX_GL_INTFORMAT_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
671 | #define TINYKTX_GL_INTFORMAT_R8_SNORM 0x8F94
672 | #define TINYKTX_GL_INTFORMAT_RG8_SNORM 0x8F95
673 | #define TINYKTX_GL_INTFORMAT_RGB8_SNORM 0x8F96
674 | #define TINYKTX_GL_INTFORMAT_RGBA8_SNORM 0x8F97
675 | #define TINYKTX_GL_INTFORMAT_R16_SNORM 0x8F98
676 | #define TINYKTX_GL_INTFORMAT_RG16_SNORM 0x8F99
677 | #define TINYKTX_GL_INTFORMAT_RGB16_SNORM 0x8F9A
678 | #define TINYKTX_GL_INTFORMAT_RGBA16_SNORM 0x8F9B
679 | #define TINYKTX_GL_INTFORMAT_ALPHA8_SNORM 0x9014
680 | #define TINYKTX_GL_INTFORMAT_LUMINANCE8_SNORM 0x9015
681 | #define TINYKTX_GL_INTFORMAT_LUMINANCE8_ALPHA8_SNORM 0x9016
682 | #define TINYKTX_GL_INTFORMAT_INTENSITY8_SNORM 0x9017
683 | #define TINYKTX_GL_INTFORMAT_ALPHA16_SNORM 0x9018
684 | #define TINYKTX_GL_INTFORMAT_LUMINANCE16_SNORM 0x9019
685 | #define TINYKTX_GL_INTFORMAT_LUMINANCE16_ALPHA16_SNORM 0x901A
686 | #define TINYKTX_GL_INTFORMAT_INTENSITY16_SNORM 0x901B
687 |
688 | #define TINYKTX_GL_PALETTE4_RGB8_OES 0x8B90
689 | #define TINYKTX_GL_PALETTE4_RGBA8_OES 0x8B91
690 | #define TINYKTX_GL_PALETTE4_R5_G6_B5_OES 0x8B92
691 | #define TINYKTX_GL_PALETTE4_RGBA4_OES 0x8B93
692 | #define TINYKTX_GL_PALETTE4_RGB5_A1_OES 0x8B94
693 | #define TINYKTX_GL_PALETTE8_RGB8_OES 0x8B95
694 | #define TINYKTX_GL_PALETTE8_RGBA8_OES 0x8B96
695 | #define TINYKTX_GL_PALETTE8_R5_G6_B5_OES 0x8B97
696 | #define TINYKTX_GL_PALETTE8_RGBA4_OES 0x8B98
697 | #define TINYKTX_GL_PALETTE8_RGB5_A1_OES 0x8B99
698 |
699 | // compressed formats
700 |
701 | #define TINYKTX_GL_COMPRESSED_RGB_S3TC_DXT1 0x83F0
702 | #define TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT1 0x83F1
703 | #define TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT3 0x83F2
704 | #define TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT5 0x83F3
705 | #define TINYKTX_GL_COMPRESSED_3DC_X_AMD 0x87F9
706 | #define TINYKTX_GL_COMPRESSED_3DC_XY_AMD 0x87FA
707 | #define TINYKTX_GL_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA 0x87EE
708 | #define TINYKTX_GL_COMPRESSED_SRGB_PVRTC_2BPPV1 0x8A54
709 | #define TINYKTX_GL_COMPRESSED_SRGB_PVRTC_4BPPV1 0x8A55
710 | #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1 0x8A56
711 | #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1 0x8A57
712 | #define TINYKTX_GL_COMPRESSED_RGB_PVRTC_4BPPV1 0x8C00
713 | #define TINYKTX_GL_COMPRESSED_RGB_PVRTC_2BPPV1 0x8C01
714 | #define TINYKTX_GL_COMPRESSED_RGBA_PVRTC_4BPPV1 0x8C02
715 | #define TINYKTX_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 0x8C03
716 | #define TINYKTX_GL_COMPRESSED_SRGB_S3TC_DXT1 0x8C4C
717 | #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1 0x8C4D
718 | #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3 0x8C4E
719 | #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5 0x8C4F
720 | #define TINYKTX_GL_COMPRESSED_LUMINANCE_LATC1 0x8C70
721 | #define TINYKTX_GL_COMPRESSED_SIGNED_LUMINANCE_LATC1 0x8C71
722 | #define TINYKTX_GL_COMPRESSED_LUMINANCE_ALPHA_LATC2 0x8C72
723 | #define TINYKTX_GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2 0x8C73
724 | #define TINYKTX_GL_COMPRESSED_ATC_RGB 0x8C92
725 | #define TINYKTX_GL_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA 0x8C93
726 | #define TINYKTX_GL_COMPRESSED_RED_RGTC1 0x8DBB
727 | #define TINYKTX_GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
728 | #define TINYKTX_GL_COMPRESSED_RED_GREEN_RGTC2 0x8DBD
729 | #define TINYKTX_GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2 0x8DBE
730 | #define TINYKTX_GL_COMPRESSED_ETC1_RGB8_OES 0x8D64
731 | #define TINYKTX_GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
732 | #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
733 | #define TINYKTX_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
734 | #define TINYKTX_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
735 | #define TINYKTX_GL_COMPRESSED_R11_EAC 0x9270
736 | #define TINYKTX_GL_COMPRESSED_SIGNED_R11_EAC 0x9271
737 | #define TINYKTX_GL_COMPRESSED_RG11_EAC 0x9272
738 | #define TINYKTX_GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
739 | #define TINYKTX_GL_COMPRESSED_RGB8_ETC2 0x9274
740 | #define TINYKTX_GL_COMPRESSED_SRGB8_ETC2 0x9275
741 | #define TINYKTX_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
742 | #define TINYKTX_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
743 | #define TINYKTX_GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
744 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
745 | #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2 0x93F0
746 | #define TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2 0x93F1
747 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_4x4 0x93B0
748 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_5x4 0x93B1
749 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_5x5 0x93B2
750 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_6x5 0x93B3
751 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_6x6 0x93B4
752 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x5 0x93B5
753 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x6 0x93B6
754 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x8 0x93B7
755 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x5 0x93B8
756 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x6 0x93B9
757 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x8 0x93BA
758 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x10 0x93BB
759 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_12x10 0x93BC
760 | #define TINYKTX_GL_COMPRESSED_RGBA_ASTC_12x12 0x93BD
761 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 0x93D0
762 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 0x93D1
763 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 0x93D2
764 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 0x93D3
765 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 0x93D4
766 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 0x93D5
767 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 0x93D6
768 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 0x93D7
769 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 0x93D8
770 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 0x93D9
771 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 0x93DA
772 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 0x93DB
773 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 0x93DC
774 | #define TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 0x93DD
775 |
776 | #ifdef TINYKTX_IMPLEMENTATION
777 |
778 | typedef struct TinyKtx_Header {
779 | uint8_t identifier[12];
780 | uint32_t endianness;
781 | uint32_t glType;
782 | uint32_t glTypeSize;
783 | uint32_t glFormat;
784 | uint32_t glInternalFormat;
785 | uint32_t glBaseInternalFormat;
786 | uint32_t pixelWidth;
787 | uint32_t pixelHeight;
788 | uint32_t pixelDepth;
789 | uint32_t numberOfArrayElements;
790 | uint32_t numberOfFaces;
791 | uint32_t numberOfMipmapLevels;
792 | uint32_t bytesOfKeyValueData;
793 |
794 | } TinyKtx_Header;
795 |
796 | typedef struct TinyKtx_KeyValuePair {
797 | uint32_t size;
798 | } TinyKtx_KeyValuePair; // followed by at least size bytes (aligned to 4)
799 |
800 |
801 | typedef struct TinyKtx_Context {
802 | TinyKtx_Callbacks callbacks;
803 | void *user;
804 | uint64_t headerPos;
805 | uint64_t firstImagePos;
806 |
807 | TinyKtx_Header header;
808 |
809 | TinyKtx_KeyValuePair const *keyData;
810 | bool headerValid;
811 | bool sameEndian;
812 |
813 | uint32_t mipMapSizes[TINYKTX_MAX_MIPMAPLEVELS];
814 | uint8_t const *mipmaps[TINYKTX_MAX_MIPMAPLEVELS];
815 |
816 | } TinyKtx_Context;
817 |
818 | static uint8_t TinyKtx_fileIdentifier[12] = {
819 | 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
820 | };
821 |
822 | static void TinyKtx_NullErrorFunc(void *user, char const *msg) {}
823 |
824 | TinyKtx_ContextHandle TinyKtx_CreateContext(TinyKtx_Callbacks const *callbacks, void *user) {
825 | TinyKtx_Context *ctx = (TinyKtx_Context *) callbacks->allocFn(user, sizeof(TinyKtx_Context));
826 | if (ctx == NULL)
827 | return NULL;
828 |
829 | memset(ctx, 0, sizeof(TinyKtx_Context));
830 | memcpy(&ctx->callbacks, callbacks, sizeof(TinyKtx_Callbacks));
831 | ctx->user = user;
832 | if (ctx->callbacks.errorFn == NULL) {
833 | ctx->callbacks.errorFn = &TinyKtx_NullErrorFunc;
834 | }
835 |
836 | if (ctx->callbacks.readFn == NULL) {
837 | ctx->callbacks.errorFn(user, "TinyKtx must have read callback");
838 | return NULL;
839 | }
840 | if (ctx->callbacks.allocFn == NULL) {
841 | ctx->callbacks.errorFn(user, "TinyKtx must have alloc callback");
842 | return NULL;
843 | }
844 | if (ctx->callbacks.freeFn == NULL) {
845 | ctx->callbacks.errorFn(user, "TinyKtx must have free callback");
846 | return NULL;
847 | }
848 | if (ctx->callbacks.seekFn == NULL) {
849 | ctx->callbacks.errorFn(user, "TinyKtx must have seek callback");
850 | return NULL;
851 | }
852 | if (ctx->callbacks.tellFn == NULL) {
853 | ctx->callbacks.errorFn(user, "TinyKtx must have tell callback");
854 | return NULL;
855 | }
856 |
857 | TinyKtx_Reset(ctx);
858 |
859 | return ctx;
860 | }
861 |
862 | void TinyKtx_DestroyContext(TinyKtx_ContextHandle handle) {
863 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
864 | if (ctx == NULL)
865 | return;
866 | TinyKtx_Reset(handle);
867 |
868 | ctx->callbacks.freeFn(ctx->user, ctx);
869 | }
870 |
871 | void TinyKtx_Reset(TinyKtx_ContextHandle handle) {
872 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
873 | if (ctx == NULL)
874 | return;
875 |
876 | // backup user provided callbacks and data
877 | TinyKtx_Callbacks callbacks;
878 | memcpy(&callbacks, &ctx->callbacks, sizeof(TinyKtx_Callbacks));
879 | void *user = ctx->user;
880 |
881 | // free memory of sub data
882 | if (ctx->keyData != NULL) {
883 | callbacks.freeFn(user, (void *) ctx->keyData);
884 | }
885 |
886 | for (int i = 0; i < TINYKTX_MAX_MIPMAPLEVELS; ++i) {
887 | if (ctx->mipmaps[i] != NULL) {
888 | callbacks.freeFn(user, (void *) ctx->mipmaps[i]);
889 | }
890 | }
891 |
892 | // reset to default state
893 | memset(ctx, 0, sizeof(TinyKtx_Context));
894 | memcpy(&ctx->callbacks, &callbacks, sizeof(TinyKtx_Callbacks));
895 | ctx->user = user;
896 |
897 | }
898 |
899 |
900 | bool TinyKtx_ReadHeader(TinyKtx_ContextHandle handle) {
901 |
902 | static uint32_t const sameEndianDecider = 0x04030201;
903 | static uint32_t const differentEndianDecider = 0x01020304;
904 |
905 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
906 | if (ctx == NULL)
907 | return false;
908 |
909 | ctx->headerPos = ctx->callbacks.tellFn(ctx->user);
910 | ctx->callbacks.readFn(ctx->user, &ctx->header, sizeof(TinyKtx_Header));
911 |
912 | if (memcmp(&ctx->header.identifier, TinyKtx_fileIdentifier, 12) != 0) {
913 | ctx->callbacks.errorFn(ctx->user, "Not a KTX file or corrupted as identified isn't valid");
914 | return false;
915 | }
916 |
917 | if (ctx->header.endianness == sameEndianDecider) {
918 | ctx->sameEndian = true;
919 | } else if (ctx->header.endianness == differentEndianDecider) {
920 | ctx->sameEndian = false;
921 | } else {
922 | // corrupt or mid endian?
923 | ctx->callbacks.errorFn(ctx->user, "Endian Error");
924 | return false;
925 | }
926 |
927 | if (ctx->header.numberOfFaces != 1 && ctx->header.numberOfFaces != 6) {
928 | ctx->callbacks.errorFn(ctx->user, "no. of Faces must be 1 or 6");
929 | return false;
930 | }
931 |
932 | ctx->keyData = (TinyKtx_KeyValuePair const *) ctx->callbacks.allocFn(ctx->user, ctx->header.bytesOfKeyValueData);
933 | ctx->callbacks.readFn(ctx->user, (void *) ctx->keyData, ctx->header.bytesOfKeyValueData);
934 |
935 | ctx->firstImagePos = ctx->callbacks.tellFn(ctx->user);
936 |
937 | ctx->headerValid = true;
938 | return true;
939 | }
940 |
941 | bool TinyKtx_GetValue(TinyKtx_ContextHandle handle, char const *key, void const **value) {
942 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
943 | if (ctx == NULL)
944 | return false;
945 | if (ctx->headerValid == false) {
946 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
947 | return false;
948 | }
949 |
950 | if (ctx->keyData == NULL) {
951 | ctx->callbacks.errorFn(ctx->user, "No key value data in this KTX");
952 | return false;
953 | }
954 |
955 | TinyKtx_KeyValuePair const *curKey = ctx->keyData;
956 | while (((uint8_t *) curKey - (uint8_t *) ctx->keyData) < ctx->header.bytesOfKeyValueData) {
957 | char const *kvp = (char const *) curKey;
958 |
959 | if (strcmp(kvp, key) == 0) {
960 | size_t sl = strlen(kvp);
961 | *value = (void const *) (kvp + sl);
962 | return true;
963 | }
964 | curKey = curKey + ((curKey->size + 3u) & ~3u);
965 | }
966 | return false;
967 | }
968 |
969 | bool TinyKtx_Is1D(TinyKtx_ContextHandle handle) {
970 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
971 | if (ctx == NULL)
972 | return false;
973 | if (ctx->headerValid == false) {
974 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
975 | return false;
976 | }
977 | return (ctx->header.pixelHeight <= 1) && (ctx->header.pixelDepth <= 1 );
978 | }
979 | bool TinyKtx_Is2D(TinyKtx_ContextHandle handle) {
980 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
981 | if (ctx == NULL)
982 | return false;
983 | if (ctx->headerValid == false) {
984 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
985 | return false;
986 | }
987 |
988 | return (ctx->header.pixelHeight > 1 && ctx->header.pixelDepth <= 1);
989 | }
990 | bool TinyKtx_Is3D(TinyKtx_ContextHandle handle) {
991 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
992 | if (ctx == NULL)
993 | return false;
994 | if (ctx->headerValid == false) {
995 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
996 | return false;
997 | }
998 |
999 | return (ctx->header.pixelHeight > 1 && ctx->header.pixelDepth > 1);
1000 | }
1001 |
1002 | bool TinyKtx_IsCubemap(TinyKtx_ContextHandle handle) {
1003 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1004 | if (ctx == NULL)
1005 | return false;
1006 | if (ctx->headerValid == false) {
1007 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1008 | return false;
1009 | }
1010 |
1011 | return (ctx->header.numberOfFaces == 6);
1012 | }
1013 | bool TinyKtx_IsArray(TinyKtx_ContextHandle handle) {
1014 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1015 | if (ctx == NULL)
1016 | return false;
1017 | if (ctx->headerValid == false) {
1018 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1019 | return false;
1020 | }
1021 |
1022 | return (ctx->header.numberOfArrayElements > 1);
1023 | }
1024 |
1025 | bool TinyKtx_Dimensions(TinyKtx_ContextHandle handle,
1026 | uint32_t *width,
1027 | uint32_t *height,
1028 | uint32_t *depth,
1029 | uint32_t *slices) {
1030 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1031 | if (ctx == NULL)
1032 | return false;
1033 | if (ctx->headerValid == false) {
1034 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1035 | return false;
1036 | }
1037 |
1038 | if (width)
1039 | *width = ctx->header.pixelWidth;
1040 | if (height)
1041 | *height = ctx->header.pixelWidth;
1042 | if (depth)
1043 | *depth = ctx->header.pixelDepth;
1044 | if (slices)
1045 | *slices = ctx->header.numberOfArrayElements;
1046 | return true;
1047 | }
1048 |
1049 | uint32_t TinyKtx_Width(TinyKtx_ContextHandle handle) {
1050 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1051 | if (ctx == NULL)
1052 | return 0;
1053 | if (ctx->headerValid == false) {
1054 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1055 | return 0;
1056 | }
1057 | return ctx->header.pixelWidth;
1058 |
1059 | }
1060 |
1061 | uint32_t TinyKtx_Height(TinyKtx_ContextHandle handle) {
1062 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1063 | if (ctx == NULL)
1064 | return 0;
1065 | if (ctx->headerValid == false) {
1066 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1067 | return 0;
1068 | }
1069 |
1070 | return ctx->header.pixelHeight;
1071 | }
1072 |
1073 | uint32_t TinyKtx_Depth(TinyKtx_ContextHandle handle) {
1074 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1075 | if (ctx == NULL)
1076 | return 0;
1077 | if (ctx->headerValid == false) {
1078 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1079 | return 0;
1080 | }
1081 | return ctx->header.pixelDepth;
1082 | }
1083 |
1084 | uint32_t TinyKtx_ArraySlices(TinyKtx_ContextHandle handle) {
1085 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1086 | if (ctx == NULL)
1087 | return 0;
1088 | if (ctx->headerValid == false) {
1089 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1090 | return 0;
1091 | }
1092 |
1093 | return ctx->header.numberOfArrayElements;
1094 | }
1095 |
1096 | uint32_t TinyKtx_NumberOfMipmaps(TinyKtx_ContextHandle handle) {
1097 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1098 | if (ctx == NULL)
1099 | return 0;
1100 | if (ctx->headerValid == false) {
1101 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1102 | return 0;
1103 | }
1104 |
1105 | return ctx->header.numberOfMipmapLevels ? ctx->header.numberOfMipmapLevels : 1;
1106 | }
1107 |
1108 | bool TinyKtx_NeedsGenerationOfMipmaps(TinyKtx_ContextHandle handle) {
1109 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1110 | if (ctx == NULL)
1111 | return false;
1112 | if (ctx->headerValid == false) {
1113 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1114 | return false;
1115 | }
1116 |
1117 | return ctx->header.numberOfMipmapLevels == 0;
1118 | }
1119 |
1120 | bool TinyKtx_NeedsEndianCorrecting(TinyKtx_ContextHandle handle) {
1121 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1122 | if (ctx == NULL)
1123 | return false;
1124 | if (ctx->headerValid == false) {
1125 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1126 | return false;
1127 | }
1128 |
1129 | return ctx->sameEndian == false;
1130 | }
1131 |
1132 | bool TinyKtx_GetFormatGL(TinyKtx_ContextHandle handle, uint32_t *glformat, uint32_t *gltype, uint32_t *glinternalformat, uint32_t* typesize, uint32_t* glbaseinternalformat) {
1133 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1134 | if (ctx == NULL)
1135 | return false;
1136 | if (ctx->headerValid == false) {
1137 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1138 | return false;
1139 | }
1140 |
1141 | *glformat = ctx->header.glFormat;
1142 | *gltype = ctx->header.glType;
1143 | *glinternalformat = ctx->header.glInternalFormat;
1144 | *glbaseinternalformat = ctx->header.glBaseInternalFormat;
1145 | *typesize = ctx->header.glBaseInternalFormat;
1146 |
1147 | return true;
1148 | }
1149 |
1150 | static uint32_t TinyKtx_imageSize(TinyKtx_ContextHandle handle, uint32_t mipmaplevel, bool seekLast) {
1151 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1152 |
1153 | if (mipmaplevel >= ctx->header.numberOfMipmapLevels) {
1154 | ctx->callbacks.errorFn(ctx->user, "Invalid mipmap level");
1155 | return 0;
1156 | }
1157 | if (mipmaplevel >= TINYKTX_MAX_MIPMAPLEVELS) {
1158 | ctx->callbacks.errorFn(ctx->user, "Invalid mipmap level");
1159 | return 0;
1160 | }
1161 | if (!seekLast && ctx->mipMapSizes[mipmaplevel] != 0)
1162 | return ctx->mipMapSizes[mipmaplevel];
1163 |
1164 | uint64_t currentOffset = ctx->firstImagePos;
1165 | for (uint32_t i = 0; i <= mipmaplevel; ++i) {
1166 | uint32_t size;
1167 | // if we have already read this mipmaps size use it
1168 | if (ctx->mipMapSizes[i] != 0) {
1169 | size = ctx->mipMapSizes[i];
1170 | if (seekLast && i == mipmaplevel) {
1171 | ctx->callbacks.seekFn(ctx->user, currentOffset + sizeof(uint32_t));
1172 | }
1173 | } else {
1174 | // otherwise seek and read it
1175 | ctx->callbacks.seekFn(ctx->user, currentOffset);
1176 | size_t readchk = ctx->callbacks.readFn(ctx->user, &size, sizeof(uint32_t));
1177 | if(readchk != 4) {
1178 | ctx->callbacks.errorFn(ctx->user, "Reading image size error");
1179 | return 0;
1180 | }
1181 | // so in the really small print KTX v1 states GL_UNPACK_ALIGNMENT = 4
1182 | // which PVR Texture Tool and I missed. It means pad to 1, 2, 4, 8
1183 | // note 3 or 6 bytes are rounded up.
1184 | // we rely on the loader setting this right, we should handle file with
1185 | // it not to standard but its really the level up that has to do this
1186 |
1187 | if (ctx->header.numberOfFaces == 6 && ctx->header.numberOfArrayElements == 0) {
1188 | size = ((size + 3u) & ~3u) * 6; // face padding and 6 faces
1189 | }
1190 |
1191 | ctx->mipMapSizes[i] = size;
1192 | }
1193 | currentOffset += (size + sizeof(uint32_t) + 3u) & ~3u; // size + mip padding
1194 | }
1195 |
1196 | return ctx->mipMapSizes[mipmaplevel];
1197 | }
1198 |
1199 | uint32_t TinyKtx_ImageSize(TinyKtx_ContextHandle handle, uint32_t mipmaplevel) {
1200 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1201 | if (ctx == NULL) return 0;
1202 |
1203 | if (ctx->headerValid == false) {
1204 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1205 | return 0;
1206 | }
1207 | return TinyKtx_imageSize(handle, mipmaplevel, false);
1208 | }
1209 |
1210 | void const *TinyKtx_ImageRawData(TinyKtx_ContextHandle handle, uint32_t mipmaplevel) {
1211 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1212 | if (ctx == NULL)
1213 | return NULL;
1214 |
1215 | if (ctx->headerValid == false) {
1216 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1217 | return NULL;
1218 | }
1219 |
1220 | if (mipmaplevel >= ctx->header.numberOfMipmapLevels) {
1221 | ctx->callbacks.errorFn(ctx->user, "Invalid mipmap level");
1222 | return NULL;
1223 | }
1224 |
1225 | if (mipmaplevel >= TINYKTX_MAX_MIPMAPLEVELS) {
1226 | ctx->callbacks.errorFn(ctx->user, "Invalid mipmap level");
1227 | return NULL;
1228 | }
1229 |
1230 | if (ctx->mipmaps[mipmaplevel] != NULL)
1231 | return ctx->mipmaps[mipmaplevel];
1232 |
1233 | uint32_t size = TinyKtx_imageSize(handle, mipmaplevel, true);
1234 | if (size == 0)
1235 | return NULL;
1236 |
1237 | ctx->mipmaps[mipmaplevel] = (uint8_t const*) ctx->callbacks.allocFn(ctx->user, size);
1238 | if (ctx->mipmaps[mipmaplevel]) {
1239 | ctx->callbacks.readFn(ctx->user, (void *) ctx->mipmaps[mipmaplevel], size);
1240 | }
1241 |
1242 | return ctx->mipmaps[mipmaplevel];
1243 | }
1244 |
1245 | #define FT(fmt, type, intfmt, size) *glformat = TINYKTX_GL_FORMAT_##fmt; \
1246 | *gltype = TINYKTX_GL_TYPE_##type; \
1247 | *glinternalformat = TINYKTX_GL_INTFORMAT_##intfmt; \
1248 | *typesize = size; \
1249 | return true;
1250 | #define FTC(fmt, intfmt) *glformat = TINYKTX_GL_FORMAT_##fmt; \
1251 | *gltype = TINYKTX_GL_TYPE_COMPRESSED; \
1252 | *glinternalformat = TINYKTX_GL_COMPRESSED_##intfmt; \
1253 | *typesize = 1; \
1254 | return true;
1255 |
1256 | bool TinyKtx_CrackFormatToGL(TinyKtx_Format format,
1257 | uint32_t *glformat,
1258 | uint32_t *gltype,
1259 | uint32_t *glinternalformat,
1260 | uint32_t *typesize) {
1261 | switch (format) {
1262 | case TKTX_R4G4_UNORM_PACK8: FT(RG, UNSIGNED_SHORT_4_4_4_4, RGB4, 1)
1263 | case TKTX_R4G4B4A4_UNORM_PACK16: FT(RGBA, UNSIGNED_SHORT_4_4_4_4, RGBA4, 2)
1264 |
1265 | case TKTX_B4G4R4A4_UNORM_PACK16: FT(BGRA, UNSIGNED_SHORT_4_4_4_4_REV, RGBA4, 2)
1266 |
1267 | case TKTX_R5G6B5_UNORM_PACK16: FT(RGB, UNSIGNED_SHORT_5_6_5_REV, RGB565, 2)
1268 | case TKTX_B5G6R5_UNORM_PACK16: FT(BGR, UNSIGNED_SHORT_5_6_5, RGB565, 2)
1269 |
1270 | case TKTX_R5G5B5A1_UNORM_PACK16: FT(RGBA, UNSIGNED_SHORT_5_5_5_1, RGB5_A1, 2)
1271 | case TKTX_A1R5G5B5_UNORM_PACK16: FT(RGBA, UNSIGNED_SHORT_1_5_5_5_REV, RGB5_A1, 2)
1272 | case TKTX_B5G5R5A1_UNORM_PACK16: FT(BGRA, UNSIGNED_SHORT_5_5_5_1, RGB5_A1, 2)
1273 |
1274 | case TKTX_A2R10G10B10_UNORM_PACK32: FT(BGRA, UNSIGNED_INT_2_10_10_10_REV, RGB10_A2, 4)
1275 | case TKTX_A2R10G10B10_UINT_PACK32: FT(BGRA_INTEGER, UNSIGNED_INT_2_10_10_10_REV, RGB10_A2, 4)
1276 | case TKTX_A2B10G10R10_UNORM_PACK32: FT(RGBA, UNSIGNED_INT_2_10_10_10_REV, RGB10_A2, 4)
1277 | case TKTX_A2B10G10R10_UINT_PACK32: FT(RGBA_INTEGER, UNSIGNED_INT_2_10_10_10_REV, RGB10_A2, 4)
1278 |
1279 | case TKTX_R8_UNORM: FT(RED, UNSIGNED_BYTE, R8, 1)
1280 | case TKTX_R8_SNORM: FT(RED, BYTE, R8_SNORM, 1)
1281 | case TKTX_R8_UINT: FT(RED_INTEGER, UNSIGNED_BYTE, R8UI, 1)
1282 | case TKTX_R8_SINT: FT(RED_INTEGER, BYTE, R8I, 1)
1283 | case TKTX_R8_SRGB: FT(SLUMINANCE, UNSIGNED_BYTE, SRGB8, 1)
1284 |
1285 | case TKTX_R8G8_UNORM: FT(RG, UNSIGNED_BYTE, RG8, 1)
1286 | case TKTX_R8G8_SNORM: FT(RG, BYTE, RG8_SNORM, 1)
1287 | case TKTX_R8G8_UINT: FT(RG_INTEGER, UNSIGNED_BYTE, RG8UI, 1)
1288 | case TKTX_R8G8_SINT: FT(RG_INTEGER, BYTE, RG8I, 1)
1289 | case TKTX_R8G8_SRGB: FT(SLUMINANCE_ALPHA, UNSIGNED_BYTE, SRGB8, 1)
1290 |
1291 | case TKTX_R8G8B8_UNORM: FT(RGB, UNSIGNED_BYTE, RGB8, 1)
1292 | case TKTX_R8G8B8_SNORM: FT(RGB, BYTE, RGB8_SNORM, 1)
1293 | case TKTX_R8G8B8_UINT: FT(RGB_INTEGER, UNSIGNED_BYTE, RGB8UI, 1)
1294 | case TKTX_R8G8B8_SINT: FT(RGB_INTEGER, BYTE, RGB8I, 1)
1295 | case TKTX_R8G8B8_SRGB: FT(SRGB, UNSIGNED_BYTE, SRGB8, 1)
1296 |
1297 | case TKTX_B8G8R8_UNORM: FT(BGR, UNSIGNED_BYTE, RGB8, 1)
1298 | case TKTX_B8G8R8_SNORM: FT(BGR, BYTE, RGB8_SNORM, 1)
1299 | case TKTX_B8G8R8_UINT: FT(BGR_INTEGER, UNSIGNED_BYTE, RGB8UI, 1)
1300 | case TKTX_B8G8R8_SINT: FT(BGR_INTEGER, BYTE, RGB8I, 1)
1301 | case TKTX_B8G8R8_SRGB: FT(BGR, UNSIGNED_BYTE, SRGB8, 1)
1302 |
1303 | case TKTX_R8G8B8A8_UNORM:FT(RGBA, UNSIGNED_BYTE, RGBA8, 1)
1304 | case TKTX_R8G8B8A8_SNORM:FT(RGBA, BYTE, RGBA8_SNORM, 1)
1305 | case TKTX_R8G8B8A8_UINT: FT(RGBA_INTEGER, UNSIGNED_BYTE, RGBA8UI, 1)
1306 | case TKTX_R8G8B8A8_SINT: FT(RGBA_INTEGER, BYTE, RGBA8I, 1)
1307 | case TKTX_R8G8B8A8_SRGB: FT(SRGB_ALPHA, UNSIGNED_BYTE, SRGB8, 1)
1308 |
1309 | case TKTX_B8G8R8A8_UNORM: FT(BGRA, UNSIGNED_BYTE, RGBA8, 1)
1310 | case TKTX_B8G8R8A8_SNORM: FT(BGRA, BYTE, RGBA8_SNORM, 1)
1311 | case TKTX_B8G8R8A8_UINT: FT(BGRA_INTEGER, UNSIGNED_BYTE, RGBA8UI, 1)
1312 | case TKTX_B8G8R8A8_SINT: FT(BGRA_INTEGER, BYTE, RGBA8I, 1)
1313 | case TKTX_B8G8R8A8_SRGB: FT(BGRA, UNSIGNED_BYTE, SRGB8, 1)
1314 |
1315 | case TKTX_E5B9G9R9_UFLOAT_PACK32: FT(BGR, UNSIGNED_INT_5_9_9_9_REV, RGB9_E5, 4);
1316 | case TKTX_A8B8G8R8_UNORM_PACK32: FT(ABGR, UNSIGNED_BYTE, RGBA8, 1)
1317 | case TKTX_A8B8G8R8_SNORM_PACK32: FT(ABGR, BYTE, RGBA8, 1)
1318 | case TKTX_A8B8G8R8_UINT_PACK32: FT(ABGR, UNSIGNED_BYTE, RGBA8UI, 1)
1319 | case TKTX_A8B8G8R8_SINT_PACK32: FT(ABGR, BYTE, RGBA8I, 1)
1320 | case TKTX_A8B8G8R8_SRGB_PACK32: FT(ABGR, UNSIGNED_BYTE, SRGB8, 1)
1321 | case TKTX_B10G11R11_UFLOAT_PACK32: FT(BGR, UNSIGNED_INT_10F_11F_11F_REV, R11F_G11F_B10F, 4)
1322 |
1323 | case TKTX_R16_UNORM: FT(RED, UNSIGNED_SHORT, R16, 2)
1324 | case TKTX_R16_SNORM: FT(RED, SHORT, R16_SNORM, 2)
1325 | case TKTX_R16_UINT: FT(RED_INTEGER, UNSIGNED_SHORT, R16UI, 2)
1326 | case TKTX_R16_SINT: FT(RED_INTEGER, SHORT, R16I, 2)
1327 | case TKTX_R16_SFLOAT:FT(RED, HALF_FLOAT, R16F, 2)
1328 |
1329 | case TKTX_R16G16_UNORM: FT(RG, UNSIGNED_SHORT, RG16, 2)
1330 | case TKTX_R16G16_SNORM: FT(RG, SHORT, RG16_SNORM, 2)
1331 | case TKTX_R16G16_UINT: FT(RG_INTEGER, UNSIGNED_SHORT, RG16UI, 2)
1332 | case TKTX_R16G16_SINT: FT(RG_INTEGER, SHORT, RG16I, 2)
1333 | case TKTX_R16G16_SFLOAT:FT(RG, HALF_FLOAT, RG16F, 2)
1334 |
1335 | case TKTX_R16G16B16_UNORM: FT(RGB, UNSIGNED_SHORT, RGB16, 2)
1336 | case TKTX_R16G16B16_SNORM: FT(RGB, SHORT, RGB16_SNORM, 2)
1337 | case TKTX_R16G16B16_UINT: FT(RGB_INTEGER, UNSIGNED_SHORT, RGB16UI, 2)
1338 | case TKTX_R16G16B16_SINT: FT(RGB_INTEGER, SHORT, RGB16I, 2)
1339 | case TKTX_R16G16B16_SFLOAT: FT(RGB, HALF_FLOAT, RGB16F, 2)
1340 |
1341 | case TKTX_R16G16B16A16_UNORM: FT(RGBA, UNSIGNED_SHORT, RGBA16, 2)
1342 | case TKTX_R16G16B16A16_SNORM: FT(RGBA, SHORT, RGBA16_SNORM, 2)
1343 | case TKTX_R16G16B16A16_UINT: FT(RGBA_INTEGER, UNSIGNED_SHORT, RGBA16UI, 2)
1344 | case TKTX_R16G16B16A16_SINT: FT(RGBA_INTEGER, SHORT, RGBA16I, 2)
1345 | case TKTX_R16G16B16A16_SFLOAT:FT(RGBA, HALF_FLOAT, RGBA16F, 2)
1346 |
1347 | case TKTX_R32_UINT: FT(RED_INTEGER, UNSIGNED_INT, R32UI, 4)
1348 | case TKTX_R32_SINT: FT(RED_INTEGER, INT, R32I, 4)
1349 | case TKTX_R32_SFLOAT: FT(RED, FLOAT, R32F, 4)
1350 |
1351 | case TKTX_R32G32_UINT: FT(RG_INTEGER, UNSIGNED_INT, RG32UI, 4)
1352 | case TKTX_R32G32_SINT: FT(RG_INTEGER, INT, RG32I, 4)
1353 | case TKTX_R32G32_SFLOAT: FT(RG, FLOAT, RG32F, 4)
1354 |
1355 | case TKTX_R32G32B32_UINT: FT(RGB_INTEGER, UNSIGNED_INT, RGB32UI, 4)
1356 | case TKTX_R32G32B32_SINT: FT(RGB_INTEGER, INT, RGB32I, 4)
1357 | case TKTX_R32G32B32_SFLOAT: FT(RGB_INTEGER, FLOAT, RGB32F, 4)
1358 |
1359 | case TKTX_R32G32B32A32_UINT: FT(RGBA_INTEGER, UNSIGNED_INT, RGBA32UI, 4)
1360 | case TKTX_R32G32B32A32_SINT: FT(RGBA_INTEGER, INT, RGBA32I, 4)
1361 | case TKTX_R32G32B32A32_SFLOAT:FT(RGBA, FLOAT, RGBA32F, 4)
1362 |
1363 | case TKTX_BC1_RGB_UNORM_BLOCK: FTC(RGB, RGB_S3TC_DXT1)
1364 | case TKTX_BC1_RGB_SRGB_BLOCK: FTC(RGB, SRGB_S3TC_DXT1)
1365 | case TKTX_BC1_RGBA_UNORM_BLOCK: FTC(RGBA, RGBA_S3TC_DXT1)
1366 | case TKTX_BC1_RGBA_SRGB_BLOCK: FTC(RGBA, SRGB_ALPHA_S3TC_DXT1)
1367 | case TKTX_BC2_UNORM_BLOCK: FTC(RGBA, RGBA_S3TC_DXT3)
1368 | case TKTX_BC2_SRGB_BLOCK: FTC(RGBA, SRGB_ALPHA_S3TC_DXT3)
1369 | case TKTX_BC3_UNORM_BLOCK: FTC(RGBA, RGBA_S3TC_DXT5)
1370 | case TKTX_BC3_SRGB_BLOCK: FTC(RGBA, SRGB_ALPHA_S3TC_DXT5)
1371 | case TKTX_BC4_UNORM_BLOCK: FTC(RED, RED_RGTC1)
1372 | case TKTX_BC4_SNORM_BLOCK: FTC(RED, SIGNED_RED_RGTC1)
1373 | case TKTX_BC5_UNORM_BLOCK: FTC(RG, RED_GREEN_RGTC2)
1374 | case TKTX_BC5_SNORM_BLOCK: FTC(RG, SIGNED_RED_GREEN_RGTC2)
1375 | case TKTX_BC6H_UFLOAT_BLOCK: FTC(RGB, RGB_BPTC_UNSIGNED_FLOAT)
1376 | case TKTX_BC6H_SFLOAT_BLOCK: FTC(RGB, RGB_BPTC_SIGNED_FLOAT)
1377 | case TKTX_BC7_UNORM_BLOCK: FTC(RGBA, RGBA_BPTC_UNORM)
1378 | case TKTX_BC7_SRGB_BLOCK: FTC(RGBA, SRGB_ALPHA_BPTC_UNORM)
1379 |
1380 | case TKTX_ETC2_R8G8B8_UNORM_BLOCK: FTC(RGB, RGB8_ETC2)
1381 | case TKTX_ETC2_R8G8B8A1_UNORM_BLOCK: FTC(RGBA, RGB8_PUNCHTHROUGH_ALPHA1_ETC2)
1382 | case TKTX_ETC2_R8G8B8A8_UNORM_BLOCK: FTC(RGBA, RGBA8_ETC2_EAC)
1383 | case TKTX_ETC2_R8G8B8_SRGB_BLOCK: FTC(SRGB, SRGB8_ETC2)
1384 | case TKTX_ETC2_R8G8B8A1_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)
1385 | case TKTX_ETC2_R8G8B8A8_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ETC2_EAC)
1386 | case TKTX_EAC_R11_UNORM_BLOCK: FTC(RED, R11_EAC)
1387 | case TKTX_EAC_R11G11_UNORM_BLOCK: FTC(RG, RG11_EAC)
1388 | case TKTX_EAC_R11_SNORM_BLOCK: FTC(RED, SIGNED_R11_EAC)
1389 | case TKTX_EAC_R11G11_SNORM_BLOCK: FTC(RG, SIGNED_RG11_EAC)
1390 |
1391 | case TKTX_PVR_2BPP_UNORM_BLOCK: FTC(RGB, RGB_PVRTC_2BPPV1)
1392 | case TKTX_PVR_2BPPA_UNORM_BLOCK: FTC(RGBA, RGBA_PVRTC_2BPPV1);
1393 | case TKTX_PVR_4BPP_UNORM_BLOCK: FTC(RGB, RGB_PVRTC_4BPPV1)
1394 | case TKTX_PVR_4BPPA_UNORM_BLOCK: FTC(RGB, RGB_PVRTC_4BPPV1)
1395 | case TKTX_PVR_2BPP_SRGB_BLOCK: FTC(SRGB, SRGB_PVRTC_2BPPV1)
1396 | case TKTX_PVR_2BPPA_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB_ALPHA_PVRTC_2BPPV1);
1397 | case TKTX_PVR_4BPP_SRGB_BLOCK: FTC(SRGB, SRGB_PVRTC_2BPPV1)
1398 | case TKTX_PVR_4BPPA_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB_ALPHA_PVRTC_2BPPV1);
1399 |
1400 | case TKTX_ASTC_4x4_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_4x4)
1401 | case TKTX_ASTC_4x4_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_4x4)
1402 | case TKTX_ASTC_5x4_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_5x4)
1403 | case TKTX_ASTC_5x4_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_5x4)
1404 | case TKTX_ASTC_5x5_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_5x5)
1405 | case TKTX_ASTC_5x5_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_5x5)
1406 | case TKTX_ASTC_6x5_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_6x5)
1407 | case TKTX_ASTC_6x5_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_6x5)
1408 | case TKTX_ASTC_6x6_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_6x6)
1409 | case TKTX_ASTC_6x6_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_6x6)
1410 | case TKTX_ASTC_8x5_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_8x5)
1411 | case TKTX_ASTC_8x5_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_8x5)
1412 | case TKTX_ASTC_8x6_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_8x6)
1413 | case TKTX_ASTC_8x6_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_8x6)
1414 | case TKTX_ASTC_8x8_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_8x8)
1415 | case TKTX_ASTC_8x8_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_8x8)
1416 | case TKTX_ASTC_10x5_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_10x5)
1417 | case TKTX_ASTC_10x5_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_10x5)
1418 | case TKTX_ASTC_10x6_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_10x6)
1419 | case TKTX_ASTC_10x6_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_10x6)
1420 | case TKTX_ASTC_10x8_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_10x8);
1421 | case TKTX_ASTC_10x8_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_10x8)
1422 | case TKTX_ASTC_10x10_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_10x10)
1423 | case TKTX_ASTC_10x10_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_10x10)
1424 | case TKTX_ASTC_12x10_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_12x10)
1425 | case TKTX_ASTC_12x10_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_12x10)
1426 | case TKTX_ASTC_12x12_UNORM_BLOCK: FTC(RGBA, RGBA_ASTC_12x12)
1427 | case TKTX_ASTC_12x12_SRGB_BLOCK: FTC(SRGB_ALPHA, SRGB8_ALPHA8_ASTC_12x12)
1428 |
1429 | default:break;
1430 | }
1431 | return false;
1432 | }
1433 | #undef FT
1434 | #undef FTC
1435 |
1436 | TinyKtx_Format TinyKtx_CrackFormatFromGL(uint32_t const glformat,
1437 | uint32_t const gltype,
1438 | uint32_t const glinternalformat,
1439 | uint32_t const typesize) {
1440 | switch (glinternalformat) {
1441 | case TINYKTX_GL_COMPRESSED_RGB_S3TC_DXT1: return TKTX_BC1_RGB_UNORM_BLOCK;
1442 | case TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT1: return TKTX_BC1_RGBA_UNORM_BLOCK;
1443 | case TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT3: return TKTX_BC2_UNORM_BLOCK;
1444 | case TINYKTX_GL_COMPRESSED_RGBA_S3TC_DXT5: return TKTX_BC3_UNORM_BLOCK;
1445 | case TINYKTX_GL_COMPRESSED_3DC_X_AMD: return TKTX_BC4_UNORM_BLOCK;
1446 | case TINYKTX_GL_COMPRESSED_3DC_XY_AMD: return TKTX_BC5_UNORM_BLOCK;
1447 | case TINYKTX_GL_COMPRESSED_SRGB_PVRTC_2BPPV1: return TKTX_PVR_2BPP_SRGB_BLOCK;
1448 | case TINYKTX_GL_COMPRESSED_SRGB_PVRTC_4BPPV1: return TKTX_PVR_2BPPA_SRGB_BLOCK;
1449 | case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1: return TKTX_PVR_2BPPA_SRGB_BLOCK;
1450 | case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1: return TKTX_PVR_4BPPA_SRGB_BLOCK;
1451 | case TINYKTX_GL_COMPRESSED_RGB_PVRTC_4BPPV1: return TKTX_PVR_4BPP_UNORM_BLOCK;
1452 | case TINYKTX_GL_COMPRESSED_RGB_PVRTC_2BPPV1: return TKTX_PVR_2BPP_UNORM_BLOCK;
1453 | case TINYKTX_GL_COMPRESSED_RGBA_PVRTC_4BPPV1: return TKTX_PVR_4BPPA_UNORM_BLOCK;
1454 | case TINYKTX_GL_COMPRESSED_RGBA_PVRTC_2BPPV1: return TKTX_PVR_2BPPA_UNORM_BLOCK;
1455 | case TINYKTX_GL_COMPRESSED_SRGB_S3TC_DXT1: return TKTX_BC1_RGB_SRGB_BLOCK;
1456 | case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1: return TKTX_BC1_RGBA_SRGB_BLOCK;
1457 | case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3: return TKTX_BC2_SRGB_BLOCK;
1458 | case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5: return TKTX_BC3_SRGB_BLOCK;
1459 | case TINYKTX_GL_COMPRESSED_LUMINANCE_LATC1: return TKTX_BC4_UNORM_BLOCK;
1460 | case TINYKTX_GL_COMPRESSED_SIGNED_LUMINANCE_LATC1: return TKTX_BC4_SNORM_BLOCK;
1461 | case TINYKTX_GL_COMPRESSED_LUMINANCE_ALPHA_LATC2: return TKTX_BC5_UNORM_BLOCK;
1462 | case TINYKTX_GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2: return TKTX_BC5_SNORM_BLOCK;
1463 | case TINYKTX_GL_COMPRESSED_RED_RGTC1: return TKTX_BC4_UNORM_BLOCK;
1464 | case TINYKTX_GL_COMPRESSED_SIGNED_RED_RGTC1: return TKTX_BC4_SNORM_BLOCK;
1465 | case TINYKTX_GL_COMPRESSED_RED_GREEN_RGTC2: return TKTX_BC5_UNORM_BLOCK;
1466 | case TINYKTX_GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2: return TKTX_BC5_SNORM_BLOCK;
1467 | case TINYKTX_GL_COMPRESSED_ETC1_RGB8_OES: return TKTX_ETC2_R8G8B8_UNORM_BLOCK;
1468 | case TINYKTX_GL_COMPRESSED_RGBA_BPTC_UNORM: return TKTX_BC7_UNORM_BLOCK;
1469 | case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: return TKTX_BC7_SRGB_BLOCK;
1470 | case TINYKTX_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: return TKTX_BC6H_SFLOAT_BLOCK;
1471 | case TINYKTX_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: return TKTX_BC6H_UFLOAT_BLOCK;
1472 | case TINYKTX_GL_COMPRESSED_R11_EAC: return TKTX_EAC_R11_UNORM_BLOCK;
1473 | case TINYKTX_GL_COMPRESSED_SIGNED_R11_EAC: return TKTX_EAC_R11_SNORM_BLOCK;
1474 | case TINYKTX_GL_COMPRESSED_RG11_EAC: return TKTX_EAC_R11G11_UNORM_BLOCK;
1475 | case TINYKTX_GL_COMPRESSED_SIGNED_RG11_EAC: return TKTX_EAC_R11G11_UNORM_BLOCK;
1476 | case TINYKTX_GL_COMPRESSED_RGB8_ETC2: return TKTX_ETC2_R8G8B8_UNORM_BLOCK;
1477 | case TINYKTX_GL_COMPRESSED_SRGB8_ETC2: return TKTX_ETC2_R8G8B8_SRGB_BLOCK;
1478 | case TINYKTX_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: return TKTX_ETC2_R8G8B8A1_UNORM_BLOCK;
1479 | case TINYKTX_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: return TKTX_ETC2_R8G8B8A1_SRGB_BLOCK;
1480 | case TINYKTX_GL_COMPRESSED_RGBA8_ETC2_EAC: return TKTX_ETC2_R8G8B8A8_UNORM_BLOCK;
1481 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: return TKTX_ETC2_R8G8B8A8_SRGB_BLOCK;
1482 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_4x4: return TKTX_ASTC_4x4_UNORM_BLOCK;
1483 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_5x4: return TKTX_ASTC_5x4_UNORM_BLOCK;
1484 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_5x5: return TKTX_ASTC_5x5_UNORM_BLOCK;
1485 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_6x5: return TKTX_ASTC_6x5_UNORM_BLOCK;
1486 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_6x6: return TKTX_ASTC_6x6_UNORM_BLOCK;
1487 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x5: return TKTX_ASTC_8x5_UNORM_BLOCK;
1488 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x6: return TKTX_ASTC_8x6_UNORM_BLOCK;
1489 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_8x8: return TKTX_ASTC_8x8_UNORM_BLOCK;
1490 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x5: return TKTX_ASTC_10x5_UNORM_BLOCK;
1491 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x6: return TKTX_ASTC_10x6_UNORM_BLOCK;
1492 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x8: return TKTX_ASTC_10x8_UNORM_BLOCK;
1493 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_10x10: return TKTX_ASTC_10x10_UNORM_BLOCK;
1494 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_12x10: return TKTX_ASTC_12x10_UNORM_BLOCK;
1495 | case TINYKTX_GL_COMPRESSED_RGBA_ASTC_12x12: return TKTX_ASTC_12x12_UNORM_BLOCK;
1496 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4: return TKTX_ASTC_4x4_SRGB_BLOCK;
1497 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4: return TKTX_ASTC_5x4_SRGB_BLOCK;
1498 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5: return TKTX_ASTC_5x5_SRGB_BLOCK;
1499 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5: return TKTX_ASTC_6x5_SRGB_BLOCK;
1500 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6: return TKTX_ASTC_6x6_SRGB_BLOCK;
1501 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5: return TKTX_ASTC_8x5_SRGB_BLOCK;
1502 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6: return TKTX_ASTC_8x6_SRGB_BLOCK;
1503 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8: return TKTX_ASTC_8x8_SRGB_BLOCK;
1504 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5: return TKTX_ASTC_10x5_SRGB_BLOCK;
1505 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6: return TKTX_ASTC_10x6_SRGB_BLOCK;
1506 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8: return TKTX_ASTC_10x8_SRGB_BLOCK;
1507 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10: return TKTX_ASTC_10x10_SRGB_BLOCK;
1508 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10: return TKTX_ASTC_12x10_SRGB_BLOCK;
1509 | case TINYKTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12: return TKTX_ASTC_12x12_SRGB_BLOCK;
1510 |
1511 | // non compressed
1512 | case TINYKTX_GL_INTFORMAT_RGB4:
1513 | if(glformat == TINYKTX_GL_FORMAT_RG) {
1514 | return TKTX_R4G4_UNORM_PACK8;
1515 | }
1516 | break;
1517 |
1518 | case TINYKTX_GL_INTFORMAT_RGBA4:
1519 | if(glformat == TINYKTX_GL_FORMAT_RGBA) {
1520 | return TKTX_R4G4B4A4_UNORM_PACK16;
1521 | } else if(glformat == TINYKTX_GL_FORMAT_BGRA) {
1522 | return TKTX_B4G4R4A4_UNORM_PACK16;
1523 | }
1524 | break;
1525 | case TINYKTX_GL_INTFORMAT_RGB565:
1526 | if(gltype == TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_6_5 || glformat == TINYKTX_GL_FORMAT_BGR) {
1527 | return TKTX_B5G6R5_UNORM_PACK16;
1528 | } else {
1529 | return TKTX_R5G6B5_UNORM_PACK16;
1530 | }
1531 | break;
1532 |
1533 | case TINYKTX_GL_INTFORMAT_RGB5_A1:
1534 | if (gltype == TINYKTX_GL_TYPE_UNSIGNED_SHORT_1_5_5_5_REV) {
1535 | return TKTX_A1R5G5B5_UNORM_PACK16;
1536 | } else if (gltype == TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_5_5_1) {
1537 | if(glformat == TINYKTX_GL_FORMAT_BGRA) {
1538 | return TKTX_B5G5R5A1_UNORM_PACK16;
1539 | } else {
1540 | return TKTX_R5G5B5A1_UNORM_PACK16;
1541 | }
1542 | }
1543 | break;
1544 | case TINYKTX_GL_INTFORMAT_R8_SNORM:
1545 | case TINYKTX_GL_INTFORMAT_R8:
1546 | if(gltype == TINYKTX_GL_TYPE_BYTE || glinternalformat == TINYKTX_GL_INTFORMAT_R8_SNORM) {
1547 | return TKTX_R8_SNORM;
1548 | } else {
1549 | return TKTX_R8_UNORM;
1550 | }
1551 | break;
1552 | case TINYKTX_GL_INTFORMAT_RG8_SNORM:
1553 | case TINYKTX_GL_INTFORMAT_RG8:
1554 | if(gltype == TINYKTX_GL_TYPE_BYTE ||
1555 | glinternalformat == TINYKTX_GL_INTFORMAT_RG8_SNORM) {
1556 | return TKTX_R8G8_SNORM;
1557 | } else {
1558 | return TKTX_R8G8_UNORM;
1559 | }
1560 | break;
1561 | case TINYKTX_GL_INTFORMAT_RGB8_SNORM:
1562 | case TINYKTX_GL_INTFORMAT_RGB8:
1563 | if(glformat == TINYKTX_GL_FORMAT_BGR) {
1564 | if(gltype == TINYKTX_GL_TYPE_BYTE ||
1565 | glinternalformat == TINYKTX_GL_INTFORMAT_RGB8_SNORM) {
1566 | return TKTX_B8G8R8_SNORM;
1567 | } else {
1568 | return TKTX_B8G8R8_UNORM;
1569 | }
1570 | } else {
1571 | if(gltype == TINYKTX_GL_TYPE_BYTE ||
1572 | glinternalformat == TINYKTX_GL_INTFORMAT_RGB8_SNORM) {
1573 | return TKTX_R8G8B8_SNORM;
1574 | } else {
1575 | return TKTX_R8G8B8_UNORM;
1576 | }
1577 | }
1578 | break;
1579 | case TINYKTX_GL_INTFORMAT_RGBA8_SNORM:
1580 | case TINYKTX_GL_INTFORMAT_RGBA8:
1581 | if(glformat == TINYKTX_GL_FORMAT_RGBA) {
1582 | if(gltype == TINYKTX_GL_TYPE_BYTE ||
1583 | glinternalformat == TINYKTX_GL_INTFORMAT_RGBA8_SNORM) {
1584 | return TKTX_R8G8B8A8_SNORM;
1585 | } else if(gltype == TINYKTX_GL_TYPE_UNSIGNED_BYTE) {
1586 | return TKTX_R8G8B8A8_UNORM;
1587 | }
1588 | } else if(glformat == TINYKTX_GL_FORMAT_BGRA) {
1589 | if(gltype == TINYKTX_GL_TYPE_BYTE ||
1590 | glinternalformat == TINYKTX_GL_INTFORMAT_RGBA8_SNORM) {
1591 | return TKTX_B8G8R8A8_SNORM;
1592 | } else if(gltype == TINYKTX_GL_TYPE_UNSIGNED_BYTE) {
1593 | return TKTX_B8G8R8A8_UNORM;
1594 | }
1595 | } else if(glformat == TINYKTX_GL_FORMAT_ABGR) {
1596 | if(gltype == TINYKTX_GL_TYPE_BYTE ||
1597 | glinternalformat == TINYKTX_GL_INTFORMAT_RGBA8_SNORM) {
1598 | return TKTX_A8B8G8R8_SNORM_PACK32;
1599 | } else if(gltype == TINYKTX_GL_TYPE_UNSIGNED_BYTE) {
1600 | return TKTX_A8B8G8R8_UNORM_PACK32;
1601 | }
1602 | }
1603 | break;
1604 |
1605 | case TINYKTX_GL_INTFORMAT_R16: return TKTX_R16_UNORM;
1606 | case TINYKTX_GL_INTFORMAT_RG16: return TKTX_R16G16_UNORM;
1607 | case TINYKTX_GL_INTFORMAT_RGB16: return TKTX_R16G16B16_UNORM;
1608 | case TINYKTX_GL_INTFORMAT_RGBA16: return TKTX_R16G16B16A16_UNORM;
1609 |
1610 | case TINYKTX_GL_INTFORMAT_R16_SNORM:return TKTX_R16_SNORM;
1611 | case TINYKTX_GL_INTFORMAT_RG16_SNORM: return TKTX_R16G16_SNORM;
1612 | case TINYKTX_GL_INTFORMAT_RGB16_SNORM: return TKTX_R16G16B16_SNORM;
1613 | case TINYKTX_GL_INTFORMAT_RGBA16_SNORM: return TKTX_R16G16B16A16_SNORM;
1614 |
1615 | case TINYKTX_GL_INTFORMAT_R8I: return TKTX_R8_SINT;
1616 | case TINYKTX_GL_INTFORMAT_RG8I: return TKTX_R8G8_SINT;
1617 | case TINYKTX_GL_INTFORMAT_RGB8I:
1618 | if(glformat == TINYKTX_GL_FORMAT_RGB || glformat == TINYKTX_GL_FORMAT_RGB_INTEGER) {
1619 | return TKTX_R8G8B8_SINT;
1620 | } else if(glformat == TINYKTX_GL_FORMAT_BGR || glformat == TINYKTX_GL_FORMAT_BGR_INTEGER) {
1621 | return TKTX_B8G8R8_SINT;
1622 | }
1623 | break;
1624 |
1625 | case TINYKTX_GL_INTFORMAT_RGBA8I:
1626 | if(glformat == TINYKTX_GL_FORMAT_RGBA || glformat == TINYKTX_GL_FORMAT_RGBA_INTEGER) {
1627 | return TKTX_R8G8B8A8_SINT;
1628 | } else if(glformat == TINYKTX_GL_FORMAT_BGRA || glformat == TINYKTX_GL_FORMAT_BGRA_INTEGER) {
1629 | return TKTX_B8G8R8A8_SINT;
1630 | } else if(glformat == TINYKTX_GL_FORMAT_ABGR) {
1631 | return TKTX_A8B8G8R8_SINT_PACK32;
1632 | }
1633 | break;
1634 |
1635 | case TINYKTX_GL_INTFORMAT_R16I: return TKTX_R16_SINT;
1636 | case TINYKTX_GL_INTFORMAT_RG16I: return TKTX_R16G16_SINT;
1637 | case TINYKTX_GL_INTFORMAT_RGB16I:return TKTX_R16G16B16_SINT;
1638 | case TINYKTX_GL_INTFORMAT_RGBA16I:return TKTX_R16G16B16A16_SINT;
1639 |
1640 | case TINYKTX_GL_INTFORMAT_R32I: return TKTX_R32_SINT;
1641 | case TINYKTX_GL_INTFORMAT_RG32I: return TKTX_R32G32_SINT;
1642 | case TINYKTX_GL_INTFORMAT_RGB32I:
1643 | if(glformat == TINYKTX_GL_FORMAT_RGB || glformat == TINYKTX_GL_FORMAT_RGB_INTEGER) {
1644 | return TKTX_R32G32B32_SINT;
1645 | }
1646 | break;
1647 | case TINYKTX_GL_INTFORMAT_RGBA32I:return TKTX_R32G32B32A32_SINT;
1648 |
1649 | case TINYKTX_GL_INTFORMAT_R8UI: return TKTX_R8_UINT;
1650 | case TINYKTX_GL_INTFORMAT_RG8UI: return TKTX_R8G8_UINT;
1651 | case TINYKTX_GL_INTFORMAT_RGB8UI:
1652 | if(glformat == TINYKTX_GL_FORMAT_RGB || glformat == TINYKTX_GL_FORMAT_RGB_INTEGER) {
1653 | return TKTX_R8G8B8_UINT;
1654 | } else if(glformat == TINYKTX_GL_FORMAT_BGR || glformat == TINYKTX_GL_FORMAT_BGR_INTEGER) {
1655 | return TKTX_B8G8R8_UINT;
1656 | }
1657 | break;
1658 | case TINYKTX_GL_INTFORMAT_RGBA8UI:
1659 | if(glformat == TINYKTX_GL_FORMAT_RGBA || glformat == TINYKTX_GL_FORMAT_RGBA_INTEGER) {
1660 | return TKTX_R8G8B8A8_UINT;
1661 | } else if(glformat == TINYKTX_GL_FORMAT_BGRA || glformat == TINYKTX_GL_FORMAT_BGRA_INTEGER) {
1662 | return TKTX_B8G8R8A8_UINT;
1663 | } else if(glformat == TINYKTX_GL_FORMAT_ABGR) {
1664 | return TKTX_A8B8G8R8_UINT_PACK32;
1665 | }
1666 | break;
1667 |
1668 | case TINYKTX_GL_INTFORMAT_R16UI: return TKTX_R16_UINT;
1669 | case TINYKTX_GL_INTFORMAT_RG16UI: return TKTX_R16G16_UINT;
1670 | case TINYKTX_GL_INTFORMAT_RGB16UI:return TKTX_R16G16B16_UINT;
1671 | case TINYKTX_GL_INTFORMAT_RGBA16UI: return TKTX_R16G16B16A16_UINT;
1672 |
1673 | case TINYKTX_GL_INTFORMAT_R32UI: return TKTX_R32_UINT;
1674 | case TINYKTX_GL_INTFORMAT_RG32UI: return TKTX_R32G32_UINT;
1675 | case TINYKTX_GL_INTFORMAT_RGB32UI: return TKTX_R32G32B32_UINT;
1676 | case TINYKTX_GL_INTFORMAT_RGBA32UI: return TKTX_R32G32B32A32_UINT;
1677 |
1678 | case TINYKTX_GL_INTFORMAT_R16F: return TKTX_R16_SFLOAT;
1679 | case TINYKTX_GL_INTFORMAT_RG16F: return TKTX_R16G16_SFLOAT;
1680 | case TINYKTX_GL_INTFORMAT_RGB16F: return TKTX_R16G16B16_SFLOAT;
1681 | case TINYKTX_GL_INTFORMAT_RGBA16F: return TKTX_R16G16B16A16_SFLOAT;
1682 |
1683 | case TINYKTX_GL_INTFORMAT_R32F: return TKTX_R32_SFLOAT;
1684 | case TINYKTX_GL_INTFORMAT_RG32F: return TKTX_R32G32_SFLOAT;
1685 | case TINYKTX_GL_INTFORMAT_RGB32F: return TKTX_R32G32B32_SFLOAT;
1686 | case TINYKTX_GL_INTFORMAT_RGBA32F: return TKTX_R32G32B32A32_SFLOAT;
1687 |
1688 | case TINYKTX_GL_INTFORMAT_R11F_G11F_B10F: return TKTX_B10G11R11_UFLOAT_PACK32; //??
1689 | case TINYKTX_GL_INTFORMAT_UNSIGNED_INT_10F_11F_11F_REV: return TKTX_B10G11R11_UFLOAT_PACK32; //?
1690 | case TINYKTX_GL_INTFORMAT_RGB9_E5: return TKTX_E5B9G9R9_UFLOAT_PACK32;
1691 | case TINYKTX_GL_INTFORMAT_SLUMINANCE8_ALPHA8: return TKTX_R8G8_SRGB;
1692 | case TINYKTX_GL_INTFORMAT_SLUMINANCE8: return TKTX_R8_SRGB;
1693 |
1694 | case TINYKTX_GL_INTFORMAT_ALPHA8: return TKTX_R8_UNORM;
1695 | case TINYKTX_GL_INTFORMAT_ALPHA16: return TKTX_R16_UNORM;
1696 | case TINYKTX_GL_INTFORMAT_LUMINANCE8: return TKTX_R8_UNORM;
1697 | case TINYKTX_GL_INTFORMAT_LUMINANCE16: return TKTX_R16_UNORM;
1698 | case TINYKTX_GL_INTFORMAT_LUMINANCE8_ALPHA8: return TKTX_R8G8_UNORM;
1699 | case TINYKTX_GL_INTFORMAT_LUMINANCE16_ALPHA16: return TKTX_R16G16_UNORM;
1700 | case TINYKTX_GL_INTFORMAT_INTENSITY8: return TKTX_R8_UNORM;
1701 | case TINYKTX_GL_INTFORMAT_INTENSITY16: return TKTX_R16_UNORM;
1702 |
1703 | case TINYKTX_GL_INTFORMAT_ALPHA8_SNORM: return TKTX_R8_SNORM;
1704 | case TINYKTX_GL_INTFORMAT_LUMINANCE8_SNORM: return TKTX_R8_SNORM;
1705 | case TINYKTX_GL_INTFORMAT_LUMINANCE8_ALPHA8_SNORM: return TKTX_R8G8_SNORM;
1706 | case TINYKTX_GL_INTFORMAT_INTENSITY8_SNORM: return TKTX_R8_SNORM;
1707 | case TINYKTX_GL_INTFORMAT_ALPHA16_SNORM: return TKTX_R16_SNORM;
1708 | case TINYKTX_GL_INTFORMAT_LUMINANCE16_SNORM: return TKTX_R16_SNORM;
1709 | case TINYKTX_GL_INTFORMAT_LUMINANCE16_ALPHA16_SNORM: return TKTX_R16G16_SNORM;
1710 | case TINYKTX_GL_INTFORMAT_INTENSITY16_SNORM: return TKTX_R16_SNORM;
1711 |
1712 | case TINYKTX_GL_INTFORMAT_SRGB8:
1713 | case TINYKTX_GL_INTFORMAT_SRGB8_ALPHA8:
1714 | if (glformat == TINYKTX_GL_FORMAT_SLUMINANCE) {
1715 | return TKTX_R8_SRGB;
1716 | } else if (glformat == TINYKTX_GL_FORMAT_SLUMINANCE_ALPHA) {
1717 | return TKTX_R8G8_SRGB;
1718 | } else if (glformat == TINYKTX_GL_FORMAT_SRGB) {
1719 | return TKTX_R8G8B8_SRGB;
1720 | } else if (glformat == TINYKTX_GL_FORMAT_SRGB_ALPHA) {
1721 | return TKTX_R8G8B8A8_SRGB;
1722 | } else if (glformat == TINYKTX_GL_FORMAT_BGR) {
1723 | return TKTX_B8G8R8_SRGB;
1724 | } else if (glformat == TINYKTX_GL_FORMAT_BGRA) {
1725 | return TKTX_B8G8R8A8_SRGB;
1726 | } else if (glformat == TINYKTX_GL_FORMAT_ABGR) {
1727 | return TKTX_A8B8G8R8_SRGB_PACK32;
1728 | }
1729 | break;
1730 | case TINYKTX_GL_INTFORMAT_RGB10_A2:
1731 | if(glformat == TINYKTX_GL_FORMAT_BGRA) {
1732 | return TKTX_A2R10G10B10_UNORM_PACK32;
1733 | } else if(glformat == TINYKTX_GL_FORMAT_RGBA) {
1734 | return TKTX_A2B10G10R10_UNORM_PACK32;
1735 | } else if(glformat == TINYKTX_GL_FORMAT_BGRA_INTEGER) {
1736 | return TKTX_A2R10G10B10_UINT_PACK32;
1737 | } else if(glformat == TINYKTX_GL_FORMAT_RGBA_INTEGER) {
1738 | return TKTX_A2B10G10R10_UINT_PACK32;
1739 | }
1740 | break;
1741 |
1742 | // apparently we get FORMAT formats in the internal format slot sometimes
1743 | case TINYKTX_GL_FORMAT_RED:
1744 | switch(gltype) {
1745 | case TINYKTX_GL_TYPE_BYTE: return TKTX_R8_SNORM;
1746 | case TINYKTX_GL_TYPE_UNSIGNED_BYTE: return TKTX_R8_UNORM;
1747 | case TINYKTX_GL_TYPE_SHORT: return TKTX_R16_SNORM;
1748 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT:return TKTX_R16_UNORM;
1749 | case TINYKTX_GL_TYPE_INT: return TKTX_R32_SINT;
1750 | case TINYKTX_GL_TYPE_UNSIGNED_INT: return TKTX_R32_UINT;
1751 | case TINYKTX_GL_TYPE_FLOAT: return TKTX_R32_SFLOAT;
1752 | // case TINYKTX_GL_TYPE_DOUBLE: return TKTX_R64G64B64A64_SFLOAT;
1753 | case TINYKTX_GL_TYPE_HALF_FLOAT: return TKTX_R16_SFLOAT;
1754 | default: return TKTX_UNDEFINED;
1755 | }
1756 | case TINYKTX_GL_FORMAT_RG:
1757 | switch(gltype) {
1758 | case TINYKTX_GL_TYPE_BYTE: return TKTX_R8G8_SNORM;
1759 | case TINYKTX_GL_TYPE_UNSIGNED_BYTE: return TKTX_R8G8_UNORM;
1760 | case TINYKTX_GL_TYPE_SHORT: return TKTX_R16G16_SNORM;
1761 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT:return TKTX_R16G16_UNORM;
1762 | case TINYKTX_GL_TYPE_INT: return TKTX_R32G32_SINT;
1763 | case TINYKTX_GL_TYPE_UNSIGNED_INT: return TKTX_R32G32_UINT;
1764 | case TINYKTX_GL_TYPE_FLOAT: return TKTX_R32G32_SFLOAT;
1765 | // case TINYKTX_GL_TYPE_DOUBLE: return TKTX_R64G64_SFLOAT;
1766 | case TINYKTX_GL_TYPE_HALF_FLOAT: return TKTX_R16G16_SFLOAT;
1767 | default: return TKTX_UNDEFINED;
1768 | }
1769 |
1770 | case TINYKTX_GL_FORMAT_RGB:
1771 | switch(gltype) {
1772 | case TINYKTX_GL_TYPE_BYTE: return TKTX_R8G8B8_SNORM;
1773 | case TINYKTX_GL_TYPE_UNSIGNED_BYTE: return TKTX_R8G8B8_UNORM;
1774 | case TINYKTX_GL_TYPE_SHORT: return TKTX_R16G16B16_SNORM;
1775 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT:return TKTX_R16G16B16_UNORM;
1776 | case TINYKTX_GL_TYPE_INT: return TKTX_R32G32B32_SINT;
1777 | case TINYKTX_GL_TYPE_UNSIGNED_INT: return TKTX_R32G32B32_UINT;
1778 | case TINYKTX_GL_TYPE_FLOAT: return TKTX_R32G32B32_SFLOAT;
1779 | // case TINYKTX_GL_TYPE_DOUBLE: return TKTX_R64G64B64_SFLOAT;
1780 | case TINYKTX_GL_TYPE_HALF_FLOAT: return TKTX_R16G16B16_SFLOAT;
1781 | default: return TKTX_UNDEFINED;
1782 | }
1783 | case TINYKTX_GL_FORMAT_RGBA:
1784 | switch(gltype) {
1785 | case TINYKTX_GL_TYPE_BYTE: return TKTX_R8G8B8A8_SNORM;
1786 | case TINYKTX_GL_TYPE_UNSIGNED_BYTE: return TKTX_R8G8B8A8_UNORM;
1787 | case TINYKTX_GL_TYPE_SHORT: return TKTX_R16G16B16A16_SNORM;
1788 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT:return TKTX_R16G16B16A16_UNORM;
1789 | case TINYKTX_GL_TYPE_INT: return TKTX_R32G32B32A32_SINT;
1790 | case TINYKTX_GL_TYPE_UNSIGNED_INT: return TKTX_R32G32B32A32_UINT;
1791 | case TINYKTX_GL_TYPE_FLOAT: return TKTX_R32G32B32A32_SFLOAT;
1792 | // case TINYKTX_GL_TYPE_DOUBLE: return TKTX_R64G64B64A64_SFLOAT;
1793 | case TINYKTX_GL_TYPE_HALF_FLOAT: return TKTX_R16G16B16A16_SFLOAT;
1794 | default: return TKTX_UNDEFINED;
1795 | }
1796 |
1797 | // can't handle yet
1798 | case TINYKTX_GL_INTFORMAT_ALPHA4:
1799 | case TINYKTX_GL_INTFORMAT_ALPHA12:
1800 | case TINYKTX_GL_INTFORMAT_LUMINANCE4:
1801 | case TINYKTX_GL_INTFORMAT_LUMINANCE12:
1802 | case TINYKTX_GL_INTFORMAT_LUMINANCE4_ALPHA4:
1803 | case TINYKTX_GL_INTFORMAT_LUMINANCE6_ALPHA2:
1804 | case TINYKTX_GL_INTFORMAT_LUMINANCE12_ALPHA4:
1805 | case TINYKTX_GL_INTFORMAT_LUMINANCE12_ALPHA12:
1806 | case TINYKTX_GL_INTFORMAT_INTENSITY4:
1807 | case TINYKTX_GL_INTFORMAT_INTENSITY12:
1808 | case TINYKTX_GL_INTFORMAT_RGB2:
1809 | case TINYKTX_GL_INTFORMAT_RGB5:
1810 | case TINYKTX_GL_INTFORMAT_RGB10:
1811 | case TINYKTX_GL_INTFORMAT_RGB12:
1812 | case TINYKTX_GL_INTFORMAT_RGBA2:
1813 | case TINYKTX_GL_INTFORMAT_RGBA12:
1814 | case TINYKTX_GL_INTFORMAT_FLOAT_32_UNSIGNED_INT_24_8_REV:
1815 | case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2:
1816 | case TINYKTX_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2:
1817 | case TINYKTX_GL_COMPRESSED_ATC_RGB:
1818 | case TINYKTX_GL_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA:
1819 | case TINYKTX_GL_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA:
1820 | default: break;
1821 | }
1822 | return TKTX_UNDEFINED;
1823 | }
1824 |
1825 | uint32_t TinyKtx_ElementCountFromGLFormat(uint32_t fmt){
1826 | switch(fmt) {
1827 | case TINYKTX_GL_FORMAT_RED:
1828 | case TINYKTX_GL_FORMAT_GREEN:
1829 | case TINYKTX_GL_FORMAT_BLUE:
1830 | case TINYKTX_GL_FORMAT_ALPHA:
1831 | case TINYKTX_GL_FORMAT_LUMINANCE:
1832 | case TINYKTX_GL_FORMAT_INTENSITY:
1833 | case TINYKTX_GL_FORMAT_RED_INTEGER:
1834 | case TINYKTX_GL_FORMAT_GREEN_INTEGER:
1835 | case TINYKTX_GL_FORMAT_BLUE_INTEGER:
1836 | case TINYKTX_GL_FORMAT_ALPHA_INTEGER:
1837 | case TINYKTX_GL_FORMAT_SLUMINANCE:
1838 | case TINYKTX_GL_FORMAT_RED_SNORM:
1839 | return 1;
1840 |
1841 | case TINYKTX_GL_FORMAT_RG_INTEGER:
1842 | case TINYKTX_GL_FORMAT_RG:
1843 | case TINYKTX_GL_FORMAT_LUMINANCE_ALPHA:
1844 | case TINYKTX_GL_FORMAT_SLUMINANCE_ALPHA:
1845 | case TINYKTX_GL_FORMAT_RG_SNORM:
1846 | return 2;
1847 |
1848 | case TINYKTX_GL_FORMAT_BGR:
1849 | case TINYKTX_GL_FORMAT_RGB:
1850 | case TINYKTX_GL_FORMAT_SRGB:
1851 | case TINYKTX_GL_FORMAT_RGB_INTEGER:
1852 | case TINYKTX_GL_FORMAT_BGR_INTEGER:
1853 | case TINYKTX_GL_FORMAT_RGB_SNORM:
1854 | return 3;
1855 |
1856 | case TINYKTX_GL_FORMAT_BGRA:
1857 | case TINYKTX_GL_FORMAT_RGBA:
1858 | case TINYKTX_GL_FORMAT_ABGR:
1859 | case TINYKTX_GL_FORMAT_SRGB_ALPHA:
1860 | case TINYKTX_GL_FORMAT_RGBA_INTEGER:
1861 | case TINYKTX_GL_FORMAT_BGRA_INTEGER:
1862 | case TINYKTX_GL_FORMAT_RGBA_SNORM:
1863 | return 4;
1864 | }
1865 |
1866 | return 0;
1867 | }
1868 | bool TinyKtx_ByteDividableFromGLType(uint32_t type){
1869 | switch(type) {
1870 | case TINYKTX_GL_TYPE_COMPRESSED:
1871 | case TINYKTX_GL_TYPE_UNSIGNED_BYTE_3_3_2:
1872 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT_4_4_4_4:
1873 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_5_5_1:
1874 | case TINYKTX_GL_TYPE_UNSIGNED_INT_8_8_8_8:
1875 | case TINYKTX_GL_TYPE_UNSIGNED_INT_10_10_10_2:
1876 | case TINYKTX_GL_TYPE_UNSIGNED_BYTE_2_3_3_REV:
1877 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_6_5:
1878 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT_5_6_5_REV:
1879 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT_4_4_4_4_REV:
1880 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT_1_5_5_5_REV:
1881 | case TINYKTX_GL_TYPE_UNSIGNED_INT_8_8_8_8_REV:
1882 | case TINYKTX_GL_TYPE_UNSIGNED_INT_2_10_10_10_REV:
1883 | case TINYKTX_GL_TYPE_UNSIGNED_INT_24_8:
1884 | case TINYKTX_GL_TYPE_UNSIGNED_INT_5_9_9_9_REV:
1885 | case TINYKTX_GL_TYPE_UNSIGNED_INT_10F_11F_11F_REV:
1886 | case TINYKTX_GL_TYPE_FLOAT_32_UNSIGNED_INT_24_8_REV:
1887 | return false;
1888 | case TINYKTX_GL_TYPE_BYTE:
1889 | case TINYKTX_GL_TYPE_UNSIGNED_BYTE:
1890 | case TINYKTX_GL_TYPE_SHORT:
1891 | case TINYKTX_GL_TYPE_UNSIGNED_SHORT:
1892 | case TINYKTX_GL_TYPE_INT:
1893 | case TINYKTX_GL_TYPE_UNSIGNED_INT:
1894 | case TINYKTX_GL_TYPE_FLOAT:
1895 | case TINYKTX_GL_TYPE_DOUBLE:
1896 | case TINYKTX_GL_TYPE_HALF_FLOAT:
1897 | return true;
1898 | }
1899 | return false;
1900 | }
1901 | TinyKtx_Format TinyKtx_GetFormat(TinyKtx_ContextHandle handle) {
1902 | uint32_t glformat;
1903 | uint32_t gltype;
1904 | uint32_t glinternalformat;
1905 | uint32_t typesize;
1906 | uint32_t glbaseinternalformat;
1907 |
1908 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1909 | if (ctx == NULL)
1910 | return TKTX_UNDEFINED;
1911 |
1912 | if (ctx->headerValid == false) {
1913 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1914 | return TKTX_UNDEFINED;
1915 | }
1916 |
1917 | if(TinyKtx_GetFormatGL(handle, &glformat, &gltype, &glinternalformat, &typesize, &glbaseinternalformat) == false)
1918 | return TKTX_UNDEFINED;
1919 |
1920 | return TinyKtx_CrackFormatFromGL(glformat, gltype, glinternalformat, typesize);
1921 | }
1922 | static uint32_t TinyKtx_MipMapReduce(uint32_t value, uint32_t mipmaplevel) {
1923 |
1924 | // handle 0 being passed in
1925 | if(value <= 1) return 1;
1926 |
1927 | // there are better ways of doing this (log2 etc.) but this doesn't require any
1928 | // dependecies and isn't used enough to matter imho
1929 | for (uint32_t i = 0u; i < mipmaplevel;++i) {
1930 | if(value <= 1) return 1;
1931 | value = value / 2;
1932 | }
1933 | return value;
1934 | }
1935 |
1936 | // KTX specifys GL_UNPACK_ALIGNMENT = 4 which means some files have unexpected padding
1937 | // that probably means you can't just memcpy the data out if you aren't using a GL
1938 | // texture with GL_UNPACK_ALIGNMENT of 4
1939 | // this will be true if this mipmap level is 'unpacked' so has padding on each row
1940 | // you will need to handle.
1941 | bool TinyKtx_IsMipMapLevelUnpacked(TinyKtx_ContextHandle handle, uint32_t mipmaplevel) {
1942 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1943 | if (ctx == NULL)
1944 | return false;
1945 | if (ctx->headerValid == false) {
1946 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1947 | return false;
1948 | }
1949 |
1950 | if (ctx->header.glTypeSize < 4 &&
1951 | TinyKtx_ByteDividableFromGLType(ctx->header.glType)) {
1952 |
1953 | uint32_t const s = ctx->header.glTypeSize;
1954 | uint32_t const n = TinyKtx_ElementCountFromGLFormat(ctx->header.glFormat);
1955 | if (n == 0) {
1956 | ctx->callbacks.errorFn(ctx->user, "TinyKtx_ElementCountFromGLFormat error");
1957 | return false;
1958 | }
1959 |
1960 | uint32_t const w = TinyKtx_MipMapReduce(ctx->header.pixelWidth, mipmaplevel);
1961 | uint32_t const snl = s * n * w;
1962 | uint32_t const k = ((snl + 3u) & ~3u);
1963 |
1964 | if(k != snl) {
1965 | return true;
1966 | }
1967 | }
1968 | return false;
1969 | }
1970 | uint32_t TinyKtx_UnpackedRowStride(TinyKtx_ContextHandle handle, uint32_t mipmaplevel) {
1971 | TinyKtx_Context *ctx = (TinyKtx_Context *) handle;
1972 | if (ctx == NULL)
1973 | return 0;
1974 | if (ctx->headerValid == false) {
1975 | ctx->callbacks.errorFn(ctx->user, "Header data hasn't been read yet or its invalid");
1976 | return 0;
1977 | }
1978 |
1979 | if (ctx->header.glTypeSize < 4 &&
1980 | TinyKtx_ByteDividableFromGLType(ctx->header.glType)) {
1981 |
1982 | uint32_t const s = ctx->header.glTypeSize;
1983 | uint32_t const n = TinyKtx_ElementCountFromGLFormat(ctx->header.glFormat);
1984 | if (n == 0) {
1985 | ctx->callbacks.errorFn(ctx->user, "TinyKtx_ElementCountFromGLFormat error");
1986 | return 0;
1987 | }
1988 |
1989 | uint32_t const w = TinyKtx_MipMapReduce(ctx->header.pixelWidth, mipmaplevel);
1990 | uint32_t const snl = s * n * w;
1991 | uint32_t const k = ((snl + 3u) & ~3u);
1992 | return k;
1993 | }
1994 | return 0;
1995 | }
1996 |
1997 |
1998 | bool TinyKtx_WriteImageGL(TinyKtx_WriteCallbacks const *callbacks,
1999 | void *user,
2000 | uint32_t width,
2001 | uint32_t height,
2002 | uint32_t depth,
2003 | uint32_t slices,
2004 | uint32_t mipmaplevels,
2005 | uint32_t format,
2006 | uint32_t internalFormat,
2007 | uint32_t baseFormat,
2008 | uint32_t type,
2009 | uint32_t typeSize,
2010 | bool cubemap,
2011 | uint32_t const *mipmapsizes,
2012 | void const **mipmaps) {
2013 |
2014 | TinyKtx_Header header;
2015 | memcpy(header.identifier, TinyKtx_fileIdentifier, 12);
2016 | header.endianness = 0x04030201;
2017 | header.glFormat = format;
2018 | header.glInternalFormat = internalFormat;
2019 | header.glBaseInternalFormat = baseFormat;
2020 | header.glType = type;
2021 | header.glTypeSize = typeSize;
2022 | header.pixelWidth = width;
2023 | header.pixelHeight = (height == 1) ? 0 : height;
2024 | header.pixelDepth = (depth == 1) ? 0 : depth;
2025 | header.numberOfArrayElements = (slices == 1) ? 0 : slices;
2026 | header.numberOfFaces = cubemap ? 6 : 1;
2027 | header.numberOfMipmapLevels = mipmaplevels;
2028 | // TODO keyvalue pair data
2029 | header.bytesOfKeyValueData = 0;
2030 | callbacks->writeFn(user, &header, sizeof(TinyKtx_Header));
2031 |
2032 | uint32_t w = (width == 0) ? 1 : width;
2033 | uint32_t h = (height == 0) ? 1 : height;
2034 | uint32_t d = (depth == 0) ? 1 : depth;
2035 | uint32_t sl = (slices == 0) ? 1 : slices;
2036 | static uint8_t const padding[4] = {0, 0, 0, 0};
2037 |
2038 | for (uint32_t i = 0u; i < mipmaplevels; ++i) {
2039 |
2040 | bool writeRaw = true;
2041 |
2042 | if( typeSize < 4 &&
2043 | TinyKtx_ByteDividableFromGLType(type)) {
2044 |
2045 | uint32_t const s = typeSize;
2046 | uint32_t const n = TinyKtx_ElementCountFromGLFormat(format);
2047 | if (n == 0) {
2048 | callbacks->errorFn(user, "TinyKtx_ElementCountFromGLFormat error");
2049 | return false;
2050 | }
2051 | uint32_t const snl = s * n * w;
2052 | uint32_t const k = ((snl + 3u) & ~3u);
2053 |
2054 | uint32_t const size = (k * h * d * snl);
2055 | if (size < mipmapsizes[i]) {
2056 | callbacks->errorFn(user, "Internal size error, padding should only ever expand");
2057 | return false;
2058 | }
2059 |
2060 | // if we need to expand for padding take the slow per row write route
2061 | if (size > mipmapsizes[i]) {
2062 | callbacks->writeFn(user, &size, sizeof(uint32_t));
2063 |
2064 | uint8_t const *src = (uint8_t const*) mipmaps[i];
2065 | for (uint32_t ww = 0u; ww < sl; ++ww) {
2066 | for (uint32_t zz = 0; zz < d; ++zz) {
2067 | for (uint32_t yy = 0; yy < h; ++yy) {
2068 | callbacks->writeFn(user, src, snl);
2069 | callbacks->writeFn(user, padding, k - snl);
2070 | src += snl;
2071 | }
2072 | }
2073 | }
2074 | uint32_t paddCount = ((size + 3u) & ~3u) - size;
2075 | if(paddCount > 3) {
2076 | callbacks->errorFn(user, "Internal error: padding bytes > 3");
2077 | return false;
2078 | }
2079 |
2080 | callbacks->writeFn(user, padding, paddCount);
2081 | writeRaw = false;
2082 | }
2083 | }
2084 |
2085 | if(writeRaw) {
2086 | uint32_t const size = ((mipmapsizes[i] + 3u) & ~3u);
2087 | callbacks->writeFn(user, mipmapsizes + i, sizeof(uint32_t));
2088 | callbacks->writeFn(user, mipmaps[i], mipmapsizes[i]);
2089 | callbacks->writeFn(user, padding, size - mipmapsizes[i]);
2090 | }
2091 |
2092 | if(w > 1) w = w / 2;
2093 | if(h > 1) h = h / 2;
2094 | if(d > 1) d = d / 2;
2095 | }
2096 |
2097 | return true;
2098 | }
2099 |
2100 | bool TinyKtx_WriteImage(TinyKtx_WriteCallbacks const *callbacks,
2101 | void *user,
2102 | uint32_t width,
2103 | uint32_t height,
2104 | uint32_t depth,
2105 | uint32_t slices,
2106 | uint32_t mipmaplevels,
2107 | TinyKtx_Format format,
2108 | bool cubemap,
2109 | uint32_t const *mipmapsizes,
2110 | void const **mipmaps) {
2111 | uint32_t glformat;
2112 | uint32_t glinternalFormat;
2113 | uint32_t gltype;
2114 | uint32_t gltypeSize;
2115 | if (TinyKtx_CrackFormatToGL(format, &glformat, &gltype, &glinternalFormat, &gltypeSize) == false)
2116 | return false;
2117 |
2118 | return TinyKtx_WriteImageGL(callbacks,
2119 | user,
2120 | width,
2121 | height,
2122 | depth,
2123 | slices,
2124 | mipmaplevels,
2125 | glformat,
2126 | glinternalFormat,
2127 | glinternalFormat, //??
2128 | gltype,
2129 | gltypeSize,
2130 | cubemap,
2131 | mipmapsizes,
2132 | mipmaps
2133 | );
2134 |
2135 | }
2136 |
2137 | // tiny_imageformat/tinyimageformat.h pr tinyimageformat_base.h needs included
2138 | // before tinyktx.h for this functionality
2139 | #ifdef TINYIMAGEFORMAT_BASE_H_
2140 | TinyImageFormat TinyImageFormat_FromTinyKtxFormat(TinyKtx_Format format)
2141 | {
2142 | switch(format) {
2143 | case TKTX_UNDEFINED: return TinyImageFormat_UNDEFINED;
2144 | case TKTX_R4G4_UNORM_PACK8: return TinyImageFormat_R4G4_UNORM;
2145 | case TKTX_R4G4B4A4_UNORM_PACK16: return TinyImageFormat_R4G4B4A4_UNORM;
2146 | case TKTX_B4G4R4A4_UNORM_PACK16: return TinyImageFormat_B4G4R4A4_UNORM;
2147 | case TKTX_R5G6B5_UNORM_PACK16: return TinyImageFormat_R5G6B5_UNORM;
2148 | case TKTX_B5G6R5_UNORM_PACK16: return TinyImageFormat_B5G6R5_UNORM;
2149 | case TKTX_R5G5B5A1_UNORM_PACK16: return TinyImageFormat_R5G5B5A1_UNORM;
2150 | case TKTX_B5G5R5A1_UNORM_PACK16: return TinyImageFormat_B5G5R5A1_UNORM;
2151 | case TKTX_A1R5G5B5_UNORM_PACK16: return TinyImageFormat_A1R5G5B5_UNORM;
2152 | case TKTX_R8_UNORM: return TinyImageFormat_R8_UNORM;
2153 | case TKTX_R8_SNORM: return TinyImageFormat_R8_SNORM;
2154 | case TKTX_R8_UINT: return TinyImageFormat_R8_UINT;
2155 | case TKTX_R8_SINT: return TinyImageFormat_R8_SINT;
2156 | case TKTX_R8_SRGB: return TinyImageFormat_R8_SRGB;
2157 | case TKTX_R8G8_UNORM: return TinyImageFormat_R8G8_UNORM;
2158 | case TKTX_R8G8_SNORM: return TinyImageFormat_R8G8_SNORM;
2159 | case TKTX_R8G8_UINT: return TinyImageFormat_R8G8_UINT;
2160 | case TKTX_R8G8_SINT: return TinyImageFormat_R8G8_SINT;
2161 | case TKTX_R8G8_SRGB: return TinyImageFormat_R8G8_SRGB;
2162 | case TKTX_R8G8B8_UNORM: return TinyImageFormat_R8G8B8_UNORM;
2163 | case TKTX_R8G8B8_SNORM: return TinyImageFormat_R8G8B8_SNORM;
2164 | case TKTX_R8G8B8_UINT: return TinyImageFormat_R8G8B8_UINT;
2165 | case TKTX_R8G8B8_SINT: return TinyImageFormat_R8G8B8_SINT;
2166 | case TKTX_R8G8B8_SRGB: return TinyImageFormat_R8G8B8_SRGB;
2167 | case TKTX_B8G8R8_UNORM: return TinyImageFormat_B8G8R8_UNORM;
2168 | case TKTX_B8G8R8_SNORM: return TinyImageFormat_B8G8R8_SNORM;
2169 | case TKTX_B8G8R8_UINT: return TinyImageFormat_B8G8R8_UINT;
2170 | case TKTX_B8G8R8_SINT: return TinyImageFormat_B8G8R8_SINT;
2171 | case TKTX_B8G8R8_SRGB: return TinyImageFormat_B8G8R8_SRGB;
2172 | case TKTX_R8G8B8A8_UNORM: return TinyImageFormat_R8G8B8A8_UNORM;
2173 | case TKTX_R8G8B8A8_SNORM: return TinyImageFormat_R8G8B8A8_SNORM;
2174 | case TKTX_R8G8B8A8_UINT: return TinyImageFormat_R8G8B8A8_UINT;
2175 | case TKTX_R8G8B8A8_SINT: return TinyImageFormat_R8G8B8A8_SINT;
2176 | case TKTX_R8G8B8A8_SRGB: return TinyImageFormat_R8G8B8A8_SRGB;
2177 | case TKTX_B8G8R8A8_UNORM: return TinyImageFormat_B8G8R8A8_UNORM;
2178 | case TKTX_B8G8R8A8_SNORM: return TinyImageFormat_B8G8R8A8_SNORM;
2179 | case TKTX_B8G8R8A8_UINT: return TinyImageFormat_B8G8R8A8_UINT;
2180 | case TKTX_B8G8R8A8_SINT: return TinyImageFormat_B8G8R8A8_SINT;
2181 | case TKTX_B8G8R8A8_SRGB: return TinyImageFormat_B8G8R8A8_SRGB;
2182 | case TKTX_E5B9G9R9_UFLOAT_PACK32: return TinyImageFormat_E5B9G9R9_UFLOAT;
2183 | case TKTX_A2R10G10B10_UNORM_PACK32: return TinyImageFormat_B10G10R10A2_UNORM;
2184 | case TKTX_A2R10G10B10_UINT_PACK32: return TinyImageFormat_B10G10R10A2_UINT;
2185 | case TKTX_A2B10G10R10_UNORM_PACK32: return TinyImageFormat_R10G10B10A2_UNORM;
2186 | case TKTX_A2B10G10R10_UINT_PACK32: return TinyImageFormat_R10G10B10A2_UINT;
2187 | case TKTX_B10G11R11_UFLOAT_PACK32: return TinyImageFormat_B10G11R11_UFLOAT;
2188 | case TKTX_R16_UNORM: return TinyImageFormat_R16_UNORM;
2189 | case TKTX_R16_SNORM: return TinyImageFormat_R16_SNORM;
2190 | case TKTX_R16_UINT: return TinyImageFormat_R16_UINT;
2191 | case TKTX_R16_SINT: return TinyImageFormat_R16_SINT;
2192 | case TKTX_R16_SFLOAT: return TinyImageFormat_R16_SFLOAT;
2193 | case TKTX_R16G16_UNORM: return TinyImageFormat_R16G16_UNORM;
2194 | case TKTX_R16G16_SNORM: return TinyImageFormat_R16G16_SNORM;
2195 | case TKTX_R16G16_UINT: return TinyImageFormat_R16G16_UINT;
2196 | case TKTX_R16G16_SINT: return TinyImageFormat_R16G16_SINT;
2197 | case TKTX_R16G16_SFLOAT: return TinyImageFormat_R16G16_SFLOAT;
2198 | case TKTX_R16G16B16_UNORM: return TinyImageFormat_R16G16B16_UNORM;
2199 | case TKTX_R16G16B16_SNORM: return TinyImageFormat_R16G16B16_SNORM;
2200 | case TKTX_R16G16B16_UINT: return TinyImageFormat_R16G16B16_UINT;
2201 | case TKTX_R16G16B16_SINT: return TinyImageFormat_R16G16B16_SINT;
2202 | case TKTX_R16G16B16_SFLOAT: return TinyImageFormat_R16G16B16_SFLOAT;
2203 | case TKTX_R16G16B16A16_UNORM: return TinyImageFormat_R16G16B16A16_UNORM;
2204 | case TKTX_R16G16B16A16_SNORM: return TinyImageFormat_R16G16B16A16_SNORM;
2205 | case TKTX_R16G16B16A16_UINT: return TinyImageFormat_R16G16B16A16_UINT;
2206 | case TKTX_R16G16B16A16_SINT: return TinyImageFormat_R16G16B16A16_SINT;
2207 | case TKTX_R16G16B16A16_SFLOAT: return TinyImageFormat_R16G16B16A16_SFLOAT;
2208 | case TKTX_R32_UINT: return TinyImageFormat_R32_UINT;
2209 | case TKTX_R32_SINT: return TinyImageFormat_R32_SINT;
2210 | case TKTX_R32_SFLOAT: return TinyImageFormat_R32_SFLOAT;
2211 | case TKTX_R32G32_UINT: return TinyImageFormat_R32G32_UINT;
2212 | case TKTX_R32G32_SINT: return TinyImageFormat_R32G32_SINT;
2213 | case TKTX_R32G32_SFLOAT: return TinyImageFormat_R32G32_SFLOAT;
2214 | case TKTX_R32G32B32_UINT: return TinyImageFormat_R32G32B32_UINT;
2215 | case TKTX_R32G32B32_SINT: return TinyImageFormat_R32G32B32_SINT;
2216 | case TKTX_R32G32B32_SFLOAT: return TinyImageFormat_R32G32B32_SFLOAT;
2217 | case TKTX_R32G32B32A32_UINT: return TinyImageFormat_R32G32B32A32_UINT;
2218 | case TKTX_R32G32B32A32_SINT: return TinyImageFormat_R32G32B32A32_SINT;
2219 | case TKTX_R32G32B32A32_SFLOAT: return TinyImageFormat_R32G32B32A32_SFLOAT;
2220 | case TKTX_BC1_RGB_UNORM_BLOCK: return TinyImageFormat_DXBC1_RGB_UNORM;
2221 | case TKTX_BC1_RGB_SRGB_BLOCK: return TinyImageFormat_DXBC1_RGB_SRGB;
2222 | case TKTX_BC1_RGBA_UNORM_BLOCK: return TinyImageFormat_DXBC1_RGBA_UNORM;
2223 | case TKTX_BC1_RGBA_SRGB_BLOCK: return TinyImageFormat_DXBC1_RGBA_SRGB;
2224 | case TKTX_BC2_UNORM_BLOCK: return TinyImageFormat_DXBC2_UNORM;
2225 | case TKTX_BC2_SRGB_BLOCK: return TinyImageFormat_DXBC2_SRGB;
2226 | case TKTX_BC3_UNORM_BLOCK: return TinyImageFormat_DXBC3_UNORM;
2227 | case TKTX_BC3_SRGB_BLOCK: return TinyImageFormat_DXBC3_SRGB;
2228 | case TKTX_BC4_UNORM_BLOCK: return TinyImageFormat_DXBC4_UNORM;
2229 | case TKTX_BC4_SNORM_BLOCK: return TinyImageFormat_DXBC4_SNORM;
2230 | case TKTX_BC5_UNORM_BLOCK: return TinyImageFormat_DXBC5_UNORM;
2231 | case TKTX_BC5_SNORM_BLOCK: return TinyImageFormat_DXBC5_SNORM;
2232 | case TKTX_BC6H_UFLOAT_BLOCK: return TinyImageFormat_DXBC6H_UFLOAT;
2233 | case TKTX_BC6H_SFLOAT_BLOCK: return TinyImageFormat_DXBC6H_SFLOAT;
2234 | case TKTX_BC7_UNORM_BLOCK: return TinyImageFormat_DXBC7_UNORM;
2235 | case TKTX_BC7_SRGB_BLOCK: return TinyImageFormat_DXBC7_SRGB;
2236 | case TKTX_PVR_2BPP_UNORM_BLOCK: return TinyImageFormat_PVRTC1_2BPP_UNORM;
2237 | case TKTX_PVR_2BPPA_UNORM_BLOCK: return TinyImageFormat_PVRTC1_2BPP_UNORM;
2238 | case TKTX_PVR_4BPP_UNORM_BLOCK: return TinyImageFormat_PVRTC1_4BPP_UNORM;
2239 | case TKTX_PVR_4BPPA_UNORM_BLOCK: return TinyImageFormat_PVRTC1_4BPP_UNORM;
2240 | case TKTX_PVR_2BPP_SRGB_BLOCK: return TinyImageFormat_PVRTC1_2BPP_SRGB;
2241 | case TKTX_PVR_2BPPA_SRGB_BLOCK: return TinyImageFormat_PVRTC1_2BPP_SRGB;
2242 | case TKTX_PVR_4BPP_SRGB_BLOCK: return TinyImageFormat_PVRTC1_4BPP_SRGB;
2243 | case TKTX_PVR_4BPPA_SRGB_BLOCK: return TinyImageFormat_PVRTC1_4BPP_SRGB;
2244 |
2245 | case TKTX_ETC2_R8G8B8_UNORM_BLOCK: return TinyImageFormat_ETC2_R8G8B8_UNORM;
2246 | case TKTX_ETC2_R8G8B8A1_UNORM_BLOCK: return TinyImageFormat_ETC2_R8G8B8A1_UNORM;
2247 | case TKTX_ETC2_R8G8B8A8_UNORM_BLOCK: return TinyImageFormat_ETC2_R8G8B8A8_UNORM;
2248 | case TKTX_ETC2_R8G8B8_SRGB_BLOCK: return TinyImageFormat_ETC2_R8G8B8_SRGB;
2249 | case TKTX_ETC2_R8G8B8A1_SRGB_BLOCK: return TinyImageFormat_ETC2_R8G8B8A1_SRGB;
2250 | case TKTX_ETC2_R8G8B8A8_SRGB_BLOCK: return TinyImageFormat_ETC2_R8G8B8A8_SRGB;
2251 | case TKTX_EAC_R11_UNORM_BLOCK: return TinyImageFormat_ETC2_EAC_R11_UNORM;
2252 | case TKTX_EAC_R11G11_UNORM_BLOCK: return TinyImageFormat_ETC2_EAC_R11G11_UNORM;
2253 | case TKTX_EAC_R11_SNORM_BLOCK: return TinyImageFormat_ETC2_EAC_R11_SNORM;
2254 | case TKTX_EAC_R11G11_SNORM_BLOCK: return TinyImageFormat_ETC2_EAC_R11G11_SNORM;
2255 | case TKTX_ASTC_4x4_UNORM_BLOCK: return TinyImageFormat_ASTC_4x4_UNORM;
2256 | case TKTX_ASTC_4x4_SRGB_BLOCK: return TinyImageFormat_ASTC_4x4_SRGB;
2257 | case TKTX_ASTC_5x4_UNORM_BLOCK: return TinyImageFormat_ASTC_5x4_UNORM;
2258 | case TKTX_ASTC_5x4_SRGB_BLOCK: return TinyImageFormat_ASTC_5x4_SRGB;
2259 | case TKTX_ASTC_5x5_UNORM_BLOCK: return TinyImageFormat_ASTC_5x5_UNORM;
2260 | case TKTX_ASTC_5x5_SRGB_BLOCK: return TinyImageFormat_ASTC_5x5_SRGB;
2261 | case TKTX_ASTC_6x5_UNORM_BLOCK: return TinyImageFormat_ASTC_6x5_UNORM;
2262 | case TKTX_ASTC_6x5_SRGB_BLOCK: return TinyImageFormat_ASTC_6x5_SRGB;
2263 | case TKTX_ASTC_6x6_UNORM_BLOCK: return TinyImageFormat_ASTC_6x6_UNORM;
2264 | case TKTX_ASTC_6x6_SRGB_BLOCK: return TinyImageFormat_ASTC_6x6_SRGB;
2265 | case TKTX_ASTC_8x5_UNORM_BLOCK: return TinyImageFormat_ASTC_8x5_UNORM;
2266 | case TKTX_ASTC_8x5_SRGB_BLOCK: return TinyImageFormat_ASTC_8x5_SRGB;
2267 | case TKTX_ASTC_8x6_UNORM_BLOCK: return TinyImageFormat_ASTC_8x6_UNORM;
2268 | case TKTX_ASTC_8x6_SRGB_BLOCK: return TinyImageFormat_ASTC_8x6_SRGB;
2269 | case TKTX_ASTC_8x8_UNORM_BLOCK: return TinyImageFormat_ASTC_8x8_UNORM;
2270 | case TKTX_ASTC_8x8_SRGB_BLOCK: return TinyImageFormat_ASTC_8x8_SRGB;
2271 | case TKTX_ASTC_10x5_UNORM_BLOCK: return TinyImageFormat_ASTC_10x5_UNORM;
2272 | case TKTX_ASTC_10x5_SRGB_BLOCK: return TinyImageFormat_ASTC_10x5_SRGB;
2273 | case TKTX_ASTC_10x6_UNORM_BLOCK: return TinyImageFormat_ASTC_10x6_UNORM;
2274 | case TKTX_ASTC_10x6_SRGB_BLOCK: return TinyImageFormat_ASTC_10x6_SRGB;
2275 | case TKTX_ASTC_10x8_UNORM_BLOCK: return TinyImageFormat_ASTC_10x8_UNORM;
2276 | case TKTX_ASTC_10x8_SRGB_BLOCK: return TinyImageFormat_ASTC_10x8_SRGB;
2277 | case TKTX_ASTC_10x10_UNORM_BLOCK: return TinyImageFormat_ASTC_10x10_UNORM;
2278 | case TKTX_ASTC_10x10_SRGB_BLOCK: return TinyImageFormat_ASTC_10x10_SRGB;
2279 | case TKTX_ASTC_12x10_UNORM_BLOCK: return TinyImageFormat_ASTC_12x10_UNORM;
2280 | case TKTX_ASTC_12x10_SRGB_BLOCK: return TinyImageFormat_ASTC_12x10_SRGB;
2281 | case TKTX_ASTC_12x12_UNORM_BLOCK: return TinyImageFormat_ASTC_12x12_UNORM;
2282 | case TKTX_ASTC_12x12_SRGB_BLOCK: return TinyImageFormat_ASTC_12x12_SRGB;
2283 |
2284 | case TKTX_A8B8G8R8_UNORM_PACK32:break;
2285 | case TKTX_A8B8G8R8_SNORM_PACK32:break;
2286 | case TKTX_A8B8G8R8_UINT_PACK32:break;
2287 | case TKTX_A8B8G8R8_SINT_PACK32:break;
2288 | case TKTX_A8B8G8R8_SRGB_PACK32:break;
2289 | }
2290 |
2291 | return TinyImageFormat_UNDEFINED;
2292 | }
2293 |
2294 | TinyKtx_Format TinyImageFormat_ToTinyKtxFormat(TinyImageFormat format) {
2295 |
2296 | switch (format) {
2297 | case TinyImageFormat_UNDEFINED: return TKTX_UNDEFINED;
2298 | case TinyImageFormat_R4G4_UNORM: return TKTX_R4G4_UNORM_PACK8;
2299 | case TinyImageFormat_R4G4B4A4_UNORM: return TKTX_R4G4B4A4_UNORM_PACK16;
2300 | case TinyImageFormat_B4G4R4A4_UNORM: return TKTX_B4G4R4A4_UNORM_PACK16;
2301 | case TinyImageFormat_R5G6B5_UNORM: return TKTX_R5G6B5_UNORM_PACK16;
2302 | case TinyImageFormat_B5G6R5_UNORM: return TKTX_B5G6R5_UNORM_PACK16;
2303 | case TinyImageFormat_R5G5B5A1_UNORM: return TKTX_R5G5B5A1_UNORM_PACK16;
2304 | case TinyImageFormat_B5G5R5A1_UNORM: return TKTX_B5G5R5A1_UNORM_PACK16;
2305 | case TinyImageFormat_A1R5G5B5_UNORM: return TKTX_A1R5G5B5_UNORM_PACK16;
2306 | case TinyImageFormat_R8_UNORM: return TKTX_R8_UNORM;
2307 | case TinyImageFormat_R8_SNORM: return TKTX_R8_SNORM;
2308 | case TinyImageFormat_R8_UINT: return TKTX_R8_UINT;
2309 | case TinyImageFormat_R8_SINT: return TKTX_R8_SINT;
2310 | case TinyImageFormat_R8_SRGB: return TKTX_R8_SRGB;
2311 | case TinyImageFormat_R8G8_UNORM: return TKTX_R8G8_UNORM;
2312 | case TinyImageFormat_R8G8_SNORM: return TKTX_R8G8_SNORM;
2313 | case TinyImageFormat_R8G8_UINT: return TKTX_R8G8_UINT;
2314 | case TinyImageFormat_R8G8_SINT: return TKTX_R8G8_SINT;
2315 | case TinyImageFormat_R8G8_SRGB: return TKTX_R8G8_SRGB;
2316 | case TinyImageFormat_R8G8B8_UNORM: return TKTX_R8G8B8_UNORM;
2317 | case TinyImageFormat_R8G8B8_SNORM: return TKTX_R8G8B8_SNORM;
2318 | case TinyImageFormat_R8G8B8_UINT: return TKTX_R8G8B8_UINT;
2319 | case TinyImageFormat_R8G8B8_SINT: return TKTX_R8G8B8_SINT;
2320 | case TinyImageFormat_R8G8B8_SRGB: return TKTX_R8G8B8_SRGB;
2321 | case TinyImageFormat_B8G8R8_UNORM: return TKTX_B8G8R8_UNORM;
2322 | case TinyImageFormat_B8G8R8_SNORM: return TKTX_B8G8R8_SNORM;
2323 | case TinyImageFormat_B8G8R8_UINT: return TKTX_B8G8R8_UINT;
2324 | case TinyImageFormat_B8G8R8_SINT: return TKTX_B8G8R8_SINT;
2325 | case TinyImageFormat_B8G8R8_SRGB: return TKTX_B8G8R8_SRGB;
2326 | case TinyImageFormat_R8G8B8A8_UNORM: return TKTX_R8G8B8A8_UNORM;
2327 | case TinyImageFormat_R8G8B8A8_SNORM: return TKTX_R8G8B8A8_SNORM;
2328 | case TinyImageFormat_R8G8B8A8_UINT: return TKTX_R8G8B8A8_UINT;
2329 | case TinyImageFormat_R8G8B8A8_SINT: return TKTX_R8G8B8A8_SINT;
2330 | case TinyImageFormat_R8G8B8A8_SRGB: return TKTX_R8G8B8A8_SRGB;
2331 | case TinyImageFormat_B8G8R8A8_UNORM: return TKTX_B8G8R8A8_UNORM;
2332 | case TinyImageFormat_B8G8R8A8_SNORM: return TKTX_B8G8R8A8_SNORM;
2333 | case TinyImageFormat_B8G8R8A8_UINT: return TKTX_B8G8R8A8_UINT;
2334 | case TinyImageFormat_B8G8R8A8_SINT: return TKTX_B8G8R8A8_SINT;
2335 | case TinyImageFormat_B8G8R8A8_SRGB: return TKTX_B8G8R8A8_SRGB;
2336 | case TinyImageFormat_R10G10B10A2_UNORM: return TKTX_A2B10G10R10_UNORM_PACK32;
2337 | case TinyImageFormat_R10G10B10A2_UINT: return TKTX_A2B10G10R10_UINT_PACK32;
2338 | case TinyImageFormat_B10G10R10A2_UNORM: return TKTX_A2R10G10B10_UNORM_PACK32;
2339 | case TinyImageFormat_B10G10R10A2_UINT: return TKTX_A2R10G10B10_UINT_PACK32;
2340 | case TinyImageFormat_R16_UNORM: return TKTX_R16_UNORM;
2341 | case TinyImageFormat_R16_SNORM: return TKTX_R16_SNORM;
2342 | case TinyImageFormat_R16_UINT: return TKTX_R16_UINT;
2343 | case TinyImageFormat_R16_SINT: return TKTX_R16_SINT;
2344 | case TinyImageFormat_R16_SFLOAT: return TKTX_R16_SFLOAT;
2345 | case TinyImageFormat_R16G16_UNORM: return TKTX_R16G16_UNORM;
2346 | case TinyImageFormat_R16G16_SNORM: return TKTX_R16G16_SNORM;
2347 | case TinyImageFormat_R16G16_UINT: return TKTX_R16G16_UINT;
2348 | case TinyImageFormat_R16G16_SINT: return TKTX_R16G16_SINT;
2349 | case TinyImageFormat_R16G16_SFLOAT: return TKTX_R16G16_SFLOAT;
2350 | case TinyImageFormat_R16G16B16_UNORM: return TKTX_R16G16B16_UNORM;
2351 | case TinyImageFormat_R16G16B16_SNORM: return TKTX_R16G16B16_SNORM;
2352 | case TinyImageFormat_R16G16B16_UINT: return TKTX_R16G16B16_UINT;
2353 | case TinyImageFormat_R16G16B16_SINT: return TKTX_R16G16B16_SINT;
2354 | case TinyImageFormat_R16G16B16_SFLOAT: return TKTX_R16G16B16_SFLOAT;
2355 | case TinyImageFormat_R16G16B16A16_UNORM: return TKTX_R16G16B16A16_UNORM;
2356 | case TinyImageFormat_R16G16B16A16_SNORM: return TKTX_R16G16B16A16_SNORM;
2357 | case TinyImageFormat_R16G16B16A16_UINT: return TKTX_R16G16B16A16_UINT;
2358 | case TinyImageFormat_R16G16B16A16_SINT: return TKTX_R16G16B16A16_SINT;
2359 | case TinyImageFormat_R16G16B16A16_SFLOAT: return TKTX_R16G16B16A16_SFLOAT;
2360 | case TinyImageFormat_R32_UINT: return TKTX_R32_UINT;
2361 | case TinyImageFormat_R32_SINT: return TKTX_R32_SINT;
2362 | case TinyImageFormat_R32_SFLOAT: return TKTX_R32_SFLOAT;
2363 | case TinyImageFormat_R32G32_UINT: return TKTX_R32G32_UINT;
2364 | case TinyImageFormat_R32G32_SINT: return TKTX_R32G32_SINT;
2365 | case TinyImageFormat_R32G32_SFLOAT: return TKTX_R32G32_SFLOAT;
2366 | case TinyImageFormat_R32G32B32_UINT: return TKTX_R32G32B32_UINT;
2367 | case TinyImageFormat_R32G32B32_SINT: return TKTX_R32G32B32_SINT;
2368 | case TinyImageFormat_R32G32B32_SFLOAT: return TKTX_R32G32B32_SFLOAT;
2369 | case TinyImageFormat_R32G32B32A32_UINT: return TKTX_R32G32B32A32_UINT;
2370 | case TinyImageFormat_R32G32B32A32_SINT: return TKTX_R32G32B32A32_SINT;
2371 | case TinyImageFormat_R32G32B32A32_SFLOAT: return TKTX_R32G32B32A32_SFLOAT;
2372 | case TinyImageFormat_B10G11R11_UFLOAT: return TKTX_B10G11R11_UFLOAT_PACK32;
2373 | case TinyImageFormat_E5B9G9R9_UFLOAT: return TKTX_E5B9G9R9_UFLOAT_PACK32;
2374 |
2375 | case TinyImageFormat_DXBC1_RGB_UNORM: return TKTX_BC1_RGB_UNORM_BLOCK;
2376 | case TinyImageFormat_DXBC1_RGB_SRGB: return TKTX_BC1_RGB_SRGB_BLOCK;
2377 | case TinyImageFormat_DXBC1_RGBA_UNORM: return TKTX_BC1_RGBA_UNORM_BLOCK;
2378 | case TinyImageFormat_DXBC1_RGBA_SRGB: return TKTX_BC1_RGBA_SRGB_BLOCK;
2379 | case TinyImageFormat_DXBC2_UNORM: return TKTX_BC2_UNORM_BLOCK;
2380 | case TinyImageFormat_DXBC2_SRGB: return TKTX_BC2_SRGB_BLOCK;
2381 | case TinyImageFormat_DXBC3_UNORM: return TKTX_BC3_UNORM_BLOCK;
2382 | case TinyImageFormat_DXBC3_SRGB: return TKTX_BC3_SRGB_BLOCK;
2383 | case TinyImageFormat_DXBC4_UNORM: return TKTX_BC4_UNORM_BLOCK;
2384 | case TinyImageFormat_DXBC4_SNORM: return TKTX_BC4_SNORM_BLOCK;
2385 | case TinyImageFormat_DXBC5_UNORM: return TKTX_BC5_UNORM_BLOCK;
2386 | case TinyImageFormat_DXBC5_SNORM: return TKTX_BC5_SNORM_BLOCK;
2387 | case TinyImageFormat_DXBC6H_UFLOAT: return TKTX_BC6H_UFLOAT_BLOCK;
2388 | case TinyImageFormat_DXBC6H_SFLOAT: return TKTX_BC6H_SFLOAT_BLOCK;
2389 | case TinyImageFormat_DXBC7_UNORM: return TKTX_BC7_UNORM_BLOCK;
2390 | case TinyImageFormat_DXBC7_SRGB: return TKTX_BC7_SRGB_BLOCK;
2391 | case TinyImageFormat_PVRTC1_2BPP_UNORM: return TKTX_PVR_2BPPA_UNORM_BLOCK;
2392 | case TinyImageFormat_PVRTC1_4BPP_UNORM: return TKTX_PVR_4BPPA_UNORM_BLOCK;
2393 | case TinyImageFormat_PVRTC1_2BPP_SRGB: return TKTX_PVR_2BPPA_SRGB_BLOCK;
2394 | case TinyImageFormat_PVRTC1_4BPP_SRGB: return TKTX_PVR_4BPPA_SRGB_BLOCK;
2395 |
2396 | default: return TKTX_UNDEFINED;
2397 | };
2398 |
2399 | return TKTX_UNDEFINED;
2400 | }
2401 | #endif // end TinyImageFormat conversion
2402 |
2403 | #endif // end implementation
2404 |
2405 | #ifdef __cplusplus
2406 | };
2407 | #endif
2408 |
2409 | #endif // end header
2410 | /*
2411 | MIT License
2412 |
2413 | Copyright (c) 2019 DeanoC
2414 |
2415 | Permission is hereby granted, free of charge, to any person obtaining a copy
2416 | of this software and associated documentation files (the "Software"), to deal
2417 | in the Software without restriction, including without limitation the rights
2418 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2419 | copies of the Software, and to permit persons to whom the Software is
2420 | furnished to do so, subject to the following conditions:
2421 |
2422 | The above copyright notice and this permission notice shall be included in all
2423 | copies or substantial portions of the Software.
2424 |
2425 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2426 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2427 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2428 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2429 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2430 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2431 | SOFTWARE.
2432 | */
2433 |
--------------------------------------------------------------------------------
/include/tiny_ktx/tinyktx2.h:
--------------------------------------------------------------------------------
1 | // MIT license see full LICENSE text at end of file
2 | #pragma once
3 | #ifndef TINY_KTX_TINYKTX2_H
4 | #define TINY_KTX_TINYKTX2_H
5 |
6 | #ifndef TINYKTX_HAVE_UINTXX_T
7 | #include // for uint32_t and int64_t
8 | #endif
9 | #ifndef TINYKTX_HAVE_BOOL
10 | #include // for bool
11 | #endif
12 | #ifndef TINYKTX_HAVE_SIZE_T
13 | #include // for size_t
14 | #endif
15 | #ifndef TINYKTX_HAVE_MEMCPY
16 | #include // for memcpy
17 | #endif
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | typedef struct TinyKtx2_Context *TinyKtx2_ContextHandle;
24 |
25 | #define TINYKTX2_MAX_MIPMAPLEVELS 16
26 |
27 | typedef void *(*TinyKtx2_AllocFunc)(void *user, size_t size);
28 | typedef void (*TinyKtx2_FreeFunc)(void *user, void *memory);
29 | typedef size_t (*TinyKtx2_ReadFunc)(void *user, void *buffer, size_t byteCount);
30 | typedef bool (*TinyKtx2_SeekFunc)(void *user, int64_t offset);
31 | typedef int64_t (*TinyKtx2_TellFunc)(void *user);
32 | typedef void (*TinyKtx2_ErrorFunc)(void *user, char const *msg);
33 | typedef bool (*TinyKtx2_SuperDecompress)(void* user, void* const sgdData, void const* src, size_t srcSize, void const* dst, size_t dstSize);
34 |
35 | typedef struct TinyKtx2_SuperDecompressTableEntry {
36 | uint32_t superId;
37 | TinyKtx2_SuperDecompress decompressor;
38 | } TinyKtx2_SuperDecompressTableEntry;
39 |
40 | typedef struct TinyKtx2_Callbacks {
41 | TinyKtx2_ErrorFunc error;
42 | TinyKtx2_AllocFunc alloc;
43 | TinyKtx2_FreeFunc free;
44 | TinyKtx2_ReadFunc read;
45 | TinyKtx2_SeekFunc seek;
46 | TinyKtx2_TellFunc tell;
47 |
48 | size_t numSuperDecompressors;
49 | TinyKtx2_SuperDecompressTableEntry const* superDecompressors;
50 | } TinyKtx2_Callbacks;
51 |
52 | TinyKtx2_ContextHandle TinyKtx2_CreateContext(TinyKtx2_Callbacks const *callbacks, void *user);
53 | void TinyKtx2_DestroyContext(TinyKtx_ContextHandle handle);
54 |
55 | // reset lets you reuse the context for another file (saves an alloc/free cycle)
56 | void TinyKtx2_Reset(TinyKtx2_ContextHandle handle);
57 |
58 | // call this to read the header file should already be at the start of the KTX data
59 | bool TinyKtx2_ReadHeader(TinyKtx2_ContextHandle handle);
60 |
61 | // this is slow linear search. TODO add iterator style reading of key value pairs
62 | bool TinyKtx2_GetValue(TinyKtx2_ContextHandle handle, char const *key, void const **value);
63 |
64 | bool TinyKtx2_Is1D(TinyKtx2_ContextHandle handle);
65 | bool TinyKtx2_Is2D(TinyKtx2_ContextHandle handle);
66 | bool TinyKtx2_Is3D(TinyKtx2_ContextHandle handle);
67 | bool TinyKtx2_IsCubemap(TinyKtx2_ContextHandle handle);
68 | bool TinyKtx2_IsArray(TinyKtx2_ContextHandle handle);
69 |
70 | bool TinyKtx2_Dimensions(TinyKtx2_ContextHandle handle, uint32_t* width, uint32_t* height, uint32_t* depth, uint32_t* slices);
71 | uint32_t TinyKtx2_Width(TinyKtx2_ContextHandle handle);
72 | uint32_t TinyKtx2_Height(TinyKtx2_ContextHandle handle);
73 | uint32_t TinyKtx2_Depth(TinyKtx2_ContextHandle handle);
74 | uint32_t TinyKtx2_ArraySlices(TinyKtx2_ContextHandle handle);
75 |
76 | bool TinyKtx2_GetFormatGL(TinyKtx2_ContextHandle handle, uint32_t *glformat, uint32_t *gltype, uint32_t *glinternalformat, uint32_t* typesize, uint32_t* glbaseinternalformat);
77 |
78 | bool TinyKtx2_NeedsGenerationOfMipmaps(TinyKtx2_ContextHandle handle);
79 | bool TinyKtx2_NeedsEndianCorrecting(TinyKtx2_ContextHandle handle);
80 |
81 | uint32_t TinyKtx2_NumberOfMipmaps(TinyKtx2_ContextHandle handle);
82 | uint32_t TinyKtx2_ImageSize(TinyKtx2_ContextHandle handle, uint32_t mipmaplevel);
83 |
84 | bool TinyKtx2_IsMipMapLevelUnpacked(TinyKtx2_ContextHandle handle, uint32_t mipmaplevel);
85 | // this is required to read Unpacked data correctly
86 | uint32_t TinyKtx2_UnpackedRowStride(TinyKtx2_ContextHandle handle, uint32_t mipmaplevel);
87 |
88 | // data return by ImageRawData is owned by the context. Don't free it!
89 | void const *TinyKtx2_ImageRawData(TinyKtx2_ContextHandle handle, uint32_t mipmaplevel);
90 |
91 | typedef void (*TinyKtx2_WriteFunc)(void *user, void const *buffer, size_t byteCount);
92 |
93 | typedef struct TinyKtx2_WriteCallbacks {
94 | TinyKtx2_ErrorFunc error;
95 | TinyKtx2_AllocFunc alloc;
96 | TinyKtx2_FreeFunc free;
97 | TinyKtx2_WriteFunc write;
98 | } TinyKtx2_WriteCallbacks;
99 |
100 |
101 | bool TinyKtx2_WriteImageGL(TinyKtx2_WriteCallbacks const *callbacks,
102 | void *user,
103 | uint32_t width,
104 | uint32_t height,
105 | uint32_t depth,
106 | uint32_t slices,
107 | uint32_t mipmaplevels,
108 | uint32_t format,
109 | uint32_t internalFormat,
110 | uint32_t baseFormat,
111 | uint32_t type,
112 | uint32_t typeSize,
113 | bool cubemap,
114 | uint32_t const *mipmapsizes,
115 | void const **mipmaps);
116 |
117 | // ktx v1 is based on GL (slightly confusing imho) texture format system
118 | // there is format, internal format, type etc.
119 |
120 | // we try and expose a more dx12/vulkan/metal style of format
121 | // but obviously still need to GL data so bare with me.
122 | // a TinyKTX_Format is the equivilent to GL/KTX Format and Type
123 | // the API doesn't expose the actual values (which come from GL itself)
124 | // but provide an API call to crack them back into the actual GL values).
125 |
126 | // Ktx v2 is based on VkFormat and also DFD, so we now base the
127 | // enumeration values of TinyKtx_Format on the Vkformat values where possible
128 |
129 | #ifndef TINYKTX_DEFINED
130 | typedef enum TinyImageFormat_VkFormat {
131 | TIF_VK_FORMAT_UNDEFINED = 0,
132 | TIF_VK_FORMAT_R4G4_UNORM_PACK8 = 1,
133 | TIF_VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
134 | TIF_VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
135 | TIF_VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
136 | TIF_VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
137 | TIF_VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
138 | TIF_VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
139 | TIF_VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
140 | TIF_VK_FORMAT_R8_UNORM = 9,
141 | TIF_VK_FORMAT_R8_SNORM = 10,
142 | TIF_VK_FORMAT_R8_USCALED = 11,
143 | TIF_VK_FORMAT_R8_SSCALED = 12,
144 | TIF_VK_FORMAT_R8_UINT = 13,
145 | TIF_VK_FORMAT_R8_SINT = 14,
146 | TIF_VK_FORMAT_R8_SRGB = 15,
147 | TIF_VK_FORMAT_R8G8_UNORM = 16,
148 | TIF_VK_FORMAT_R8G8_SNORM = 17,
149 | TIF_VK_FORMAT_R8G8_USCALED = 18,
150 | TIF_VK_FORMAT_R8G8_SSCALED = 19,
151 | TIF_VK_FORMAT_R8G8_UINT = 20,
152 | TIF_VK_FORMAT_R8G8_SINT = 21,
153 | TIF_VK_FORMAT_R8G8_SRGB = 22,
154 | TIF_VK_FORMAT_R8G8B8_UNORM = 23,
155 | TIF_VK_FORMAT_R8G8B8_SNORM = 24,
156 | TIF_VK_FORMAT_R8G8B8_USCALED = 25,
157 | TIF_VK_FORMAT_R8G8B8_SSCALED = 26,
158 | TIF_VK_FORMAT_R8G8B8_UINT = 27,
159 | TIF_VK_FORMAT_R8G8B8_SINT = 28,
160 | TIF_VK_FORMAT_R8G8B8_SRGB = 29,
161 | TIF_VK_FORMAT_B8G8R8_UNORM = 30,
162 | TIF_VK_FORMAT_B8G8R8_SNORM = 31,
163 | TIF_VK_FORMAT_B8G8R8_USCALED = 32,
164 | TIF_VK_FORMAT_B8G8R8_SSCALED = 33,
165 | TIF_VK_FORMAT_B8G8R8_UINT = 34,
166 | TIF_VK_FORMAT_B8G8R8_SINT = 35,
167 | TIF_VK_FORMAT_B8G8R8_SRGB = 36,
168 | TIF_VK_FORMAT_R8G8B8A8_UNORM = 37,
169 | TIF_VK_FORMAT_R8G8B8A8_SNORM = 38,
170 | TIF_VK_FORMAT_R8G8B8A8_USCALED = 39,
171 | TIF_VK_FORMAT_R8G8B8A8_SSCALED = 40,
172 | TIF_VK_FORMAT_R8G8B8A8_UINT = 41,
173 | TIF_VK_FORMAT_R8G8B8A8_SINT = 42,
174 | TIF_VK_FORMAT_R8G8B8A8_SRGB = 43,
175 | TIF_VK_FORMAT_B8G8R8A8_UNORM = 44,
176 | TIF_VK_FORMAT_B8G8R8A8_SNORM = 45,
177 | TIF_VK_FORMAT_B8G8R8A8_USCALED = 46,
178 | TIF_VK_FORMAT_B8G8R8A8_SSCALED = 47,
179 | TIF_VK_FORMAT_B8G8R8A8_UINT = 48,
180 | TIF_VK_FORMAT_B8G8R8A8_SINT = 49,
181 | TIF_VK_FORMAT_B8G8R8A8_SRGB = 50,
182 | TIF_VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
183 | TIF_VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
184 | TIF_VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
185 | TIF_VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
186 | TIF_VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
187 | TIF_VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
188 | TIF_VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
189 | TIF_VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
190 | TIF_VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
191 | TIF_VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
192 | TIF_VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
193 | TIF_VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
194 | TIF_VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
195 | TIF_VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
196 | TIF_VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
197 | TIF_VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
198 | TIF_VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
199 | TIF_VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
200 | TIF_VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
201 | TIF_VK_FORMAT_R16_UNORM = 70,
202 | TIF_VK_FORMAT_R16_SNORM = 71,
203 | TIF_VK_FORMAT_R16_USCALED = 72,
204 | TIF_VK_FORMAT_R16_SSCALED = 73,
205 | TIF_VK_FORMAT_R16_UINT = 74,
206 | TIF_VK_FORMAT_R16_SINT = 75,
207 | TIF_VK_FORMAT_R16_SFLOAT = 76,
208 | TIF_VK_FORMAT_R16G16_UNORM = 77,
209 | TIF_VK_FORMAT_R16G16_SNORM = 78,
210 | TIF_VK_FORMAT_R16G16_USCALED = 79,
211 | TIF_VK_FORMAT_R16G16_SSCALED = 80,
212 | TIF_VK_FORMAT_R16G16_UINT = 81,
213 | TIF_VK_FORMAT_R16G16_SINT = 82,
214 | TIF_VK_FORMAT_R16G16_SFLOAT = 83,
215 | TIF_VK_FORMAT_R16G16B16_UNORM = 84,
216 | TIF_VK_FORMAT_R16G16B16_SNORM = 85,
217 | TIF_VK_FORMAT_R16G16B16_USCALED = 86,
218 | TIF_VK_FORMAT_R16G16B16_SSCALED = 87,
219 | TIF_VK_FORMAT_R16G16B16_UINT = 88,
220 | TIF_VK_FORMAT_R16G16B16_SINT = 89,
221 | TIF_VK_FORMAT_R16G16B16_SFLOAT = 90,
222 | TIF_VK_FORMAT_R16G16B16A16_UNORM = 91,
223 | TIF_VK_FORMAT_R16G16B16A16_SNORM = 92,
224 | TIF_VK_FORMAT_R16G16B16A16_USCALED = 93,
225 | TIF_VK_FORMAT_R16G16B16A16_SSCALED = 94,
226 | TIF_VK_FORMAT_R16G16B16A16_UINT = 95,
227 | TIF_VK_FORMAT_R16G16B16A16_SINT = 96,
228 | TIF_VK_FORMAT_R16G16B16A16_SFLOAT = 97,
229 | TIF_VK_FORMAT_R32_UINT = 98,
230 | TIF_VK_FORMAT_R32_SINT = 99,
231 | TIF_VK_FORMAT_R32_SFLOAT = 100,
232 | TIF_VK_FORMAT_R32G32_UINT = 101,
233 | TIF_VK_FORMAT_R32G32_SINT = 102,
234 | TIF_VK_FORMAT_R32G32_SFLOAT = 103,
235 | TIF_VK_FORMAT_R32G32B32_UINT = 104,
236 | TIF_VK_FORMAT_R32G32B32_SINT = 105,
237 | TIF_VK_FORMAT_R32G32B32_SFLOAT = 106,
238 | TIF_VK_FORMAT_R32G32B32A32_UINT = 107,
239 | TIF_VK_FORMAT_R32G32B32A32_SINT = 108,
240 | TIF_VK_FORMAT_R32G32B32A32_SFLOAT = 109,
241 | TIF_VK_FORMAT_R64_UINT = 110,
242 | TIF_VK_FORMAT_R64_SINT = 111,
243 | TIF_VK_FORMAT_R64_SFLOAT = 112,
244 | TIF_VK_FORMAT_R64G64_UINT = 113,
245 | TIF_VK_FORMAT_R64G64_SINT = 114,
246 | TIF_VK_FORMAT_R64G64_SFLOAT = 115,
247 | TIF_VK_FORMAT_R64G64B64_UINT = 116,
248 | TIF_VK_FORMAT_R64G64B64_SINT = 117,
249 | TIF_VK_FORMAT_R64G64B64_SFLOAT = 118,
250 | TIF_VK_FORMAT_R64G64B64A64_UINT = 119,
251 | TIF_VK_FORMAT_R64G64B64A64_SINT = 120,
252 | TIF_VK_FORMAT_R64G64B64A64_SFLOAT = 121,
253 | TIF_VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
254 | TIF_VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
255 | TIF_VK_FORMAT_D16_UNORM = 124,
256 | TIF_VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
257 | TIF_VK_FORMAT_D32_SFLOAT = 126,
258 | TIF_VK_FORMAT_S8_UINT = 127,
259 | TIF_VK_FORMAT_D16_UNORM_S8_UINT = 128,
260 | TIF_VK_FORMAT_D24_UNORM_S8_UINT = 129,
261 | TIF_VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
262 | TIF_VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
263 | TIF_VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
264 | TIF_VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
265 | TIF_VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
266 | TIF_VK_FORMAT_BC2_UNORM_BLOCK = 135,
267 | TIF_VK_FORMAT_BC2_SRGB_BLOCK = 136,
268 | TIF_VK_FORMAT_BC3_UNORM_BLOCK = 137,
269 | TIF_VK_FORMAT_BC3_SRGB_BLOCK = 138,
270 | TIF_VK_FORMAT_BC4_UNORM_BLOCK = 139,
271 | TIF_VK_FORMAT_BC4_SNORM_BLOCK = 140,
272 | TIF_VK_FORMAT_BC5_UNORM_BLOCK = 141,
273 | TIF_VK_FORMAT_BC5_SNORM_BLOCK = 142,
274 | TIF_VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
275 | TIF_VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
276 | TIF_VK_FORMAT_BC7_UNORM_BLOCK = 145,
277 | TIF_VK_FORMAT_BC7_SRGB_BLOCK = 146,
278 | TIF_VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
279 | TIF_VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
280 | TIF_VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
281 | TIF_VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
282 | TIF_VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
283 | TIF_VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
284 | TIF_VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
285 | TIF_VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
286 | TIF_VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
287 | TIF_VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
288 | TIF_VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
289 | TIF_VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
290 | TIF_VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
291 | TIF_VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
292 | TIF_VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
293 | TIF_VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
294 | TIF_VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
295 | TIF_VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
296 | TIF_VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
297 | TIF_VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
298 | TIF_VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
299 | TIF_VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
300 | TIF_VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
301 | TIF_VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
302 | TIF_VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
303 | TIF_VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
304 | TIF_VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
305 | TIF_VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
306 | TIF_VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
307 | TIF_VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
308 | TIF_VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
309 | TIF_VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
310 | TIF_VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
311 | TIF_VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
312 | TIF_VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
313 | TIF_VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
314 | TIF_VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
315 | TIF_VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184,
316 |
317 | TIF_VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000,
318 | TIF_VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001,
319 | TIF_VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002,
320 | TIF_VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003,
321 | TIF_VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004,
322 | TIF_VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005,
323 | TIF_VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006,
324 | TIF_VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007,
325 | TIF_VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008,
326 | TIF_VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009,
327 | TIF_VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010,
328 | TIF_VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011,
329 | TIF_VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012,
330 | TIF_VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013,
331 | TIF_VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014,
332 | TIF_VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015,
333 | TIF_VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016,
334 | TIF_VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017,
335 | TIF_VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018,
336 | TIF_VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019,
337 | TIF_VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020,
338 | TIF_VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021,
339 | TIF_VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022,
340 | TIF_VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023,
341 | TIF_VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024,
342 | TIF_VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025,
343 | TIF_VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026,
344 | TIF_VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027,
345 | TIF_VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028,
346 | TIF_VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029,
347 | TIF_VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030,
348 | TIF_VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031,
349 | TIF_VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032,
350 | TIF_VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033,
351 | TIF_VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000,
352 | TIF_VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001,
353 | TIF_VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002,
354 | TIF_VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003,
355 | TIF_VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004,
356 | TIF_VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005,
357 | TIF_VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006,
358 | TIF_VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007,
359 | } TinyKTX_VkFormat;
360 |
361 | #define TINYKTX_MEV(x) TKTX_##x = TIF_VK_FORMAT_##x
362 | typedef enum TinyKtx_Format {
363 | TINYKTX_MEV(UNDEFINED),
364 | TINYKTX_MEV(R4G4_UNORM_PACK8),
365 | TINYKTX_MEV(R4G4B4A4_UNORM_PACK16),
366 | TINYKTX_MEV(B4G4R4A4_UNORM_PACK16),
367 | TINYKTX_MEV(R5G6B5_UNORM_PACK16),
368 | TINYKTX_MEV(B5G6R5_UNORM_PACK16),
369 | TINYKTX_MEV(R5G5B5A1_UNORM_PACK16),
370 | TINYKTX_MEV(B5G5R5A1_UNORM_PACK16),
371 | TINYKTX_MEV(A1R5G5B5_UNORM_PACK16),
372 |
373 | TINYKTX_MEV(R8_UNORM),
374 | TINYKTX_MEV(R8_SNORM),
375 | TINYKTX_MEV(R8_UINT),
376 | TINYKTX_MEV(R8_SINT),
377 | TINYKTX_MEV(R8_SRGB),
378 |
379 | TINYKTX_MEV(R8G8_UNORM),
380 | TINYKTX_MEV(R8G8_SNORM),
381 | TINYKTX_MEV(R8G8_UINT),
382 | TINYKTX_MEV(R8G8_SINT),
383 | TINYKTX_MEV(R8G8_SRGB),
384 |
385 | TINYKTX_MEV(R8G8B8_UNORM),
386 | TINYKTX_MEV(R8G8B8_SNORM),
387 | TINYKTX_MEV(R8G8B8_UINT),
388 | TINYKTX_MEV(R8G8B8_SINT),
389 | TINYKTX_MEV(R8G8B8_SRGB),
390 | TINYKTX_MEV(B8G8R8_UNORM),
391 | TINYKTX_MEV(B8G8R8_SNORM),
392 | TINYKTX_MEV(B8G8R8_UINT),
393 | TINYKTX_MEV(B8G8R8_SINT),
394 | TINYKTX_MEV(B8G8R8_SRGB),
395 |
396 | TINYKTX_MEV(R8G8B8A8_UNORM),
397 | TINYKTX_MEV(R8G8B8A8_SNORM),
398 | TINYKTX_MEV(R8G8B8A8_UINT),
399 | TINYKTX_MEV(R8G8B8A8_SINT),
400 | TINYKTX_MEV(R8G8B8A8_SRGB),
401 | TINYKTX_MEV(B8G8R8A8_UNORM),
402 | TINYKTX_MEV(B8G8R8A8_SNORM),
403 | TINYKTX_MEV(B8G8R8A8_UINT),
404 | TINYKTX_MEV(B8G8R8A8_SINT),
405 | TINYKTX_MEV(B8G8R8A8_SRGB),
406 |
407 | TINYKTX_MEV(A8B8G8R8_UNORM_PACK32),
408 | TINYKTX_MEV(A8B8G8R8_SNORM_PACK32),
409 | TINYKTX_MEV(A8B8G8R8_UINT_PACK32),
410 | TINYKTX_MEV(A8B8G8R8_SINT_PACK32),
411 | TINYKTX_MEV(A8B8G8R8_SRGB_PACK32),
412 |
413 | TINYKTX_MEV(E5B9G9R9_UFLOAT_PACK32),
414 | TINYKTX_MEV(A2R10G10B10_UNORM_PACK32),
415 | TINYKTX_MEV(A2R10G10B10_UINT_PACK32),
416 | TINYKTX_MEV(A2B10G10R10_UNORM_PACK32),
417 | TINYKTX_MEV(A2B10G10R10_UINT_PACK32),
418 | TINYKTX_MEV(B10G11R11_UFLOAT_PACK32),
419 |
420 | TINYKTX_MEV(R16_UNORM),
421 | TINYKTX_MEV(R16_SNORM),
422 | TINYKTX_MEV(R16_UINT),
423 | TINYKTX_MEV(R16_SINT),
424 | TINYKTX_MEV(R16_SFLOAT),
425 | TINYKTX_MEV(R16G16_UNORM),
426 | TINYKTX_MEV(R16G16_SNORM),
427 | TINYKTX_MEV(R16G16_UINT),
428 | TINYKTX_MEV(R16G16_SINT),
429 | TINYKTX_MEV(R16G16_SFLOAT),
430 | TINYKTX_MEV(R16G16B16_UNORM),
431 | TINYKTX_MEV(R16G16B16_SNORM),
432 | TINYKTX_MEV(R16G16B16_UINT),
433 | TINYKTX_MEV(R16G16B16_SINT),
434 | TINYKTX_MEV(R16G16B16_SFLOAT),
435 | TINYKTX_MEV(R16G16B16A16_UNORM),
436 | TINYKTX_MEV(R16G16B16A16_SNORM),
437 | TINYKTX_MEV(R16G16B16A16_UINT),
438 | TINYKTX_MEV(R16G16B16A16_SINT),
439 | TINYKTX_MEV(R16G16B16A16_SFLOAT),
440 | TINYKTX_MEV(R32_UINT),
441 | TINYKTX_MEV(R32_SINT),
442 | TINYKTX_MEV(R32_SFLOAT),
443 | TINYKTX_MEV(R32G32_UINT),
444 | TINYKTX_MEV(R32G32_SINT),
445 | TINYKTX_MEV(R32G32_SFLOAT),
446 | TINYKTX_MEV(R32G32B32_UINT),
447 | TINYKTX_MEV(R32G32B32_SINT),
448 | TINYKTX_MEV(R32G32B32_SFLOAT),
449 | TINYKTX_MEV(R32G32B32A32_UINT),
450 | TINYKTX_MEV(R32G32B32A32_SINT),
451 | TINYKTX_MEV(R32G32B32A32_SFLOAT),
452 |
453 | TINYKTX_MEV(BC1_RGB_UNORM_BLOCK),
454 | TINYKTX_MEV(BC1_RGB_SRGB_BLOCK),
455 | TINYKTX_MEV(BC1_RGBA_UNORM_BLOCK),
456 | TINYKTX_MEV(BC1_RGBA_SRGB_BLOCK),
457 | TINYKTX_MEV(BC2_UNORM_BLOCK),
458 | TINYKTX_MEV(BC2_SRGB_BLOCK),
459 | TINYKTX_MEV(BC3_UNORM_BLOCK),
460 | TINYKTX_MEV(BC3_SRGB_BLOCK),
461 | TINYKTX_MEV(BC4_UNORM_BLOCK),
462 | TINYKTX_MEV(BC4_SNORM_BLOCK),
463 | TINYKTX_MEV(BC5_UNORM_BLOCK),
464 | TINYKTX_MEV(BC5_SNORM_BLOCK),
465 | TINYKTX_MEV(BC6H_UFLOAT_BLOCK),
466 | TINYKTX_MEV(BC6H_SFLOAT_BLOCK),
467 | TINYKTX_MEV(BC7_UNORM_BLOCK),
468 | TINYKTX_MEV(BC7_SRGB_BLOCK),
469 |
470 | TINYKTX_MEV(ETC2_R8G8B8_UNORM_BLOCK),
471 | TINYKTX_MEV(ETC2_R8G8B8A1_UNORM_BLOCK),
472 | TINYKTX_MEV(ETC2_R8G8B8A8_UNORM_BLOCK),
473 | TINYKTX_MEV(ETC2_R8G8B8_SRGB_BLOCK),
474 | TINYKTX_MEV(ETC2_R8G8B8A1_SRGB_BLOCK),
475 | TINYKTX_MEV(ETC2_R8G8B8A8_SRGB_BLOCK),
476 | TINYKTX_MEV(EAC_R11_UNORM_BLOCK),
477 | TINYKTX_MEV(EAC_R11G11_UNORM_BLOCK),
478 | TINYKTX_MEV(EAC_R11_SNORM_BLOCK),
479 | TINYKTX_MEV(EAC_R11G11_SNORM_BLOCK),
480 |
481 | TKTX_PVR_2BPP_BLOCK = TIF_VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,
482 | TKTX_PVR_2BPPA_BLOCK = TIF_VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG,
483 | TKTX_PVR_4BPP_BLOCK = TIF_VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG,
484 | TKTX_PVR_4BPPA_BLOCK = TIF_VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG,
485 | TKTX_PVR_2BPP_SRGB_BLOCK = TIF_VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,
486 | TKTX_PVR_2BPPA_SRGB_BLOCK = TIF_VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,
487 | TKTX_PVR_4BPP_SRGB_BLOCK = TIF_VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,
488 | TKTX_PVR_4BPPA_SRGB_BLOCK = TIF_VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG,
489 |
490 | TINYKTX_MEV(ASTC_4x4_UNORM_BLOCK),
491 | TINYKTX_MEV(ASTC_4x4_SRGB_BLOCK),
492 | TINYKTX_MEV(ASTC_5x4_UNORM_BLOCK),
493 | TINYKTX_MEV(ASTC_5x4_SRGB_BLOCK),
494 | TINYKTX_MEV(ASTC_5x5_UNORM_BLOCK),
495 | TINYKTX_MEV(ASTC_5x5_SRGB_BLOCK),
496 | TINYKTX_MEV(ASTC_6x5_UNORM_BLOCK),
497 | TINYKTX_MEV(ASTC_6x5_SRGB_BLOCK),
498 | TINYKTX_MEV(ASTC_6x6_UNORM_BLOCK),
499 | TINYKTX_MEV(ASTC_6x6_SRGB_BLOCK),
500 | TINYKTX_MEV(ASTC_8x5_UNORM_BLOCK),
501 | TINYKTX_MEV(ASTC_8x5_SRGB_BLOCK),
502 | TINYKTX_MEV(ASTC_8x6_UNORM_BLOCK),
503 | TINYKTX_MEV(ASTC_8x6_SRGB_BLOCK),
504 | TINYKTX_MEV(ASTC_8x8_UNORM_BLOCK),
505 | TINYKTX_MEV(ASTC_8x8_SRGB_BLOCK),
506 | TINYKTX_MEV(ASTC_10x5_UNORM_BLOCK),
507 | TINYKTX_MEV(ASTC_10x5_SRGB_BLOCK),
508 | TINYKTX_MEV(ASTC_10x6_UNORM_BLOCK),
509 | TINYKTX_MEV(ASTC_10x6_SRGB_BLOCK),
510 | TINYKTX_MEV(ASTC_10x8_UNORM_BLOCK),
511 | TINYKTX_MEV(ASTC_10x8_SRGB_BLOCK),
512 | TINYKTX_MEV(ASTC_10x10_UNORM_BLOCK),
513 | TINYKTX_MEV(ASTC_10x10_SRGB_BLOCK),
514 | TINYKTX_MEV(ASTC_12x10_UNORM_BLOCK),
515 | TINYKTX_MEV(ASTC_12x10_SRGB_BLOCK),
516 | TINYKTX_MEV(ASTC_12x12_UNORM_BLOCK),
517 | TINYKTX_MEV(ASTC_12x12_SRGB_BLOCK),
518 |
519 | } TinyKtx_Format;
520 | #undef TINYKTX_MEV
521 |
522 | #define TINYKTX_DEFINED
523 | #endif
524 |
525 | TinyKtx_Format TinyKtx_GetFormat(TinyKtx2_ContextHandle handle);
526 | bool TinyKtx2_WriteImage(TinyKtx2_WriteCallbacks const *callbacks,
527 | void *user,
528 | uint32_t width,
529 | uint32_t height,
530 | uint32_t depth,
531 | uint32_t slices,
532 | uint32_t mipmaplevels,
533 | TinyKtx_Format format,
534 | bool cubemap,
535 | uint32_t const *mipmapsizes,
536 | void const **mipmaps);
537 |
538 | #ifdef TINYKTX2_IMPLEMENTATION
539 |
540 | typedef struct TinyKtx2_KeyValuePair {
541 | uint32_t size;
542 | } TinyKtx2_KeyValuePair; // followed by at least size bytes (aligned to 4)
543 |
544 | typedef struct TinyKtx2_HeaderV2 {
545 | uint8_t identifier[12];
546 | TinyKtx_Format vkFormat;
547 | uint32_t pixelWidth;
548 | uint32_t pixelHeight;
549 | uint32_t pixelDepth;
550 | uint32_t arrayElementCount;
551 | uint32_t faceCount;
552 | uint32_t levelCount;
553 | uint32_t supercompressionScheme;
554 |
555 | uint32_t dfdByteOffset;
556 | uint32_t dfdByteLength;
557 | uint32_t kvdByteOffset;
558 | uint32_t kvdByteLength;
559 | uint64_t sgdByteOffset;
560 | uint64_t sgdByteLength;
561 | } TinyKtx2_Header;
562 |
563 | typedef struct TinyKtx2_Level {
564 | uint64_t byteOffset;
565 | uint64_t byteLength;
566 | uint64_t uncompressedByteLength;
567 | } TinyKtx2_Level;
568 |
569 | typedef enum TinyKtx2_SuperCompressionScheme {
570 | TKTX2_SUPERCOMPRESSION_NONE = 0,
571 | TKTX2_SUPERCOMPRESSION_CRN = 1,
572 | TKTX2_SUPERCOMPRESSION_ZLIB = 2,
573 | TKTX2_SUPERCOMPRESSION_ZSTD = 3,
574 | } TinyKtx2_SuperCompressionScheme;
575 |
576 | typedef struct TinyKtx2_Context {
577 | TinyKtx2_Callbacks callbacks;
578 | void *user;
579 | uint64_t headerPos;
580 | uint64_t firstImagePos;
581 |
582 | TinyKtx2_Header header;
583 |
584 | TinyKtx2_KeyValuePair const *keyData;
585 | bool headerValid;
586 | bool sameEndian;
587 | void* sgdData;
588 |
589 | TinyKtx2_Level levels[TINYKTX_MAX_MIPMAPLEVELS];
590 | uint8_t const *mipmaps[TINYKTX_MAX_MIPMAPLEVELS];
591 |
592 | } TinyKtx2_Context;
593 |
594 |
595 | static uint8_t TinyKtx2_fileIdentifier[12] = {
596 | 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x32, 0x30, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
597 | };
598 |
599 | static void TinyKtx2_NullErrorFunc(void *user, char const *msg) {}
600 |
601 | TinyKtx2_ContextHandle TinyKtx2_CreateContext(TinyKtx2_Callbacks const *callbacks, void *user) {
602 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) callbacks->alloc(user, sizeof(TinyKtx2_Context));
603 | if (ctx == NULL)
604 | return NULL;
605 |
606 | memset(ctx, 0, sizeof(TinyKtx2_Context));
607 | memcpy(&ctx->callbacks, callbacks, sizeof(TinyKtx2_Callbacks));
608 | ctx->user = user;
609 | if (ctx->callbacks.error == NULL) {
610 | ctx->callbacks.error = &TinyKtx_NullErrorFunc;
611 | }
612 |
613 | if (ctx->callbacks.read == NULL) {
614 | ctx->callbacks.error(user, "TinyKtx must have read callback");
615 | return NULL;
616 | }
617 | if (ctx->callbacks.alloc == NULL) {
618 | ctx->callbacks.error(user, "TinyKtx must have alloc callback");
619 | return NULL;
620 | }
621 | if (ctx->callbacks.free == NULL) {
622 | ctx->callbacks.error(user, "TinyKtx must have free callback");
623 | return NULL;
624 | }
625 | if (ctx->callbacks.seek == NULL) {
626 | ctx->callbacks.error(user, "TinyKtx must have seek callback");
627 | return NULL;
628 | }
629 | if (ctx->callbacks.tell == NULL) {
630 | ctx->callbacks.error(user, "TinyKtx must have tell callback");
631 | return NULL;
632 | }
633 |
634 | TinyKtx2_Reset(ctx);
635 |
636 | return ctx;
637 | }
638 |
639 | void TinyKtx2_DestroyContext(TinyKtx2_ContextHandle handle) {
640 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
641 | if (ctx == NULL)
642 | return;
643 | TinyKtx2_Reset(handle);
644 |
645 | ctx->callbacks.free(ctx->user, ctx);
646 | }
647 |
648 | void TinyKtx2_Reset(TinyKtx2_ContextHandle handle) {
649 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
650 | if (ctx == NULL)
651 | return;
652 |
653 | // backup user provided callbacks and data
654 | TinyKtx2_Callbacks callbacks;
655 | memcpy(&callbacks, &ctx->callbacks, sizeof(TinyKtx_Callbacks));
656 | void *user = ctx->user;
657 |
658 | // free any super compression global data we've allocated
659 | if (ctx->sgdData != NULL) {
660 | callbacks.free(user, (void *) ctx->sgdData);
661 | }
662 |
663 | // free memory of sub data
664 | if (ctx->keyData != NULL) {
665 | callbacks.free(user, (void *) ctx->keyData);
666 | }
667 |
668 | for (int i = 0; i < TINYKTX_MAX_MIPMAPLEVELS; ++i) {
669 | if (ctx->mipmaps[i] != NULL) {
670 | callbacks.free(user, (void *) ctx->mipmaps[i]);
671 | }
672 | }
673 |
674 | // reset to default state
675 | memset(ctx, 0, sizeof(TinyKtx_Context));
676 | memcpy(&ctx->callbacks, &callbacks, sizeof(TinyKtx_Callbacks));
677 | ctx->user = user;
678 |
679 | }
680 |
681 |
682 | bool TinyKtx2_ReadHeader(TinyKtx_ContextHandle handle) {
683 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
684 | if (ctx == NULL)
685 | return false;
686 |
687 |
688 | ctx->headerPos = ctx->callbacks.tell(ctx->user);
689 | ctx->callbacks.read(ctx->user, &ctx->header, sizeof(TinyKtx2_Header));
690 |
691 | if (memcmp(&ctx->header.identifier, TinyKtx2_fileIdentifier, 12) != 0) {
692 | ctx->callbacks.error(ctx->user, "Not a KTX V2 file or corrupted as identified isn't valid");
693 | return false;
694 | }
695 |
696 | if (ctx->header.faceCount != 1 && ctx->header.faceCount != 6) {
697 | ctx->callbacks.error(ctx->user, "no. of Faces must be 1 or 6");
698 | return false;
699 | }
700 | // cap level to max
701 | if(ctx->header.levelCount >= TINYKTX2_MAX_MIPMAPLEVELS) {
702 | ctx->header.levelCount = TINYKTX2_MAX_MIPMAPLEVELS;
703 | }
704 | // 0 level count means wants mip maps from the 1 stored
705 | uint32_t const levelCount = ctx->header.levelCount ? ctx->header.levelCount : 1;
706 |
707 | ctx->callbacks.read(ctx->user, &ctx->levels, sizeof(TinyKtx2_Header) * levelCount);
708 |
709 | if(ctx->header.sgdByteLength > 0) {
710 | ctx->sgdData = ctx->callbacks.alloc(ctx->user, ctx->header.sgdByteLength);
711 | ctx->callbacks.seek(ctx->user, ctx->header.sgdByteOffset);
712 | ctx->callbacks.read(ctx->user, ctx->sgdData, ctx->header.sgdByteLength);
713 | }
714 |
715 | return true;
716 | }
717 |
718 | bool TinyKtx2_GetValue(TinyKtx2_ContextHandle handle, char const *key, void const **value) {
719 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
720 | if (ctx == NULL)
721 | return false;
722 | if (ctx->headerValid == false) {
723 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
724 | return false;
725 | }
726 |
727 | if (ctx->keyData == NULL) {
728 | ctx->callbacks.error(ctx->user, "No key value data in this KTX");
729 | return false;
730 | }
731 |
732 | TinyKtx2_KeyValuePair const *curKey = ctx->keyData;
733 | while (((uint8_t *) curKey - (uint8_t *) ctx->keyData) < ctx->header.bytesOfKeyValueData) {
734 | char const *kvp = (char const *) curKey;
735 |
736 | if (strcmp(kvp, key) == 0) {
737 | size_t sl = strlen(kvp);
738 | *value = (void const *) (kvp + sl);
739 | return true;
740 | }
741 | curKey = curKey + ((curKey->size + 3u) & ~3u);
742 | }
743 | return false;
744 | }
745 |
746 | bool TinyKtx2_Is1D(TinyKtx2_ContextHandle handle) {
747 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
748 | if (ctx == NULL)
749 | return false;
750 | if (ctx->headerValid == false) {
751 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
752 | return false;
753 | }
754 | return (ctx->header.pixelHeight <= 1) && (ctx->header.pixelDepth <= 1 );
755 | }
756 | bool TinyKtx2_Is2D(TinyKtx_ContextHandle handle) {
757 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
758 | if (ctx == NULL)
759 | return false;
760 | if (ctx->headerValid == false) {
761 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
762 | return false;
763 | }
764 |
765 | return (ctx->header.pixelHeight > 1 && ctx->header.pixelDepth <= 1);
766 | }
767 | bool TinyKtx2_Is3D(TinyKtx2_ContextHandle handle) {
768 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
769 | if (ctx == NULL)
770 | return false;
771 | if (ctx->headerValid == false) {
772 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
773 | return false;
774 | }
775 |
776 | return (ctx->header.pixelHeight > 1 && ctx->header.pixelDepth > 1);
777 | }
778 |
779 | bool TinyKtx2_IsCubemap(TinyKtx2_ContextHandle handle) {
780 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
781 | if (ctx == NULL)
782 | return false;
783 | if (ctx->headerValid == false) {
784 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
785 | return false;
786 | }
787 |
788 | return (ctx->header.numberOfFaces == 6);
789 | }
790 | bool TinyKtx2_IsArray(TinyKtx2_ContextHandle handle) {
791 | TinyKtx_Context *ctx = (TinyKtx2_Context *) handle;
792 | if (ctx == NULL)
793 | return false;
794 | if (ctx->headerValid == false) {
795 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
796 | return false;
797 | }
798 |
799 | return (ctx->header.numberOfArrayElements > 1);
800 | }
801 |
802 | bool TinyKtx2_Dimensions(TinyKtx2_ContextHandle handle,
803 | uint32_t *width,
804 | uint32_t *height,
805 | uint32_t *depth,
806 | uint32_t *slices) {
807 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
808 | if (ctx == NULL)
809 | return false;
810 | if (ctx->headerValid == false) {
811 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
812 | return false;
813 | }
814 | if (width)
815 | *width = ctx->header.pixelWidth;
816 | if (height)
817 | *height = ctx->header.pixelWidth;
818 | if (depth)
819 | *depth = ctx->header.pixelDepth;
820 | if (slices)
821 | *slices = ctx->header.numberOfArrayElements;
822 | return true;
823 | }
824 |
825 | uint32_t TinyKtx2_Width(TinyKtx2_ContextHandle handle) {
826 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
827 | if (ctx == NULL)
828 | return 0;
829 | if (ctx->headerValid == false) {
830 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
831 | return 0;
832 | }
833 | return ctx->header.pixelWidth;
834 |
835 | }
836 |
837 | uint32_t TinyKtx2_Height(TinyKtx2_ContextHandle handle) {
838 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
839 | if (ctx == NULL)
840 | return 0;
841 | if (ctx->headerValid == false) {
842 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
843 | return 0;
844 | }
845 |
846 | return ctx->header.pixelHeight;
847 | }
848 |
849 | uint32_t TinyKtx2_Depth(TinyKtx2_ContextHandle handle) {
850 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
851 | if (ctx == NULL)
852 | return 0;
853 | if (ctx->headerValid == false) {
854 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
855 | return 0;
856 | }
857 | return ctx->header.pixelDepth;
858 | }
859 |
860 | uint32_t TinyKtx2_ArraySlices(TinyKtx2_ContextHandle handle) {
861 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
862 | if (ctx == NULL)
863 | return 0;
864 | if (ctx->headerValid == false) {
865 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
866 | return 0;
867 | }
868 |
869 | return ctx->header.numberOfArrayElements;
870 | }
871 |
872 | uint32_t TinyKtx2_NumberOfMipmaps(TinyKtx2_ContextHandle handle) {
873 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
874 | if (ctx == NULL)
875 | return 0;
876 | if (ctx->headerValid == false) {
877 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
878 | return 0;
879 | }
880 | return ctx->header.levelCount ? ctx->header.levelCount : 1;
881 | }
882 |
883 | bool TinyKtx2_NeedsGenerationOfMipmaps(TinyKtx2_ContextHandle handle) {
884 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
885 | if (ctx == NULL)
886 | return false;
887 | if (ctx->headerValid == false) {
888 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
889 | return false;
890 | }
891 |
892 | return ctx->header.levelCount == 0;
893 | }
894 |
895 | uint32_t TinyKtx_ImageSize(TinyKtx_ContextHandle handle, uint32_t mipmaplevel) {
896 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
897 |
898 | if (mipmaplevel >= ctx->header.levelCount) {
899 | ctx->callbacks.error(ctx->user, "Invalid mipmap level");
900 | return 0;
901 | }
902 | if (mipmaplevel >= TINYKTX2_MAX_MIPMAPLEVELS) {
903 | ctx->callbacks.error(ctx->user, "Invalid mipmap level");
904 | return 0;
905 | }
906 |
907 | return ctx->levels[mipmaplevel].uncompressedByteLength;
908 | }
909 |
910 | void const *TinyKtx2_ImageRawData(TinyKtx2_ContextHandle handle, uint32_t mipmaplevel) {
911 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
912 | if (ctx == NULL)
913 | return NULL;
914 |
915 | if (ctx->headerValid == false) {
916 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
917 | return NULL;
918 | }
919 |
920 | if (mipmaplevel >= ctx->header.levelCount) {
921 | ctx->callbacks.error(ctx->user, "Invalid mipmap level");
922 | return NULL;
923 | }
924 |
925 | if (mipmaplevel >= TINYKTX2_MAX_MIPMAPLEVELS) {
926 | ctx->callbacks.error(ctx->user, "Invalid mipmap level");
927 | return NULL;
928 | }
929 |
930 | if (ctx->mipmaps[mipmaplevel] != NULL)
931 | return ctx->mipmaps[mipmaplevel];
932 |
933 | TinyKtx_Level* lvl = &ctx->levels[mipmaplevel];
934 | if (lvl->byteLength == 0 || lvl->uncompressedByteLength == 0)
935 | return NULL;
936 |
937 | // allocate decompressed buffer
938 | ctx->mipmaps[mipmaplevel] = (uint8_t const*) ctx->callbacks.alloc(ctx->user, lvl->uncompressedByteLength);
939 | if (ctx->mipmaps[mipmaplevel] == NULL)
940 | return NULL;
941 |
942 | // handle no super compression first (save an buffer allocation)
943 | if(ctx->header.supercompressionScheme == TKTX2_SUPERCOMPRESSION_NONE) {
944 | if(lvl->uncompressedByteLength != lvl->byteLength) {
945 | ctx->callbacks.error(ctx->user, "mipmap image data has no super compression but compressed and uncompressed data sizes are different");
946 | ctx->callbacks.free(ctx->user, (void*)ctx->mipmaps[mipmaplevel]);
947 | return NULL;
948 | }
949 | ctx->callbacks.seek(ctx->user, lvl->byteOffset);
950 | ctx->callbacks.read(ctx->user, (void *) ctx->mipmaps[mipmaplevel], lvl->byteLength);
951 | return ctx->mipmaps[mipmaplevel];
952 | }
953 |
954 | // this data is super compressed, we need to see if the user provided a decompressor and if so use it
955 |
956 | TinyKtx_SuperDecompress decompressor = NULL;
957 | // see if the user provided the decompressor we need
958 | for(size_t i = 0; i < ctx->callbacks.numSuperDecompressors;++i) {
959 | if(ctx->callbacks.superDecompressors[i].superId == ctx->headerV2.supercompressionScheme) {
960 | decompressor = ctx->callbacks.superDecompressors[i].decompressor;
961 | }
962 | }
963 | if(decompressor == NULL) {
964 | ctx->callbacks.error(ctx->user, "user did not provide a decompressor for use with this type of super decompressor");
965 | ctx->callbacks.free(ctx->user, (void*)ctx->mipmaps[mipmaplevel]);
966 | return NULL;
967 | }
968 |
969 | // read the compressed data into its own buffer (free once decompression has occured)
970 | uint8_t const* compressedBuffer = (uint8_t const*)ctx->callbacks.alloc(ctx->user, lvl->byteLength);
971 | if(compressedBuffer == NULL) {
972 | ctx->callbacks.free(ctx->user, (void*)ctx->mipmaps[mipmaplevel]);
973 | return NULL;
974 | }
975 | ctx->callbacks.seek(ctx->user, lvl->byteOffset);
976 | ctx->callbacks.read(ctx->user, (void *) compressedBuffer, lvl->byteLength);
977 | bool okay = decompressor(ctx->user, ctx->sgdData, compressedBuffer, lvl->byteLength, ctx->mipmaps[mipmaplevel], lvl->uncompressedByteLength);
978 |
979 | if(!okay) {
980 | ctx->callbacks.error(ctx->user, "user decompressor failed");
981 | ctx->callbacks.free(ctx->user, (void *) compressedBuffer);
982 | ctx->callbacks.free(ctx->user, (void *) ctx->mipmaps[mipmaplevel]);
983 | return NULL;
984 | }
985 |
986 | ctx->callbacks.free(ctx->user, (void *) compressedBuffer);
987 | return ctx->mipmaps[mipmaplevel];
988 |
989 | }
990 |
991 | TinyKtx_Format TinyKtx2_GetFormat(TinyKtx2_ContextHandle handle) {
992 | TinyKtx2_Context *ctx = (TinyKtx2_Context *) handle;
993 | if (ctx == NULL)
994 | return TKTX_UNDEFINED;
995 |
996 | if (ctx->headerValid == false) {
997 | ctx->callbacks.error(ctx->user, "Header data hasn't been read yet or its invalid");
998 | return TKTX_UNDEFINED;
999 | }
1000 | // TODO handle DFD only described formats (VK_FORMAT_UNDEFINED)
1001 | return (TinyKtx_Format)ctx->header.vkFormat;
1002 | }
1003 | static uint32_t TinyKtx2_MipMapReduce(uint32_t value, uint32_t mipmaplevel) {
1004 |
1005 | // handle 0 being passed in
1006 | if(value <= 1) return 1;
1007 |
1008 | // there are better ways of doing this (log2 etc.) but this doesn't require any
1009 | // dependecies and isn't used enough to matter imho
1010 | for (uint32_t i = 0u; i < mipmaplevel;++i) {
1011 | if(value <= 1) return 1;
1012 | value = value / 2;
1013 | }
1014 | return value;
1015 | }
1016 |
1017 |
1018 |
1019 | bool TinyKtx2_WriteImage(TinyKtx2_WriteCallbacks const *callbacks,
1020 | void *user,
1021 | uint32_t width,
1022 | uint32_t height,
1023 | uint32_t depth,
1024 | uint32_t slices,
1025 | uint32_t mipmaplevels,
1026 | TinyKtx_Format format,
1027 | bool cubemap,
1028 | uint32_t const *mipmapsizes,
1029 | void const **mipmaps) {
1030 | ASSERT(false);
1031 | }
1032 | #endif
1033 |
1034 | #ifdef __cplusplus
1035 | };
1036 | #endif
1037 |
1038 | #endif // end header
1039 | /*
1040 | MIT License
1041 |
1042 | Copyright (c) 2019 DeanoC
1043 |
1044 | Permission is hereby granted, free of charge, to any person obtaining a copy
1045 | of this software and associated documentation files (the "Software"), to deal
1046 | in the Software without restriction, including without limitation the rights
1047 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1048 | copies of the Software, and to permit persons to whom the Software is
1049 | furnished to do so, subject to the following conditions:
1050 |
1051 | The above copyright notice and this permission notice shall be included in all
1052 | copies or substantial portions of the Software.
1053 |
1054 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1055 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1056 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1057 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1058 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1059 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1060 | SOFTWARE.
1061 | */
1062 |
--------------------------------------------------------------------------------
/src/tinyktx.c:
--------------------------------------------------------------------------------
1 | #define TINYKTX_IMPLEMENTATION
2 | #include "tiny_imageformat/tinyimageformat_base.h"
3 | #include "tiny_ktx/tinyktx.h"
4 |
--------------------------------------------------------------------------------
/tests/runner.cpp:
--------------------------------------------------------------------------------
1 | #define CATCH_CONFIG_RUNNER
2 | #include "al2o3_catch2/catch2.hpp"
3 | #include "utils_simple_logmanager/logmanager.h"
4 |
5 | int main(int argc, char const *argv[]) {
6 | auto logger = SimpleLogManager_Alloc();
7 |
8 | auto ret = Catch::Session().run(argc, (char **) argv);
9 |
10 | SimpleLogManager_Free(logger);
11 |
12 | return ret;
13 | }
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tests/test_tinyktx.cpp:
--------------------------------------------------------------------------------
1 | #include "tiny_ktx/tinyktx.h"
2 | #include "al2o3_platform/platform.h"
3 | #include "al2o3_memory/memory.h"
4 | #include "al2o3_catch2/catch2.hpp"
5 | #include "al2o3_vfile/vfile.hpp"
6 | #include "al2o3_stb/stb_image.h"
7 | #include "al2o3_os/filesystem.h"
8 |
9 | static const char* gBasePath = "input/testimages";
10 |
11 | #define SET_PATH() char existCurDir[1024]; \
12 | Os_GetCurrentDir(existCurDir, sizeof(existCurDir)); \
13 | char path[2048]; \
14 | strcpy(path, existCurDir); \
15 | strcat(path, gBasePath); \
16 | Os_SetCurrentDir(path)
17 | #define RESTORE_PATH() Os_SetCurrentDir(existCurDir)
18 |
19 | static void tinyktxCallbackError(void *user, char const *msg) {
20 | LOGERROR("Tiny_Ktx ERROR: %s", msg);
21 | }
22 | static void *tinyktxCallbackAlloc(void *user, size_t size) {
23 | return MEMORY_MALLOC(size);
24 | }
25 | static void tinyktxCallbackFree(void *user, void *data) {
26 | MEMORY_FREE(data);
27 | }
28 | static size_t tinyktxCallbackRead(void *user, void* data, size_t size) {
29 | auto handle = (VFile_Handle) user;
30 | return VFile_Read(handle, data, size);
31 | }
32 | static bool tinyktxCallbackSeek(void *user, int64_t offset) {
33 | auto handle = (VFile_Handle) user;
34 | return VFile_Seek(handle, offset, VFile_SD_Begin);
35 | }
36 | static int64_t tinyktxCallbackTell(void *user) {
37 | auto handle = (VFile_Handle) user;
38 | return VFile_Tell(handle);
39 | }
40 | static int stbIoCallbackRead(void *user, char *data, int size) {
41 | auto handle = (VFile_Handle) user;
42 | return (int) VFile_Read(handle, data, size);
43 | }
44 | static void stbIoCallbackSkip(void *user, int n) {
45 | auto handle = (VFile_Handle) user;
46 | VFile_Seek(handle, n, VFile_SD_Current);
47 | }
48 | static int stbIoCallbackEof(void *user) {
49 | auto handle = (VFile_Handle) user;
50 | return VFile_IsEOF(handle);
51 | }
52 |
53 |
54 | TEST_CASE("Check Files", "[TinyKtx Loader]") {
55 | SET_PATH();
56 | #define CHK_FILE_EXISTS(filename) \
57 | { VFile::ScopedFile reffile = VFile::File::FromFile(filename, Os_FM_ReadBinary); \
58 | if(!reffile) { \
59 | LOGERROR("This must run in the directory input/testimages/ that can be got from http://github/DeanoC/taylor_imagetests"); \
60 | REQUIRE(reffile); \
61 | } }
62 |
63 | CHK_FILE_EXISTS("rgb-reference.ktx");
64 | CHK_FILE_EXISTS("rgb.ppm");
65 | CHK_FILE_EXISTS("luminance-reference-metadata.ktx");
66 | CHK_FILE_EXISTS("luminance.pgm");
67 | CHK_FILE_EXISTS("level0.ppm");
68 | CHK_FILE_EXISTS("level1.ppm");
69 | CHK_FILE_EXISTS("level2.ppm");
70 | CHK_FILE_EXISTS("level3.ppm");
71 | CHK_FILE_EXISTS("level4.ppm");
72 | CHK_FILE_EXISTS("level5.ppm");
73 | CHK_FILE_EXISTS("level6.ppm");
74 |
75 | #undef CHK_FILE_EXISTS
76 |
77 | }
78 |
79 | TEST_CASE("TinyKtx Create/Destroy Context", "[TinyKtx Loader]") {
80 | TinyKtx_Callbacks callbacks {
81 | &tinyktxCallbackError,
82 | &tinyktxCallbackAlloc,
83 | &tinyktxCallbackFree,
84 | tinyktxCallbackRead,
85 | &tinyktxCallbackSeek,
86 | &tinyktxCallbackTell
87 | };
88 |
89 | VFile::ScopedFile file = VFile::File::FromFile("rgb-reference.ktx", Os_FM_ReadBinary);
90 | if(!file) {
91 | LOGERROR("This must run in the directory input/testimages/ that can be got from http://github/DeanoC/taylor_imagetests");
92 | REQUIRE(file);
93 | }
94 |
95 | auto ctx = TinyKtx_CreateContext(&callbacks, (void*)file.owned);
96 | REQUIRE(ctx);
97 |
98 | TinyKtx_DestroyContext(ctx);
99 | }
100 |
101 | TEST_CASE("TinyKtx readheader & dimensions", "[TinyKtx Loader]") {
102 | TinyKtx_Callbacks callbacks {
103 | &tinyktxCallbackError,
104 | &tinyktxCallbackAlloc,
105 | &tinyktxCallbackFree,
106 | tinyktxCallbackRead,
107 | &tinyktxCallbackSeek,
108 | &tinyktxCallbackTell
109 | };
110 |
111 | VFile::ScopedFile file = VFile::File::FromFile("rgb-reference.ktx", Os_FM_ReadBinary);
112 | REQUIRE(file);
113 | auto ctx = TinyKtx_CreateContext(&callbacks, (void*)file.owned);
114 | REQUIRE(TinyKtx_ReadHeader(ctx));
115 |
116 | auto w = TinyKtx_Width(ctx);
117 | auto h = TinyKtx_Height(ctx);
118 | auto d = TinyKtx_Depth(ctx);
119 | auto s = TinyKtx_ArraySlices(ctx);
120 |
121 | uint32_t wd, hd, dd, sd;
122 | TinyKtx_Dimensions(ctx, &wd, &hd, &dd, &sd);
123 |
124 | REQUIRE(w == wd);
125 | REQUIRE(h == hd);
126 | REQUIRE(d == dd);
127 | REQUIRE(s == sd);
128 |
129 | REQUIRE(w == 128);
130 | REQUIRE(h == 128);
131 | REQUIRE(d == 0);
132 | REQUIRE(s == 0);
133 |
134 | REQUIRE(TinyKtx_NumberOfMipmaps(ctx) == 1);
135 |
136 | TinyKtx_DestroyContext(ctx);
137 | }
138 |
139 | static bool CmpFlipped( uint32_t w,
140 | uint32_t h,
141 | uint8_t pixByte,
142 | uint32_t srcStride,
143 | uint32_t dstStride,
144 | uint8_t const* src,
145 | uint8_t const* dst) {
146 |
147 | dst = dst + ((h-1) * dstStride);
148 |
149 | for (auto i = 0u; i < h; ++i) {
150 | uint8_t const *srcBackup = src;
151 | uint8_t const *dstBackup = dst;
152 |
153 | for (auto j = 0u; j < w; ++j) {
154 | for(auto p = 0u; p < pixByte;++p) {
155 | if(src[p] != dst[p]) return false;
156 | }
157 | src += pixByte;
158 | dst += pixByte;
159 | }
160 |
161 | src = srcBackup + srcStride;
162 | dst = dstBackup - dstStride;
163 | }
164 |
165 | return true;
166 | }
167 |
168 | static bool CmpSame( uint32_t w,
169 | uint32_t h,
170 | uint8_t pixByte,
171 | uint32_t srcStride,
172 | uint32_t dstStride,
173 | uint8_t const* src,
174 | uint8_t const* dst) {
175 |
176 | for (auto i = 0u; i < h; ++i) {
177 | uint8_t const *srcBackup = src;
178 | uint8_t const *dstBackup = dst;
179 |
180 | for (auto j = 0u; j < w; ++j) {
181 | for(auto p = 0u; p < pixByte;++p) {
182 | if(src[p] != dst[p]) return false;
183 | }
184 | src += pixByte;
185 | dst += pixByte;
186 | }
187 |
188 | src = srcBackup + srcStride;
189 | dst = dstBackup + dstStride;
190 | }
191 |
192 | return true;
193 | }
194 |
195 | TEST_CASE("TinyKtx rgb-reference okay", "[TinyKtx Loader]") {
196 | TinyKtx_Callbacks callbacks {
197 | &tinyktxCallbackError,
198 | &tinyktxCallbackAlloc,
199 | &tinyktxCallbackFree,
200 | tinyktxCallbackRead,
201 | &tinyktxCallbackSeek,
202 | &tinyktxCallbackTell
203 | };
204 |
205 | stbi_io_callbacks stbi_callbacks{
206 | &stbIoCallbackRead,
207 | &stbIoCallbackSkip,
208 | &stbIoCallbackEof
209 | };
210 |
211 | VFile::ScopedFile file = VFile::File::FromFile("rgb-reference.ktx", Os_FM_ReadBinary);
212 | VFile::ScopedFile reffile = VFile::File::FromFile("rgb.ppm", Os_FM_ReadBinary);
213 | REQUIRE(file);
214 | REQUIRE(reffile);
215 |
216 | auto ctx = TinyKtx_CreateContext(&callbacks, (void*)file.owned);
217 |
218 | REQUIRE(TinyKtx_ReadHeader(ctx));
219 |
220 | size_t origin = VFile_Tell(reffile);
221 |
222 | int w = 0, h = 0, cmp = 0;
223 | stbi_info_from_callbacks(&stbi_callbacks, (void*)reffile.owned, &w, &h, &cmp);
224 | REQUIRE(w == TinyKtx_Width(ctx));
225 | REQUIRE(h == TinyKtx_Height(ctx));
226 | REQUIRE(TinyKtx_GetFormat(ctx) == TKTX_R8G8B8_UNORM);
227 |
228 | VFile_Seek(reffile, origin, VFile_SD_Begin);
229 | stbi_uc *refdata = stbi_load_from_callbacks(&stbi_callbacks, (void*)reffile.owned, &w, &h, &cmp, cmp);
230 | REQUIRE(refdata);
231 |
232 | auto ktxdata = (uint8_t const*)TinyKtx_ImageRawData(ctx, 0);
233 | REQUIRE(CmpFlipped(w, h, 3, w * cmp, w * cmp, refdata, ktxdata));
234 |
235 | MEMORY_FREE((void*)refdata);
236 | TinyKtx_DestroyContext(ctx);
237 | }
238 |
239 | TEST_CASE("TinyKtx luminance-reference okay", "[TinyKtx Loader]") {
240 | TinyKtx_Callbacks callbacks {
241 | &tinyktxCallbackError,
242 | &tinyktxCallbackAlloc,
243 | &tinyktxCallbackFree,
244 | tinyktxCallbackRead,
245 | &tinyktxCallbackSeek,
246 | &tinyktxCallbackTell
247 | };
248 |
249 | stbi_io_callbacks stbi_callbacks{
250 | &stbIoCallbackRead,
251 | &stbIoCallbackSkip,
252 | &stbIoCallbackEof
253 | };
254 |
255 | VFile::ScopedFile file = VFile::File::FromFile("luminance-reference-metadata.ktx", Os_FM_ReadBinary);
256 | VFile::ScopedFile reffile = VFile::File::FromFile("luminance.pgm", Os_FM_ReadBinary);
257 | REQUIRE(file);
258 | REQUIRE(reffile);
259 |
260 | auto ctx = TinyKtx_CreateContext(&callbacks, (void*)file.owned);
261 |
262 | REQUIRE(TinyKtx_ReadHeader(ctx));
263 |
264 | size_t origin = VFile_Tell(reffile);
265 |
266 | int w = 0, h = 0, cmp = 0;
267 | stbi_info_from_callbacks(&stbi_callbacks, (void*)reffile.owned, &w, &h, &cmp);
268 | REQUIRE(w == TinyKtx_Width(ctx));
269 | REQUIRE(h == TinyKtx_Height(ctx));
270 | REQUIRE(TinyKtx_GetFormat(ctx) == TKTX_R8_UNORM);
271 | REQUIRE(cmp == 1);
272 |
273 | VFile_Seek(reffile, origin, VFile_SD_Begin);
274 | stbi_uc *refdata = stbi_load_from_callbacks(&stbi_callbacks, (void*)reffile.owned, &w, &h, &cmp, cmp);
275 | REQUIRE(refdata);
276 |
277 | auto ktxdata = (uint8_t const*)TinyKtx_ImageRawData(ctx, 0);
278 | REQUIRE(CmpSame(w, h, 1, w * cmp, w * cmp, refdata, ktxdata));
279 |
280 | MEMORY_FREE((void*)refdata);
281 | TinyKtx_DestroyContext(ctx);
282 | }
283 |
284 | TEST_CASE("TinyKtx git hub #2 (image size before image raw data broken) fix test", "[TinyKtx Loader]") {
285 | TinyKtx_Callbacks callbacks {
286 | &tinyktxCallbackError,
287 | &tinyktxCallbackAlloc,
288 | &tinyktxCallbackFree,
289 | tinyktxCallbackRead,
290 | &tinyktxCallbackSeek,
291 | &tinyktxCallbackTell
292 | };
293 |
294 | stbi_io_callbacks stbi_callbacks{
295 | &stbIoCallbackRead,
296 | &stbIoCallbackSkip,
297 | &stbIoCallbackEof
298 | };
299 |
300 | VFile::ScopedFile file = VFile::File::FromFile("rgb-reference.ktx", Os_FM_ReadBinary);
301 | VFile::ScopedFile reffile = VFile::File::FromFile("rgb.ppm", Os_FM_ReadBinary);
302 | REQUIRE(file);
303 | REQUIRE(reffile);
304 | auto ctx = TinyKtx_CreateContext(&callbacks, (void*)file.owned);
305 |
306 | REQUIRE(TinyKtx_ReadHeader(ctx));
307 |
308 |
309 | size_t origin = VFile_Tell(reffile);
310 |
311 | int w = 0, h = 0, cmp = 0;
312 | stbi_info_from_callbacks(&stbi_callbacks, (void*)reffile.owned, &w, &h, &cmp);
313 |
314 | uint64_t memoryRequirement = sizeof(stbi_uc) * w * h * cmp;
315 |
316 | // perform an image size op, this shouldn't break the later image raw data if this if fixed
317 | REQUIRE(memoryRequirement == TinyKtx_ImageSize(ctx, 0));
318 |
319 | VFile_Seek(reffile, origin, VFile_SD_Begin);
320 | stbi_uc const *refdata = stbi_load_from_callbacks(&stbi_callbacks, (void*)reffile.owned, &w, &h, &cmp, cmp);
321 | REQUIRE(refdata);
322 |
323 | auto ktxdata = (uint8_t const*)TinyKtx_ImageRawData(ctx, 0);
324 | REQUIRE(CmpFlipped(w, h, 3, w * cmp, w * cmp, refdata, ktxdata));
325 |
326 | MEMORY_FREE((void*)refdata);
327 | TinyKtx_DestroyContext(ctx);
328 | }
329 |
330 | TEST_CASE("TinyKtx mipmap reference check", "[TinyKtx Loader]") {
331 | TinyKtx_Callbacks callbacks {
332 | &tinyktxCallbackError,
333 | &tinyktxCallbackAlloc,
334 | &tinyktxCallbackFree,
335 | tinyktxCallbackRead,
336 | &tinyktxCallbackSeek,
337 | &tinyktxCallbackTell
338 | };
339 |
340 | stbi_io_callbacks stbi_callbacks{
341 | &stbIoCallbackRead,
342 | &stbIoCallbackSkip,
343 | &stbIoCallbackEof
344 | };
345 |
346 | VFile::ScopedFile file = VFile::File::FromFile("rgb-mipmap-reference.ktx", Os_FM_ReadBinary);
347 | VFile::ScopedFile reffile[7] {
348 | VFile::File::FromFile("level0.ppm", Os_FM_ReadBinary),
349 | VFile::File::FromFile("level1.ppm", Os_FM_ReadBinary),
350 | VFile::File::FromFile("level2.ppm", Os_FM_ReadBinary),
351 | VFile::File::FromFile("level3.ppm", Os_FM_ReadBinary),
352 | VFile::File::FromFile("level4.ppm", Os_FM_ReadBinary),
353 | VFile::File::FromFile("level5.ppm", Os_FM_ReadBinary),
354 | VFile::File::FromFile("level6.ppm", Os_FM_ReadBinary),
355 | };
356 | REQUIRE(file);
357 |
358 | auto ctx = TinyKtx_CreateContext(&callbacks, (void*)file.owned);
359 | REQUIRE(TinyKtx_ReadHeader(ctx));
360 |
361 | REQUIRE(TinyKtx_NumberOfMipmaps(ctx) == 7);
362 |
363 | for (auto i = 0u; i < 7; ++i) {
364 | size_t origin = VFile_Tell(reffile[i]);
365 | int w = 0, h = 0, cmp = 0;
366 |
367 | stbi_info_from_callbacks(&stbi_callbacks, (void*)reffile[i].owned, &w, &h, &cmp);
368 | VFile_Seek(reffile[i], origin, VFile_SD_Begin);
369 | stbi_uc const *refdata = stbi_load_from_callbacks(&stbi_callbacks, (void*)reffile[i].owned, &w, &h, &cmp, cmp);
370 | REQUIRE(refdata);
371 |
372 | uint32_t const srcStride = w * cmp;
373 | uint32_t dstStride = srcStride;
374 |
375 | if( i < 5) {
376 | uint64_t const memoryRequirement = sizeof(stbi_uc) * w * h * cmp;
377 | REQUIRE(memoryRequirement == TinyKtx_ImageSize(ctx, i));
378 | REQUIRE(!TinyKtx_IsMipMapLevelUnpacked(ctx,i));
379 | } else {
380 | REQUIRE(TinyKtx_IsMipMapLevelUnpacked(ctx,i));
381 | dstStride = TinyKtx_UnpackedRowStride(ctx,i);
382 | if(i == 5) {
383 | REQUIRE(dstStride == 8);
384 | } else if(i == 6) {
385 | REQUIRE(dstStride == 4);
386 | }
387 | }
388 |
389 | auto ktxdata = (uint8_t const*)TinyKtx_ImageRawData(ctx, i);
390 | REQUIRE(CmpFlipped(w, h, 3, srcStride, dstStride, refdata, ktxdata));
391 | MEMORY_FREE((void*)refdata);
392 | }
393 |
394 | TinyKtx_DestroyContext(ctx);
395 | }
--------------------------------------------------------------------------------
/tests/test_tinyktx_tinyimageformat.cpp:
--------------------------------------------------------------------------------
1 | #include "al2o3_platform/platform.h"
2 | #include "tiny_imageformat/tinyimageformat_base.h"
3 | #include "tiny_ktx/tinyktx.h"
4 |
--------------------------------------------------------------------------------