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:
authorAntony Riakiotakis <kalast@gmail.com>2011-10-20 03:04:48 +0400
committerAntony Riakiotakis <kalast@gmail.com>2011-10-20 03:04:48 +0400
commit364fcde86d3cdcb09d075a0445fc2e1eb64170d5 (patch)
treeb8a36f336f1512e8a650ea71ff4bba63e7b5c7c8
parent0e66576f02afebdb4016249a9d7013ee5c1f0c36 (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.
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp56
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)
{