* Copyright 2023-2023 The Khronos Group Inc.
* Copyright 2023-2023 RasterGrid Kft.
* SPDX-License-Identifier: Apache-2.0
*/
* @internal
* @file
* @~English
*
* @brief Wrapper functions for ZLIB compression/decompression using miniz.
*
* @author Daniel Rakos, RasterGrid
*/
#include "ktx.h"
#include "ktxint.h"
#include <assert.h>
#if !KTX_FEATURE_WRITE
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
#endif
#include "basisu/encoder/basisu_miniz.h"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#else
namespace buminiz {
typedef unsigned long mz_ulong;
enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 };
mz_ulong mz_compressBound(mz_ulong source_len);
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
}
#endif
using namespace buminiz;
extern "C" {
* @internal
* @~English
* @brief Returns upper bound for compresses data using miniz (ZLIB).
*
* @param srcLength source data length
*
* @author Daniel Rakos, RasterGrid
*/
ktx_size_t ktxCompressZLIBBounds(ktx_size_t srcLength) {
return mz_compressBound((mz_ulong)srcLength);
}
* @internal
* @~English
* @brief Compresses data using miniz (ZLIB)
*
* @param pDest destination data buffer
* @param pDestLength destination data buffer size
* (filled with written byte count on success)
* @param pSrc source data buffer
* @param srcLength source data size
* @param level compression level (between 1 and 9)
*
* @author Daniel Rakos, RasterGrid
*/
KTX_error_code ktxCompressZLIBInt(unsigned char* pDest,
ktx_size_t* pDestLength,
const unsigned char* pSrc,
ktx_size_t srcLength,
ktx_uint32_t level) {
if ((srcLength | *pDestLength) > 0xFFFFFFFFU) return KTX_INVALID_VALUE;
mz_ulong mzCompressedSize = (mz_ulong)*pDestLength;
int status = mz_compress2(pDest, &mzCompressedSize, pSrc, (mz_ulong)srcLength, level);
switch (status) {
case MZ_OK:
*pDestLength = mzCompressedSize;
return KTX_SUCCESS;
case MZ_PARAM_ERROR:
return KTX_INVALID_VALUE;
case MZ_BUF_ERROR:
#ifdef DEBUG
assert(false && "Deflate dstSize too small.");
#endif
return KTX_OUT_OF_MEMORY;
case MZ_MEM_ERROR:
#ifdef DEBUG
assert(false && "Deflate workspace too small.");
#endif
return KTX_OUT_OF_MEMORY;
default:
#ifdef DEBUG
assert(true);
#endif
return KTX_INVALID_OPERATION;
}
}
* @internal
* @~English
* @brief Uncompresses data using miniz (ZLIB)
*
* @param pDest destination data buffer
* @param pDestLength destination data buffer size
* (filled with written byte count on success)
* @param pSrc source data buffer
* @param srcLength source data size
*
* @author Daniel Rakos, RasterGrid
*/
KTX_error_code ktxUncompressZLIBInt(unsigned char* pDest,
ktx_size_t* pDestLength,
const unsigned char* pSrc,
ktx_size_t srcLength) {
if ((srcLength | *pDestLength) > 0xFFFFFFFFU) return KTX_INVALID_VALUE;
mz_ulong mzUncompressedSize = (mz_ulong)*pDestLength;
int status = mz_uncompress(pDest, &mzUncompressedSize, pSrc, (mz_ulong)srcLength);
switch (status) {
case MZ_OK:
*pDestLength = mzUncompressedSize;
return KTX_SUCCESS;
case MZ_BUF_ERROR:
return KTX_DECOMPRESS_LENGTH_ERROR;
case MZ_MEM_ERROR:
return KTX_OUT_OF_MEMORY;
default:
return KTX_FILE_DATA_ERROR;
}
}
}