فهرست منبع

Updated tinyexr.

Branimir Karadžić 7 سال پیش
والد
کامیت
e7ba2faf74
1فایلهای تغییر یافته به همراه54 افزوده شده و 35 حذف شده
  1. 54 35
      3rdparty/tinyexr/tinyexr.h

+ 54 - 35
3rdparty/tinyexr/tinyexr.h

@@ -124,7 +124,8 @@ extern "C" {
 #define TINYEXR_PIXELTYPE_HALF (1)
 #define TINYEXR_PIXELTYPE_HALF (1)
 #define TINYEXR_PIXELTYPE_FLOAT (2)
 #define TINYEXR_PIXELTYPE_FLOAT (2)
 
 
-#define TINYEXR_MAX_ATTRIBUTES (128)
+#define TINYEXR_MAX_HEADER_ATTRIBUTES (1024)
+#define TINYEXR_MAX_CUSTOM_ATTRIBUTES (128)
 
 
 #define TINYEXR_COMPRESSIONTYPE_NONE (0)
 #define TINYEXR_COMPRESSIONTYPE_NONE (0)
 #define TINYEXR_COMPRESSIONTYPE_RLE (1)
 #define TINYEXR_COMPRESSIONTYPE_RLE (1)
@@ -206,7 +207,7 @@ typedef struct _EXRHeader {
   // Custom attributes(exludes required attributes(e.g. `channels`,
   // Custom attributes(exludes required attributes(e.g. `channels`,
   // `compression`, etc)
   // `compression`, etc)
   int num_custom_attributes;
   int num_custom_attributes;
-  EXRAttribute custom_attributes[TINYEXR_MAX_ATTRIBUTES];
+  EXRAttribute *custom_attributes; // array of EXRAttribute. size = `num_custom_attributes`.
 
 
   EXRChannelInfo *channels;  // [num_channels]
   EXRChannelInfo *channels;  // [num_channels]
 
 
@@ -8215,8 +8216,8 @@ static void hufBuildEncTable(
   //    for all array entries.
   //    for all array entries.
   //
   //
 
 
-  int hlink[HUF_ENCSIZE];
-  long long *fHeap[HUF_ENCSIZE];
+  std::vector<int> hlink(HUF_ENCSIZE);
+  std::vector<long long *> fHeap(HUF_ENCSIZE);
 
 
   *im = 0;
   *im = 0;
 
 
@@ -8275,8 +8276,8 @@ static void hufBuildEncTable(
 
 
   std::make_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
   std::make_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
 
 
-  long long scode[HUF_ENCSIZE];
-  memset(scode, 0, sizeof(long long) * HUF_ENCSIZE);
+  std::vector<long long> scode(HUF_ENCSIZE);
+  memset(scode.data(), 0, sizeof(long long) * HUF_ENCSIZE);
 
 
   while (nf > 1) {
   while (nf > 1) {
     //
     //
@@ -8348,8 +8349,8 @@ static void hufBuildEncTable(
   // code table from scode into frq.
   // code table from scode into frq.
   //
   //
 
 
-  hufCanonicalCodeTable(scode);
-  memcpy(frq, scode, sizeof(long long) * HUF_ENCSIZE);
+  hufCanonicalCodeTable(scode.data());
+  memcpy(frq, scode.data(), sizeof(long long) * HUF_ENCSIZE);
 }
 }
 
 
 //
 //
@@ -8813,7 +8814,7 @@ static bool hufDecode(const long long *hcode,  // i : encoding table
   return true;
   return true;
 }
 }
 
 
-static void countFrequencies(long long freq[HUF_ENCSIZE],
+static void countFrequencies(std::vector<long long> &freq,
                              const unsigned short data[/*n*/], int n) {
                              const unsigned short data[/*n*/], int n) {
   for (int i = 0; i < HUF_ENCSIZE; ++i) freq[i] = 0;
   for (int i = 0; i < HUF_ENCSIZE; ++i) freq[i] = 0;
 
 
@@ -8844,21 +8845,21 @@ static int hufCompress(const unsigned short raw[], int nRaw,
                        char compressed[]) {
                        char compressed[]) {
   if (nRaw == 0) return 0;
   if (nRaw == 0) return 0;
 
 
-  long long freq[HUF_ENCSIZE];
+  std::vector<long long> freq(HUF_ENCSIZE);
 
 
   countFrequencies(freq, raw, nRaw);
   countFrequencies(freq, raw, nRaw);
 
 
   int im = 0;
   int im = 0;
   int iM = 0;
   int iM = 0;
-  hufBuildEncTable(freq, &im, &iM);
+  hufBuildEncTable(freq.data(), &im, &iM);
 
 
   char *tableStart = compressed + 20;
   char *tableStart = compressed + 20;
   char *tableEnd = tableStart;
   char *tableEnd = tableStart;
-  hufPackEncTable(freq, im, iM, &tableEnd);
+  hufPackEncTable(freq.data(), im, iM, &tableEnd);
   int tableLength = tableEnd - tableStart;
   int tableLength = tableEnd - tableStart;
 
 
   char *dataStart = tableEnd;
   char *dataStart = tableEnd;
-  int nBits = hufEncode(freq, raw, nRaw, iM, dataStart);
+  int nBits = hufEncode(freq.data(), raw, nRaw, iM, dataStart);
   int data_length = (nBits + 7) / 8;
   int data_length = (nBits + 7) / 8;
 
 
   writeUInt(compressed, im);
   writeUInt(compressed, im);
@@ -9003,7 +9004,7 @@ static bool CompressPiz(unsigned char *outPtr, unsigned int *outSize,
                         const unsigned char *inPtr, size_t inSize,
                         const unsigned char *inPtr, size_t inSize,
                         const std::vector<ChannelInfo> &channelInfo,
                         const std::vector<ChannelInfo> &channelInfo,
                         int data_width, int num_lines) {
                         int data_width, int num_lines) {
-  unsigned char bitmap[BITMAP_SIZE];
+  std::vector<unsigned char> bitmap(BITMAP_SIZE);
   unsigned short minNonZero;
   unsigned short minNonZero;
   unsigned short maxNonZero;
   unsigned short maxNonZero;
 
 
@@ -9054,12 +9055,12 @@ static bool CompressPiz(unsigned char *outPtr, unsigned int *outSize,
     }
     }
   }
   }
 
 
-  bitmapFromData(&tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()), bitmap,
+  bitmapFromData(&tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()), bitmap.data(),
                  minNonZero, maxNonZero);
                  minNonZero, maxNonZero);
 
 
-  unsigned short lut[USHORT_RANGE];
-  unsigned short maxValue = forwardLutFromBitmap(bitmap, lut);
-  applyLut(lut, &tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()));
+  std::vector<unsigned short> lut(USHORT_RANGE);
+  unsigned short maxValue = forwardLutFromBitmap(bitmap.data(), lut.data());
+  applyLut(lut.data(), &tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()));
 
 
   //
   //
   // Store range compression info in _outBuffer
   // Store range compression info in _outBuffer
@@ -9129,7 +9130,7 @@ static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
     return true;
     return true;
   }
   }
 
 
-  unsigned char bitmap[BITMAP_SIZE];
+  std::vector<unsigned char> bitmap(BITMAP_SIZE);
   unsigned short minNonZero;
   unsigned short minNonZero;
   unsigned short maxNonZero;
   unsigned short maxNonZero;
 
 
@@ -9139,7 +9140,7 @@ static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
   return false;
   return false;
 #endif
 #endif
 
 
-  memset(bitmap, 0, BITMAP_SIZE);
+  memset(bitmap.data(), 0, BITMAP_SIZE);
 
 
   const unsigned char *ptr = inPtr;
   const unsigned char *ptr = inPtr;
   minNonZero = *(reinterpret_cast<const unsigned short *>(ptr));
   minNonZero = *(reinterpret_cast<const unsigned short *>(ptr));
@@ -9156,9 +9157,9 @@ static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
     ptr += maxNonZero - minNonZero + 1;
     ptr += maxNonZero - minNonZero + 1;
   }
   }
 
 
-  unsigned short lut[USHORT_RANGE];
-  memset(lut, 0, sizeof(unsigned short) * USHORT_RANGE);
-  unsigned short maxValue = reverseLutFromBitmap(bitmap, lut);
+  std::vector<unsigned short> lut(USHORT_RANGE);
+  memset(lut.data(), 0, sizeof(unsigned short) * USHORT_RANGE);
+  unsigned short maxValue = reverseLutFromBitmap(bitmap.data(), lut.data());
 
 
   //
   //
   // Huffman decoding
   // Huffman decoding
@@ -9212,7 +9213,7 @@ static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
   // Expand the pixel data to their original range
   // Expand the pixel data to their original range
   //
   //
 
 
