tinyexr: Sync with upstream 1.0.7

(cherry picked from commit b70e2af3b7)
This commit is contained in:
Rémi Verschelde 2023-08-07 18:25:37 +02:00
parent d29ec6af45
commit a2e4df43a3
No known key found for this signature in database
GPG Key ID: C3336907360768E1
1 changed files with 87 additions and 9 deletions

View File

@ -114,6 +114,11 @@ extern "C" {
#define TINYEXR_USE_STB_ZLIB (0)
#endif
// Use nanozlib.
#ifndef TINYEXR_USE_NANOZLIB
#define TINYEXR_USE_NANOZLIB (0)
#endif
// Disable PIZ compression when applying cpplint.
#ifndef TINYEXR_USE_PIZ
#define TINYEXR_USE_PIZ (1)
@ -608,7 +613,10 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
#define NOMINMAX
#endif
#include <windows.h> // for UTF-8 and memory-mapping
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
#define TINYEXR_USE_WIN32_MMAP (1)
#endif
#elif defined(__linux__) || defined(__unix__)
#include <fcntl.h> // for open()
@ -650,7 +658,7 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
#include <omp.h>
#endif
#if TINYEXR_USE_MINIZ
#if defined(TINYEXR_USE_MINIZ) && (TINYEXR_USE_MINIZ==1)
#include <miniz.h>
#else
// Issue #46. Please include your own zlib-compatible API header before
@ -658,6 +666,11 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
//#include "zlib.h"
#endif
#if defined(TINYEXR_USE_NANOZLIB) && (TINYEXR_USE_NANOZLIB==1)
#define NANOZLIB_IMPLEMENTATION
#include "nanozlib.h"
#endif
#if TINYEXR_USE_STB_ZLIB
// Since we don't know where a project has stb_image.h and stb_image_write.h
// and whether they are in the include path, we don't include them here, and
@ -668,6 +681,7 @@ extern "C" int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuf
extern "C" unsigned char *stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality);
#endif
#if TINYEXR_USE_ZFP
#ifdef __clang__
@ -1343,7 +1357,7 @@ static bool CompressZip(unsigned char *dst,
}
}
#if TINYEXR_USE_MINIZ
#if defined(TINYEXR_USE_MINIZ) && (TINYEXR_USE_MINIZ==1)
//
// Compress the data using miniz
//
@ -1357,7 +1371,7 @@ static bool CompressZip(unsigned char *dst,
}
compressedSize = outSize;
#elif TINYEXR_USE_STB_ZLIB
#elif defined(TINYEXR_USE_STB_ZLIB) && (TINYEXR_USE_STB_ZLIB==1)
int outSize;
unsigned char* ret = stbi_zlib_compress(const_cast<unsigned char*>(&tmpBuf.at(0)), src_size, &outSize, 8);
if (!ret) {
@ -1366,6 +1380,18 @@ static bool CompressZip(unsigned char *dst,
memcpy(dst, ret, outSize);
free(ret);
compressedSize = outSize;
#elif defined(TINYEXR_USE_NANOZLIB) && (TINYEXR_USE_NANOZLIB==1)
uint64_t dstSize = nanoz_compressBound(static_cast<uint64_t>(src_size));
int outSize{0};
unsigned char *ret = nanoz_compress(&tmpBuf.at(0), src_size, &outSize, /* quality */8);
if (!ret) {
return false;
}
memcpy(dst, ret, outSize);
free(ret);
compressedSize = outSize;
#else
uLong outSize = compressBound(static_cast<uLong>(src_size));
@ -1398,7 +1424,7 @@ static bool DecompressZip(unsigned char *dst,
}
std::vector<unsigned char> tmpBuf(*uncompressed_size);
#if TINYEXR_USE_MINIZ
#if defined(TINYEXR_USE_MINIZ) && (TINYEXR_USE_MINIZ==1)
int ret =
mz_uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size);
if (MZ_OK != ret) {
@ -1410,6 +1436,17 @@ static bool DecompressZip(unsigned char *dst,
if (ret < 0) {
return false;
}
#elif defined(TINYEXR_USE_NANOZLIB) && (TINYEXR_USE_NANOZLIB==1)
uint64_t dest_size = (*uncompressed_size);
uint64_t uncomp_size{0};
nanoz_status_t ret =
nanoz_uncompress(src, src_size, dest_size, &tmpBuf.at(0), &uncomp_size);
if (NANOZ_SUCCESS != ret) {
return false;
}
if ((*uncompressed_size) != uncomp_size) {
return false;
}
#else
int ret = uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size);
if (Z_OK != ret) {
@ -5715,7 +5752,7 @@ static bool isValidTile(const EXRHeader* exr_header,
static bool ReconstructTileOffsets(OffsetData& offset_data,
const EXRHeader* exr_header,
const unsigned char* head, const unsigned char* marker, const size_t /*size*/,
const unsigned char* head, const unsigned char* marker, const size_t size,
bool isMultiPartFile,
bool isDeep) {
int numXLevels = offset_data.num_x_levels;
@ -5724,11 +5761,20 @@ static bool ReconstructTileOffsets(OffsetData& offset_data,
for (unsigned int dx = 0; dx < offset_data.offsets[l][dy].size(); ++dx) {
tinyexr::tinyexr_uint64 tileOffset = tinyexr::tinyexr_uint64(marker - head);
if (isMultiPartFile) {
if ((marker + sizeof(int)) >= (head + size)) {
return false;
}
//int partNumber;
marker += sizeof(int);
}
if ((marker + 4 * sizeof(int)) >= (head + size)) {
return false;
}
int tileX;
memcpy(&tileX, marker, sizeof(int));
tinyexr::swap4(&tileX);
@ -5750,6 +5796,9 @@ static bool ReconstructTileOffsets(OffsetData& offset_data,
marker += sizeof(int);
if (isDeep) {
if ((marker + 2 * sizeof(tinyexr::tinyexr_int64)) >= (head + size)) {
return false;
}
tinyexr::tinyexr_int64 packed_offset_table_size;
memcpy(&packed_offset_table_size, marker, sizeof(tinyexr::tinyexr_int64));
tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64*>(&packed_offset_table_size));
@ -5763,13 +5812,26 @@ static bool ReconstructTileOffsets(OffsetData& offset_data,
// next Int64 is unpacked sample size - skip that too
marker += packed_offset_table_size + packed_sample_size + 8;
if (marker >= (head + size)) {
return false;
}
} else {
int dataSize;
memcpy(&dataSize, marker, sizeof(int));
if ((marker + sizeof(uint32_t)) >= (head + size)) {
return false;
}
uint32_t dataSize;
memcpy(&dataSize, marker, sizeof(uint32_t));
tinyexr::swap4(&dataSize);
marker += sizeof(int);
marker += sizeof(uint32_t);
marker += dataSize;
if (marker >= (head + size)) {
return false;
}
}
if (!isValidTile(exr_header, offset_data,
@ -5781,6 +5843,19 @@ static bool ReconstructTileOffsets(OffsetData& offset_data,
if (level_idx < 0) {
return false;
}
if (size_t(level_idx) >= offset_data.offsets.size()) {
return false;
}
if (size_t(tileY) >= offset_data.offsets[size_t(level_idx)].size()) {
return false;
}
if (size_t(tileX) >= offset_data.offsets[size_t(level_idx)][size_t(tileY)].size()) {
return false;
}
offset_data.offsets[size_t(level_idx)][size_t(tileY)][size_t(tileX)] = tileOffset;
}
}
@ -7043,13 +7118,16 @@ static bool EncodePixelData(/* out */ std::vector<unsigned char>& out_data,
} else if ((compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) ||
(compression_type == TINYEXR_COMPRESSIONTYPE_ZIP)) {
#if TINYEXR_USE_MINIZ
#if defined(TINYEXR_USE_MINIZ) && (TINYEXR_USE_MINIZ==1)
std::vector<unsigned char> block(mz_compressBound(
static_cast<unsigned long>(buf.size())));
#elif TINYEXR_USE_STB_ZLIB
// there is no compressBound() function, so we use a value that
// is grossly overestimated, but should always work
std::vector<unsigned char> block(256 + 2 * buf.size());
#elif defined(TINYEXR_USE_NANOZLIB) && (TINYEXR_USE_NANOZLIB == 1)
std::vector<unsigned char> block(nanoz_compressBound(
static_cast<unsigned long>(buf.size())));
#else
std::vector<unsigned char> block(
compressBound(static_cast<uLong>(buf.size())));