MCPcopy Create free account
hub / github.com/ARM-software/astc-encoder / LoadEXRMultipartImageFromMemory

Function LoadEXRMultipartImageFromMemory

Source/ThirdParty/tinyexr.h:10501–10630  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

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

Callers 1

Calls 7

SetErrorMessageFunction · 0.85
swap8Function · 0.85
PrecalculateTileInfoFunction · 0.85
InitTileOffsetsFunction · 0.85
swap4Function · 0.85
DecodeChunkFunction · 0.85

Tested by

no test coverage detected