-
Notifications
You must be signed in to change notification settings - Fork 114
Open
Description
Steps to reproduce: run the function below, open exr with TEV, inspect the channel values.
In the multi-line comment where we set channel names, I suppose TEV behave like that.
Is my guess correct? If yes, could it be fixed (or is it fixed already? I am using version 1.26), since both TEV and TinyEXR are very popular tools.
bool TestTinyExrWrite()
{
EXRHeader header;
EXRImage image;
InitEXRHeader(&header);
InitEXRImage(&image);
int width = 1920;
int height = 1080;
int num_channels = 4;
// Set up header
header.num_channels = num_channels;
header.channels = new EXRChannelInfo[num_channels];
header.pixel_types = new int[num_channels];
header.requested_pixel_types = new int[num_channels];
const char names[4] = { 'R', 'G', 'B', 'A' };
/// TEV Viewer works like this:
/// It "blindly" reorders the channels in alphabetical order,
/// which means even if you pack data in RGBA order and set header.channels also,
/// it displays data wrongly as ABGR.
/// In the channel names below, where NONE is a valid common channel name and H comes first,
/// no matter how we order them,
/// TEV will show a single H-channel image with 0.9f as value, because it comes first.
//const char names[4] = { 'O', 'H', 'P', 'Q' };
for (int i = 0; i < num_channels; i++) {
header.channels[i].name[0] = names[i];
header.channels[i].name[1] = '\0';
header.pixel_types[i] = TINYEXR_PIXELTYPE_HALF;
header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF;
}
header.compression_type = TINYEXR_COMPRESSIONTYPE_NONE; // No compression for simplicity
// Allocate data for each channel
image.num_channels = num_channels;
image.width = width;
image.height = height;
image.images = new unsigned char* [num_channels];
// Create distinct test values for each channel:
// Channel A: all 1.0f
// Channel R: all 0.9f
// Channel G: all 0.6f
// Channel B: all 0.1f
auto fToU16 = [](float value) {
tinyexr::FP32 f32;
f32.f = value;
return tinyexr::float_to_half_full(f32).u;
};
std::vector<uint16_t> dataR(width * height, fToU16(0.9f));
std::vector<uint16_t> dataG(width * height, fToU16(0.6f));
std::vector<uint16_t> dataB(width * height, fToU16(0.1f));
std::vector<uint16_t> dataA(width * height, fToU16(1.0f));
image.images[0] = reinterpret_cast<unsigned char*>(dataR.data());
image.images[1] = reinterpret_cast<unsigned char*>(dataG.data());
image.images[2] = reinterpret_cast<unsigned char*>(dataB.data());
image.images[3] = reinterpret_cast<unsigned char*>(dataA.data());
// Save the EXR file
const char* err = nullptr;
int ret = SaveEXRImageToFile(&image, &header, <ANY LOCATION>, &err);
if (ret != TINYEXR_SUCCESS) {
printf("Error: %s\n", err);
return 1;
}
// Cleanup
delete[] header.channels;
delete[] header.requested_pixel_types;
delete[] image.images;
printf("EXR file 'test.exr' created successfully.\n");
return true;
}
Metadata
Metadata
Assignees
Labels
No labels