3
3
** Copyright Contributors to the OpenEXR Project.
4
4
*/
5
5
6
+ #include < fstream>
7
+
6
8
#include " internal_compress.h"
7
9
#include " internal_decompress.h"
8
10
@@ -32,8 +34,8 @@ internal_exr_undo_ht (
32
34
{
33
35
exr_result_t rv = EXR_ERR_SUCCESS;
34
36
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 (
37
39
decode->channel_count , decode->channels , cs_to_file_ch);
38
40
39
41
ojph::mem_infile infile;
@@ -44,41 +46,131 @@ internal_exr_undo_ht (
44
46
cs.read_headers (&infile);
45
47
46
48
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 ();
49
50
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 ;
53
55
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);
55
67
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 ());
57
71
58
72
cs.create ();
59
73
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 ())
64
79
{
65
-
66
80
for (uint32_t c = 0 ; c < decode->channel_count ; c++)
67
81
{
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));
70
86
71
- assert (next_comp == c) ;
87
+ if (decode-> channels [file_c]. height == 0 ) continue ;
72
88
73
- int16_t * channel_pixels = line_pixels + width * cs_to_file_ch[c] ;
89
+ uint8_t * line_pixels = static_cast < uint8_t *> (uncompressed_data) ;
74
90
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++)
76
94
{
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
+ }
78
133
}
79
134
}
135
+ }
136
+ else
137
+ {
138
+ uint8_t * line_pixels = static_cast <uint8_t *> (uncompressed_data);
80
139
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
+ }
82
174
}
83
175
84
176
infile.close ();
@@ -91,71 +183,162 @@ internal_exr_apply_ht (exr_encode_pipeline_t* encode)
91
183
{
92
184
exr_result_t rv = EXR_ERR_SUCCESS;
93
185
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 (
96
188
encode->channel_count , encode->channels , cs_to_file_ch);
97
189
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 ;
100
192
101
193
ojph::codestream cs;
102
- cs.set_planar (false );
103
194
104
195
ojph::param_siz siz = cs.access_siz ();
196
+ ojph::param_nlt nlt = cs.access_nlt ();
105
197
198
+ bool isPlanar = false ;
106
199
siz.set_num_components (encode->channel_count );
200
+ int bpl = 0 ;
107
201
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);
109
226
110
227
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));
114
229
115
230
ojph::param_cod cod = cs.access_cod ();
116
231
117
- cod.set_color_transform (isRGB);
232
+ cod.set_color_transform (isRGB && !isPlanar );
118
233
cod.set_reversible (true );
119
234
cod.set_block_dims (128 , 32 );
120
235
cod.set_num_decomposition (5 );
121
236
122
- ojph::param_nlt nlt = cs.access_nlt ();
123
- nlt.set_type3_transformation (65535 , true );
124
-
125
237
ojph::mem_outfile output;
126
238
127
239
output.open ();
128
240
129
241
cs.write_headers (&output);
130
242
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 );
136
243
ojph::ui32 next_comp = 0 ;
137
244
ojph::line_buf* cur_line = cs.exchange (NULL , next_comp);
138
245
139
- for (ojph::ui32 i = 0 ; i < height; ++i )
246
+ if (cs. is_planar () )
140
247
{
141
- const char * in_buf;
142
-
143
248
for (ojph::ui32 c = 0 ; c < encode->channel_count ; c++)
144
249
{
145
- assert (next_comp == c) ;
250
+ if (encode-> channels [c]. height == 0 ) continue ;
146
251
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 ;
149
255
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++)
151
259
{
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
+ }
153
299
}
154
-
155
- cur_line = cs.exchange (cur_line, next_comp);
156
300
}
301
+ }
302
+ else
303
+ {
304
+ const uint8_t * line_pixels =
305
+ static_cast <const uint8_t *> (encode->packed_buffer );
157
306
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
+ }
159
342
}
160
343
161
344
cs.flush ();
@@ -164,12 +347,19 @@ internal_exr_apply_ht (exr_encode_pipeline_t* encode)
164
347
165
348
int compressed_sz = static_cast <size_t > (output.tell ());
166
349
350
+ // std::ofstream outf ("out7.j2c", std::ios::binary);
351
+ // outf.write ((char*) output.get_data (), compressed_sz);
352
+ // outf.close ();
353
+
167
354
if (compressed_sz < encode->packed_bytes )
168
355
{
169
356
memcpy (encode->compressed_buffer , output.get_data (), compressed_sz);
170
357
encode->compressed_bytes = compressed_sz;
171
358
}
172
- else { encode->compressed_bytes = encode->packed_bytes ; }
359
+ else
360
+ {
361
+ encode->compressed_bytes = encode->packed_bytes ;
362
+ }
173
363
174
364
return rv;
175
365
}
0 commit comments