TinyEXR: Sync with upstream master branch
Fixes #24247.
(cherry picked from commit 9105538b45
)
This commit is contained in:
parent
0921e68913
commit
2e18a4acdf
|
@ -355,7 +355,7 @@ License: Expat and BSD-3-clause
|
||||||
|
|
||||||
Files: ./thirdparty/tinyexr/
|
Files: ./thirdparty/tinyexr/
|
||||||
Comment: TinyEXR
|
Comment: TinyEXR
|
||||||
Copyright: 2014-2017, Syoyo Fujita
|
Copyright: 2014-2018, Syoyo Fujita
|
||||||
2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
|
2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
|
|
||||||
|
|
|
@ -450,7 +450,7 @@ are provided to reapply them.
|
||||||
## tinyexr
|
## tinyexr
|
||||||
|
|
||||||
- Upstream: https://github.com/syoyo/tinyexr
|
- Upstream: https://github.com/syoyo/tinyexr
|
||||||
- Version: git (2d5375f, 2018)
|
- Version: git (5ae30aa, 2018)
|
||||||
- License: BSD-3-Clause
|
- License: BSD-3-Clause
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|
|
@ -116,6 +116,8 @@ extern "C" {
|
||||||
#define TINYEXR_ERROR_UNSUPPORTED_FORMAT (-7)
|
#define TINYEXR_ERROR_UNSUPPORTED_FORMAT (-7)
|
||||||
#define TINYEXR_ERROR_INVALID_HEADER (-8)
|
#define TINYEXR_ERROR_INVALID_HEADER (-8)
|
||||||
#define TINYEXR_ERROR_UNSUPPORTED_FEATURE (-9)
|
#define TINYEXR_ERROR_UNSUPPORTED_FEATURE (-9)
|
||||||
|
#define TINYEXR_ERROR_CANT_WRITE_FILE (-10)
|
||||||
|
#define TINYEXR_ERROR_SERIALZATION_FAILED (-11)
|
||||||
|
|
||||||
// @note { OpenEXR file format: http://www.openexr.com/openexrfilelayout.pdf }
|
// @note { OpenEXR file format: http://www.openexr.com/openexrfilelayout.pdf }
|
||||||
|
|
||||||
|
@ -279,9 +281,12 @@ extern int LoadEXR(float **out_rgba, int *width, int *height,
|
||||||
// Save image as fp16(HALF) format when `save_as_fp16` is positive non-zero
|
// Save image as fp16(HALF) format when `save_as_fp16` is positive non-zero
|
||||||
// value.
|
// value.
|
||||||
// Save image as fp32(FLOAT) format when `save_as_fp16` is 0.
|
// Save image as fp32(FLOAT) format when `save_as_fp16` is 0.
|
||||||
|
// Use ZIP compression by default.
|
||||||
|
// Returns negative value and may set error string in `err` when there's an
|
||||||
|
// error
|
||||||
extern int SaveEXR(const float *data, const int width, const int height,
|
extern int SaveEXR(const float *data, const int width, const int height,
|
||||||
const int components, const int save_as_fp16,
|
const int components, const int save_as_fp16,
|
||||||
const char *filename);
|
const char *filename, const char **err);
|
||||||
|
|
||||||
// Initialize EXRHeader struct
|
// Initialize EXRHeader struct
|
||||||
extern void InitEXRHeader(EXRHeader *exr_header);
|
extern void InitEXRHeader(EXRHeader *exr_header);
|
||||||
|
@ -400,9 +405,9 @@ extern int SaveEXRImageToFile(const EXRImage *image,
|
||||||
|
|
||||||
// Saves multi-channel, single-frame OpenEXR image to a memory.
|
// Saves multi-channel, single-frame OpenEXR image to a memory.
|
||||||
// Image is compressed using EXRImage.compression value.
|
// Image is compressed using EXRImage.compression value.
|
||||||
// Return the number of bytes if succes.
|
// Return the number of bytes if success.
|
||||||
// Returns negative value and may set error string in `err` when there's an
|
// Return zero and will set error string in `err` when there's an
|
||||||
// error
|
// error.
|
||||||
// When there was an error message, Application must free `err` with
|
// When there was an error message, Application must free `err` with
|
||||||
// FreeEXRErrorMessage()
|
// FreeEXRErrorMessage()
|
||||||
extern size_t SaveEXRImageToMemory(const EXRImage *image,
|
extern size_t SaveEXRImageToMemory(const EXRImage *image,
|
||||||
|
@ -524,15 +529,23 @@ namespace miniz {
|
||||||
#if __has_warning("-Wcomma")
|
#if __has_warning("-Wcomma")
|
||||||
#pragma clang diagnostic ignored "-Wcomma"
|
#pragma clang diagnostic ignored "-Wcomma"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __has_warning("-Wmacro-redefined")
|
#if __has_warning("-Wmacro-redefined")
|
||||||
#pragma clang diagnostic ignored "-Wmacro-redefined"
|
#pragma clang diagnostic ignored "-Wmacro-redefined"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __has_warning("-Wcast-qual")
|
#if __has_warning("-Wcast-qual")
|
||||||
#pragma clang diagnostic ignored "-Wcast-qual"
|
#pragma clang diagnostic ignored "-Wcast-qual"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_warning("-Wtautological-constant-compare")
|
||||||
|
#pragma clang diagnostic ignored "-Wtautological-constant-compare"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP
|
/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP
|
||||||
|
@ -2518,10 +2531,10 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r,
|
||||||
tinfl_status status = TINFL_STATUS_FAILED;
|
tinfl_status status = TINFL_STATUS_FAILED;
|
||||||
mz_uint32 num_bits, dist, counter, num_extra;
|
mz_uint32 num_bits, dist, counter, num_extra;
|
||||||
tinfl_bit_buf_t bit_buf;
|
tinfl_bit_buf_t bit_buf;
|
||||||
const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end =
|
const mz_uint8 *pIn_buf_cur = pIn_buf_next,
|
||||||
pIn_buf_next + *pIn_buf_size;
|
*const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
|
||||||
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end =
|
mz_uint8 *pOut_buf_cur = pOut_buf_next,
|
||||||
pOut_buf_next + *pOut_buf_size;
|
*const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
|
||||||
size_t out_buf_size_mask =
|
size_t out_buf_size_mask =
|
||||||
(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)
|
(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)
|
||||||
? (size_t)-1
|
? (size_t)-1
|
||||||
|
@ -2938,9 +2951,8 @@ void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len,
|
||||||
tinfl_status status = tinfl_decompress(
|
tinfl_status status = tinfl_decompress(
|
||||||
&decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size,
|
&decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size,
|
||||||
(mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL,
|
(mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL,
|
||||||
&dst_buf_size,
|
&dst_buf_size, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) |
|
||||||
(flags & ~TINFL_FLAG_HAS_MORE_INPUT) |
|
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
|
||||||
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
|
|
||||||
if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) {
|
if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) {
|
||||||
MZ_FREE(pBuf);
|
MZ_FREE(pBuf);
|
||||||
*pOut_len = 0;
|
*pOut_len = 0;
|
||||||
|
@ -2993,8 +3005,9 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size,
|
||||||
tinfl_status status =
|
tinfl_status status =
|
||||||
tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs,
|
tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs,
|
||||||
&in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
|
&in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
|
||||||
(flags & ~(TINFL_FLAG_HAS_MORE_INPUT |
|
(flags &
|
||||||
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
|
~(TINFL_FLAG_HAS_MORE_INPUT |
|
||||||
|
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
|
||||||
in_buf_ofs += in_buf_size;
|
in_buf_ofs += in_buf_size;
|
||||||
if ((dst_buf_size) &&
|
if ((dst_buf_size) &&
|
||||||
(!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
|
(!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
|
||||||
|
@ -3119,9 +3132,7 @@ static const mz_uint8 s_tdefl_large_dist_extra[128] = {
|
||||||
|
|
||||||
// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted
|
// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted
|
||||||
// values.
|
// values.
|
||||||
typedef struct {
|
typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq;
|
||||||
mz_uint16 m_key, m_sym_index;
|
|
||||||
} tdefl_sym_freq;
|
|
||||||
static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms,
|
static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms,
|
||||||
tdefl_sym_freq *pSyms0,
|
tdefl_sym_freq *pSyms0,
|
||||||
tdefl_sym_freq *pSyms1) {
|
tdefl_sym_freq *pSyms1) {
|
||||||
|
@ -5265,10 +5276,9 @@ mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index,
|
||||||
n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS);
|
n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS);
|
||||||
n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
|
n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
|
||||||
pStat->m_comment_size = n;
|
pStat->m_comment_size = n;
|
||||||
memcpy(pStat->m_comment,
|
memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
|
||||||
p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
|
MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
|
||||||
MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
|
MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS),
|
||||||
MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS),
|
|
||||||
n);
|
n);
|
||||||
pStat->m_comment[n] = '\0';
|
pStat->m_comment[n] = '\0';
|
||||||
|
|
||||||
|
@ -10087,9 +10097,10 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
|
||||||
unsigned short *outLine =
|
unsigned short *outLine =
|
||||||
reinterpret_cast<unsigned short *>(out_images[c]);
|
reinterpret_cast<unsigned short *>(out_images[c]);
|
||||||
if (line_order == 0) {
|
if (line_order == 0) {
|
||||||
outLine += (y + v) * x_stride;
|
outLine += (size_t(y) + v) * size_t(x_stride);
|
||||||
} else {
|
} else {
|
||||||
outLine += (height - 1 - (y + v)) * x_stride;
|
outLine +=
|
||||||
|
(size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int u = 0; u < width; u++) {
|
for (int u = 0; u < width; u++) {
|
||||||
|
@ -10105,9 +10116,10 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
|
||||||
} else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) {
|
} else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) {
|
||||||
float *outLine = reinterpret_cast<float *>(out_images[c]);
|
float *outLine = reinterpret_cast<float *>(out_images[c]);
|
||||||
if (line_order == 0) {
|
if (line_order == 0) {
|
||||||
outLine += (y + v) * x_stride;
|
outLine += (size_t(y) + v) * size_t(x_stride);
|
||||||
} else {
|
} else {
|
||||||
outLine += (height - 1 - (y + v)) * x_stride;
|
outLine +=
|
||||||
|
(size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reinterpret_cast<const unsigned char *>(line_ptr + width) >
|
if (reinterpret_cast<const unsigned char *>(line_ptr + width) >
|
||||||
|
@ -10140,9 +10152,10 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
|
||||||
|
|
||||||
float *outLine = reinterpret_cast<float *>(out_images[c]);
|
float *outLine = reinterpret_cast<float *>(out_images[c]);
|
||||||
if (line_order == 0) {
|
if (line_order == 0) {
|
||||||
outLine += (y + v) * x_stride;
|
outLine += (size_t(y) + v) * size_t(x_stride);
|
||||||
} else {
|
} else {
|
||||||
outLine += (height - 1 - (y + v)) * x_stride;
|
outLine +=
|
||||||
|
(size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reinterpret_cast<const unsigned char *>(line_ptr + width) >
|
if (reinterpret_cast<const unsigned char *>(line_ptr + width) >
|
||||||
|
@ -10167,9 +10180,10 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
|
||||||
unsigned int *outLine =
|
unsigned int *outLine =
|
||||||
reinterpret_cast<unsigned int *>(out_images[c]);
|
reinterpret_cast<unsigned int *>(out_images[c]);
|
||||||
if (line_order == 0) {
|
if (line_order == 0) {
|
||||||
outLine += (y + v) * x_stride;
|
outLine += (size_t(y) + v) * size_t(x_stride);
|
||||||
} else {
|
} else {
|
||||||
outLine += (height - 1 - (y + v)) * x_stride;
|
outLine +=
|
||||||
|
(size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int u = 0; u < width; u++) {
|
for (int u = 0; u < width; u++) {
|
||||||
|
@ -11133,21 +11147,53 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((idxA == 0) && (idxR == -1) && (idxG == -1) && (idxB == -1)) {
|
if (exr_header.num_channels == 1) {
|
||||||
// Alpha channel only.
|
// Grayscale channel only.
|
||||||
|
|
||||||
if (exr_header.tiled) {
|
|
||||||
// todo.implement this
|
|
||||||
}
|
|
||||||
(*out_rgba) = reinterpret_cast<float *>(
|
(*out_rgba) = reinterpret_cast<float *>(
|
||||||
malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
|
malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
|
||||||
static_cast<size_t>(exr_image.height)));
|
static_cast<size_t>(exr_image.height)));
|
||||||
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
|
|
||||||
const float val = reinterpret_cast<float **>(exr_image.images)[0][i];
|
if (exr_header.tiled) {
|
||||||
(*out_rgba)[4 * i + 0] = val;
|
// todo.implement this
|
||||||
(*out_rgba)[4 * i + 1] = val;
|
|
||||||
(*out_rgba)[4 * i + 2] = val;
|
for (int it = 0; it < exr_image.num_tiles; it++) {
|
||||||
(*out_rgba)[4 * i + 3] = val;
|
for (int j = 0; j < exr_header.tile_size_y; j++) {
|
||||||
|
for (int i = 0; i < exr_header.tile_size_x; i++) {
|
||||||
|
const int ii =
|
||||||
|
exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
|
||||||
|
const int jj =
|
||||||
|
exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
|
||||||
|
const int idx = ii + jj * exr_image.width;
|
||||||
|
|
||||||
|
// out of region check.
|
||||||
|
if (ii >= exr_image.width) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (jj >= exr_image.height) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const int srcIdx = i + j * exr_header.tile_size_x;
|
||||||
|
unsigned char **src = exr_image.tiles[it].images;
|
||||||
|
(*out_rgba)[4 * idx + 0] =
|
||||||
|
reinterpret_cast<float **>(src)[0][srcIdx];
|
||||||
|
(*out_rgba)[4 * idx + 1] =
|
||||||
|
reinterpret_cast<float **>(src)[0][srcIdx];
|
||||||
|
(*out_rgba)[4 * idx + 2] =
|
||||||
|
reinterpret_cast<float **>(src)[0][srcIdx];
|
||||||
|
(*out_rgba)[4 * idx + 3] =
|
||||||
|
reinterpret_cast<float **>(src)[0][srcIdx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
|
||||||
|
const float val = reinterpret_cast<float **>(exr_image.images)[0][i];
|
||||||
|
(*out_rgba)[4 * i + 0] = val;
|
||||||
|
(*out_rgba)[4 * i + 1] = val;
|
||||||
|
(*out_rgba)[4 * i + 2] = val;
|
||||||
|
(*out_rgba)[4 * i + 3] = val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Assume RGB(A)
|
// Assume RGB(A)
|
||||||
|
@ -11179,7 +11225,7 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
|
||||||
static_cast<size_t>(exr_image.height)));
|
static_cast<size_t>(exr_image.height)));
|
||||||
if (exr_header.tiled) {
|
if (exr_header.tiled) {
|
||||||
for (int it = 0; it < exr_image.num_tiles; it++) {
|
for (int it = 0; it < exr_image.num_tiles; it++) {
|
||||||
for (int j = 0; j < exr_header.tile_size_y; j++)
|
for (int j = 0; j < exr_header.tile_size_y; j++) {
|
||||||
for (int i = 0; i < exr_header.tile_size_x; i++) {
|
for (int i = 0; i < exr_header.tile_size_x; i++) {
|
||||||
const int ii =
|
const int ii =
|
||||||
exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
|
exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
|
||||||
|
@ -11209,6 +11255,7 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
|
||||||
(*out_rgba)[4 * idx + 3] = 1.0;
|
(*out_rgba)[4 * idx + 3] = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
|
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
|
||||||
|
@ -11356,18 +11403,53 @@ int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
|
||||||
malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
|
malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
|
||||||
static_cast<size_t>(exr_image.height)));
|
static_cast<size_t>(exr_image.height)));
|
||||||
|
|
||||||
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
|
if (exr_header.tiled) {
|
||||||
(*out_rgba)[4 * i + 0] =
|
for (int it = 0; it < exr_image.num_tiles; it++) {
|
||||||
reinterpret_cast<float **>(exr_image.images)[idxR][i];
|
for (int j = 0; j < exr_header.tile_size_y; j++)
|
||||||
(*out_rgba)[4 * i + 1] =
|
for (int i = 0; i < exr_header.tile_size_x; i++) {
|
||||||
reinterpret_cast<float **>(exr_image.images)[idxG][i];
|
const int ii =
|
||||||
(*out_rgba)[4 * i + 2] =
|
exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
|
||||||
reinterpret_cast<float **>(exr_image.images)[idxB][i];
|
const int jj =
|
||||||
if (idxA != -1) {
|
exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
|
||||||
(*out_rgba)[4 * i + 3] =
|
const int idx = ii + jj * exr_image.width;
|
||||||
reinterpret_cast<float **>(exr_image.images)[idxA][i];
|
|
||||||
} else {
|
// out of region check.
|
||||||
(*out_rgba)[4 * i + 3] = 1.0;
|
if (ii >= exr_image.width) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (jj >= exr_image.height) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const int srcIdx = i + j * exr_header.tile_size_x;
|
||||||
|
unsigned char **src = exr_image.tiles[it].images;
|
||||||
|
(*out_rgba)[4 * idx + 0] =
|
||||||
|
reinterpret_cast<float **>(src)[idxR][srcIdx];
|
||||||
|
(*out_rgba)[4 * idx + 1] =
|
||||||
|
reinterpret_cast<float **>(src)[idxG][srcIdx];
|
||||||
|
(*out_rgba)[4 * idx + 2] =
|
||||||
|
reinterpret_cast<float **>(src)[idxB][srcIdx];
|
||||||
|
if (idxA != -1) {
|
||||||
|
(*out_rgba)[4 * idx + 3] =
|
||||||
|
reinterpret_cast<float **>(src)[idxA][srcIdx];
|
||||||
|
} else {
|
||||||
|
(*out_rgba)[4 * idx + 3] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
|
||||||
|
(*out_rgba)[4 * i + 0] =
|
||||||
|
reinterpret_cast<float **>(exr_image.images)[idxR][i];
|
||||||
|
(*out_rgba)[4 * i + 1] =
|
||||||
|
reinterpret_cast<float **>(exr_image.images)[idxG][i];
|
||||||
|
(*out_rgba)[4 * i + 2] =
|
||||||
|
reinterpret_cast<float **>(exr_image.images)[idxB][i];
|
||||||
|
if (idxA != -1) {
|
||||||
|
(*out_rgba)[4 * i + 3] =
|
||||||
|
reinterpret_cast<float **>(exr_image.images)[idxA][i];
|
||||||
|
} else {
|
||||||
|
(*out_rgba)[4 * i + 3] = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11452,7 +11534,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
|
||||||
if (exr_image == NULL || memory_out == NULL ||
|
if (exr_image == NULL || memory_out == NULL ||
|
||||||
exr_header->compression_type < 0) {
|
exr_header->compression_type < 0) {
|
||||||
tinyexr::SetErrorMessage("Invalid argument for SaveEXRImageToMemory", err);
|
tinyexr::SetErrorMessage("Invalid argument for SaveEXRImageToMemory", err);
|
||||||
return 0; // @fixme
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !TINYEXR_USE_PIZ
|
#if !TINYEXR_USE_PIZ
|
||||||
|
@ -11623,8 +11705,6 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
|
||||||
sizeof(
|
sizeof(
|
||||||
tinyexr::tinyexr_int64); // sizeof(header) + sizeof(offsetTable)
|
tinyexr::tinyexr_int64); // sizeof(header) + sizeof(offsetTable)
|
||||||
|
|
||||||
std::vector<unsigned char> data;
|
|
||||||
|
|
||||||
std::vector<std::vector<unsigned char> > data_list(
|
std::vector<std::vector<unsigned char> > data_list(
|
||||||
static_cast<size_t>(num_blocks));
|
static_cast<size_t>(num_blocks));
|
||||||
std::vector<size_t> channel_offset_list(
|
std::vector<size_t> channel_offset_list(
|
||||||
|
@ -11863,9 +11943,9 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
|
||||||
} else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
|
} else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
|
||||||
#if TINYEXR_USE_PIZ
|
#if TINYEXR_USE_PIZ
|
||||||
unsigned int bufLen =
|
unsigned int bufLen =
|
||||||
1024 + static_cast<unsigned int>(
|
8192 + static_cast<unsigned int>(
|
||||||
1.2 * static_cast<unsigned int>(
|
2 * static_cast<unsigned int>(
|
||||||
buf.size())); // @fixme { compute good bound. }
|
buf.size())); // @fixme { compute good bound. }
|
||||||
std::vector<unsigned char> block(bufLen);
|
std::vector<unsigned char> block(bufLen);
|
||||||
unsigned int outSize = static_cast<unsigned int>(block.size());
|
unsigned int outSize = static_cast<unsigned int>(block.size());
|
||||||
|
|
||||||
|
@ -11924,13 +12004,12 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
|
||||||
} // omp parallel
|
} // omp parallel
|
||||||
|
|
||||||
for (size_t i = 0; i < static_cast<size_t>(num_blocks); i++) {
|
for (size_t i = 0; i < static_cast<size_t>(num_blocks); i++) {
|
||||||
data.insert(data.end(), data_list[i].begin(), data_list[i].end());
|
|
||||||
|
|
||||||
offsets[i] = offset;
|
offsets[i] = offset;
|
||||||
tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64 *>(&offsets[i]));
|
tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64 *>(&offsets[i]));
|
||||||
offset += data_list[i].size();
|
offset += data_list[i].size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t totalSize = static_cast<size_t>(offset);
|
||||||
{
|
{
|
||||||
memory.insert(
|
memory.insert(
|
||||||
memory.end(), reinterpret_cast<unsigned char *>(&offsets.at(0)),
|
memory.end(), reinterpret_cast<unsigned char *>(&offsets.at(0)),
|
||||||
|
@ -11938,14 +12017,21 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
|
||||||
sizeof(tinyexr::tinyexr_uint64) * static_cast<size_t>(num_blocks));
|
sizeof(tinyexr::tinyexr_uint64) * static_cast<size_t>(num_blocks));
|
||||||
}
|
}
|
||||||
|
|
||||||
{ memory.insert(memory.end(), data.begin(), data.end()); }
|
if ( memory.size() == 0 ) {
|
||||||
|
tinyexr::SetErrorMessage("Output memory size is zero", err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
assert(memory.size() > 0);
|
(*memory_out) = static_cast<unsigned char *>(malloc(totalSize));
|
||||||
|
|
||||||
(*memory_out) = static_cast<unsigned char *>(malloc(memory.size()));
|
|
||||||
memcpy((*memory_out), &memory.at(0), memory.size());
|
memcpy((*memory_out), &memory.at(0), memory.size());
|
||||||
|
unsigned char *memory_ptr = *memory_out + memory.size();
|
||||||
|
|
||||||
return memory.size(); // OK
|
for (size_t i = 0; i < static_cast<size_t>(num_blocks); i++) {
|
||||||
|
memcpy(memory_ptr, &data_list[i].at(0), data_list[i].size());
|
||||||
|
memory_ptr += data_list[i].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalSize; // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
|
int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
|
||||||
|
@ -11960,7 +12046,7 @@ int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
|
||||||
if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
|
if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
|
||||||
tinyexr::SetErrorMessage("PIZ compression is not supported in this build",
|
tinyexr::SetErrorMessage("PIZ compression is not supported in this build",
|
||||||
err);
|
err);
|
||||||
return 0;
|
return TINYEXR_ERROR_UNSUPPORTED_FEATURE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -11968,7 +12054,7 @@ int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
|
||||||
if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
|
if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
|
||||||
tinyexr::SetErrorMessage("ZFP compression is not supported in this build",
|
tinyexr::SetErrorMessage("ZFP compression is not supported in this build",
|
||||||
err);
|
err);
|
||||||
return 0;
|
return TINYEXR_ERROR_UNSUPPORTED_FEATURE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -11980,19 +12066,28 @@ int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
|
||||||
#endif
|
#endif
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
tinyexr::SetErrorMessage("Cannot write a file", err);
|
tinyexr::SetErrorMessage("Cannot write a file", err);
|
||||||
return TINYEXR_ERROR_CANT_OPEN_FILE;
|
return TINYEXR_ERROR_CANT_WRITE_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *mem = NULL;
|
unsigned char *mem = NULL;
|
||||||
size_t mem_size = SaveEXRImageToMemory(exr_image, exr_header, &mem, err);
|
size_t mem_size = SaveEXRImageToMemory(exr_image, exr_header, &mem, err);
|
||||||
|
if (mem_size == 0) {
|
||||||
|
return TINYEXR_ERROR_SERIALZATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t written_size = 0;
|
||||||
if ((mem_size > 0) && mem) {
|
if ((mem_size > 0) && mem) {
|
||||||
fwrite(mem, 1, mem_size, fp);
|
written_size = fwrite(mem, 1, mem_size, fp);
|
||||||
}
|
}
|
||||||
free(mem);
|
free(mem);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
if (written_size != mem_size) {
|
||||||
|
tinyexr::SetErrorMessage("Cannot write a file", err);
|
||||||
|
return TINYEXR_ERROR_CANT_WRITE_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
return TINYEXR_SUCCESS;
|
return TINYEXR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12861,20 +12956,27 @@ int LoadEXRMultipartImageFromFile(EXRImage *exr_images,
|
||||||
}
|
}
|
||||||
|
|
||||||
int SaveEXR(const float *data, int width, int height, int components,
|
int SaveEXR(const float *data, int width, int height, int components,
|
||||||
const int save_as_fp16, const char *outfilename) {
|
const int save_as_fp16, const char *outfilename, const char **err) {
|
||||||
if ((components == 1) || components == 3 || components == 4) {
|
if ((components == 1) || components == 3 || components == 4) {
|
||||||
// OK
|
// OK
|
||||||
} else {
|
} else {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Unsupported component value : " << components << std::endl;
|
||||||
|
|
||||||
|
tinyexr::SetErrorMessage(ss.str(), err);
|
||||||
return TINYEXR_ERROR_INVALID_ARGUMENT;
|
return TINYEXR_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume at least 16x16 pixels.
|
|
||||||
if (width < 16) return TINYEXR_ERROR_INVALID_ARGUMENT;
|
|
||||||
if (height < 16) return TINYEXR_ERROR_INVALID_ARGUMENT;
|
|
||||||
|
|
||||||
EXRHeader header;
|
EXRHeader header;
|
||||||
InitEXRHeader(&header);
|
InitEXRHeader(&header);
|
||||||
|
|
||||||
|
if ((width < 16) && (height < 16)) {
|
||||||
|
// No compression for small image.
|
||||||
|
header.compression_type = TINYEXR_COMPRESSIONTYPE_NONE;
|
||||||
|
} else {
|
||||||
|
header.compression_type = TINYEXR_COMPRESSIONTYPE_ZIP;
|
||||||
|
}
|
||||||
|
|
||||||
EXRImage image;
|
EXRImage image;
|
||||||
InitEXRImage(&image);
|
InitEXRImage(&image);
|
||||||
|
|
||||||
|
@ -12980,8 +13082,7 @@ int SaveEXR(const float *data, int width, int height, int components,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *err;
|
int ret = SaveEXRImageToFile(&image, &header, outfilename, err);
|
||||||
int ret = SaveEXRImageToFile(&image, &header, outfilename, &err);
|
|
||||||
if (ret != TINYEXR_SUCCESS) {
|
if (ret != TINYEXR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue