diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2011-10-20 03:04:48 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2011-10-20 03:04:48 +0400 |
commit | 364fcde86d3cdcb09d075a0445fc2e1eb64170d5 (patch) | |
tree | b8a36f336f1512e8a650ea71ff4bba63e7b5c7c8 /source/blender/imbuf/intern | |
parent | 0e66576f02afebdb4016249a9d7013ee5c1f0c36 (diff) |
#fix: Saving OpenEXR images as floats ignores color profile. This was not noticable in renderer because it works in linear color space. Painting on the image editor, saving and reloading was problematic though.
Diffstat (limited to 'source/blender/imbuf/intern')
-rw-r--r-- | source/blender/imbuf/intern/openexr/openexr_api.cpp | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index e064d7f760d..aa7defb2f39 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -342,27 +342,55 @@ static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flag FrameBuffer frameBuffer; OutputFile *file = new OutputFile(name, header); - int xstride = sizeof(float) * channels; - int ystride = - xstride*width; - float *rect[4] = {NULL, NULL, NULL, NULL}; - - /* last scanline, stride negative */ - rect[0]= ibuf->rect_float + channels*(height-1)*width; - rect[1]= rect[0]+1; - rect[2]= rect[0]+2; - rect[3]= (channels >= 4)? rect[0]+3:rect[0]; /* red as alpha, is this needed since alpha isnt written? */ - - frameBuffer.insert ("R", Slice (FLOAT, (char *)rect[0], xstride, ystride)); - frameBuffer.insert ("G", Slice (FLOAT, (char *)rect[1], xstride, ystride)); - frameBuffer.insert ("B", Slice (FLOAT, (char *)rect[2], xstride, ystride)); + int xstride = sizeof(float) * 4; + int ystride = xstride*width; + float *init_to = new float [4 * width*height * sizeof(float)]; + float *from, *to = init_to; + + frameBuffer.insert ("R", Slice (FLOAT, (char *)init_to, xstride, ystride)); + frameBuffer.insert ("G", Slice (FLOAT, (char *)(init_to + 1), xstride, ystride)); + frameBuffer.insert ("B", Slice (FLOAT, (char *)(init_to + 2), xstride, ystride)); if (ibuf->depth==32 && channels >= 4) - frameBuffer.insert ("A", Slice (FLOAT, (char *)rect[3], xstride, ystride)); + frameBuffer.insert ("A", Slice (FLOAT, (char *)(init_to + 3), xstride, ystride)); if (write_zbuf) frameBuffer.insert ("Z", Slice (FLOAT, (char *) (ibuf->zbuf_float + (height-1)*width), sizeof(float), sizeof(float) * -width)); + + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) { + for (int i = ibuf->y-1; i >= 0; i--) + { + from= ibuf->rect_float + channels*i*width; + + for (int j = ibuf->x; j > 0; j--) + { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = (channels >= 4)? from[3]: 1.0f; + to+= 4; from += 4; + } + } + } + else { + for (int i = ibuf->y-1; i >= 0; i--) + { + from= ibuf->rect_float + channels*i*width; + + for (int j = ibuf->x; j > 0; j--) + { + to[0] = srgb_to_linearrgb(from[0]); + to[1] = srgb_to_linearrgb(from[1]); + to[2] = srgb_to_linearrgb(from[2]); + to[3] = (channels >= 4)? from[3]: 1.0f; + to+= 4; from += 4; + } + } + } + file->setFrameBuffer (frameBuffer); file->writePixels (height); delete file; + delete [] init_to; } catch (const std::exception &exc) { |