Skip to content

Commit 5c68638

Browse files
authored
Merge pull request syoyo#182 from tom7/release
Fix overflow on huge files (and some small typos)
2 parents d02bdda + 2a3ffbf commit 5c68638

File tree

1 file changed

+68
-60
lines changed

1 file changed

+68
-60
lines changed

tinyexr.h

+68-60
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ extern "C" {
104104
#endif
105105

106106
// Use miniz or not to decode ZIP format pixel. Linking with zlib
107-
// required if this flas is 0 and TINYEXR_USE_STB_ZLIB is 0.
107+
// required if this flag is 0 and TINYEXR_USE_STB_ZLIB is 0.
108108
#ifndef TINYEXR_USE_MINIZ
109109
#define TINYEXR_USE_MINIZ (1)
110110
#endif
@@ -114,7 +114,7 @@ extern "C" {
114114
#define TINYEXR_USE_STB_ZLIB (0)
115115
#endif
116116

117-
// Disable PIZ comporession when applying cpplint.
117+
// Disable PIZ compression when applying cpplint.
118118
#ifndef TINYEXR_USE_PIZ
119119
#define TINYEXR_USE_PIZ (1)
120120
#endif
@@ -185,11 +185,11 @@ typedef struct TEXRVersion {
185185
int version; // this must be 2
186186
// tile format image;
187187
// not zero for only a single-part "normal" tiled file (according to spec.)
188-
int tiled;
188+
int tiled;
189189
int long_name; // long name attribute
190190
// deep image(EXR 2.0);
191191
// for a multi-part file, indicates that at least one part is of type deep* (according to spec.)
192-
int non_image;
192+
int non_image;
193193
int multipart; // multi-part(EXR 2.0)
194194
} EXRVersion;
195195

@@ -1507,7 +1507,7 @@ static int rleCompress(int inLength, const char in[], signed char out[]) {
15071507

15081508
//
15091509
// Uncompress an array of bytes compressed with rleCompress().
1510-
// Returns the length of the oncompressed data, or 0 if the
1510+
// Returns the length of the uncompressed data, or 0 if the
15111511
// length of the uncompressed data would be more than maxLength.
15121512
//
15131513

@@ -3670,7 +3670,7 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
36703670
}
36713671
}
36723672
#else
3673-
assert(0 && "PIZ is enabled in this build");
3673+
assert(0 && "PIZ is disabled in this build");
36743674
return false;
36753675
#endif
36763676

@@ -4063,7 +4063,7 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
40634063
for (int u = 0; u < width; u++) {
40644064
tinyexr::FP16 hf;
40654065

4066-
// address may not be aliged. use byte-wise copy for safety.#76
4066+
// address may not be aligned. use byte-wise copy for safety.#76
40674067
// hf.u = line_ptr[u];
40684068
tinyexr::cpy2(&(hf.u), line_ptr + u);
40694069

@@ -4120,7 +4120,7 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
41204120

41214121
if (reinterpret_cast<const unsigned char *>(line_ptr + width) >
41224122
(data_ptr + data_len)) {
4123-
// Corrupsed data
4123+
// Corrupted data
41244124
return false;
41254125
}
41264126

@@ -4269,8 +4269,8 @@ static unsigned char **AllocateImage(int num_channels,
42694269
if (success) {
42704270
(*success) = true;
42714271
}
4272-
}
4273-
4272+
}
4273+
42744274
return images;
42754275
}
42764276

@@ -4773,8 +4773,8 @@ static bool ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info, std::st
47734773
struct OffsetData {
47744774
OffsetData() : num_x_levels(0), num_y_levels(0) {}
47754775
std::vector<std::vector<std::vector <tinyexr::tinyexr_uint64> > > offsets;
4776-
int num_x_levels;
4777-
int num_y_levels;
4776+
int num_x_levels;
4777+
int num_y_levels;
47784778
};
47794779

