Skip to content

Commit 634028a

Browse files
committed
for EXR->J2C encoding, read only 1 scanline at a time instead of the whole image
1 parent 9e0b51c commit 634028a

File tree

2 files changed

+115
-57
lines changed

2 files changed

+115
-57
lines changed

src/apps/common/ojph_img_io.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,13 @@ namespace ojph {
524524
public:
525525
exr_in()
526526
{
527-
pixels.resizeErase(0, 0);
528-
529527
fname = NULL;
530528

531529
width = height = num_comps = 0;
530+
use_Rgba_interface = false;
531+
this->rgba_input_file = NULL;
532+
this->data_window.makeEmpty();
533+
pixels.resizeErase(0, 0);
532534

533535
cur_line = 0;
534536

@@ -541,7 +543,12 @@ namespace ojph {
541543
}
542544
virtual ~exr_in()
543545
{
544-
pixels.resizeErase(0, 0);
546+
if (true == this->use_Rgba_interface)
547+
{
548+
delete rgba_input_file;
549+
pixels.resizeErase(0, 0);
550+
}
551+
545552
close();
546553
}
547554

@@ -572,6 +579,11 @@ namespace ojph {
572579

573580
const char* fname;
574581
ui32 width, height;
582+
583+
bool use_Rgba_interface;
584+
Imf::RgbaInputFile *rgba_input_file;
585+
Imath::Box2i data_window;
586+
575587
ui32 num_comps;
576588
ui32 cur_line;
577589

src/apps/others/ojph_img_io.cpp

Lines changed: 100 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,6 +2115,8 @@ namespace ojph {
21152115
/////////////////////////////////////////////////////////////////////////////
21162116
void exr_in::open(const char* filename)
21172117
{
2118+
fname = filename;
2119+
21182120
// check if this is a valid OpenEXR file
21192121
bool is_tiled_openexr_file = false;
21202122
bool is_deep_openexr_file = false;
@@ -2176,29 +2178,32 @@ namespace ojph {
21762178
const char* name = i.name();
21772179
fprintf(stderr, "channel %d name = %s\n", channel_index, name);
21782180

2179-
if (channel_index >= MAXIMUM_NUMBER_OF_COMPONENTS_EXR_IN)
2180-
{
2181-
fprintf(stderr, "ERROR on line %d of file %s in function %s():\n channel_index = %d, this software currently supports %d channels\n",
2182-
__LINE__, __FILE__, __FUNCTION__, channel_index, MAXIMUM_NUMBER_OF_COMPONENTS_EXR_IN);
2183-
return;
2184-
}
2185-
21862181
switch (channel.type)
21872182
{
21882183
case Imf::PixelType::UINT:
21892184
fprintf(stderr, "channel %d type = UINT\n", channel_index);
2190-
this->bit_depth[channel_index] = 32;
2191-
this->is_signed[channel_index] = false;
2185+
if (channel_index < MAXIMUM_NUMBER_OF_COMPONENTS_EXR_IN)
2186+
{
2187+
this->bit_depth[channel_index] = 32;
2188+
this->is_signed[channel_index] = false;
2189+
}
2190+
21922191
break;
21932192
case Imf::PixelType::HALF:
21942193
fprintf(stderr, "channel %d type = HALF\n", channel_index);
2195-
this->bit_depth[channel_index] = 16;
2196-
this->is_signed[channel_index] = true;
2194+
if (channel_index < MAXIMUM_NUMBER_OF_COMPONENTS_EXR_IN)
2195+
{
2196+
this->bit_depth[channel_index] = 16;
2197+
this->is_signed[channel_index] = true;
2198+
}
21972199
break;
21982200
case Imf::PixelType::FLOAT:
21992201
fprintf(stderr, "channel %d type = FLOAT\n", channel_index);
2200-
this->bit_depth[channel_index] = 32;
2201-
this->is_signed[channel_index] = true;
2202+
if (channel_index < MAXIMUM_NUMBER_OF_COMPONENTS_EXR_IN)
2203+
{
2204+
this->bit_depth[channel_index] = 32;
2205+
this->is_signed[channel_index] = true;
2206+
}
22022207
break;
22032208
default:
22042209
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",
@@ -2209,7 +2214,10 @@ namespace ojph {
22092214

22102215
fprintf(stderr, "channel %d xSampling = %d\n", channel_index, channel.xSampling);
22112216
fprintf(stderr, "channel %d ySampling = %d\n", channel_index, channel.ySampling);
2212-
this->subsampling[channel_index] = point(channel.xSampling, channel.ySampling);
2217+
if (channel_index < MAXIMUM_NUMBER_OF_COMPONENTS_EXR_IN)
2218+
{
2219+
this->subsampling[channel_index] = point(channel.xSampling, channel.ySampling);
2220+
}
22132221
fprintf(stderr, "channel %d pLinear = %s\n", channel_index, channel.pLinear ? "true" : "false");
22142222

22152223
// increment channel index at the end of the loop
@@ -2218,6 +2226,13 @@ namespace ojph {
22182226

22192227
this->num_comps = channel_index;
22202228

2229+
if (channel_index > MAXIMUM_NUMBER_OF_COMPONENTS_EXR_IN)
2230+
{
2231+
fprintf(stderr, "ERROR on line %d of file %s in function %s():\n channel_index = %d, this software currently supports %d channels\n",
2232+
__LINE__, __FILE__, __FUNCTION__, channel_index, MAXIMUM_NUMBER_OF_COMPONENTS_EXR_IN);
2233+
return;
2234+
}
2235+
22212236
// check if this is a complete OpenEXR file
22222237
if (false == file.isComplete())
22232238
{
@@ -2234,16 +2249,29 @@ namespace ojph {
22342249
// if the channels are RGB or RGBA then use the simple RGBA interface to read the pixel data
22352250
if ((3 == this->num_comps && true == has_RGB && false == has_alpha && bit_depth[0] == 16 && bit_depth[1] == 16 && bit_depth[2] == 16) ||
22362251
(4 == this->num_comps && true == has_RGB && true == has_alpha && bit_depth[0] == 16 && bit_depth[1] == 16 && bit_depth[2] == 16 && bit_depth[3] == 16))
2252+
{
2253+
this->use_Rgba_interface = true;
2254+
}
2255+
else
2256+
{
2257+
this->use_Rgba_interface = false;
2258+
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",
2259+
__FILE__, __LINE__, __FUNCTION__, this->num_comps);
2260+
exit(-1);
2261+
}
2262+
2263+
if (true == this->use_Rgba_interface)
22372264
{
22382265
try {
2239-
Imf::RgbaInputFile rgba_input_file(filename);
2240-
Imath::Box2i dw = rgba_input_file.dataWindow();
2241-
int width = dw.max.x - dw.min.x + 1;
2242-
int height = dw.max.y - dw.min.y + 1;
2266+
rgba_input_file = new Imf::RgbaInputFile(filename);
2267+
data_window = rgba_input_file->dataWindow();
2268+
int width = data_window.max.x - data_window.min.x + 1;
2269+
int height = data_window.max.y - data_window.min.y + 1;
22432270

2244-
pixels.resizeErase(height, width);
2245-
rgba_input_file.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width);
2246-
rgba_input_file.readPixels(dw.min.y, dw.max.y);
2271+
// reserve memory for 1 scanline
2272+
pixels.resizeErase(1, width);
2273+
// reserve memory for the whole image
2274+
//pixels.resizeErase(height, width);
22472275

22482276
}
22492277
catch (const std::exception& e) {
@@ -2253,8 +2281,9 @@ namespace ojph {
22532281
}
22542282
else
22552283
{
2256-
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",
2257-
__FILE__, __LINE__, __FUNCTION__, this->num_comps);
2284+
fprintf(stderr, "ERROR in file %s on line %d in function %s:\n Unable to use RGBA interface this->use_Rgba_interface = %s\n",
2285+
__FILE__, __LINE__, __FUNCTION__, this->use_Rgba_interface ? "true" : "false" );
2286+
exit(-1);
22582287
}
22592288

22602289
}
@@ -2264,48 +2293,65 @@ namespace ojph {
22642293
assert(comp_num < num_comps);
22652294
assert((ui32)line->size >= width);
22662295

2267-
if (bit_depth[comp_num] != 16)
2296+
if (true == this->use_Rgba_interface)
22682297
{
2269-
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",
2270-
__FILE__, __LINE__, __FUNCTION__, comp_num, bit_depth[comp_num]);
2271-
return 0;
2272-
}
2273-
2274-
switch (comp_num)
2275-
{
2276-
case 0:
2277-
for (ui32 i = 0; i < width; i++)
2298+
// if this is the first component then read a new line
2299+
if (0 == comp_num)
22782300
{
2279-
line->i32[i] = (si16)pixels[cur_line][i].r.bits();
2280-
}
2281-
break;
2282-
case 1:
2283-
for (ui32 i = 0; i < width; i++)
2284-
{
2285-
line->i32[i] = (si16)pixels[cur_line][i].g.bits();
2301+
try {
2302+
rgba_input_file->setFrameBuffer(&pixels[0][0] - data_window.min.x - data_window.min.y * width, 1, width);
2303+
rgba_input_file->readPixels(data_window.min.y);
2304+
}
2305+
catch (const std::exception& e) {
2306+
std::cerr << "error reading image file " << e.what() << std::endl;
2307+
return 0;
2308+
}
22862309
}
2287-
break;
2288-
case 2:
2289-
for (ui32 i = 0; i < width; i++)
2310+
2311+
if (bit_depth[comp_num] != 16)
22902312
{
2291-
line->i32[i] = (si16)pixels[cur_line][i].b.bits();
2313+
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",
2314+
__FILE__, __LINE__, __FUNCTION__, comp_num, bit_depth[comp_num]);
2315+
return 0;
22922316
}
2293-
break;
2294-
case 3:
2295-
for (ui32 i = 0; i < width; i++)
2317+
2318+
switch (comp_num)
22962319
{
2297-
line->i32[i] = (si16)pixels[cur_line][i].a.bits();
2320+
case 0:
2321+
for (ui32 i = 0; i < width; i++)
2322+
{
2323+
line->i32[i] = (si16)pixels[0][i].r.bits();
2324+
}
2325+
break;
2326+
case 1:
2327+
for (ui32 i = 0; i < width; i++)
2328+
{
2329+
line->i32[i] = (si16)pixels[0][i].g.bits();
2330+
}
2331+
break;
2332+
case 2:
2333+
for (ui32 i = 0; i < width; i++)
2334+
{
2335+
line->i32[i] = (si16)pixels[0][i].b.bits();
2336+
}
2337+
break;
2338+
case 3:
2339+
for (ui32 i = 0; i < width; i++)
2340+
{
2341+
line->i32[i] = (si16)pixels[0][i].a.bits();
2342+
}
2343+
break;
2344+
default:
2345+
fprintf(stderr, "ERROR in file %s on line %d in function %s:\n comp_num = %d, this software currently only supports num_comps = 1-4\n",
2346+
__FILE__, __LINE__, __FUNCTION__, comp_num);
2347+
return 0;
2348+
break;
22982349
}
2299-
break;
2300-
default:
2301-
fprintf(stderr, "ERROR in file %s on line %d in function %s:\n comp_num = %d, this software currently only supports num_comps = 1-4\n",
2302-
__FILE__, __LINE__, __FUNCTION__, comp_num);
2303-
return 0;
2304-
break;
23052350
}
23062351

23072352
if (comp_num == (num_comps-1))
23082353
{
2354+
data_window.min.y += 1;
23092355
cur_line++;
23102356
}
23112357

0 commit comments

Comments
 (0)