/* -*- tab-width: 4; -*- */1/* vi: set sw=2 ts=4 expandtab: */23/* $Id$ */45/*6* Copyright 2010-2020 The Khronos Group Inc.7* SPDX-License-Identifier: Apache-2.08*/91011/*12* Author: Mark Callow from original code by Georg Kolling13*/1415#ifndef KTXINT_H16#define KTXINT_H1718#include <math.h>1920/* Define this to include the ETC unpack software in the library. */21#ifndef SUPPORT_SOFTWARE_ETC_UNPACK22/* Include for all GL versions because have seen OpenGL ES 323* implementaions that do not support ETC1 (ARM Mali emulator v1.0)!24*/25#define SUPPORT_SOFTWARE_ETC_UNPACK 126#endif2728#ifndef MAX29#define MAX(x, y) (((x) > (y)) ? (x) : (y))30#endif31#ifndef MIN32#define MIN(x, y) (((x) < (y)) ? (x) : (y))33#endif3435#define QUOTE(x) #x36#define STR(x) QUOTE(x)3738#define KTX2_IDENTIFIER_REF { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x32, 0x30, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }39#define KTX2_HEADER_SIZE (80)4041#ifdef __cplusplus42extern "C" {43#endif4445/**46* @internal47* @brief used to pass GL context capabilites to subroutines.48*/49#define _KTX_NO_R16_FORMATS 0x050#define _KTX_R16_FORMATS_NORM 0x151#define _KTX_R16_FORMATS_SNORM 0x252#define _KTX_ALL_R16_FORMATS (_KTX_R16_FORMATS_NORM | _KTX_R16_FORMATS_SNORM)53extern GLint _ktxR16Formats;54extern GLboolean _ktxSupportsSRGB;5556/**57* @internal58* @~English59* @brief KTX file header.60*61* See the KTX specification for descriptions.62*/63typedef struct KTX_header {64ktx_uint8_t identifier[12];65ktx_uint32_t endianness;66ktx_uint32_t glType;67ktx_uint32_t glTypeSize;68ktx_uint32_t glFormat;69ktx_uint32_t glInternalformat;70ktx_uint32_t glBaseInternalformat;71ktx_uint32_t pixelWidth;72ktx_uint32_t pixelHeight;73ktx_uint32_t pixelDepth;74ktx_uint32_t numberOfArrayElements;75ktx_uint32_t numberOfFaces;76ktx_uint32_t numberOfMipLevels;77ktx_uint32_t bytesOfKeyValueData;78} KTX_header;7980/* This will cause compilation to fail if the struct size doesn't match */81typedef int KTX_header_SIZE_ASSERT [sizeof(KTX_header) == KTX_HEADER_SIZE];8283/**84* @internal85* @~English86* @brief 32-bit KTX 2 index entry.87*/88typedef struct ktxIndexEntry32 {89ktx_uint32_t byteOffset; /*!< Offset of item from start of file. */90ktx_uint32_t byteLength; /*!< Number of bytes of data in the item. */91} ktxIndexEntry32;92/**93* @internal94* @~English95* @brief 64-bit KTX 2 index entry.96*/97typedef struct ktxIndexEntry64 {98ktx_uint64_t byteOffset; /*!< Offset of item from start of file. */99ktx_uint64_t byteLength; /*!< Number of bytes of data in the item. */100} ktxIndexEntry64;101102/**103* @internal104* @~English105* @brief KTX 2 file header.106*107* See the KTX 2 specification for descriptions.108*/109typedef struct KTX_header2 {110ktx_uint8_t identifier[12];111ktx_uint32_t vkFormat;112ktx_uint32_t typeSize;113ktx_uint32_t pixelWidth;114ktx_uint32_t pixelHeight;115ktx_uint32_t pixelDepth;116ktx_uint32_t layerCount;117ktx_uint32_t faceCount;118ktx_uint32_t levelCount;119ktx_uint32_t supercompressionScheme;120ktxIndexEntry32 dataFormatDescriptor;121ktxIndexEntry32 keyValueData;122ktxIndexEntry64 supercompressionGlobalData;123} KTX_header2;124125/* This will cause compilation to fail if the struct size doesn't match */126typedef int KTX_header2_SIZE_ASSERT [sizeof(KTX_header2) == KTX2_HEADER_SIZE];127128/**129* @internal130* @~English131* @brief KTX 2 level index entry.132*/133typedef struct ktxLevelIndexEntry {134ktx_uint64_t byteOffset; /*!< Offset of level from start of file. */135ktx_uint64_t byteLength;136/*!< Number of bytes of compressed image data in the level. */137ktx_uint64_t uncompressedByteLength;138/*!< Number of bytes of uncompressed image data in the level. */139} ktxLevelIndexEntry;140141/**142* @internal143* @~English144* @brief Structure for supplemental information about the texture.145*146* _ktxCheckHeader returns supplemental information about the texture in this147* structure that is derived during checking of the file header.148*/149typedef struct KTX_supplemental_info150{151ktx_uint8_t compressed;152ktx_uint8_t generateMipmaps;153ktx_uint16_t textureDimension;154} KTX_supplemental_info;155/**156* @internal157* @var ktx_uint8_t KTX_supplemental_info::compressed158* @~English159* @brief KTX_TRUE, if this a compressed texture, KTX_FALSE otherwise?160*/161/**162* @internal163* @var ktx_uint8_t KTX_supplemental_info::generateMipmaps164* @~English165* @brief KTX_TRUE, if mipmap generation is required, KTX_FALSE otherwise.166*/167/**168* @internal169* @var ktx_uint16_t KTX_supplemental_info::textureDimension170* @~English171* @brief The number of dimensions, 1, 2 or 3, of data in the texture image.172*/173174/*175* @internal176* CheckHeader1177*178* Reads the KTX file header and performs some sanity checking on the values179*/180KTX_error_code ktxCheckHeader1_(KTX_header* pHeader,181KTX_supplemental_info* pSuppInfo);182183/*184* @internal185* CheckHeader2186*187* Reads the KTX 2 file header and performs some sanity checking on the values188*/189KTX_error_code ktxCheckHeader2_(KTX_header2* pHeader,190KTX_supplemental_info* pSuppInfo);191192/*193* SwapEndian16: Swaps endianness in an array of 16-bit values194*/195void _ktxSwapEndian16(ktx_uint16_t* pData16, ktx_size_t count);196197/*198* SwapEndian32: Swaps endianness in an array of 32-bit values199*/200void _ktxSwapEndian32(ktx_uint32_t* pData32, ktx_size_t count);201202/*203* SwapEndian32: Swaps endianness in an array of 64-bit values204*/205void _ktxSwapEndian64(ktx_uint64_t* pData64, ktx_size_t count);206207/*208* UnpackETC: uncompresses an ETC compressed texture image209*/210KTX_error_code _ktxUnpackETC(const GLubyte* srcETC, const GLenum srcFormat,211ktx_uint32_t active_width, ktx_uint32_t active_height,212GLubyte** dstImage,213GLenum* format, GLenum* internalFormat, GLenum* type,214GLint R16Formats, GLboolean supportsSRGB);215216/*217* @internal218* ktxCompressZLIBBounds219*220* Returns upper bound for compresses data using miniz (ZLIB)221*/222ktx_size_t ktxCompressZLIBBounds(ktx_size_t srcLength);223224/*225* @internal226* ktxCompressZLIBInt227*228* Compresses data using miniz (ZLIB)229*/230KTX_error_code ktxCompressZLIBInt(unsigned char* pDest,231ktx_size_t* pDestLength,232const unsigned char* pSrc,233ktx_size_t srcLength,234ktx_uint32_t level);235236/*237* @internal238* ktxUncompressZLIBInt239*240* Uncompresses data using miniz (ZLIB)241*/242KTX_error_code ktxUncompressZLIBInt(unsigned char* pDest,243ktx_size_t* pDestLength,244const unsigned char* pSrc,245ktx_size_t srcLength);246247/*248* Pad nbytes to next multiple of n249*/250#define _KTX_PADN(n, nbytes) (ktx_uint32_t)(n * ceilf((float)(nbytes) / n))251/*252* Calculate bytes of of padding needed to reach next multiple of n.253*/254/* Equivalent to (n * ceil(nbytes / n)) - nbytes */255#define _KTX_PADN_LEN(n, nbytes) \256(ktx_uint32_t)((n * ceilf((float)(nbytes) / n)) - (nbytes))257258/*259* Pad nbytes to next multiple of 4260*/261#define _KTX_PAD4(nbytes) _KTX_PADN(4, nbytes)262/*263* Calculate bytes of of padding needed to reach next multiple of 4.264*/265#define _KTX_PAD4_LEN(nbytes) _KTX_PADN_LEN(4, nbytes)266267/*268* Pad nbytes to next multiple of 8269*/270#define _KTX_PAD8(nbytes) _KTX_PADN(8, nbytes)271/*272* Calculate bytes of of padding needed to reach next multiple of 8.273*/274#define _KTX_PAD8_LEN(nbytes) _KTX_PADN_LEN(8, nbytes)275276/*277* Pad nbytes to KTX_GL_UNPACK_ALIGNMENT278*/279#define _KTX_PAD_UNPACK_ALIGN(nbytes) \280_KTX_PADN(KTX_GL_UNPACK_ALIGNMENT, nbytes)281/*282* Calculate bytes of of padding needed to reach KTX_GL_UNPACK_ALIGNMENT.283*/284#define _KTX_PAD_UNPACK_ALIGN_LEN(nbytes) \285_KTX_PADN_LEN(KTX_GL_UNPACK_ALIGNMENT, nbytes)286287/*288======================================289Internal utility functions290======================================291*/292293KTX_error_code printKTX2Info2(ktxStream* src, KTX_header2* header);294295/*296* fopen a file identified by a UTF-8 path.297*/298#if defined(_WIN32)299#ifndef WIN32_LEAN_AND_MEAN300#define WIN32_LEAN_AND_MEAN301#endif302#ifndef NOMINMAX303#define NOMINMAX304#endif305#include <assert.h>306#include <windows.h>307#include <shellapi.h>308#include <stdlib.h>309310// For Windows, we convert the UTF-8 path and mode to UTF-16 path and use311// _wfopen which correctly handles unicode characters.312static inline FILE* ktxFOpenUTF8(char const* path, char const* mode) {313int wpLen = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);314int wmLen = MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);315FILE* fp = NULL;316if (wpLen > 0 && wmLen > 0)317{318wchar_t* wpath = (wchar_t*)malloc(wpLen * sizeof(wchar_t));319wchar_t* wmode = (wchar_t*)malloc(wmLen * sizeof(wchar_t));320MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, wpLen);321MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, wmLen);322// Returned errno_t value is also set in the global errno.323// Apps use that for error detail as libktx only returns324// KTX_FILE_OPEN_FAILED.325(void)_wfopen_s(&fp, wpath, wmode);326free(wpath);327free(wmode);328return fp;329} else {330assert(KTX_FALSE331&& "ktxFOpenUTF8 called with zero length path or mode.");332return NULL;333}334}335#else336// For other platforms there is no need for any conversion, they337// support UTF-8 natively.338static inline FILE* ktxFOpenUTF8(char const* path, char const* mode) {339return fopen(path, mode);340}341#endif342343#ifdef __cplusplus344}345#endif346347#endif /* KTXINT_H */348349350