47804780
static int LevelIndex(int lx, int ly, int tile_level_mode, int num_x_levels) {
@@ -4834,7 +4834,7 @@ static int DecodeTiledLevel(EXRImage* exr_image, const EXRHeader* exr_header,
48344834
#else
48354835
unsigned error_flag(EF_SUCCESS);
48364836
#endif
4837-
4837+
48384838
// Although the spec says : "...the data window is subdivided into an array of smaller rectangles...",
48394839
// the IlmImf library allows the dimensions of the tile to be larger (or equal) than the dimensions of the data window.
48404840
#if 0
@@ -4878,7 +4878,7 @@ static int DecodeTiledLevel(EXRImage* exr_image, const EXRHeader* exr_header,
48784878
exr_header->tile_size_y, &alloc_success);
48794879

48804880
if (!alloc_success) {
4881-
error_flag |= EF_INVALID_DATA;
4881+
error_flag |= EF_INVALID_DATA;
48824882
continue;
48834883
}
48844884

@@ -4890,7 +4890,7 @@ static int DecodeTiledLevel(EXRImage* exr_image, const EXRHeader* exr_header,
48904890
tinyexr::tinyexr_uint64 offset = offset_data.offsets[size_t(level_index)][size_t(y_tile)][size_t(x_tile)];
48914891
if (offset + sizeof(int) * 5 > size) {
48924892
// Insufficient data size.
4893-
error_flag |= EF_INSUFFICIENT_DATA;
4893+
error_flag |= EF_INSUFFICIENT_DATA;
48944894
continue;
48954895
}
48964896

@@ -4956,7 +4956,7 @@ static int DecodeTiledLevel(EXRImage* exr_image, const EXRHeader* exr_header,
49564956
exr_image->tiles[tile_idx].level_y = tile_coordinates[3];
49574957

49584958
#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
4959-
}
4959+
}
49604960
}));
49614961
} // num_thread loop
49624962

@@ -6069,8 +6069,8 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
60696069

