33** Copyright Contributors to the OpenEXR Project.
44*/
55
6+ #include < fstream>
7+
68#include " internal_compress.h"
79#include " internal_decompress.h"
810
@@ -32,8 +34,8 @@ internal_exr_undo_ht (
3234{
3335 exr_result_t rv = EXR_ERR_SUCCESS;
3436
35- std::vector<int > cs_to_file_ch (decode->channel_count );
36- bool isRGB = make_channel_map (
37+ std::vector<CodestreamChannelInfo > cs_to_file_ch (decode->channel_count );
38+ bool isRGB = make_channel_map (
3739 decode->channel_count , decode->channels , cs_to_file_ch);
3840
3941 ojph::mem_infile infile;
@@ -44,41 +46,131 @@ internal_exr_undo_ht (
4446 cs.read_headers (&infile);
4547
4648 ojph::param_siz siz = cs.access_siz ();
47- ojph::ui32 width = siz.get_image_extent ().x - siz.get_image_offset ().x ;
48- ojph::ui32 height = siz.get_image_extent ().y - siz.get_image_offset ().y ;
49+ ojph::param_nlt nlt = cs.access_nlt ();
4950
50- assert (decode->chunk .width == width);
51- assert (decode->chunk .height == height);
52- assert (decode->channel_count == siz.get_num_components ());
51+ ojph::ui32 image_width =
52+ siz.get_image_extent ().x - siz.get_image_offset ().x ;
53+ ojph::ui32 image_height =
54+ siz.get_image_extent ().y - siz.get_image_offset ().y ;
5355
54- assert (decode->channel_count * 2 * width * height == uncompressed_size);
56+ int bpl = 0 ;
57+ bool is_planar = false ;
58+ for (ojph::ui32 c = 0 ; c < decode->channel_count ; c++)
59+ {
60+ bpl +=
61+ decode->channels [c].bytes_per_element * decode->channels [c].width ;
62+ if (decode->channels [c].x_samples > 1 ||
63+ decode->channels [c].y_samples > 1 )
64+ { is_planar = true ; }
65+ }
66+ cs.set_planar (is_planar);
5567
56- cs.set_planar (false );
68+ assert (decode->chunk .width == image_width);
69+ assert (decode->chunk .height == image_height);
70+ assert (decode->channel_count == siz.get_num_components ());
5771
5872 cs.create ();
5973
60- assert (sizeof (int16_t ) == 2 );
61- int16_t * line_pixels = static_cast <int16_t *> (uncompressed_data);
62-
63- for (uint32_t i = 0 ; i < height; ++i)
74+ assert (sizeof (uint16_t ) == 2 );
75+ assert (sizeof (uint32_t ) == 4 );
76+ ojph::ui32 next_comp = 0 ;
77+ ojph::line_buf* cur_line;
78+ if (cs.is_planar ())
6479 {
65-
6680 for (uint32_t c = 0 ; c < decode->channel_count ; c++)
6781 {
68- ojph::ui32 next_comp = 0 ;
69- ojph::line_buf* cur_line = cs.pull (next_comp);
82+ int file_c = cs_to_file_ch[c].file_index ;
83+ assert (
84+ siz.get_recon_height (c) == decode->channels [file_c].height );
85+ assert (decode->channels [file_c].width == siz.get_recon_width (c));
7086
71- assert (next_comp == c) ;
87+ if (decode-> channels [file_c]. height == 0 ) continue ;
7288
73- int16_t * channel_pixels = line_pixels + width * cs_to_file_ch[c] ;
89+ uint8_t * line_pixels = static_cast < uint8_t *> (uncompressed_data) ;
7490
75- for (uint32_t p = 0 ; p < width; p++)
91+ for (int64_t y = decode->chunk .start_y ;
92+ y < image_height + decode->chunk .start_y ;
93+ y++)
7694 {
77- *channel_pixels++ = (int16_t ) (cur_line->i32 [p]);
95+ for (ojph::ui32 line_c = 0 ; line_c < decode->channel_count ;
96+ line_c++)
97+ {
98+ if (y % decode->channels [line_c].y_samples != 0 ) continue ;
99+
100+ if (line_c == file_c)
101+ {
102+ cur_line = cs.pull (next_comp);
103+ assert (next_comp == c);
104+
105+ if (decode->channels [file_c].data_type ==
106+ EXR_PIXEL_HALF)
107+ {
108+ int16_t * channel_pixels = (int16_t *) line_pixels;
109+ for (uint32_t p = 0 ;
110+ p < decode->channels [file_c].width ;
111+ p++)
112+ {
113+ *channel_pixels++ = cur_line->i32 [p];
114+ // assert (*(channel_pixels - 1) == 0);
115+ }
116+ }
117+ else
118+ {
119+ int32_t * channel_pixels = (int32_t *) line_pixels;
120+ for (uint32_t p = 0 ;
121+ p < decode->channels [file_c].width ;
122+ p++)
123+ {
124+ *channel_pixels++ = cur_line->i32 [p];
125+ // assert (*(channel_pixels - 1) == 0);
126+ }
127+ }
128+ }
129+
130+ line_pixels += decode->channels [line_c].bytes_per_element *
131+ decode->channels [line_c].width ;
132+ }
78133 }
79134 }
135+ }
136+ else
137+ {
138+ uint8_t * line_pixels = static_cast <uint8_t *> (uncompressed_data);
80139
81- line_pixels += width * decode->channel_count ;
140+ assert (bpl * image_height == uncompressed_size);
141+
142+ for (uint32_t y = 0 ; y < image_height; ++y)
143+ {
144+ for (uint32_t c = 0 ; c < decode->channel_count ; c++)
145+ {
146+ int file_c = cs_to_file_ch[c].file_index ;
147+ cur_line = cs.pull (next_comp);
148+ assert (next_comp == c);
149+ if (decode->channels [file_c].data_type == EXR_PIXEL_HALF)
150+ {
151+ int16_t * channel_pixels =
152+ (int16_t *) (line_pixels + cs_to_file_ch[c].raster_line_offset );
153+ for (uint32_t p = 0 ; p < decode->channels [file_c].width ;
154+ p++)
155+ {
156+ *channel_pixels++ = cur_line->i32 [p];
157+ // assert (*(channel_pixels - 1) == 0);
158+ }
159+ }
160+ else
161+ {
162+ int32_t * channel_pixels =
163+ (int32_t *) (line_pixels + cs_to_file_ch[c].raster_line_offset );
164+ for (uint32_t p = 0 ; p < decode->channels [file_c].width ;
165+ p++)
166+ {
167+ *channel_pixels++ = cur_line->i32 [p];
168+ // assert (*(channel_pixels - 1) == 0);
169+ }
170+ }
171+ }
172+ line_pixels += bpl;
173+ }
82174 }
83175
84176 infile.close ();
@@ -91,71 +183,162 @@ internal_exr_apply_ht (exr_encode_pipeline_t* encode)
91183{
92184 exr_result_t rv = EXR_ERR_SUCCESS;
93185
94- std::vector<int > cs_to_file_ch (encode->channel_count );
95- bool isRGB = make_channel_map (
186+ std::vector<CodestreamChannelInfo > cs_to_file_ch (encode->channel_count );
187+ bool isRGB = make_channel_map (
96188 encode->channel_count , encode->channels , cs_to_file_ch);
97189
98- int height = encode->channels [ 0 ] .height ;
99- int width = encode->channels [ 0 ] .width ;
190+ int image_height = encode->chunk .height ;
191+ int image_width = encode->chunk .width ;
100192
101193 ojph::codestream cs;
102- cs.set_planar (false );
103194
104195 ojph::param_siz siz = cs.access_siz ();
196+ ojph::param_nlt nlt = cs.access_nlt ();
105197
198+ bool isPlanar = false ;
106199 siz.set_num_components (encode->channel_count );
200+ int bpl = 0 ;
107201 for (ojph::ui32 c = 0 ; c < encode->channel_count ; c++)
108- siz.set_component (c, ojph::point (1 , 1 ), 16 , true );
202+ {
203+ int file_c = cs_to_file_ch[c].file_index ;
204+ nlt.set_type3_transformation (
205+ c, encode->channels [file_c].data_type != EXR_PIXEL_UINT);
206+
207+ siz.set_component (
208+ c,
209+ ojph::point (
210+ encode->channels [file_c].x_samples ,
211+ encode->channels [file_c].y_samples ),
212+ encode->channels [file_c].data_type == EXR_PIXEL_HALF ? 16 : 32 ,
213+ encode->channels [file_c].data_type != EXR_PIXEL_UINT);
214+
215+ if (encode->channels [file_c].x_samples > 1 ||
216+ encode->channels [file_c].y_samples > 1 )
217+ { isPlanar = true ; }
218+
219+ // std::cout << " Component number, color, bitdepth: " << c << ", " << encode->channels[file_c].channel_name << ", " << siz.get_bit_depth(c) << std::endl;
220+
221+ bpl += encode->channels [file_c].bytes_per_element *
222+ encode->channels [file_c].width ;
223+ }
224+
225+ cs.set_planar (isPlanar);
109226
110227 siz.set_image_offset (ojph::point (0 , 0 ));
111- siz.set_tile_offset (ojph::point (0 , 0 ));
112- siz.set_image_extent (ojph::point (width, height));
113- siz.set_tile_size (ojph::size (width, height));
228+ siz.set_image_extent (ojph::point (image_width, image_height));
114229
115230 ojph::param_cod cod = cs.access_cod ();
116231
117- cod.set_color_transform (isRGB);
232+ cod.set_color_transform (isRGB && !isPlanar );
118233 cod.set_reversible (true );
119234 cod.set_block_dims (128 , 32 );
120235 cod.set_num_decomposition (5 );
121236
122- ojph::param_nlt nlt = cs.access_nlt ();
123- nlt.set_type3_transformation (65535 , true );
124-
125237 ojph::mem_outfile output;
126238
127239 output.open ();
128240
129241 cs.write_headers (&output);
130242
131- assert (
132- encode->packed_bytes == (encode->channel_count * 2 * height * width));
133-
134- const int16_t * line_pixels =
135- static_cast <const int16_t *> (encode->packed_buffer );
136243 ojph::ui32 next_comp = 0 ;
137244 ojph::line_buf* cur_line = cs.exchange (NULL , next_comp);
138245
139- for (ojph::ui32 i = 0 ; i < height; ++i )
246+ if (cs. is_planar () )
140247 {
141- const char * in_buf;
142-
143248 for (ojph::ui32 c = 0 ; c < encode->channel_count ; c++)
144249 {
145- assert (next_comp == c) ;
250+ if (encode-> channels [c]. height == 0 ) continue ;
146251
147- const int16_t * channel_pixels =
148- line_pixels + width * cs_to_file_ch[c];
252+ const uint8_t * line_pixels =
253+ static_cast <const uint8_t *> (encode->packed_buffer );
254+ int file_c = cs_to_file_ch[c].file_index ;
149255
150- for (uint32_t p = 0 ; p < width; p++)
256+ for (int64_t y = encode->chunk .start_y ;
257+ y < image_height + encode->chunk .start_y ;
258+ y++)
151259 {
152- cur_line->i32 [p] = static_cast <const ojph::si32> (*channel_pixels++);
260+ for (ojph::ui32 line_c = 0 ; line_c < encode->channel_count ;
261+ line_c++)
262+ {
263+
264+ if (y % encode->channels [line_c].y_samples != 0 ) continue ;
265+
266+ if (line_c == file_c)
267+ {
268+ if (encode->channels [file_c].data_type ==
269+ EXR_PIXEL_HALF)
270+ {
271+ int16_t * channel_pixels = (int16_t *) (line_pixels);
272+ for (uint32_t p = 0 ;
273+ p < encode->channels [file_c].width ;
274+ p++)
275+ {
276+ // assert (*channel_pixels == 0);
277+ cur_line->i32 [p] = *channel_pixels++;
278+ }
279+ }
280+ else
281+ {
282+ int32_t * channel_pixels = (int32_t *) (line_pixels);
283+ for (uint32_t p = 0 ;
284+ p < encode->channels [file_c].width ;
285+ p++)
286+ {
287+ // assert (*channel_pixels == 0);
288+ cur_line->i32 [p] = *channel_pixels++;
289+ }
290+ }
291+
292+ assert (next_comp == c);
293+ cur_line = cs.exchange (cur_line, next_comp);
294+ }
295+
296+ line_pixels += encode->channels [line_c].bytes_per_element *
297+ encode->channels [line_c].width ;
298+ }
153299 }
154-
155- cur_line = cs.exchange (cur_line, next_comp);
156300 }
301+ }
302+ else
303+ {
304+ const uint8_t * line_pixels =
305+ static_cast <const uint8_t *> (encode->packed_buffer );
157306
158- line_pixels += width * encode->channel_count ;
307+ assert (bpl * image_height == encode->packed_bytes );
308+
309+ for (int y = 0 ; y < image_height; y++)
310+ {
311+ for (ojph::ui32 c = 0 ; c < encode->channel_count ; c++)
312+ {
313+ int file_c = cs_to_file_ch[c].file_index ;
314+
315+ if (encode->channels [file_c].data_type == EXR_PIXEL_HALF)
316+ {
317+ int16_t * channel_pixels =
318+ (int16_t *) (line_pixels + cs_to_file_ch[c].raster_line_offset );
319+ for (uint32_t p = 0 ; p < encode->channels [file_c].width ;
320+ p++)
321+ {
322+ cur_line->i32 [p] = *channel_pixels++;
323+ // assert (cur_line->i32[p] == 0);
324+ }
325+ }
326+ else
327+ {
328+ int32_t * channel_pixels =
329+ (int32_t *) (line_pixels + cs_to_file_ch[c].raster_line_offset );
330+ for (uint32_t p = 0 ; p < encode->channels [file_c].width ;
331+ p++)
332+ {
333+ cur_line->i32 [p] = *channel_pixels++;
334+ // assert (cur_line->i32[p] == 0);
335+ }
336+ }
337+ assert (next_comp == c);
338+ cur_line = cs.exchange (cur_line, next_comp);
339+ }
340+ line_pixels += bpl;
341+ }
159342 }
160343
161344 cs.flush ();
@@ -164,12 +347,19 @@ internal_exr_apply_ht (exr_encode_pipeline_t* encode)
164347
165348 int compressed_sz = static_cast <size_t > (output.tell ());
166349
350+ // std::ofstream outf ("out7.j2c", std::ios::binary);
351+ // outf.write ((char*) output.get_data (), compressed_sz);
352+ // outf.close ();
353+
167354 if (compressed_sz < encode->packed_bytes )
168355 {
169356 memcpy (encode->compressed_buffer , output.get_data (), compressed_sz);
170357 encode->compressed_bytes = compressed_sz;
171358 }
172- else { encode->compressed_bytes = encode->packed_bytes ; }
359+ else
360+ {
361+ encode->compressed_bytes = encode->packed_bytes ;
362+ }
173363
174364 return rv;
175365}
0 commit comments