-  applyLut(lut, &tmpBuffer.at(0), static_cast<int>(tmpBufSize));
+  applyLut(lut.data(), &tmpBuffer.at(0), static_cast<int>(tmpBufSize));
 
 
   for (int y = 0; y < num_lines; y++) {
   for (int y = 0; y < num_lines; y++) {
     for (size_t i = 0; i < channelData.size(); ++i) {
     for (size_t i = 0; i < channelData.size(); ++i) {
@@ -10101,6 +10102,7 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
   }
   }
 
 
   if (version->multipart) {
   if (version->multipart) {
+
     if (size > 0 && marker[0] == '\0') {
     if (size > 0 && marker[0] == '\0') {
       // End of header list.
       // End of header list.
       if (empty_header) {
       if (empty_header) {
@@ -10153,7 +10155,7 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
 
 
   // Read attributes
   // Read attributes
   size_t orig_size = size;
   size_t orig_size = size;
-  for (;;) {
+  for (size_t nattr = 0; nattr < TINYEXR_MAX_HEADER_ATTRIBUTES; nattr++) {
     if (0 == size) {
     if (0 == size) {
       return TINYEXR_ERROR_INVALID_DATA;
       return TINYEXR_ERROR_INVALID_DATA;
     } else if (marker[0] == '\0') {
     } else if (marker[0] == '\0') {
@@ -10316,8 +10318,8 @@ static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
         tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->chunk_count));
         tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->chunk_count));
       }
       }
     } else {
     } else {
-      // Custom attribute(up to TINYEXR_MAX_ATTRIBUTES)
-      if (info->attributes.size() < TINYEXR_MAX_ATTRIBUTES) {
+      // Custom attribute(up to TINYEXR_MAX_CUSTOM_ATTRIBUTES)
+      if (info->attributes.size() < TINYEXR_MAX_CUSTOM_ATTRIBUTES) {
         EXRAttribute attrib;
         EXRAttribute attrib;
 #ifdef _MSC_VER
 #ifdef _MSC_VER
         strncpy_s(attrib.name, attr_name.c_str(), 255);
         strncpy_s(attrib.name, attr_name.c_str(), 255);
@@ -10447,15 +10449,27 @@ static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) {
     exr_header->requested_pixel_types[c] = info.channels[c].pixel_type;
     exr_header->requested_pixel_types[c] = info.channels[c].pixel_type;
   }
   }
 
 
-  assert(info.attributes.size() < TINYEXR_MAX_ATTRIBUTES);
   exr_header->num_custom_attributes = static_cast<int>(info.attributes.size());
   exr_header->num_custom_attributes = static_cast<int>(info.attributes.size());
 
 
-  for (size_t i = 0; i < info.attributes.size(); i++) {
-    memcpy(exr_header->custom_attributes[i].name, info.attributes[i].name, 256);
-    memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type, 256);
-    exr_header->custom_attributes[i].size = info.attributes[i].size;
-    // Just copy poiner
-    exr_header->custom_attributes[i].value = info.attributes[i].value;
+  if (exr_header->num_custom_attributes > 0) {
+    // TODO(syoyo): Report warning when # of attributes exceeds `TINYEXR_MAX_CUSTOM_ATTRIBUTES`
+    if (exr_header->num_custom_attributes > TINYEXR_MAX_CUSTOM_ATTRIBUTES) {
+      exr_header->num_custom_attributes = TINYEXR_MAX_CUSTOM_ATTRIBUTES;
+    }
+
+    exr_header->custom_attributes = static_cast<EXRAttribute *>(
+        malloc(sizeof(EXRAttribute) * size_t(exr_header->num_custom_attributes)));
+
+    for (size_t i = 0; i < info.attributes.size(); i++) {
+      memcpy(exr_header->custom_attributes[i].name, info.attributes[i].name, 256);
+      memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type, 256);
+      exr_header->custom_attributes[i].size = info.attributes[i].size;
+      // Just copy poiner
+      exr_header->custom_attributes[i].value = info.attributes[i].value;
+    }
+
+  } else {
+    exr_header->custom_attributes = NULL;
   }
   }
 
 
   exr_header->header_len = info.header_len;
   exr_header->header_len = info.header_len;
@@ -11768,7 +11782,7 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
 #ifdef _MSC_VER
 #ifdef _MSC_VER
   FILE *fp = NULL;
   FILE *fp = NULL;
   errno_t errcode = fopen_s(&fp, filename, "rb");
   errno_t errcode = fopen_s(&fp, filename, "rb");
-  if ((!errcode) || (!fp)) {
+  if ((0 != errcode) || (!fp)) {
     if (err) {
     if (err) {
       (*err) = "Cannot read file.";
       (*err) = "Cannot read file.";
     }
     }
@@ -12193,6 +12207,10 @@ int FreeEXRHeader(EXRHeader *exr_header) {
     }
     }
   }
   }
 
 
+  if (exr_header->custom_attributes) {
+    free(exr_header->custom_attributes);
+  }
+
   return TINYEXR_SUCCESS;
   return TINYEXR_SUCCESS;
 }
 }
 
 
@@ -12222,6 +12240,7 @@ int FreeEXRImage(EXRImage *exr_image) {
         free(exr_image->tiles[tid].images);
         free(exr_image->tiles[tid].images);
       }
       }
     }
     }
+    free(exr_image->tiles);
   }
   }
 
 
   return TINYEXR_SUCCESS;
   return TINYEXR_SUCCESS;