@@ -2051,18 +2051,54 @@ namespace ojph {
20512051// ///////////////////////////////////////////////////////////////////////////
20522052 void exr_in::open (const char * filename)
20532053 {
2054+ // check if this is a valid OpenEXR file
2055+ bool is_tiled_openexr_file = false ;
2056+ bool is_deep_openexr_file = false ;
2057+ bool is_mulitpart_openexr_file = false ;
2058+ bool is_valid_openexr_file = Imf::isOpenExrFile (filename,
2059+ is_tiled_openexr_file, is_deep_openexr_file, is_mulitpart_openexr_file);
2060+
2061+ if (false == is_valid_openexr_file)
2062+ {
2063+ fprintf (stderr, " ERROR on line %d of file %s in function %s():\n the input file %s is not a valid OpenEXR file\n " ,
2064+ __LINE__, __FILE__, __FUNCTION__, filename);
2065+ return ;
2066+ }
2067+
2068+ if (true == is_tiled_openexr_file || true == is_deep_openexr_file || true == is_mulitpart_openexr_file)
2069+ {
2070+ fprintf (stderr, " ERROR on line %d of file %s in function %s():\n the input file %s is a valid OpenEXR file but is not yet supported by this software.\n " ,
2071+ __LINE__, __FILE__, __FUNCTION__, filename);
2072+ if (true == is_tiled_openexr_file)
2073+ {
2074+ fprintf (stderr, " the input file %s is tiled.\n " , filename);
2075+ }
2076+ if (true == is_deep_openexr_file)
2077+ {
2078+ fprintf (stderr, " the input file %s is deep.\n " , filename);
2079+ }
2080+ if (true == is_mulitpart_openexr_file)
2081+ {
2082+ fprintf (stderr, " the input file %s is multi-part.\n " , filename);
2083+ }
2084+ return ;
2085+ }
2086+
2087+ bool has_RGB = false ;
2088+ bool has_alpha = false ;
2089+
2090+ // first open with most generic interface to see if the file can be supported by the easier RGBA interface
20542091 try {
20552092 Imf::InputFile file (filename);
20562093 Imath::Box2i dw = file.header ().dataWindow ();
20572094 int width = dw.max .x - dw.min .x + 1 ;
20582095 int height = dw.max .y - dw.min .y + 1 ;
20592096
2060- bool has_alpha = file.header ().channels ().findChannel (" A" );
2061-
2062- if (file.header ().channels ().begin ().channel ().type == Imf::HALF)
2063- this ->bit_depth [0 ] = 16 ;
2064- else
2065- this ->bit_depth [0 ] = 32 ;
2097+ has_alpha = file.header ().channels ().findChannel (" A" );
2098+ bool has_R = file.header ().channels ().findChannel (" R" );
2099+ bool has_G = file.header ().channels ().findChannel (" G" );
2100+ bool has_B = file.header ().channels ().findChannel (" B" );
2101+ has_RGB = has_R ? has_G ? has_B : false : false ;
20662102
20672103 this ->width = width;
20682104 this ->height = height;
@@ -2079,45 +2115,127 @@ namespace ojph {
20792115 {
20802116 case Imf::PixelType::UINT:
20812117 fprintf (stderr, " channel %d type = UINT\n " , channel_index);
2118+ this ->bit_depth [channel_index] = 32 ;
20822119 break ;
20832120 case Imf::PixelType::HALF:
20842121 fprintf (stderr, " channel %d type = HALF\n " , channel_index);
2122+ this ->bit_depth [channel_index] = 16 ;
20852123 break ;
20862124 case Imf::PixelType::FLOAT:
20872125 fprintf (stderr, " channel %d type = FLOAT\n " , channel_index);
2126+ this ->bit_depth [channel_index] = 32 ;
20882127 break ;
20892128 default :
20902129 fprintf (stderr, " ERROR on line %d of file %s in function %s():\n channel %d PixelType = %d, this should be UINT=0, HALF=1 or FLOAT=2\n " ,
20912130 __LINE__, __FILE__, __FUNCTION__, channel_index, channel.type );
2131+ return ;
20922132 break ;
20932133 }
20942134
20952135 fprintf (stderr, " channel %d xSampling = %d\n " , channel_index, channel.xSampling );
20962136 fprintf (stderr, " channel %d ySampling = %d\n " , channel_index, channel.ySampling );
2097-
20982137 fprintf (stderr, " channel %d pLinear = %s\n " , channel_index, channel.pLinear ? " true" : " false" );
20992138
21002139 channel_index++;
21012140 }
21022141
2103- this ->num_comps = 3 ; // descriptor field can indicate 1, 3, or 4 comps
2104-
2105- Imf::Array2D<Imf::Rgba> pixels (width, height);
2106-
2107- // file.setFrameBuffer(&pixels[0][0], 1, width);
2108- // file.readPixels(dw.min.y, dw.max.y);
2142+ this ->num_comps = channel_index;
21092143
2144+ // check if this is a complete OpenEXR file
2145+ if (false == file.isComplete ())
2146+ {
2147+ fprintf (stderr, " ERROR on line %d of file %s in function %s():\n the input file %s is not complete and therefore not yet supported by this software.\n " ,
2148+ __LINE__, __FILE__, __FUNCTION__, filename);
2149+ return ;
2150+ }
21102151 }
21112152 catch (const std::exception& e) {
21122153 std::cerr << " error reading image file " << filename << " : " << e.what () << std::endl;
21132154 return ;
21142155 }
2156+
2157+ // if the channels are RGB or RGBA then use the simple RGBA interface to read the pixel data
2158+ if ((3 == this ->num_comps && true == has_RGB && false == has_alpha && bit_depth[0 ] == 16 && bit_depth[1 ] == 16 && bit_depth[2 ] == 16 ) ||
2159+ (4 == this ->num_comps && true == has_RGB && true == has_alpha && bit_depth[0 ] == 16 && bit_depth[1 ] == 16 && bit_depth[2 ] == 16 ))
2160+ {
2161+ try {
2162+ // Imf::RgbaInputFile file(filename);
2163+ Imf::RgbaInputFile rgba_input_file (filename);
2164+ Imath::Box2i dw = rgba_input_file.dataWindow ();
2165+ int width = dw.max .x - dw.min .x + 1 ;
2166+ int height = dw.max .y - dw.min .y + 1 ;
2167+
2168+ pixels.resizeErase (height, width);
2169+ rgba_input_file.setFrameBuffer (&pixels[0 ][0 ] - dw.min .x - dw.min .y * width, 1 , width);
2170+ rgba_input_file.readPixels (dw.min .y , dw.max .y );
2171+
2172+ }
2173+ catch (const std::exception& e) {
2174+ std::cerr << " error reading image file " << filename << " : " << e.what () << std::endl;
2175+ return ;
2176+ }
2177+ }
2178+ else
2179+ {
2180+ fprintf (stderr, " ERROR in file %s on line %d in function %s:\n Unable to use RGBA interface because this->num_comps = %d and has_RGB = false\n " ,
2181+ __FILE__, __LINE__, __FUNCTION__, this ->num_comps );
2182+ }
2183+
21152184 }
21162185
21172186 ui32 exr_in::read (const line_buf* line, ui32 comp_num)
21182187 {
2188+ assert (comp_num < num_comps);
2189+ assert ((ui32)line->size >= width);
21192190
2120- return 0 ;
2191+ if (bit_depth[comp_num] != 16 )
2192+ {
2193+ fprintf (stderr, " ERROR in file %s on line %d in function %s:\n bit_depth[%d] = %d, this software currently only supports reading 16-bit files\n " ,
2194+ __FILE__, __LINE__, __FUNCTION__, comp_num, bit_depth[comp_num]);
2195+ return 0 ;
2196+ }
2197+
2198+ if (cur_line < height)
2199+ {
2200+ switch (comp_num)
2201+ {
2202+ case 0 :
2203+ for (ui32 i = 0 ; i < width; i++)
2204+ {
2205+ line->i32 [i] = (si32)(pixels[cur_line][i].r );
2206+ }
2207+ break ;
2208+ case 1 :
2209+ for (ui32 i = 0 ; i < width; i++)
2210+ {
2211+ line->i32 [i] = (si32)(pixels[cur_line][i].g );
2212+ }
2213+ break ;
2214+ case 2 :
2215+ for (ui32 i = 0 ; i < width; i++)
2216+ {
2217+ line->i32 [i] = (si32)(pixels[cur_line][i].b );
2218+ }
2219+ break ;
2220+ case 3 :
2221+ for (ui32 i = 0 ; i < width; i++)
2222+ {
2223+ line->i32 [i] = (si32)(pixels[cur_line][i].a );
2224+ }
2225+ break ;
2226+ }
2227+
2228+ }
2229+
2230+ if (comp_num == 0 )
2231+ {
2232+ cur_line++;
2233+ }
2234+
2235+
2236+
2237+
2238+ return width;
21212239 }
21222240#endif
21232241}
0 commit comments