MCPcopy Create free account
hub / github.com/BinomialLLC/basis_universal / LoadEXRMultipartImageFromMemory

Function LoadEXRMultipartImageFromMemory

encoder/3rdparty/tinyexr.h:10500–10629  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

10498}
10499
10500int LoadEXRMultipartImageFromMemory(EXRImage *exr_images,
10501 const EXRHeader **exr_headers,
10502 unsigned int num_parts,
10503 const unsigned char *memory,
10504 const size_t size, const char **err) {
10505 if (exr_images == NULL || exr_headers == NULL || num_parts == 0 ||
10506 memory == NULL || (size <= tinyexr::kEXRVersionSize)) {
10507 tinyexr::SetErrorMessage(
10508 "Invalid argument for LoadEXRMultipartImageFromMemory()", err);
10509 return TINYEXR_ERROR_INVALID_ARGUMENT;
10510 }
10511
10512 // compute total header size.
10513 size_t total_header_size = 0;
10514 for (unsigned int i = 0; i < num_parts; i++) {
10515 if (exr_headers[i]->header_len == 0) {
10516 tinyexr::SetErrorMessage("EXRHeader variable is not initialized.", err);
10517 return TINYEXR_ERROR_INVALID_ARGUMENT;
10518 }
10519
10520 total_header_size += exr_headers[i]->header_len;
10521 }
10522
10523 const char *marker = reinterpret_cast<const char *>(
10524 memory + total_header_size + 4 +
10525 4); // +8 for magic number and version header.
10526
10527 marker += 1; // Skip empty header.
10528
10529 // NOTE 1:
10530 // In multipart image, There is 'part number' before chunk data.
10531 // 4 byte : part number
10532 // 4+ : chunk
10533 //
10534 // NOTE 2:
10535 // EXR spec says 'part number' is 'unsigned long' but actually this is
10536 // 'unsigned int(4 bytes)' in OpenEXR implementation...
10537 // http://www.openexr.com/openexrfilelayout.pdf
10538
10539 // Load chunk offset table.
10540 std::vector<tinyexr::OffsetData> chunk_offset_table_list;
10541 chunk_offset_table_list.reserve(num_parts);
10542 for (size_t i = 0; i < static_cast<size_t>(num_parts); i++) {
10543 chunk_offset_table_list.resize(chunk_offset_table_list.size() + 1);
10544 tinyexr::OffsetData& offset_data = chunk_offset_table_list.back();
10545 if (!exr_headers[i]->tiled || exr_headers[i]->tile_level_mode == TINYEXR_TILE_ONE_LEVEL) {
10546 tinyexr::InitSingleResolutionOffsets(offset_data, size_t(exr_headers[i]->chunk_count));
10547 std::vector<tinyexr::tinyexr_uint64>& offset_table = offset_data.offsets[0][0];
10548
10549 for (size_t c = 0; c < offset_table.size(); c++) {
10550 tinyexr::tinyexr_uint64 offset;
10551 memcpy(&offset, marker, 8);
10552 tinyexr::swap8(&offset);
10553
10554 if (offset >= size) {
10555 tinyexr::SetErrorMessage("Invalid offset size in EXR header chunks.",
10556 err);
10557 return TINYEXR_ERROR_INVALID_DATA;

Callers 1

Calls 12

SetErrorMessageFunction · 0.85
swap8Function · 0.85
PrecalculateTileInfoFunction · 0.85
InitTileOffsetsFunction · 0.85
swap4Function · 0.85
DecodeChunkFunction · 0.85
backMethod · 0.80
reserveMethod · 0.45
resizeMethod · 0.45
sizeMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected