[Bf-blender-cvs] [615f4dc] master: Fix T40547: Can't read single channel EXRs

Sergey Sharybin noreply at git.blender.org
Mon Jun 9 12:43:15 CEST 2014


Commit: 615f4dc92f03d8d08289a0d980c9cdc64acedaec
Author: Sergey Sharybin
Date:   Mon Jun 9 16:41:28 2014 +0600
https://developer.blender.org/rB615f4dc92f03d8d08289a0d980c9cdc64acedaec

Fix T40547: Can't read single channel EXRs

The root of the issue goes to the fact that we only can
read RGB EXR files, but they could be YCbCr or just Luma.
Added support for this two cases.

Note: internally EXR would still be 3 channels, so no
big memory save would happen here, at least yet.

===================================================================

M	source/blender/imbuf/intern/openexr/openexr_api.cpp

===================================================================

diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 8d8bb93..2dca311 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -1124,6 +1124,27 @@ static const char *exr_rgba_channelname(InputFile *file, const char *chan)
 	return chan;
 }
 
+static bool exr_has_rgb(InputFile *file)
+{
+	return file->header().channels().findChannel("R") != NULL &&
+	       file->header().channels().findChannel("G") != NULL &&
+	       file->header().channels().findChannel("B") != NULL;
+}
+
+static bool exr_has_luma(InputFile *file)
+{
+	/* Y channel is the luma and should always present fir luma space images,
+	 * optionally it could be also channels for chromas called BY and RY.
+	 */
+	return file->header().channels().findChannel("Y") != NULL;
+}
+
+static bool exr_has_chroma(InputFile *file)
+{
+	return file->header().channels().findChannel("BY") != NULL &&
+	       file->header().channels().findChannel("RY") != NULL;
+}
+
 static int exr_has_zbuffer(InputFile *file)
 {
 	return !(file->header().channels().findChannel("Z") == NULL);
@@ -1219,6 +1240,8 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
 					}
 				}
 				else {
+					const bool has_rgb = exr_has_rgb(file);
+					const bool has_luma = exr_has_luma(file);
 					FrameBuffer frameBuffer;
 					float *first;
 					int xstride = sizeof(float) * 4;
@@ -1231,12 +1254,22 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
 					/* but, since we read y-flipped (negative y stride) we move to last scanline */
 					first += 4 * (height - 1) * width;
 
-					frameBuffer.insert(exr_rgba_channelname(file, "R"),
-					                   Slice(Imf::FLOAT,  (char *) first, xstride, ystride));
-					frameBuffer.insert(exr_rgba_channelname(file, "G"),
-					                   Slice(Imf::FLOAT,  (char *) (first + 1), xstride, ystride));
-					frameBuffer.insert(exr_rgba_channelname(file, "B"),
-					                   Slice(Imf::FLOAT,  (char *) (first + 2), xstride, ystride));
+					if (has_rgb) {
+						frameBuffer.insert(exr_rgba_channelname(file, "R"),
+						                   Slice(Imf::FLOAT,  (char *) first, xstride, ystride));
+						frameBuffer.insert(exr_rgba_channelname(file, "G"),
+						                   Slice(Imf::FLOAT,  (char *) (first + 1), xstride, ystride));
+						frameBuffer.insert(exr_rgba_channelname(file, "B"),
+						                   Slice(Imf::FLOAT,  (char *) (first + 2), xstride, ystride));
+					}
+					else if (has_luma) {
+						frameBuffer.insert(exr_rgba_channelname(file, "Y"),
+						                   Slice(Imf::FLOAT,  (char *) first, xstride, ystride));
+						frameBuffer.insert(exr_rgba_channelname(file, "BY"),
+						                   Slice(Imf::FLOAT,  (char *) (first + 1), xstride, ystride, 1, 1, 0.5f));
+						frameBuffer.insert(exr_rgba_channelname(file, "RY"),
+						                   Slice(Imf::FLOAT,  (char *) (first + 2), xstride, ystride, 1, 1, 0.5f));
+					}
 
 					/* 1.0 is fill value, this still needs to be assigned even when (is_alpha == 0) */
 					frameBuffer.insert(exr_rgba_channelname(file, "A"),
@@ -1264,6 +1297,24 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
 					// if (flag & IM_rect)
 					//     IMB_rect_from_float(ibuf);
 
+					if (!has_rgb && has_luma) {
+						size_t a;
+						if (exr_has_chroma(file)) {
+							for (a = 0; a < (size_t) ibuf->x * ibuf->y; ++a) {
+								float *color = ibuf->rect_float + a * 4;
+								ycc_to_rgb(color[0] * 255.0f, color[1] * 255.0f, color[2] * 255.0f,
+								           &color[0], &color[1], &color[2],
+								           BLI_YCC_ITU_BT709);
+							}
+						}
+						else {
+							for (a = 0; a < (size_t) ibuf->x * ibuf->y; ++a) {
+								float *color = ibuf->rect_float + a * 4;
+								color[1] = color[2] = color[0];
+							}
+						}
+					}
+
 					/* file is no longer needed */
 					delete file;
 				}




More information about the Bf-blender-cvs mailing list