Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tinyexr: Sync with upstream 1.0.7 #80384

Merged
merged 1 commit into from
Aug 8, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 87 additions & 9 deletions thirdparty/tinyexr/tinyexr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -650,14 +658,19 @@ 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
// including `tinyexr.h`
//#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
Expand All @@ -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__
Expand Down Expand Up @@ -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
//
Expand All @@ -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) {
Expand All @@ -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));
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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));
Expand All @@ -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,
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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())));
Expand Down