@@ -109,6 +109,14 @@ ImageSourceFileTinyExr::ImageSourceFileTinyExr( DataSourceRef dataSource, ImageS
109109 setSize ( mExrImage ->width , mExrImage ->height );
110110
111111 switch ( mExrImage ->num_channels ) {
112+ case 1 :
113+ setColorModel ( ImageIo::CM_GRAY );
114+ setChannelOrder ( ImageIo::ChannelOrder::Y );
115+ break ;
116+ case 2 :
117+ setColorModel ( ImageIo::CM_GRAY );
118+ setChannelOrder ( ImageIo::ChannelOrder::YA );
119+ break ;
112120 case 3 :
113121 setColorModel ( ImageIo::CM_RGB );
114122 setChannelOrder ( ImageIo::ChannelOrder::RGB );
@@ -128,6 +136,7 @@ void ImageSourceFileTinyExr::load( ImageTargetRef target )
128136
129137 const size_t numChannels = mExrHeader ->num_channels ;
130138 const void * red = nullptr , *green = nullptr , *blue = nullptr , *alpha = nullptr ;
139+ const void * gray = nullptr ;
131140
132141 for ( size_t c = 0 ; c < numChannels; ++c ) {
133142 if ( strcmp ( mExrHeader ->channels [c].name , " R" ) == 0 )
@@ -138,38 +147,68 @@ void ImageSourceFileTinyExr::load( ImageTargetRef target )
138147 blue = mExrImage ->images [c];
139148 else if ( strcmp ( mExrHeader ->channels [c].name , " A" ) == 0 )
140149 alpha = mExrImage ->images [c];
150+ else if ( strcmp ( mExrHeader ->channels [c].name , " Y" ) == 0 )
151+ gray = mExrImage ->images [c];
141152 }
142153
143- if ( ( !red ) || ( !green ) || ( !blue ) )
144- throw ImageIoExceptionFailedLoadTinyExr ( " Unable to locate channels for RGB" );
145-
146- // load one interleaved row at a time
147- if ( getDataType () == ImageIo::FLOAT32 ) {
148- vector<float > rowData ( mWidth * mExrImage ->num_channels , 0 );
149- for ( int32_t row = 0 ; row < mHeight ; row++ ) {
150- for ( int32_t col = 0 ; col < mWidth ; col++ ) {
151- rowData.at ( col * numChannels + 0 ) = static_cast <const float *>( red )[row * mWidth + col];
152- rowData.at ( col * numChannels + 1 ) = static_cast <const float *>( green )[row * mWidth + col];
153- rowData.at ( col * numChannels + 2 ) = static_cast <const float *>( blue )[row * mWidth + col];
154- if ( alpha )
155- rowData.at ( col * numChannels + 3 ) = static_cast <const float *>( alpha )[row * mWidth + col];
156- }
154+ if ( ( !gray ) && ( ( !red ) || ( !green ) || ( !blue ) ) )
155+ throw ImageIoExceptionFailedLoadTinyExr ( " Unable to locate channels for Y or RGB" );
157156
158- ( ( *this ).*rowFunc )( target, row, rowData.data () );
157+ if ( gray ) {
158+ if ( getDataType () == ImageIo::FLOAT32 ) {
159+ vector<float > rowData ( mWidth * mExrImage ->num_channels , 0 );
160+ for ( int32_t row = 0 ; row < mHeight ; row++ ) {
161+ for ( int32_t col = 0 ; col < mWidth ; col++ ) {
162+ rowData.at ( col * numChannels + 0 ) = static_cast <const float *>( gray )[row * mWidth + col];
163+ if ( alpha )
164+ rowData.at ( col * numChannels + 1 ) = static_cast <const float *>( alpha )[row * mWidth + col];
165+ }
166+
167+ ( ( *this ).*rowFunc )( target, row, rowData.data () );
168+ }
169+ }
170+ else { // float16
171+ vector<uint16_t > rowData ( mWidth * mExrImage ->num_channels , 0 );
172+ for ( int32_t row = 0 ; row < mHeight ; row++ ) {
173+ for ( int32_t col = 0 ; col < mWidth ; col++ ) {
174+ rowData.at ( col * numChannels + 0 ) = static_cast <const uint16_t *>( gray )[row * mWidth + col];
175+ if ( alpha )
176+ rowData.at ( col * numChannels + 1 ) = static_cast <const float *>( alpha )[row * mWidth + col];
177+ }
178+
179+ ( ( *this ).*rowFunc )( target, row, rowData.data () );
180+ }
159181 }
160182 }
161- else { // float16
162- vector<uint16_t > rowData ( mWidth * mExrImage ->num_channels , 0 );
163- for ( int32_t row = 0 ; row < mHeight ; row++ ) {
164- for ( int32_t col = 0 ; col < mWidth ; col++ ) {
165- rowData.at ( col * numChannels + 0 ) = static_cast <const uint16_t *>( red )[row * mWidth + col];
166- rowData.at ( col * numChannels + 1 ) = static_cast <const uint16_t *>( green )[row * mWidth + col];
167- rowData.at ( col * numChannels + 2 ) = static_cast <const uint16_t *>( blue )[row * mWidth + col];
168- if ( alpha )
169- rowData.at ( col * numChannels + 3 ) = static_cast <const uint16_t *>( alpha )[row * mWidth + col];
183+ else {
184+ // load one interleaved row at a time
185+ if ( getDataType () == ImageIo::FLOAT32 ) {
186+ vector<float > rowData ( mWidth * mExrImage ->num_channels , 0 );
187+ for ( int32_t row = 0 ; row < mHeight ; row++ ) {
188+ for ( int32_t col = 0 ; col < mWidth ; col++ ) {
189+ rowData.at ( col * numChannels + 0 ) = static_cast <const float *>( red )[row * mWidth + col];
190+ rowData.at ( col * numChannels + 1 ) = static_cast <const float *>( green )[row * mWidth + col];
191+ rowData.at ( col * numChannels + 2 ) = static_cast <const float *>( blue )[row * mWidth + col];
192+ if ( alpha )
193+ rowData.at ( col * numChannels + 3 ) = static_cast <const float *>( alpha )[row * mWidth + col];
194+ }
195+
196+ ( ( *this ).*rowFunc )( target, row, rowData.data () );
197+ }
198+ }
199+ else { // float16
200+ vector<uint16_t > rowData ( mWidth * mExrImage ->num_channels , 0 );
201+ for ( int32_t row = 0 ; row < mHeight ; row++ ) {
202+ for ( int32_t col = 0 ; col < mWidth ; col++ ) {
203+ rowData.at ( col * numChannels + 0 ) = static_cast <const uint16_t *>( red )[row * mWidth + col];
204+ rowData.at ( col * numChannels + 1 ) = static_cast <const uint16_t *>( green )[row * mWidth + col];
205+ rowData.at ( col * numChannels + 2 ) = static_cast <const uint16_t *>( blue )[row * mWidth + col];
206+ if ( alpha )
207+ rowData.at ( col * numChannels + 3 ) = static_cast <const uint16_t *>( alpha )[row * mWidth + col];
208+ }
209+
210+ ( ( *this ).*rowFunc )( target, row, rowData.data () );
170211 }
171-
172- ( ( *this ).*rowFunc )( target, row, rowData.data () );
173212 }
174213 }
175214}
0 commit comments