60706070
if (channels.size() < 1) {
60716071
if (layername == NULL) {
6072-
tinyexr::SetErrorMessage("Layer Not Foound. Seems EXR contains channels with layer(e.g. `diffuse.R`). if you are using LoadEXR(), please try LoadEXRWithLayer(). LoadEXR() cannot load EXR having channels with layer.", err);
6073-
6072+
tinyexr::SetErrorMessage("Layer Not Found. Seems EXR contains channels with layer(e.g. `diffuse.R`). if you are using LoadEXR(), please try LoadEXRWithLayer(). LoadEXR() cannot load EXR having channels with layer.", err);
6073+
60746074
} else {
60756075
tinyexr::SetErrorMessage("Layer Not Found", err);
60766076
}
@@ -6106,22 +6106,22 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
61066106
for (int it = 0; it < exr_image.num_tiles; it++) {
61076107
for (int j = 0; j < exr_header.tile_size_y; j++) {
61086108
for (int i = 0; i < exr_header.tile_size_x; i++) {
6109-
const int ii = exr_image.tiles[it].offset_x *
6110-
static_cast<int>(exr_header.tile_size_x) +
6111-
i;
6112-
const int jj = exr_image.tiles[it].offset_y *
6113-
static_cast<int>(exr_header.tile_size_y) +
6114-
j;
6115-
const int idx = ii + jj * static_cast<int>(exr_image.width);
6109+
const size_t ii = exr_image.tiles[it].offset_x *
6110+
static_cast<size_t>(exr_header.tile_size_x) +
6111+
i;
6112+
const size_t jj = exr_image.tiles[it].offset_y *
6113+
static_cast<size_t>(exr_header.tile_size_y) +
6114+
j;
6115+
const size_t idx = ii + jj * static_cast<size_t>(exr_image.width);
61166116

61176117
// out of region check.
6118-
if (ii >= exr_image.width) {
6118+
if (ii >= static_cast<size_t>(exr_image.width)) {
61196119
continue;
61206120
}
6121-
if (jj >= exr_image.height) {
6121+
if (jj >= static_cast<size_t>(exr_image.height)) {
61226122
continue;
61236123
}
6124-
const int srcIdx = i + j * exr_header.tile_size_x;
6124+
const size_t srcIdx = i + j * exr_header.tile_size_x;
61256125
unsigned char **src = exr_image.tiles[it].images;
61266126
(*out_rgba)[4 * idx + 0] =
61276127
reinterpret_cast<float **>(src)[chIdx][srcIdx];
@@ -6135,7 +6135,9 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
61356135
}
61366136
}
61376137
} else {
6138-
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
6138+
const size_t pixel_size = static_cast<size_t>(exr_image.width) *
6139+
static_cast<size_t>(exr_image.height);
6140+
for (size_t i = 0; i < pixel_size; i++) {
61396141
const float val =
61406142
reinterpret_cast<float **>(exr_image.images)[chIdx][i];
61416143
(*out_rgba)[4 * i + 0] = val;
@@ -6176,20 +6178,20 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
61766178
for (int it = 0; it < exr_image.num_tiles; it++) {
61776179
for (int j = 0; j < exr_header.tile_size_y; j++) {
61786180
for (int i = 0; i < exr_header.tile_size_x; i++) {
6179-
const int ii =
6181+
const size_t ii =
61806182
exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
6181-
const int jj =
6183+
const size_t jj =
61826184
exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
6183-
const int idx = ii + jj * exr_image.width;
6185+
const size_t idx = ii + jj * exr_image.width;
61846186

61856187
// out of region check.
6186-
if (ii >= exr_image.width) {
6188+
if (ii >= static_cast<size_t>(exr_image.width)) {
61876189
continue;
61886190
}
6189-
if (jj >= exr_image.height) {
6191+
if (jj >= static_cast<size_t>(exr_image.height)) {
61906192
continue;
61916193
}
6192-
const int srcIdx = i + j * exr_header.tile_size_x;
6194+
const size_t srcIdx = i + j * exr_header.tile_size_x;
61936195
unsigned char **src = exr_image.tiles[it].images;
61946196
(*out_rgba)[4 * idx + 0] =
61956197
reinterpret_cast<float **>(src)[idxR][srcIdx];
@@ -6207,7 +6209,9 @@ int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
62076209
}
62086210
}
62096211
} else {
6210-
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
6212+
const size_t pixel_size = static_cast<size_t>(exr_image.width) *
6213+
static_cast<size_t>(exr_image.height);
6214+
for (size_t i = 0; i < pixel_size; i++) {
62116215
(*out_rgba)[4 * i + 0] =
62126216
reinterpret_cast<float **>(exr_image.images)[idxR][i];
62136217
(*out_rgba)[4 * i + 1] =
@@ -6384,20 +6388,20 @@ int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
63846388
for (int it = 0; it < exr_image.num_tiles; it++) {
63856389
for (int j = 0; j < exr_header.tile_size_y; j++) {
63866390
for (int i = 0; i < exr_header.tile_size_x; i++) {
6387-
const int ii =
6391+
const size_t ii =
63886392
exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
6389-
const int jj =
6393+
const size_t jj =
63906394
exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
6391-
const int idx = ii + jj * exr_image.width;
6395+
const size_t idx = ii + jj * exr_image.width;
63926396

63936397
// out of region check.
6394-
if (ii >= exr_image.width) {
6398+
if (ii >= static_cast<size_t>(exr_image.width)) {
63956399
continue;
63966400
}
6397-
if (jj >= exr_image.height) {
6401+
if (jj >= static_cast<size_t>(exr_image.height)) {
63986402
continue;
63996403
}
6400-
const int srcIdx = i + j * exr_header.tile_size_x;
6404+
const size_t srcIdx = i + j * exr_header.tile_size_x;
64016405
unsigned char **src = exr_image.tiles[it].images;
64026406
(*out_rgba)[4 * idx + 0] =
64036407
reinterpret_cast<float **>(src)[0][srcIdx];
@@ -6411,7 +6415,9 @@ int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
64116415
}
64126416
}
64136417
} else {
6414-
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
6418+
const size_t pixel_size = static_cast<size_t>(exr_image.width) *
6419+
static_cast<size_t>(exr_image.height);
6420+
for (size_t i = 0; i < pixel_size; i++) {
64156421
const float val = reinterpret_cast<float **>(exr_image.images)[0][i];
64166422
(*out_rgba)[4 * i + 0] = val;
64176423
(*out_rgba)[4 * i + 1] = val;
@@ -6450,20 +6456,20 @@ int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
64506456
for (int it = 0; it < exr_image.num_tiles; it++) {
64516457
for (int j = 0; j < exr_header.tile_size_y; j++)
64526458
for (int i = 0; i < exr_header.tile_size_x; i++) {
6453-
const int ii =
6459+
const size_t ii =
64546460
exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
6455-
const int jj =
6461+
const size_t jj =
64566462
exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
6457-
const int idx = ii + jj * exr_image.width;
6463+
const size_t idx = ii + jj * exr_image.width;
64586464

64596465
// out of region check.
6460-
if (ii >= exr_image.width) {
6466+
if (ii >= static_cast<size_t>(exr_image.width)) {
64616467
continue;
64626468
}
6463-
if (jj >= exr_image.height) {
6469+
if (jj >= static_cast<size_t>(exr_image.height)) {
64646470
continue;
64656471
}
6466-
const int srcIdx = i + j * exr_header.tile_size_x;
6472+
const size_t srcIdx = i + j * exr_header.tile_size_x;
64676473
unsigned char **src = exr_image.tiles[it].images;
64686474
(*out_rgba)[4 * idx + 0] =
64696475
reinterpret_cast<float **>(src)[idxR][srcIdx];
@@ -6480,7 +6486,9 @@ int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
64806486
}
64816487
}
64826488
} else {
6483-
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
6489+
const size_t pixel_size = static_cast<size_t>(exr_image.width) *
6490+
static_cast<size_t>(exr_image.height);
6491+
for (size_t i = 0; i < pixel_size; i++) {
64846492
(*out_rgba)[4 * i + 0] =
64856493
reinterpret_cast<float **>(exr_image.images)[idxR][i];
64866494
(*out_rgba)[4 * i + 1] =
@@ -6593,7 +6601,7 @@ namespace tinyexr
65936601

65946602
// out_data must be allocated initially with the block-header size
65956603
// of the current image(-part) type
6596-
static bool EncodePixelData(/* out */ std::vector<unsigned char>& out_data,
6604+
static bool EncodePixelData(/* out */ std::vector<unsigned char>& out_data,
65976605
const unsigned char* const* images,
65986606
int compression_type,
65996607
int /*line_order*/,
@@ -6894,13 +6902,13 @@ static int EncodeTiledLevel(const EXRImage* level_image, const EXRHeader* exr_he
68946902
int y_tile = i / num_x_tiles;
68956903

68966904
EXRTile& tile = level_image->tiles[tile_idx];
6897-
6905+
68986906
const unsigned char* const* images =
68996907
static_cast<const unsigned char* const*>(tile.images);
69006908

69016909
data_list[data_idx].resize(5*sizeof(int));
69026910
size_t data_header_size = data_list[data_idx].size();
6903-
bool ret = EncodePixelData(data_list[data_idx],
6911+
bool ret = EncodePixelData(data_list[data_idx],
69046912
images,
69056913
exr_header->compression_type,
69066914
0, // increasing y
@@ -6946,7 +6954,7 @@ static int EncodeTiledLevel(const EXRImage* level_image, const EXRHeader* exr_he
69466954

69476955
if (invalid_data) {
69486956
if (err) {
6949-
(*err) += "Failed to encode tile data.\n";
6957+
(*err) += "Failed to encode tile data.\n";
69506958
}
69516959
return TINYEXR_ERROR_INVALID_DATA;
69526960
}
@@ -7117,7 +7125,7 @@ static int EncodeChunk(const EXRImage* exr_image, const EXRHeader* exr_header,
71177125
data_list[i].resize(2*sizeof(int));
71187126
size_t data_header_size = data_list[i].size();
71197127

7120-
bool ret = EncodePixelData(data_list[i],
7128+
bool ret = EncodePixelData(data_list[i],
71217129
images,
71227130
exr_header->compression_type,
71237131
0, // increasing y
@@ -7133,7 +7141,7 @@ static int EncodeChunk(const EXRImage* exr_image, const EXRHeader* exr_header,
71337141
compression_param);
71347142
if (!ret) {
71357143
invalid_data = true;
7136-
continue; // "break" cannot be used with OpenMP
7144+
continue; // "break" cannot be used with OpenMP
71377145
}
71387146
assert(data_list[i].size() > data_header_size);
71397147
int data_len = static_cast<int>(data_list[i].size() - data_header_size);
@@ -8311,7 +8319,7 @@ int ParseEXRMultipartHeaderFromMemory(EXRHeader ***exr_headers,
83118319
(*exr_headers) =
83128320
static_cast<EXRHeader **>(malloc(sizeof(EXRHeader *) * infos.size()));
83138321

8314-
8322+
83158323
int retcode = TINYEXR_SUCCESS;
83168324

83178325
for (size_t i = 0; i < infos.size(); i++) {
@@ -8588,7 +8596,7 @@ int LoadEXRMultipartImageFromMemory(EXRImage *exr_images,
85888596
return TINYEXR_ERROR_INVALID_DATA;
85898597
}
85908598
offset_data.offsets[l][dy][dx] = offset + 4; // +4 to skip 'part number'
8591-
marker += sizeof(tinyexr::tinyexr_uint64); // = 8
8599+
marker += sizeof(tinyexr::tinyexr_uint64); // = 8
85928600
}
85938601
}
85948602
}
@@ -8599,7 +8607,7 @@ int LoadEXRMultipartImageFromMemory(EXRImage *exr_images,
85998607
for (size_t i = 0; i < static_cast<size_t>(num_parts); i++) {
86008608
tinyexr::OffsetData &offset_data = chunk_offset_table_list[i];
86018609

8602-
// First check 'part number' is identitical to 'i'
8610+
// First check 'part number' is identical to 'i'
86038611
for (unsigned int l = 0; l < offset_data.offsets.size(); ++l)
86048612
for (unsigned int dy = 0; dy < offset_data.offsets[l].size(); ++dy)
86058613
for (unsigned int dx = 0; dx < offset_data.offsets[l][dy].size(); ++dx) {
@@ -8971,7 +8979,7 @@ int SaveEXR(const float *data, int width, int height, int components,
89718979
}
89728980

89738981
#ifdef __clang__
8974-
// zero-as-null-ppinter-constant
8982+
// zero-as-null-pointer-constant
89758983
#pragma clang diagnostic pop
89768984
#endif
89778985

0 commit comments

Comments
 (0)