MCPcopy Create free account
hub / github.com/cinder/Cinder / LoadEXRMultipartImageFromMemory

Function LoadEXRMultipartImageFromMemory

include/tinyexr/tinyexr.h:8943–9072  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

8941}
8942
8943int LoadEXRMultipartImageFromMemory(EXRImage *exr_images,
8944 const EXRHeader **exr_headers,
8945 unsigned int num_parts,
8946 const unsigned char *memory,
8947 const size_t size, const char **err) {
8948 if (exr_images == NULL || exr_headers == NULL || num_parts == 0 ||
8949 memory == NULL || (size <= tinyexr::kEXRVersionSize)) {
8950 tinyexr::SetErrorMessage(
8951 "Invalid argument for LoadEXRMultipartImageFromMemory()", err);
8952 return TINYEXR_ERROR_INVALID_ARGUMENT;
8953 }
8954
8955 // compute total header size.
8956 size_t total_header_size = 0;
8957 for (unsigned int i = 0; i < num_parts; i++) {
8958 if (exr_headers[i]->header_len == 0) {
8959 tinyexr::SetErrorMessage("EXRHeader variable is not initialized.", err);
8960 return TINYEXR_ERROR_INVALID_ARGUMENT;
8961 }
8962
8963 total_header_size += exr_headers[i]->header_len;
8964 }
8965
8966 const char *marker = reinterpret_cast<const char *>(
8967 memory + total_header_size + 4 +
8968 4); // +8 for magic number and version header.
8969
8970 marker += 1; // Skip empty header.
8971
8972 // NOTE 1:
8973 // In multipart image, There is 'part number' before chunk data.
8974 // 4 byte : part number
8975 // 4+ : chunk
8976 //
8977 // NOTE 2:
8978 // EXR spec says 'part number' is 'unsigned long' but actually this is
8979 // 'unsigned int(4 bytes)' in OpenEXR implementation...
8980 // http://www.openexr.com/openexrfilelayout.pdf
8981
8982 // Load chunk offset table.
8983 std::vector<tinyexr::OffsetData> chunk_offset_table_list;
8984 chunk_offset_table_list.reserve(num_parts);
8985 for (size_t i = 0; i < static_cast<size_t>(num_parts); i++) {
8986 chunk_offset_table_list.resize(chunk_offset_table_list.size() + 1);
8987 tinyexr::OffsetData& offset_data = chunk_offset_table_list.back();
8988 if (!exr_headers[i]->tiled || exr_headers[i]->tile_level_mode == TINYEXR_TILE_ONE_LEVEL) {
8989 tinyexr::InitSingleResolutionOffsets(offset_data, size_t(exr_headers[i]->chunk_count));
8990 std::vector<tinyexr::tinyexr_uint64>& offset_table = offset_data.offsets[0][0];
8991
8992 for (size_t c = 0; c < offset_table.size(); c++) {
8993 tinyexr::tinyexr_uint64 offset;
8994 memcpy(&offset, marker, 8);
8995 tinyexr::swap8(&offset);
8996
8997 if (offset >= size) {
8998 tinyexr::SetErrorMessage("Invalid offset size in EXR header chunks.",
8999 err);
9000 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