/* -*- tab-width: 4; -*- */ /* vi: set sw=2 ts=4 expandtab: */ /* * Copyright 2018-2020 Mark Callow. * SPDX-License-Identifier: Apache-2.0 */ /** * @internal * @file texture.c * @~English * * @brief ktxTexture implementation. * * @author Mark Callow, www.edgewise-consulting.com */ #if defined(_WIN32) #define _CRT_SECURE_NO_WARNINGS #ifndef __cplusplus #undef inline #define inline __inline #endif // __cplusplus #endif #include <assert.h> #include <math.h> #include <stdlib.h> #include <string.h> #include "ktx.h" #include "ktxint.h" #include "formatsize.h" #include "filestream.h" #include "memstream.h" #include "texture1.h" #include "texture2.h" #include "unused.h" ktx_size_t ktxTexture_GetDataSize(ktxTexture* This); static ktx_uint32_t padRow(ktx_uint32_t* rowBytes); /** * @memberof ktxTexture @private * @~English * @brief Construct (initialize) a ktxTexture base class instance. * * @param[in] This pointer to a ktxTexture-sized block of memory to * initialize. * @param[in] createInfo pointer to a ktxTextureCreateInfo struct with * information describing the texture. * @param[in] formatSize pointer to a ktxFormatSize giving size information * about the texture's elements. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_INVALID_VALUE @c glInternalFormat in @p createInfo is not a * valid OpenGL internal format value. * @exception KTX_INVALID_VALUE @c numDimensions in @p createInfo is not 1, 2 * or 3. * @exception KTX_INVALID_VALUE One of <tt>base{Width,Height,Depth}</tt> in * @p createInfo is 0. * @exception KTX_INVALID_VALUE @c numFaces in @p createInfo is not 1 or 6. * @exception KTX_INVALID_VALUE @c numLevels in @p createInfo is 0. * @exception KTX_INVALID_OPERATION * The <tt>base{Width,Height,Depth}</tt> specified * in @p createInfo are inconsistent with * @c numDimensions. * @exception KTX_INVALID_OPERATION * @p createInfo is requesting a 3D array or * 3D cubemap texture. * @exception KTX_INVALID_OPERATION * @p createInfo is requesting a cubemap with * non-square or non-2D images. * @exception KTX_INVALID_OPERATION * @p createInfo is requesting more mip levels * than needed for the specified * <tt>base{Width,Height,Depth}</tt>. * @exception KTX_OUT_OF_MEMORY Not enough memory for the texture. */ KTX_error_code ktxTexture_construct(ktxTexture* This, ktxTextureCreateInfo* createInfo, ktxFormatSize* formatSize) { … } /** * @memberof ktxTexture @private * @~English * @brief Construct (initialize) the part of a ktxTexture base class that is * not related to the stream contents. * * @param[in] This pointer to a ktxTexture-sized block of memory to * initialize. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. */ KTX_error_code ktxTexture_constructFromStream(ktxTexture* This, ktxStream* pStream, ktxTextureCreateFlags createFlags) { … } /** * @memberof ktxTexture @private * @~English * @brief Free the memory associated with the texture contents * * @param[in] This pointer to the ktxTextureInt whose texture contents are * to be freed. */ void ktxTexture_destruct(ktxTexture* This) { … } /** * @defgroup reader Reader * @brief Read KTX-formatted data. * @{ */ ktxFileType_; ktxHeaderUnion_; /** * @memberof ktxTexture @private * @~English * @brief Determine if stream data is KTX1 or KTX2. * * @param pStream pointer to the ktxStream to examine. * @param pFileType pointer to a ktxFileType enum where the type of the data * will be written. * @param pHeader pointer to a ktxHeaderUnion where the header info. will be * written. */ static KTX_error_code ktxDetermineFileType_(ktxStream* pStream, ktxFileType_* pFileType, ktxHeaderUnion_* pHeader) { … } /** * @memberof ktxTexture * @~English * @brief Create a ktx1 or ktx2 texture according to the stream * data. * * See @ref ktxTexture1::ktxTexture1_CreateFromStream * "ktxTexture1_CreateFromStream" or * @ref ktxTexture2::ktxTexture2_CreateFromStream * "ktxTexture2_CreateFromStream" for details. */ KTX_error_code ktxTexture_CreateFromStream(ktxStream* pStream, ktxTextureCreateFlags createFlags, ktxTexture** newTex) { … } /** * @memberof ktxTexture * @~English * @brief Create a ktxTexture1 or ktxTexture2 from a stdio stream according * to the stream data. * * See @ref ktxTexture1::ktxTexture1_CreateFromStdioStream * "ktxTexture1_CreateFromStdioStream" or * @ref ktxTexture2::ktxTexture2_CreateFromStdioStream * "ktxTexture2_CreateFromStdioStream" for details. */ KTX_error_code ktxTexture_CreateFromStdioStream(FILE* stdioStream, ktxTextureCreateFlags createFlags, ktxTexture** newTex) { … } /** * @memberof ktxTexture * @~English * @brief Create a ktxTexture1 or ktxTexture2 from a named KTX file according * to the file contents. * * See @ref ktxTexture1::ktxTexture1_CreateFromNamedFile * "ktxTexture1_CreateFromNamedFile" or * @ref ktxTexture2::ktxTexture2_CreateFromNamedFile * "ktxTexture2_CreateFromNamedFile" for details. */ KTX_error_code ktxTexture_CreateFromNamedFile(const char* const filename, ktxTextureCreateFlags createFlags, ktxTexture** newTex) { … } /** * @memberof ktxTexture * @~English * @brief Create a ktxTexture1 or ktxTexture2 from KTX-formatted data in memory * according to the data contents. * * See @ref ktxTexture1::ktxTexture1_CreateFromMemory * "ktxTexture1_CreateFromMemory" or * @ref ktxTexture2::ktxTexture2_CreateFromMemory * "ktxTexture2_CreateFromMemory" for details. */ KTX_error_code ktxTexture_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size, ktxTextureCreateFlags createFlags, ktxTexture** newTex) { … } /** * @memberof ktxTexture * @~English * @brief Return a pointer to the texture image data. * * @param[in] This pointer to the ktxTexture object of interest. */ ktx_uint8_t* ktxTexture_GetData(ktxTexture* This) { … } /** * @memberof ktxTexture * @~English * @brief Return the total size of the texture image data in bytes. * * For a ktxTexture2 with supercompressionScheme != KTX_SS_NONE this will * return the deflated size of the data. * * @param[in] This pointer to the ktxTexture object of interest. */ ktx_size_t ktxTexture_GetDataSize(ktxTexture* This) { … } /** * @memberof ktxTexture * @~English * @brief Return the size in bytes of an elements of a texture's * images. * * For uncompressed textures an element is one texel. For compressed * textures it is one block. * * @param[in] This pointer to the ktxTexture object of interest. */ ktx_uint32_t ktxTexture_GetElementSize(ktxTexture* This) { … } /** * @memberof ktxTexture @private * @~English * @brief Calculate & return the size in bytes of an image at the specified * mip level. * * For arrays, this is the size of layer, for cubemaps, the size of a face * and for 3D textures, the size of a depth slice. * * The size reflects the padding of each row to KTX_GL_UNPACK_ALIGNMENT. * * @param[in] This pointer to the ktxTexture object of interest. * @param[in] level level of interest. * @param[in] fv enum specifying format version for which to calculate * image size. */ ktx_size_t ktxTexture_calcImageSize(ktxTexture* This, ktx_uint32_t level, ktxFormatVersionEnum fv) { … } /** * @memberof ktxTexture * @~English * @brief Iterate over the levels or faces in a ktxTexture object. * * Blocks of image data are passed to an application-supplied callback * function. This is not a strict per-image iteration. Rather it reflects how * OpenGL needs the images. For most textures the block of data includes all * images of a mip level which implies all layers of an array. However, for * non-array cube map textures the block is a single face of the mip level, * i.e the callback is called once for each face. * * This function works even if @p This->pData == 0 so it can be used to * obtain offsets and sizes for each level by callers who have loaded the data * externally. * * @param[in] This pointer to the ktxTexture object of interest. * @param[in,out] iterCb the address of a callback function which is called * with the data for each image block. * @param[in,out] userdata the address of application-specific data which is * passed to the callback along with the image data. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. The * following are returned directly by this function. @p iterCb may * return these for other causes or may return additional errors. * * @exception KTX_FILE_DATA_ERROR Mip level sizes are increasing not * decreasing * @exception KTX_INVALID_VALUE @p This is @c NULL or @p iterCb is @c NULL. * */ KTX_error_code ktxTexture_IterateLevelFaces(ktxTexture* This, PFNKTXITERCB iterCb, void* userdata) { … } /** * @internal * @brief Calculate and apply the padding needed to comply with * KTX_GL_UNPACK_ALIGNMENT. * * For uncompressed textures, KTX format specifies KTX_GL_UNPACK_ALIGNMENT = 4. * * @param[in,out] rowBytes pointer to variable containing the packed no. of * bytes in a row. The no. of bytes after padding * is written into this location. * @return the no. of bytes of padding. */ static ktx_uint32_t padRow(ktx_uint32_t* rowBytes) { … } /** * @memberof ktxTexture @private * @~English * @brief Calculate the size of an array layer at the specified mip level. * * The size of a layer is the size of an image * either the number of faces * or the number of depth slices. This is the size of a layer as needed to * find the offset within the array of images of a level and layer so the size * reflects any @c cubePadding. * * @param[in] This pointer to the ktxTexture object of interest. * @param[in] level level whose layer size to return. * * @return the layer size in bytes. */ ktx_size_t ktxTexture_layerSize(ktxTexture* This, ktx_uint32_t level, ktxFormatVersionEnum fv) { … } /** * @memberof ktxTexture @private * @~English * @brief Calculate the size of the specified mip level. * * The size of a level is the size of a layer * the number of layers. * * @param[in] This pointer to the ktxTexture object of interest. * @param[in] level level whose layer size to return. * * @return the level size in bytes. */ ktx_size_t ktxTexture_calcLevelSize(ktxTexture* This, ktx_uint32_t level, ktxFormatVersionEnum fv) { … } /** * @memberof ktxTexture @private * @~English * @brief Calculate the faceLodSize of the specified mip level. * * The faceLodSize of a level for most textures is the size of a level. For * non-array cube map textures is the size of a face. This is the size that * must be provided to OpenGL when uploading textures. Faces get uploaded 1 * at a time while all layers of an array or all slices of a 3D texture are * uploaded together. * * @param[in] This pointer to the ktxTexture object of interest. * @param[in] level level whose layer size to return. * * @return the faceLodSize size in bytes. */ ktx_size_t ktxTexture_doCalcFaceLodSize(ktxTexture* This, ktx_uint32_t level, ktxFormatVersionEnum fv) { … } /** * @memberof ktxTexture @private * @~English * @brief Return the number of bytes needed to store all the image data for * a ktxTexture. * * The caclulated size does not include space for storing the @c imageSize * fields of each mip level. * * @param[in] This pointer to the ktxTexture object of interest. * @param[in] fv enum specifying format version for which to calculate * image size. * * @return the data size in bytes. */ ktx_size_t ktxTexture_calcDataSizeTexture(ktxTexture* This) { … } /** * @memberof ktxTexture @private * @~English * @brief Get information about rows of an uncompresssed texture image at a * specified level. * * For an image at @p level of a ktxTexture provide the number of rows, the * packed (unpadded) number of bytes in a row and the padding necessary to * comply with KTX_GL_UNPACK_ALIGNMENT. * * @param[in] This pointer to the ktxTexture object of interest. * @param[in] level level of interest. * @param[in,out] numRows pointer to location to store the number of rows. * @param[in,out] pRowLengthBytes pointer to location to store number of bytes * in a row. * @param[in.out] pRowPadding pointer to location to store the number of bytes * of padding. */ void ktxTexture_rowInfo(ktxTexture* This, ktx_uint32_t level, ktx_uint32_t* numRows, ktx_uint32_t* pRowLengthBytes, ktx_uint32_t* pRowPadding) { … } /** * @memberof ktxTexture * @~English * @brief Return pitch betweeb rows of a texture image level in bytes. * * For uncompressed textures the pitch is the number of bytes between * rows of texels. For compressed textures it is the number of bytes * between rows of blocks. The value is padded to GL_UNPACK_ALIGNMENT, * if necessary. For all currently known compressed formats padding * will not be necessary. * * @param[in] This pointer to the ktxTexture object of interest. * @param[in] level level of interest. * * @return the row pitch in bytes. */ ktx_uint32_t ktxTexture_GetRowPitch(ktxTexture* This, ktx_uint32_t level) { … } /** * @memberof ktxTexture @private * @~English * @brief Query if a ktxTexture has an active stream. * * Tests if a ktxTexture has unread image data. The internal stream is closed * once all the images have been read. * * @param[in] This pointer to the ktxTexture object of interest. * * @return KTX_TRUE if there is an active stream, KTX_FALSE otherwise. */ ktx_bool_t ktxTexture_isActiveStream(ktxTexture* This) { … } /** @} */