From 7f8c2414d8fa0cc2ccfdcb236697f4bd806d81a6 Mon Sep 17 00:00:00 2001
From: wang_yue111 <648774160@qq.com>
Date: Tue, 6 Apr 2021 15:16:42 +0800
Subject: [PATCH] lighter weight reading of Luma-only images via RgbaInputFile
 (#827)

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz> 

Co-authored-by: Cary Phillips <cary@ilm.com>
---
 IlmImf/ImfRgbaFile.cpp | 89 ++++++++++++++++++++++++++++++------------
 IlmImfTest/testYca.cpp |  1 +
 2 files changed, 64 insertions(+), 26 deletions(-)

diff --git a/IlmImf/ImfRgbaFile.cpp b/IlmImf/ImfRgbaFile.cpp
index c2b604a..2ebfbed 100644
--- a/IlmImf/ImfRgbaFile.cpp
+++ b/IlmImf/ImfRgbaFile.cpp
@@ -1169,7 +1169,7 @@ RgbaInputFile::RgbaInputFile (const char name[], int numThreads):
 {
     RgbaChannels rgbaChannels = channels();
 
-    if (rgbaChannels & (WRITE_Y | WRITE_C))
+    if (rgbaChannels & WRITE_C)
 	_fromYca = new FromYca (*_inputFile, rgbaChannels);
 }
 
@@ -1181,7 +1181,7 @@ RgbaInputFile::RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int n
 {
     RgbaChannels rgbaChannels = channels();
 
-    if (rgbaChannels & (WRITE_Y | WRITE_C))
+    if (rgbaChannels & WRITE_C)
 	_fromYca = new FromYca (*_inputFile, rgbaChannels);
 }
 
@@ -1196,7 +1196,7 @@ RgbaInputFile::RgbaInputFile (const char name[],
 {
     RgbaChannels rgbaChannels = channels();
 
-    if (rgbaChannels & (WRITE_Y | WRITE_C))
+    if (rgbaChannels & WRITE_C)
 	_fromYca = new FromYca (*_inputFile, rgbaChannels);
 }
 
@@ -1211,7 +1211,7 @@ RgbaInputFile::RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
 {
     RgbaChannels rgbaChannels = channels();
 
-    if (rgbaChannels & (WRITE_Y | WRITE_C))
+    if (rgbaChannels & WRITE_C)
 	_fromYca = new FromYca (*_inputFile, rgbaChannels);
 }
 
@@ -1238,27 +1238,42 @@ RgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
 
 	FrameBuffer fb;
 
-	fb.insert (_channelNamePrefix + "R",
-		   Slice (HALF,
-			  (char *) &base[0].r,
-			  xs, ys,
-			  1, 1,		// xSampling, ySampling
-			  0.0));	// fillValue
-
-	fb.insert (_channelNamePrefix + "G",
-		   Slice (HALF,
-			  (char *) &base[0].g,
-			  xs, ys,
-			  1, 1,		// xSampling, ySampling
-			  0.0));	// fillValue
-
-	fb.insert (_channelNamePrefix + "B",
-		   Slice (HALF,
-			  (char *) &base[0].b,
-			  xs, ys,
-			  1, 1,		// xSampling, ySampling
-			  0.0));	// fillValue
-
+        if( channels() & WRITE_Y )
+        {
+            fb.insert (_channelNamePrefix + "Y",
+                    Slice (HALF,
+                            (char *) &base[0].r,
+                            xs, ys,
+                            1, 1,		// xSampling, ySampling
+                            0.0));	// fillValue
+        }
+        else
+        {
+
+
+            fb.insert (_channelNamePrefix + "R",
+                    Slice (HALF,
+                            (char *) &base[0].r,
+                            xs, ys,
+                            1, 1,		// xSampling, ySampling
+                            0.0));	// fillValue
+
+
+
+            fb.insert (_channelNamePrefix + "G",
+                    Slice (HALF,
+                            (char *) &base[0].g,
+                            xs, ys,
+                            1, 1,		// xSampling, ySampling
+                            0.0));	// fillValue
+
+            fb.insert (_channelNamePrefix + "B",
+                    Slice (HALF,
+                            (char *) &base[0].b,
+                            xs, ys,
+                            1, 1,		// xSampling, ySampling
+                            0.0));	// fillValue
+        }
 	fb.insert (_channelNamePrefix + "A",
 		   Slice (HALF,
 			  (char *) &base[0].a,
@@ -1281,7 +1296,7 @@ RgbaInputFile::setLayerName (const string &layerName)
 
     RgbaChannels rgbaChannels = channels();
 
-    if (rgbaChannels & (WRITE_Y | WRITE_C))
+    if (rgbaChannels & WRITE_C)
 	_fromYca = new FromYca (*_inputFile, rgbaChannels);
 
     FrameBuffer fb;
@@ -1300,6 +1315,28 @@ RgbaInputFile::readPixels (int scanLine1, int scanLine2)
     else
     {
 	_inputFile->readPixels (scanLine1, scanLine2);
+
+        if (channels() & WRITE_Y)
+        {
+            //
+            // Luma channel has been written into red channel
+            // Duplicate into green and blue channel to create gray image
+            //
+            const Slice* s = _inputFile->frameBuffer().findSlice(_channelNamePrefix + "Y");
+            Box2i dataWindow = _inputFile->header().dataWindow();
+
+            for( int scanLine = scanLine1  ; scanLine <= scanLine2 ; scanLine++ )
+            {
+                char* rowBase = s->base + scanLine*s->yStride;
+                for(int x = dataWindow.min.x ; x <= dataWindow.max.x ; ++x )
+                {
+                    Rgba* pixel = reinterpret_cast<Rgba*>(rowBase+x*s->xStride);
+                    pixel->g = pixel->r;
+                    pixel->b = pixel->r;
+                }
+
+            }
+        }
     }
 }
 
diff --git a/IlmImfTest/testYca.cpp b/IlmImfTest/testYca.cpp
index 0d3459e..3007552 100644
--- a/IlmImfTest/testYca.cpp
+++ b/IlmImfTest/testYca.cpp
@@ -187,6 +187,7 @@ writeReadYca (const char fileName[],
 	    else
 	    {
 		assert (p1.g == p2.g);
+		assert (p1.b == p2.b);
 	    }
 
 	    if (channels & WRITE_A)
-- 
2.23.0

