Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2017-10-19 04:55:11 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2017-11-08 01:20:22 +0300
commit05b08a3b6d864d760942c052a92c42c2bbe2c54d (patch)
tree75e2c34a06c0188672b25d2753e2d2f78ebb46f6 /source/blender/imbuf/intern/openexr/openexr_api.cpp
parent2a097527f20da98bb4c1199c2854a15eea241153 (diff)
Fix T53092: errors reading EXR files with different data/display window.
Multilayer/multiview OpenEXRs did not read the full data window like single layer, now it should be consistent.
Diffstat (limited to 'source/blender/imbuf/intern/openexr/openexr_api.cpp')
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp74
1 files changed, 45 insertions, 29 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index b3286bfbd98..451869415e7 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -1106,10 +1106,7 @@ void IMB_exrtile_write_channels(void *handle, int partx, int party, int level, c
void IMB_exr_read_channels(void *handle)
{
ExrHandle *data = (ExrHandle *)handle;
- ExrChannel *echan;
int numparts = data->ifile->parts();
- std::vector<FrameBuffer> frameBuffers(numparts);
- std::vector<InputPart> inputParts;
/* check if exr was saved with previous versions of blender which flipped images */
const StringAttribute *ta = data->ifile->header(0).findTypedAttribute <StringAttribute> ("BlenderMultiChannel");
@@ -1117,37 +1114,56 @@ void IMB_exr_read_channels(void *handle)
exr_printf("\nIMB_exr_read_channels\n%s %-6s %-22s \"%s\"\n---------------------------------------------------------------------\n", "p", "view", "name", "internal_name");
- for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
- exr_printf("%d %-6s %-22s \"%s\"\n", echan->m->part_number, echan->m->view.c_str(), echan->m->name.c_str(), echan->m->internal_name.c_str());
+ for (int i = 0; i < numparts; i++) {
+ /* Read part header. */
+ InputPart in(*data->ifile, i);
+ Header header = in.header();
+ Box2i dw = header.dataWindow();
+
+ /* Insert all matching channel into framebuffer. */
+ FrameBuffer frameBuffer;
+ ExrChannel *echan;
+
+ for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
+ if(echan->m->part_number != i) {
+ continue;
+ }
+
+ exr_printf("%d %-6s %-22s \"%s\"\n", echan->m->part_number, echan->m->view.c_str(), echan->m->name.c_str(), echan->m->internal_name.c_str());
+
+ if (echan->rect) {
+ float *rect = echan->rect;
+ size_t xstride = echan->xstride * sizeof(float);
+ size_t ystride = echan->ystride * sizeof(float);
+
+ if (!flip) {
+ /* inverse correct first pixel for datawindow coordinates */
+ rect -= echan->xstride * (dw.min.x - dw.min.y * data->width);
+ /* move to last scanline to flip to Blender convention */
+ rect += echan->xstride * (data->height - 1) * data->width;
+ ystride = -ystride;
+ }
+ else {
+ /* inverse correct first pixel for datawindow coordinates */
+ rect -= echan->xstride * (dw.min.x + dw.min.y * data->width);
+ }
- if (echan->rect) {
- if (flip)
- frameBuffers[echan->m->part_number].insert(echan->m->internal_name, Slice(Imf::FLOAT, (char *)echan->rect,
- echan->xstride * sizeof(float), echan->ystride * sizeof(float)));
+ frameBuffer.insert(echan->m->internal_name, Slice(Imf::FLOAT, (char *)rect, xstride, ystride));
+ }
else
- frameBuffers[echan->m->part_number].insert(echan->m->internal_name, Slice(Imf::FLOAT, (char *)(echan->rect + echan->xstride * (data->height - 1) * data->width),
- echan->xstride * sizeof(float), -echan->ystride * sizeof(float)));
+ printf("warning, channel with no rect set %s\n", echan->m->internal_name.c_str());
}
- else
- printf("warning, channel with no rect set %s\n", echan->m->internal_name.c_str());
- }
- for (int i = 0; i < numparts; i++) {
- InputPart in (*data->ifile, i);
- in.setFrameBuffer(frameBuffers[i]);
- inputParts.push_back(in);
- }
-
- try {
- for (int i = 0; i < numparts; i++) {
- Header header = inputParts[i].header();
- exr_printf("readPixels:readPixels[%d]: min.y: %d, max.y: %d\n", i, header.dataWindow().min.y, header.dataWindow().max.y);
- inputParts[i].readPixels(header.dataWindow().min.y, header.dataWindow().max.y);
- inputParts[i].readPixels(0, data->height - 1);
+ /* Read pixels. */
+ try {
+ in.setFrameBuffer(frameBuffer);
+ exr_printf("readPixels:readPixels[%d]: min.y: %d, max.y: %d\n", i, dw.min.y, dw.max.y);
+ in.readPixels(dw.min.y, dw.max.y);
+ }
+ catch (const std::exception& exc) {
+ std::cerr << "OpenEXR-readPixels: ERROR: " << exc.what() << std::endl;
+ break;
}
- }
- catch (const std::exception& exc) {
- std::cerr << "OpenEXR-readPixels: ERROR: " << exc.what() << std::endl;
}
}