#ifndef TINYEXR_H_
#define TINYEXR_H_
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
defined(__i386) || defined(__i486__) || defined(__i486) || \
defined(i386) || defined(__ia64__) || defined(__x86_64__)
#define TINYEXR_X86_OR_X64_CPU …
#else
#define TINYEXR_X86_OR_X64_CPU …
#endif
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || TINYEXR_X86_OR_X64_CPU
#define TINYEXR_LITTLE_ENDIAN …
#else
#define TINYEXR_LITTLE_ENDIAN …
#endif
#ifndef TINYEXR_USE_MINIZ
#define TINYEXR_USE_MINIZ …
#endif
#ifndef TINYEXR_USE_STB_ZLIB
#define TINYEXR_USE_STB_ZLIB …
#endif
#ifndef TINYEXR_USE_NANOZLIB
#define TINYEXR_USE_NANOZLIB …
#endif
#ifndef TINYEXR_USE_PIZ
#define TINYEXR_USE_PIZ …
#endif
#ifndef TINYEXR_USE_ZFP
#define TINYEXR_USE_ZFP …
#endif
#ifndef TINYEXR_USE_THREAD
#define TINYEXR_USE_THREAD …
#endif
#ifndef TINYEXR_USE_OPENMP
#ifdef _OPENMP
#define TINYEXR_USE_OPENMP …
#else
#define TINYEXR_USE_OPENMP …
#endif
#endif
#define TINYEXR_SUCCESS …
#define TINYEXR_ERROR_INVALID_MAGIC_NUMBER …
#define TINYEXR_ERROR_INVALID_EXR_VERSION …
#define TINYEXR_ERROR_INVALID_ARGUMENT …
#define TINYEXR_ERROR_INVALID_DATA …
#define TINYEXR_ERROR_INVALID_FILE …
#define TINYEXR_ERROR_INVALID_PARAMETER …
#define TINYEXR_ERROR_CANT_OPEN_FILE …
#define TINYEXR_ERROR_UNSUPPORTED_FORMAT …
#define TINYEXR_ERROR_INVALID_HEADER …
#define TINYEXR_ERROR_UNSUPPORTED_FEATURE …
#define TINYEXR_ERROR_CANT_WRITE_FILE …
#define TINYEXR_ERROR_SERIALIZATION_FAILED …
#define TINYEXR_ERROR_LAYER_NOT_FOUND …
#define TINYEXR_ERROR_DATA_TOO_LARGE …
#define TINYEXR_PIXELTYPE_UINT …
#define TINYEXR_PIXELTYPE_HALF …
#define TINYEXR_PIXELTYPE_FLOAT …
#define TINYEXR_MAX_HEADER_ATTRIBUTES …
#define TINYEXR_MAX_CUSTOM_ATTRIBUTES …
#define TINYEXR_COMPRESSIONTYPE_NONE …
#define TINYEXR_COMPRESSIONTYPE_RLE …
#define TINYEXR_COMPRESSIONTYPE_ZIPS …
#define TINYEXR_COMPRESSIONTYPE_ZIP …
#define TINYEXR_COMPRESSIONTYPE_PIZ …
#define TINYEXR_COMPRESSIONTYPE_ZFP …
#define TINYEXR_ZFP_COMPRESSIONTYPE_RATE …
#define TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION …
#define TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY …
#define TINYEXR_TILE_ONE_LEVEL …
#define TINYEXR_TILE_MIPMAP_LEVELS …
#define TINYEXR_TILE_RIPMAP_LEVELS …
#define TINYEXR_TILE_ROUND_DOWN …
#define TINYEXR_TILE_ROUND_UP …
EXRVersion;
EXRAttribute;
EXRChannelInfo;
EXRTile;
EXRBox2i;
EXRHeader;
EXRMultiPartHeader;
EXRImage;
EXRMultiPartImage;
DeepImage;
extern int LoadEXR(float **out_rgba, int *width, int *height,
const char *filename, const char **err);
extern int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
const char *filename, const char *layer_name,
const char **err);
extern int EXRLayers(const char *filename, const char **layer_names[],
int *num_layers, const char **err);
extern int IsEXR(const char *filename);
extern int IsEXRFromMemory(const unsigned char *memory, size_t size);
extern int SaveEXRToMemory(const float *data, const int width, const int height,
const int components, const int save_as_fp16,
unsigned char **buffer, const char **err);
extern int SaveEXR(const float *data, const int width, const int height,
const int components, const int save_as_fp16,
const char *filename, const char **err);
extern int EXRNumLevels(const EXRImage* exr_image);
extern void InitEXRHeader(EXRHeader *exr_header);
extern void EXRSetNameAttr(EXRHeader *exr_header, const char* name);
extern void InitEXRImage(EXRImage *exr_image);
extern int FreeEXRHeader(EXRHeader *exr_header);
extern int FreeEXRImage(EXRImage *exr_image);
extern void FreeEXRErrorMessage(const char *msg);
extern int ParseEXRVersionFromFile(EXRVersion *version, const char *filename);
extern int ParseEXRVersionFromMemory(EXRVersion *version,
const unsigned char *memory, size_t size);
extern int ParseEXRHeaderFromFile(EXRHeader *header, const EXRVersion *version,
const char *filename, const char **err);
extern int ParseEXRHeaderFromMemory(EXRHeader *header,
const EXRVersion *version,
const unsigned char *memory, size_t size,
const char **err);
extern int ParseEXRMultipartHeaderFromFile(EXRHeader ***headers,
int *num_headers,
const EXRVersion *version,
const char *filename,
const char **err);
extern int ParseEXRMultipartHeaderFromMemory(EXRHeader ***headers,
int *num_headers,
const EXRVersion *version,
const unsigned char *memory,
size_t size, const char **err);
extern int LoadEXRImageFromFile(EXRImage *image, const EXRHeader *header,
const char *filename, const char **err);
extern int LoadEXRImageFromMemory(EXRImage *image, const EXRHeader *header,
const unsigned char *memory,
const size_t size, const char **err);
extern int LoadEXRMultipartImageFromFile(EXRImage *images,
const EXRHeader **headers,
unsigned int num_parts,
const char *filename,
const char **err);
extern int LoadEXRMultipartImageFromMemory(EXRImage *images,
const EXRHeader **headers,
unsigned int num_parts,
const unsigned char *memory,
const size_t size, const char **err);
extern int SaveEXRImageToFile(const EXRImage *image,
const EXRHeader *exr_header, const char *filename,
const char **err);
extern size_t SaveEXRImageToMemory(const EXRImage *image,
const EXRHeader *exr_header,
unsigned char **memory, const char **err);
extern int SaveEXRMultipartImageToFile(const EXRImage *images,
const EXRHeader **exr_headers,
unsigned int num_parts,
const char *filename, const char **err);
extern size_t SaveEXRMultipartImageToMemory(const EXRImage *images,
const EXRHeader **exr_headers,
unsigned int num_parts,
unsigned char **memory, const char **err);
extern int LoadDeepEXR(DeepImage *out_image, const char *filename,
const char **err);
extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
const unsigned char *memory, size_t size,
const char **err);
#ifdef __cplusplus
}
#endif
#endif
#ifdef TINYEXR_IMPLEMENTATION
#ifndef TINYEXR_IMPLEMENTATION_DEFINED
#define TINYEXR_IMPLEMENTATION_DEFINED
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
#define TINYEXR_USE_WIN32_MMAP …
#endif
#elif defined(__linux__) || defined(__unix__)
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define TINYEXR_USE_POSIX_MMAP …
#endif
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <limits>
#include <string>
#include <vector>
#include <set>
#if __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900)
#define TINYEXR_HAS_CXX11 …
#include <cstdint>
#if TINYEXR_USE_THREAD
#include <atomic>
#include <thread>
#endif
#else
#define TINYEXR_HAS_CXX11 …
#endif
#if TINYEXR_USE_OPENMP
#include <omp.h>
#endif
#if defined(TINYEXR_USE_MINIZ) && (TINYEXR_USE_MINIZ==1)
#include <miniz.h>
#else
#endif
#if defined(TINYEXR_USE_NANOZLIB) && (TINYEXR_USE_NANOZLIB==1)
#define NANOZLIB_IMPLEMENTATION
#include "nanozlib.h"
#endif
#if TINYEXR_USE_STB_ZLIB
extern "C" int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
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__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#endif
#include "zfp.h"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
#define TINYEXR_CHECK_AND_RETURN_MSG(cond, msg, err) …
#define TINYEXR_CHECK_AND_RETURN_C(cond, retcode) …
namespace tinyexr {
#if __cplusplus > 199711L
tinyexr_uint64;
tinyexr_int64;
#else
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++11-long-long"
#endif
typedef unsigned long long tinyexr_uint64;
typedef long long tinyexr_int64;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
static void SetErrorMessage(const std::string &msg, const char **err) { … }
#if 0
static void SetWarningMessage(const std::string &msg, const char **warn) {
if (warn) {
#ifdef _WIN32
(*warn) = _strdup(msg.c_str());
#else
(*warn) = strdup(msg.c_str());
#endif
}
}
#endif
static const int kEXRVersionSize = …;
static void cpy2(unsigned short *dst_val, const unsigned short *src_val) { … }
static void swap2(unsigned short *val) { … }
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
static void cpy4(int *dst_val, const int *src_val) { … }
static void cpy4(unsigned int *dst_val, const unsigned int *src_val) { … }
static void cpy4(float *dst_val, const float *src_val) { … }
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
static void swap4(unsigned int *val) { … }
static void swap4(int *val) { … }
static void swap4(float *val) { … }
#if 0
static void cpy8(tinyexr::tinyexr_uint64 *dst_val, const tinyexr::tinyexr_uint64 *src_val) {
unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val);
const unsigned char *src = reinterpret_cast<const unsigned char *>(src_val);
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
}
#endif
static void swap8(tinyexr::tinyexr_uint64 *val) { … }
FP32;
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif
FP16;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
static FP32 half_to_float(FP16 h) { … }
static FP16 float_to_half_full(FP32 f) { … }
#ifdef __clang__
#pragma clang diagnostic push
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#endif
static const char *ReadString(std::string *s, const char *ptr, size_t len) { … }
static bool ReadAttribute(std::string *name, std::string *type,
std::vector<unsigned char> *data, size_t *marker_size,
const char *marker, size_t size) { … }
static void WriteAttributeToMemory(std::vector<unsigned char> *out,
const char *name, const char *type,
const unsigned char *data, int len) { … }
ChannelInfo;
Box2iInfo;
struct HeaderInfo { … };
static bool ReadChannelInfo(std::vector<ChannelInfo> &channels,
const std::vector<unsigned char> &data) { … }
static void WriteChannelInfo(std::vector<unsigned char> &data,
const std::vector<ChannelInfo> &channels) { … }
static bool CompressZip(unsigned char *dst,
tinyexr::tinyexr_uint64 &compressedSize,
const unsigned char *src, unsigned long src_size) { … }
static bool DecompressZip(unsigned char *dst,
unsigned long *uncompressed_size ,
const unsigned char *src, unsigned long src_size) { … }
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
#if __has_warning("-Wextra-semi-stmt")
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#endif
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4204)
#pragma warning(disable : 4244)
#pragma warning(disable : 4267)
#pragma warning(disable : 4996)
#endif
const int MIN_RUN_LENGTH = …;
const int MAX_RUN_LENGTH = …;
static int rleCompress(int inLength, const char in[], signed char out[]) { … }
static int rleUncompress(int inLength, int maxLength, const signed char in[],
char out[]) { … }
#ifdef __clang__
#pragma clang diagnostic pop
#endif
static bool CompressRle(unsigned char *dst,
tinyexr::tinyexr_uint64 &compressedSize,
const unsigned char *src, unsigned long src_size) { … }
static bool DecompressRle(unsigned char *dst,
const unsigned long uncompressed_size,
const unsigned char *src, unsigned long src_size) { … }
#if TINYEXR_USE_PIZ
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++11-long-long"
#pragma clang diagnostic ignored "-Wold-style-cast"
#pragma clang diagnostic ignored "-Wpadded"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wc++11-extensions"
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
#if __has_warning("-Wcast-qual")
#pragma clang diagnostic ignored "-Wcast-qual"
#endif
#if __has_warning("-Wextra-semi-stmt")
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#endif
#endif
struct PIZChannelData { … };
inline void wenc14(unsigned short a, unsigned short b, unsigned short &l,
unsigned short &h) { … }
inline void wdec14(unsigned short l, unsigned short h, unsigned short &a,
unsigned short &b) { … }
const int NBITS = …;
const int A_OFFSET = …;
const int M_OFFSET = …;
const int MOD_MASK = …;
inline void wenc16(unsigned short a, unsigned short b, unsigned short &l,
unsigned short &h) { … }
inline void wdec16(unsigned short l, unsigned short h, unsigned short &a,
unsigned short &b) { … }
static void wav2Encode(
unsigned short *in,
int nx,
int ox,
int ny,
int oy,
unsigned short mx)
{ … }
static void wav2Decode(
unsigned short *in,
int nx,
int ox,
int ny,
int oy,
unsigned short mx)
{ … }
const int HUF_ENCBITS = …;
const int HUF_DECBITS = …;
const int HUF_ENCSIZE = …;
const int HUF_DECSIZE = …;
const int HUF_DECMASK = …;
struct HufDec { … };
inline long long hufLength(long long code) { … }
inline long long hufCode(long long code) { … }
inline void outputBits(int nBits, long long bits, long long &c, int &lc,
char *&out) { … }
inline long long getBits(int nBits, long long &c, int &lc, const char *&in) { … }
static void hufCanonicalCodeTable(long long hcode[HUF_ENCSIZE]) { … }
struct FHeapCompare { … };
static bool hufBuildEncTable(
long long *frq,
int *im,
int *iM)
{ … }
const int SHORT_ZEROCODE_RUN = …;
const int LONG_ZEROCODE_RUN = …;
const int SHORTEST_LONG_RUN = …;
const int LONGEST_LONG_RUN = …;
static void hufPackEncTable(
const long long *hcode,
int im,
int iM,
char **pcode)
{ … }
static bool hufUnpackEncTable(
const char **pcode,
int ni,
int im,
int iM,
long long *hcode)
{ … }
static void hufClearDecTable(HufDec *hdecod)
{ … }
static bool hufBuildDecTable(const long long *hcode,
int im,
int iM,
HufDec *hdecod)
{ … }
static void hufFreeDecTable(HufDec *hdecod)
{ … }
inline void outputCode(long long code, long long &c, int &lc, char *&out) { … }
inline void sendCode(long long sCode, int runCount, long long runCode,
long long &c, int &lc, char *&out) { … }
static int hufEncode
(const long long *hcode,
const unsigned short *in,
const int ni,
int rlc,
char *out)
{ … }
#define getChar(c, lc, in) …
#if 0
#define getCode …
#else
static bool getCode(int po, int rlc, long long &c, int &lc, const char *&in,
const char *in_end, unsigned short *&out,
const unsigned short *ob, const unsigned short *oe) { … }
#endif
static bool hufDecode(const long long *hcode,
const HufDec *hdecod,
const char *in,
int ni,
int rlc,
int no,
unsigned short *out)
{ … }
static void countFrequencies(std::vector<long long> &freq,
const unsigned short data[], int n) { … }
static void writeUInt(char buf[4], unsigned int i) { … }
static unsigned int readUInt(const char buf[4]) { … }
static int hufCompress(const unsigned short raw[], int nRaw,
char compressed[]) { … }
static bool hufUncompress(const char compressed[], int nCompressed,
std::vector<unsigned short> *raw) { … }
const int USHORT_RANGE = …;
const int BITMAP_SIZE = …;
static void bitmapFromData(const unsigned short data[], int nData,
unsigned char bitmap[BITMAP_SIZE],
unsigned short &minNonZero,
unsigned short &maxNonZero) { … }
static unsigned short forwardLutFromBitmap(
const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]) { … }
static unsigned short reverseLutFromBitmap(
const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]) { … }
static void applyLut(const unsigned short lut[USHORT_RANGE],
unsigned short data[], int nData) { … }
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
static bool CompressPiz(unsigned char *outPtr, unsigned int *outSize,
const unsigned char *inPtr, size_t inSize,
const std::vector<ChannelInfo> &channelInfo,
int data_width, int num_lines) { … }
static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
size_t tmpBufSizeInBytes, size_t inLen, int num_channels,
const EXRChannelInfo *channels, int data_width,
int num_lines) { … }
#endif
#if TINYEXR_USE_ZFP
struct ZFPCompressionParam {
double rate;
unsigned int precision;
unsigned int __pad0;
double tolerance;
int type;
unsigned int __pad1;
ZFPCompressionParam() {
type = TINYEXR_ZFP_COMPRESSIONTYPE_RATE;
rate = 2.0;
precision = 0;
tolerance = 0.0;
}
};
static bool FindZFPCompressionParam(ZFPCompressionParam *param,
const EXRAttribute *attributes,
int num_attributes, std::string *err) {
bool foundType = false;
for (int i = 0; i < num_attributes; i++) {
if ((strcmp(attributes[i].name, "zfpCompressionType") == 0)) {
if (attributes[i].size == 1) {
param->type = static_cast<int>(attributes[i].value[0]);
foundType = true;
break;
} else {
if (err) {
(*err) +=
"zfpCompressionType attribute must be uchar(1 byte) type.\n";
}
return false;
}
}
}
if (!foundType) {
if (err) {
(*err) += "`zfpCompressionType` attribute not found.\n";
}
return false;
}
if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
for (int i = 0; i < num_attributes; i++) {
if ((strcmp(attributes[i].name, "zfpCompressionRate") == 0) &&
(attributes[i].size == 8)) {
param->rate = *(reinterpret_cast<double *>(attributes[i].value));
return true;
}
}
if (err) {
(*err) += "`zfpCompressionRate` attribute not found.\n";
}
} else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
for (int i = 0; i < num_attributes; i++) {
if ((strcmp(attributes[i].name, "zfpCompressionPrecision") == 0) &&
(attributes[i].size == 4)) {
param->rate = *(reinterpret_cast<int *>(attributes[i].value));
return true;
}
}
if (err) {
(*err) += "`zfpCompressionPrecision` attribute not found.\n";
}
} else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
for (int i = 0; i < num_attributes; i++) {
if ((strcmp(attributes[i].name, "zfpCompressionTolerance") == 0) &&
(attributes[i].size == 8)) {
param->tolerance = *(reinterpret_cast<double *>(attributes[i].value));
return true;
}
}
if (err) {
(*err) += "`zfpCompressionTolerance` attribute not found.\n";
}
} else {
if (err) {
(*err) += "Unknown value specified for `zfpCompressionType`.\n";
}
}
return false;
}
static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
size_t num_channels, const unsigned char *src,
unsigned long src_size,
const ZFPCompressionParam ¶m) {
size_t uncompressed_size =
size_t(dst_width) * size_t(dst_num_lines) * num_channels;
if (uncompressed_size == src_size) {
memcpy(dst, src, src_size);
}
zfp_stream *zfp = NULL;
zfp_field *field = NULL;
TINYEXR_CHECK_AND_RETURN_C((dst_width % 4) == 0, false);
TINYEXR_CHECK_AND_RETURN_C((dst_num_lines % 4) == 0, false);
if ((size_t(dst_width) & 3U) || (size_t(dst_num_lines) & 3U)) {
return false;
}
field =
zfp_field_2d(reinterpret_cast<void *>(const_cast<unsigned char *>(src)),
zfp_type_float, static_cast<unsigned int>(dst_width),
static_cast<unsigned int>(dst_num_lines) *
static_cast<unsigned int>(num_channels));
zfp = zfp_stream_open(NULL);
if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
zfp_stream_set_rate(zfp, param.rate, zfp_type_float, 2,
0);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
zfp_stream_set_precision(zfp, param.precision);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
zfp_stream_set_accuracy(zfp, param.tolerance);
} else {
return false;
}
size_t buf_size = zfp_stream_maximum_size(zfp, field);
std::vector<unsigned char> buf(buf_size);
memcpy(&buf.at(0), src, src_size);
bitstream *stream = stream_open(&buf.at(0), buf_size);
zfp_stream_set_bit_stream(zfp, stream);
zfp_stream_rewind(zfp);
size_t image_size = size_t(dst_width) * size_t(dst_num_lines);
for (size_t c = 0; c < size_t(num_channels); c++) {
for (size_t y = 0; y < size_t(dst_num_lines); y += 4) {
for (size_t x = 0; x < size_t(dst_width); x += 4) {
float fblock[16];
zfp_decode_block_float_2(zfp, fblock);
for (size_t j = 0; j < 4; j++) {
for (size_t i = 0; i < 4; i++) {
dst[c * image_size + ((y + j) * size_t(dst_width) + (x + i))] =
fblock[j * 4 + i];
}
}
}
}
}
zfp_field_free(field);
zfp_stream_close(zfp);
stream_close(stream);
return true;
}
static bool CompressZfp(std::vector<unsigned char> *outBuf,
unsigned int *outSize, const float *inPtr, int width,
int num_lines, int num_channels,
const ZFPCompressionParam ¶m) {
zfp_stream *zfp = NULL;
zfp_field *field = NULL;
TINYEXR_CHECK_AND_RETURN_C((width % 4) == 0, false);
TINYEXR_CHECK_AND_RETURN_C((num_lines % 4) == 0, false);
if ((size_t(width) & 3U) || (size_t(num_lines) & 3U)) {
return false;
}
field = zfp_field_2d(reinterpret_cast<void *>(const_cast<float *>(inPtr)),
zfp_type_float, static_cast<unsigned int>(width),
static_cast<unsigned int>(num_lines * num_channels));
zfp = zfp_stream_open(NULL);
if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
zfp_stream_set_rate(zfp, param.rate, zfp_type_float, 2, 0);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
zfp_stream_set_precision(zfp, param.precision);
} else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
zfp_stream_set_accuracy(zfp, param.tolerance);
} else {
return false;
}
size_t buf_size = zfp_stream_maximum_size(zfp, field);
outBuf->resize(buf_size);
bitstream *stream = stream_open(&outBuf->at(0), buf_size);
zfp_stream_set_bit_stream(zfp, stream);
zfp_field_free(field);
size_t image_size = size_t(width) * size_t(num_lines);
for (size_t c = 0; c < size_t(num_channels); c++) {
for (size_t y = 0; y < size_t(num_lines); y += 4) {
for (size_t x = 0; x < size_t(width); x += 4) {
float fblock[16];
for (size_t j = 0; j < 4; j++) {
for (size_t i = 0; i < 4; i++) {
fblock[j * 4 + i] =
inPtr[c * image_size + ((y + j) * size_t(width) + (x + i))];
}
}
zfp_encode_block_float_2(zfp, fblock);
}
}
}
zfp_stream_flush(zfp);
(*outSize) = static_cast<unsigned int>(zfp_stream_compressed_size(zfp));
zfp_stream_close(zfp);
return true;
}
#endif
#define TINYEXR_DIMENSION_THRESHOLD …
static bool DecodePixelData( unsigned char **out_images,
const int *requested_pixel_types,
const unsigned char *data_ptr, size_t data_len,
int compression_type, int line_order, int width,
int height, int x_stride, int y, int line_no,
int num_lines, size_t pixel_data_size,
size_t num_attributes,
const EXRAttribute *attributes, size_t num_channels,
const EXRChannelInfo *channels,
const std::vector<size_t> &channel_offset_list) { … }
static bool DecodeTiledPixelData(
unsigned char **out_images, int *width, int *height,
const int *requested_pixel_types, const unsigned char *data_ptr,
size_t data_len, int compression_type, int line_order, int data_width,
int data_height, int tile_offset_x, int tile_offset_y, int tile_size_x,
int tile_size_y, size_t pixel_data_size, size_t num_attributes,
const EXRAttribute *attributes, size_t num_channels,
const EXRChannelInfo *channels,
const std::vector<size_t> &channel_offset_list) { … }
static bool ComputeChannelLayout(std::vector<size_t> *channel_offset_list,
int *pixel_data_size, size_t *channel_offset,
int num_channels,
const EXRChannelInfo *channels) { … }
static unsigned char **AllocateImage(int num_channels,
const EXRChannelInfo *channels,
const int *requested_pixel_types,
int data_width, int data_height, bool *success) { … }
#ifdef _WIN32
static inline std::wstring UTF8ToWchar(const std::string &str) {
int wstr_size =
MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0);
std::wstring wstr(wstr_size, 0);
MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0],
(int)wstr.size());
return wstr;
}
#endif
static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
const EXRVersion *version, std::string *err,
const unsigned char *buf, size_t size) { … }
static bool ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info, std::string *warn, std::string *err) { … }
struct OffsetData { … };
static int LevelIndex(int lx, int ly, int tile_level_mode, int num_x_levels) { … }
static int LevelSize(int toplevel_size, int level, int tile_rounding_mode) { … }
static int DecodeTiledLevel(EXRImage* exr_image, const EXRHeader* exr_header,
const OffsetData& offset_data,
const std::vector<size_t>& channel_offset_list,
int pixel_data_size,
const unsigned char* head, const size_t size,
std::string* err) { … }
static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
const OffsetData& offset_data,
const unsigned char *head, const size_t size,
std::string *err) { … }
static bool ReconstructLineOffsets(
std::vector<tinyexr::tinyexr_uint64> *offsets, size_t n,
const unsigned char *head, const unsigned char *marker, const size_t size) { … }
static int FloorLog2(unsigned x) { … }
static int CeilLog2(unsigned x) { … }
static int RoundLog2(int x, int tile_rounding_mode) { … }
static int CalculateNumXLevels(const EXRHeader* exr_header) { … }
static int CalculateNumYLevels(const EXRHeader* exr_header) { … }
static bool CalculateNumTiles(std::vector<int>& numTiles,
int toplevel_size,
int size,
int tile_rounding_mode) { … }
static bool PrecalculateTileInfo(std::vector<int>& num_x_tiles,
std::vector<int>& num_y_tiles,
const EXRHeader* exr_header) { … }
static void InitSingleResolutionOffsets(OffsetData& offset_data, size_t num_blocks) { … }
static int InitTileOffsets(OffsetData& offset_data,
const EXRHeader* exr_header,
const std::vector<int>& num_x_tiles,
const std::vector<int>& num_y_tiles) { … }
static bool IsAnyOffsetsAreInvalid(const OffsetData& offset_data) { … }
static bool isValidTile(const EXRHeader* exr_header,
const OffsetData& offset_data,
int dx, int dy, int lx, int ly) { … }
static bool ReconstructTileOffsets(OffsetData& offset_data,
const EXRHeader* exr_header,
const unsigned char* head, const unsigned char* marker, const size_t size,
bool isMultiPartFile,
bool isDeep) { … }
static int ReadOffsets(OffsetData& offset_data,
const unsigned char* head,
const unsigned char*& marker,
const size_t size,
const char** err) { … }
static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
const unsigned char *head,
const unsigned char *marker, const size_t size,
const char **err) { … }
static void GetLayers(const EXRHeader &exr_header,
std::vector<std::string> &layer_names) { … }
struct LayerChannel { … };
static void ChannelsInLayer(const EXRHeader &exr_header,
const std::string &layer_name,
std::vector<LayerChannel> &channels) { … }
}
int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
const char **err) { … }
int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
const char **err) { … }
int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
const char *filename, const char *layername,
const char **err) { … }
int IsEXR(const char *filename) { … }
int IsEXRFromMemory(const unsigned char *memory, size_t size) { … }
int ParseEXRHeaderFromMemory(EXRHeader *exr_header, const EXRVersion *version,
const unsigned char *memory, size_t size,
const char **err) { … }
int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
const unsigned char *memory, size_t size,
const char **err) { … }
struct MemoryMappedFile { … };
int LoadEXRImageFromFile(EXRImage *exr_image, const EXRHeader *exr_header,
const char *filename, const char **err) { … }
int LoadEXRImageFromMemory(EXRImage *exr_image, const EXRHeader *exr_header,
const unsigned char *memory, const size_t size,
const char **err) { … }
namespace tinyexr
{
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
#endif
static bool EncodePixelData( std::vector<unsigned char>& out_data,
const unsigned char* const* images,
int compression_type,
int ,
int width,
int ,
int x_stride,
int line_no,
int num_lines,
size_t pixel_data_size,
const std::vector<ChannelInfo>& channels,
const std::vector<size_t>& channel_offset_list,
std::string *err,
const void* compression_param = 0)
{ … }
static int EncodeTiledLevel(const EXRImage* level_image, const EXRHeader* exr_header,
const std::vector<tinyexr::ChannelInfo>& channels,
std::vector<std::vector<unsigned char> >& data_list,
size_t start_index,
int num_x_tiles, int num_y_tiles,
const std::vector<size_t>& channel_offset_list,
int pixel_data_size,
const void* compression_param,
std::string* err) { … }
static int NumScanlines(int compression_type) { … }
static int EncodeChunk(const EXRImage* exr_image, const EXRHeader* exr_header,
const std::vector<ChannelInfo>& channels,
int num_blocks,
tinyexr_uint64 chunk_offset,
bool is_multipart,
OffsetData& offset_data,
std::vector<std::vector<unsigned char> >& data_list,
tinyexr_uint64& total_size,
std::string* err) { … }
static size_t SaveEXRNPartImageToMemory(const EXRImage* exr_images,
const EXRHeader** exr_headers,
unsigned int num_parts,
unsigned char** memory_out, const char** err) { … }
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}
size_t SaveEXRImageToMemory(const EXRImage* exr_image,
const EXRHeader* exr_header,
unsigned char** memory_out, const char** err) { … }
int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
const char *filename, const char **err) { … }
size_t SaveEXRMultipartImageToMemory(const EXRImage* exr_images,
const EXRHeader** exr_headers,
unsigned int num_parts,
unsigned char** memory_out, const char** err) { … }
int SaveEXRMultipartImageToFile(const EXRImage* exr_images,
const EXRHeader** exr_headers,
unsigned int num_parts,
const char* filename,
const char** err) { … }
int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) { … }
void InitEXRImage(EXRImage *exr_image) { … }
void FreeEXRErrorMessage(const char *msg) { … }
void InitEXRHeader(EXRHeader *exr_header) { … }
int FreeEXRHeader(EXRHeader *exr_header) { … }
void EXRSetNameAttr(EXRHeader* exr_header, const char* name) { … }
int EXRNumLevels(const EXRImage* exr_image) { … }
int FreeEXRImage(EXRImage *exr_image) { … }
int ParseEXRHeaderFromFile(EXRHeader *exr_header, const EXRVersion *exr_version,
const char *filename, const char **err) { … }
int ParseEXRMultipartHeaderFromMemory(EXRHeader ***exr_headers,
int *num_headers,
const EXRVersion *exr_version,
const unsigned char *memory, size_t size,
const char **err) { … }
int ParseEXRMultipartHeaderFromFile(EXRHeader ***exr_headers, int *num_headers,
const EXRVersion *exr_version,
const char *filename, const char **err) { … }
int ParseEXRVersionFromMemory(EXRVersion *version, const unsigned char *memory,
size_t size) { … }
int ParseEXRVersionFromFile(EXRVersion *version, const char *filename) { … }
int LoadEXRMultipartImageFromMemory(EXRImage *exr_images,
const EXRHeader **exr_headers,
unsigned int num_parts,
const unsigned char *memory,
const size_t size, const char **err) { … }
int LoadEXRMultipartImageFromFile(EXRImage *exr_images,
const EXRHeader **exr_headers,
unsigned int num_parts, const char *filename,
const char **err) { … }
int SaveEXRToMemory(const float *data, int width, int height, int components,
const int save_as_fp16, unsigned char **outbuf, const char **err) { … }
int SaveEXR(const float *data, int width, int height, int components,
const int save_as_fp16, const char *outfilename, const char **err) { … }
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
#endif