OpenJPH: /build/openjph/src/OpenJPH/src/core/codestream/ojph_params.cpp Source File

OpenJPH Open-source implementation of JPEG2000 Part-15

Loading...
Searching...
No Matches
ojph_params.cpp
Go to the documentation of this file.
1//***************************************************************************/
2// This software is released under the 2-Clause BSD license, included
3// below.
4//
5// Copyright (c) 2019, Aous Naman
6// Copyright (c) 2019, Kakadu Software Pty Ltd, Australia
7// Copyright (c) 2019, The University of New South Wales, Australia
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// 1. Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15//
16// 2. Redistributions in binary form must reproduce the above copyright
17// notice, this list of conditions and the following disclaimer in the
18// documentation and/or other materials provided with the distribution.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31//***************************************************************************/
32// This file is part of the OpenJPH software implementation.
33// File: ojph_params.cpp
34// Author: Aous Naman
35// Date: 28 August 2019
36//***************************************************************************/
37
38#define _USE_MATH_DEFINES
39#include <cmath>
40
41#include "ojph_base.h"
42#include "ojph_file.h"
43#include "ojph_params.h"
44
45#include "ojph_params_local.h"
46#include "ojph_message.h"
47
48namespace ojph {
49
51 //
52 //
53 //
54 //
55 //
57
59 void param_siz::set_image_extent(point dims)
60 {
61 state->Xsiz = dims.x;
62 state->Ysiz = dims.y;
63 }
64
66 void param_siz::set_tile_size(size s)
67 {
68 state->XTsiz = s.w;
69 state->YTsiz = s.h;
70 }
71
73 void param_siz::set_image_offset(point offset)
74 { // WARNING need to check if these are valid
75 state->XOsiz = offset.x;
76 state->YOsiz = offset.y;
77 }
78
80 void param_siz::set_tile_offset(point offset)
81 { // WARNING need to check if these are valid
82 state->XTOsiz = offset.x;
83 state->YTOsiz = offset.y;
84 }
85
87 void param_siz::set_num_components(ui32 num_comps)
88 {
89 state->set_num_components(num_comps);
90 }
91
93 void param_siz::set_component(ui32 comp_num, const point& downsampling,
94 ui32 bit_depth, bool is_signed)
95 {
96 state->set_comp_info(comp_num, downsampling, bit_depth, is_signed);
97 }
98
100 point param_siz::get_image_extent() const
101 {
102 return point(state->Xsiz, state->Ysiz);
103 }
104
106 point param_siz::get_image_offset() const
107 {
108 return point(state->XOsiz, state->YOsiz);
109 }
110
112 size param_siz::get_tile_size() const
113 {
114 return size(state->XTsiz, state->YTsiz);
115 }
116
118 point param_siz::get_tile_offset() const
119 {
120 return point(state->XTOsiz, state->YTOsiz);
121 }
122
124 ui32 param_siz::get_num_components() const
125 {
126 return state->Csiz;
127 }
128
130 ui32 param_siz::get_bit_depth(ui32 comp_num) const
131 {
132 return state->get_bit_depth(comp_num);
133 }
134
136 bool param_siz::is_signed(ui32 comp_num) const
137 {
138 return state->is_signed(comp_num);
139 }
140
142 point param_siz::get_downsampling(ui32 comp_num) const
143 {
144 return state->get_downsampling(comp_num);
145 }
146
148 ui32 param_siz::get_recon_width(ui32 comp_num) const
149 {
150 return state->get_recon_width(comp_num);
151 }
152
154 ui32 param_siz::get_recon_height(ui32 comp_num) const
155 {
156 return state->get_recon_height(comp_num);
157 }
158
160 //
161 //
162 //
163 //
164 //
166
168 void param_cod::set_num_decomposition(ui32 num_decompositions)
169 {
170 if (num_decompositions > 32)
171 OJPH_ERROR(0x00050001,
172 "maximum number of decompositions cannot exceed 32");
173 state->SPcod.num_decomp = (ui8)num_decompositions;
174 }
175
177 void param_cod::set_block_dims(ui32 width, ui32 height)
178 {
179 ui32 log_width = 31 - count_leading_zeros(width);
180 ui32 log_height = 31 - count_leading_zeros(height);
181 if (width == 0 || width != (1u << log_width)
182 || height == 0 || height != (1u << log_height)
183 || log_width < 2 || log_height < 2
184 || log_width + log_height > 12)
185 OJPH_ERROR(0x00050011, "incorrect code block dimensions");
186 state->SPcod.block_width = (ui8)(log_width - 2);
187 state->SPcod.block_height = (ui8)(log_height - 2);
188 }
189
191 void param_cod::set_precinct_size(int num_levels, size* precinct_size)
192 {
193 if (num_levels == 0 || precinct_size == NULL)
194 state->Scod &= 0xFE;
195 else
196 {
197 state->Scod |= 1;
198 for (int i = 0; i <= state->SPcod.num_decomp; ++i)
199 {
200 size t = precinct_size[i < num_levels ? i : num_levels - 1];
201
202 ui32 PPx = 31 - count_leading_zeros(t.w);
203 ui32 PPy = 31 - count_leading_zeros(t.h);
204 if (t.w == 0 || t.h == 0)
205 OJPH_ERROR(0x00050021, "precinct width or height cannot be 0");
206 if (t.w != (1u<<PPx) || t.h != (1u<<PPy))
207 OJPH_ERROR(0x00050022,
208 "precinct width and height should be a power of 2");
209 if (PPx > 15 || PPy > 15)
210 OJPH_ERROR(0x00050023, "precinct size is too large");
211 if (i > 0 && (PPx == 0 || PPy == 0))
212 OJPH_ERROR(0x00050024, "precinct size is too small");
213 state->SPcod.precinct_size[i] = (ui8)(PPx | (PPy << 4));
214 }
215 }
216 }
217
219 void param_cod::set_progression_order(const char *name)
220 {
221 int prog_order = 0;
222 size_t len = strlen(name);
223 if (len == 4)
224 {
225 if (strncmp(name, OJPH_PO_STRING_LRCP, 4) == 0)
226 prog_order = OJPH_PO_LRCP;
227 else if (strncmp(name, OJPH_PO_STRING_RLCP, 4) == 0)
228 prog_order = OJPH_PO_RLCP;
229 else if (strncmp(name, OJPH_PO_STRING_RPCL, 4) == 0)
230 prog_order = OJPH_PO_RPCL;
231 else if (strncmp(name, OJPH_PO_STRING_PCRL, 4) == 0)
232 prog_order = OJPH_PO_PCRL;
233 else if (strncmp(name, OJPH_PO_STRING_CPRL, 4) == 0)
234 prog_order = OJPH_PO_CPRL;
235 else
236 OJPH_ERROR(0x00050031, "unknown progression order");
237 }
238 else
239 OJPH_ERROR(0x00050032, "improper progression order");
240
241
242 state->SGCod.prog_order = (ui8)prog_order;
243 }
244
246 void param_cod::set_color_transform(bool color_transform)
247 {
248 state->employ_color_transform(color_transform ? 1 : 0);
249 }
250
252 void param_cod::set_reversible(bool reversible)
253 {
254 state->set_reversible(reversible);
255 }
256
258 param_coc param_cod::get_coc(ui32 component_idx)
259 {
260 local::param_cod *p = state->get_coc(component_idx);
261 if (p == state) // no COC segment marker for this component
262 p = state->add_coc_object(component_idx);
263 return param_coc(p);
264 }
265
267 ui32 param_cod::get_num_decompositions() const
268 {
269 return state->get_num_decompositions();
270 }
271
273 size param_cod::get_block_dims() const
274 {
275 return state->get_block_dims();
276 }
277
279 size param_cod::get_log_block_dims() const
280 {
281 return state->get_log_block_dims();
282 }
283
285 bool param_cod::is_reversible() const
286 {
287 return state->is_reversible();
288 }
289
291 size param_cod::get_precinct_size(ui32 level_num) const
292 {
293 return state->get_precinct_size(level_num);
294 }
295
297 size param_cod::get_log_precinct_size(ui32 level_num) const
298 {
299 return state->get_log_precinct_size(level_num);
300 }
301
303 int param_cod::get_progression_order() const
304 {
305 return state->SGCod.prog_order;
306 }
307
309 const char* param_cod::get_progression_order_as_string() const
310 {
311 if (state->SGCod.prog_order == OJPH_PO_LRCP)
312 return OJPH_PO_STRING_LRCP;
313 else if (state->SGCod.prog_order == OJPH_PO_RLCP)
314 return OJPH_PO_STRING_RLCP;
315 else if (state->SGCod.prog_order == OJPH_PO_RPCL)
316 return OJPH_PO_STRING_RPCL;
317 else if (state->SGCod.prog_order == OJPH_PO_PCRL)
318 return OJPH_PO_STRING_PCRL;
319 else if (state->SGCod.prog_order == OJPH_PO_CPRL)
320 return OJPH_PO_STRING_CPRL;
321 else
322 assert(0);
323 return "";
324 }
325
327 int param_cod::get_num_layers() const
328 {
329 return state->SGCod.num_layers;
330 }
331
333 bool param_cod::is_using_color_transform() const
334 {
335 return state->is_employing_color_transform();
336 }
337
339 bool param_cod::packets_may_use_sop() const
340 {
341 return state->packets_may_use_sop();
342 }
343
345 bool param_cod::packets_use_eph() const
346 {
347 return state->packets_use_eph();
348 }
349
351 bool param_cod::get_block_vertical_causality() const
352 {
353 return state->get_block_vertical_causality();
354 }
355
357 //
358 //
359 //
360 //
361 //
363
365 void param_coc::set_num_decomposition(ui32 num_decompositions)
366 { ojph::param_cod(state).set_num_decomposition(num_decompositions); }
367
369 void param_coc::set_block_dims(ui32 width, ui32 height)
370 { ojph::param_cod(state).set_block_dims(width, height); }
371
373 void param_coc::set_precinct_size(int num_levels, size* precinct_size)
374 { ojph::param_cod(state).set_precinct_size(num_levels, precinct_size); }
375
377 void param_coc::set_reversible(bool reversible)
378 { ojph::param_cod(state).set_reversible(reversible); }
379
381 ui32 param_coc::get_num_decompositions() const
382 { return ojph::param_cod(state).get_num_decompositions(); }
383
385 size param_coc::get_block_dims() const
386 { return ojph::param_cod(state).get_block_dims(); }
387
389 size param_coc::get_log_block_dims() const
390 { return ojph::param_cod(state).get_log_block_dims(); }
391
393 bool param_coc::is_reversible() const
394 { return ojph::param_cod(state).is_reversible(); }
395
397 size param_coc::get_precinct_size(ui32 level_num) const
398 { return ojph::param_cod(state).get_precinct_size(level_num); }
399
401 size param_coc::get_log_precinct_size(ui32 level_num) const
402 { return ojph::param_cod(state).get_log_precinct_size(level_num); }
403
405 bool param_coc::get_block_vertical_causality() const
406 { return ojph::param_cod(state).get_block_vertical_causality(); }
407
408
410 //
411 //
412 //
413 //
414 //
416
418 void param_qcd::set_irrev_quant(float delta)
419 {
420 state->set_delta(delta);
421 }
422
424 void param_qcd::set_irrev_quant(ui32 comp_idx, float delta)
425 {
426 state->set_delta(comp_idx, delta);
427 }
428
430 //
431 //
432 //
433 //
434 //
436
438 void param_nlt::set_nonlinear_transform(ui32 comp_num, ui8 nl_type)
439 {
440 state->set_nonlinear_transform(comp_num, nl_type);
441 }
442
444 bool param_nlt::get_nonlinear_transform(ui32 comp_num, ui8& bit_depth,
445 bool& is_signed, ui8& nl_type) const
446 {
447 return state->get_nonlinear_transform(comp_num, bit_depth, is_signed,
448 nl_type);
449 }
450
452 //
453 //
454 //
455 //
456 //
458
460 void comment_exchange::set_string(const char* str)
461 {
462 size_t t = strlen(str);
463 if (len > 65531)
464 OJPH_ERROR(0x000500C1,
465 "COM marker string length cannot be larger than 65531");
466 this->data = str;
467 this->len = (ui16)t;
468 this->Rcom = 1;
469 }
470
472 void comment_exchange::set_data(const char* data, ui16 len)
473 {
474 if (len > 65531)
475 OJPH_ERROR(0x000500C2,
476 "COM marker string length cannot be larger than 65531");
477 this->data = data;
478 this->len = len;
479 this->Rcom = 0;
480 }
481
483 //
484 //
485 // LOCAL
486 //
487 //
489
490 namespace local {
491
493 static inline
494 ui16 swap_byte(ui16 t)
495 {
496 return (ui16)((t << 8) | (t >> 8));
497 }
498
500 static inline
501 ui32 swap_byte(ui32 t)
502 {
503 ui32 u = swap_byte((ui16)(t & 0xFFFFu));
504 u <<= 16;
505 u |= swap_byte((ui16)(t >> 16));
506 return u;
507 }
508
510 static inline
511 ui64 swap_byte(ui64 t)
512 {
513 ui64 u = swap_byte((ui32)(t & 0xFFFFFFFFu));
514 u <<= 32;
515 u |= swap_byte((ui32)(t >> 32));
516 return u;
517 }
518
520 //
521 //
522 //
523 //
524 //
526
528 //static
529 class sqrt_energy_gains
530 {
531 public:
532 static float get_gain_l(ui32 num_decomp, bool reversible)
533 { return reversible ? gain_5x3_l[num_decomp] : gain_9x7_l[num_decomp]; }
534 static float get_gain_h(ui32 num_decomp, bool reversible)
535 { return reversible ? gain_5x3_h[num_decomp] : gain_9x7_h[num_decomp]; }
536
537 private:
538 static const float gain_9x7_l[34];
539 static const float gain_9x7_h[34];
540 static const float gain_5x3_l[34];
541 static const float gain_5x3_h[34];
542 };
543
545 const float sqrt_energy_gains::gain_9x7_l[34] = { 1.0000e+00f,
546 1.4021e+00f, 2.0304e+00f, 2.9012e+00f, 4.1153e+00f, 5.8245e+00f,
547 8.2388e+00f, 1.1652e+01f, 1.6479e+01f, 2.3304e+01f, 3.2957e+01f,
548 4.6609e+01f, 6.5915e+01f, 9.3217e+01f, 1.3183e+02f, 1.8643e+02f,
549 2.6366e+02f, 3.7287e+02f, 5.2732e+02f, 7.4574e+02f, 1.0546e+03f,
550 1.4915e+03f, 2.1093e+03f, 2.9830e+03f, 4.2185e+03f, 5.9659e+03f,
551 8.4371e+03f, 1.1932e+04f, 1.6874e+04f, 2.3864e+04f, 3.3748e+04f,
552 4.7727e+04f, 6.7496e+04f, 9.5454e+04f };
553 const float sqrt_energy_gains::gain_9x7_h[34] = { 1.4425e+00f,
554 1.9669e+00f, 2.8839e+00f, 4.1475e+00f, 5.8946e+00f, 8.3472e+00f,
555 1.1809e+01f, 1.6701e+01f, 2.3620e+01f, 3.3403e+01f, 4.7240e+01f,
556 6.6807e+01f, 9.4479e+01f, 1.3361e+02f, 1.8896e+02f, 2.6723e+02f,
557 3.7792e+02f, 5.3446e+02f, 7.5583e+02f, 1.0689e+03f, 1.5117e+03f,
558 2.1378e+03f, 3.0233e+03f, 4.2756e+03f, 6.0467e+03f, 8.5513e+03f,
559 1.2093e+04f, 1.7103e+04f, 2.4187e+04f, 3.4205e+04f, 4.8373e+04f,
560 6.8410e+04f, 9.6747e+04f, 1.3682e+05f };
561 const float sqrt_energy_gains::gain_5x3_l[34] = { 1.0000e+00f,
562 1.2247e+00f, 1.3229e+00f, 1.5411e+00f, 1.7139e+00f, 1.9605e+00f,
563 2.2044e+00f, 2.5047e+00f, 2.8277e+00f, 3.2049e+00f, 3.6238e+00f,
564 4.1033e+00f, 4.6423e+00f, 5.2548e+00f, 5.9462e+00f, 6.7299e+00f,
565 7.6159e+00f, 8.6193e+00f, 9.7544e+00f, 1.1039e+01f, 1.2493e+01f,
566 1.4139e+01f, 1.6001e+01f, 1.8108e+01f, 2.0493e+01f, 2.3192e+01f,
567 2.6246e+01f, 2.9702e+01f, 3.3614e+01f, 3.8041e+01f, 4.3051e+01f,
568 4.8721e+01f, 5.5138e+01f, 6.2399e+01f };
569 const float sqrt_energy_gains::gain_5x3_h[34] = { 1.0458e+00f,
570 1.3975e+00f, 1.4389e+00f, 1.7287e+00f, 1.8880e+00f, 2.1841e+00f,
571 2.4392e+00f, 2.7830e+00f, 3.1341e+00f, 3.5576e+00f, 4.0188e+00f,
572 4.5532e+00f, 5.1494e+00f, 5.8301e+00f, 6.5963e+00f, 7.4663e+00f,
573 8.4489e+00f, 9.5623e+00f, 1.0821e+01f, 1.2247e+01f, 1.3860e+01f,
574 1.5685e+01f, 1.7751e+01f, 2.0089e+01f, 2.2735e+01f, 2.5729e+01f,
575 2.9117e+01f, 3.2952e+01f, 3.7292e+01f, 4.2203e+01f, 4.7761e+01f,
576 5.4051e+01f, 6.1170e+01f, 6.9226e+01f };
577
579 //static
580 class bibo_gains
581 {
582 public:
583 static float get_bibo_gain_l(ui32 num_decomp, bool reversible)
584 { return reversible ? gain_5x3_l[num_decomp] : gain_9x7_l[num_decomp]; }
585 static float get_bibo_gain_h(ui32 num_decomp, bool reversible)
586 { return reversible ? gain_5x3_h[num_decomp] : gain_9x7_h[num_decomp]; }
587
588 private:
589 static const float gain_9x7_l[34];
590 static const float gain_9x7_h[34];
591 static const float gain_5x3_l[34];
592 static const float gain_5x3_h[34];
593 };
594
596 const float bibo_gains::gain_9x7_l[34] = { 1.0000e+00f, 1.3803e+00f,
597 1.3328e+00f, 1.3067e+00f, 1.3028e+00f, 1.3001e+00f, 1.2993e+00f,
598 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
599 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
600 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
601 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
602 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
603 1.2992e+00f, 1.2992e+00f };
604 const float bibo_gains::gain_9x7_h[34] = { 1.2976e+00f, 1.3126e+00f,
605 1.2757e+00f, 1.2352e+00f, 1.2312e+00f, 1.2285e+00f, 1.2280e+00f,
606 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
607 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
608 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
609 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
610 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
611 1.2278e+00f, 1.2278e+00f };
612 const float bibo_gains::gain_5x3_l[34] = { 1.0000e+00f, 1.5000e+00f,
613 1.6250e+00f, 1.6875e+00f, 1.6963e+00f, 1.7067e+00f, 1.7116e+00f,
614 1.7129e+00f, 1.7141e+00f, 1.7145e+00f, 1.7151e+00f, 1.7152e+00f,
615 1.7155e+00f, 1.7155e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
616 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
617 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
618 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
619 1.7156e+00f, 1.7156e+00f };
620 const float bibo_gains::gain_5x3_h[34] = { 2.0000e+00f, 2.5000e+00f,
621 2.7500e+00f, 2.8047e+00f, 2.8198e+00f, 2.8410e+00f, 2.8558e+00f,
622 2.8601e+00f, 2.8628e+00f, 2.8656e+00f, 2.8662e+00f, 2.8667e+00f,
623 2.8669e+00f, 2.8670e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
624 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
625 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
626 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
627 2.8671e+00f, 2.8671e+00f };
628
629
631 //
632 //
633 //
634 //
635 //
637
639 bool param_siz::write(outfile_base *file)
640 {
641 //marker size excluding header
642 Lsiz = (ui16)(38 + 3 * Csiz);
643
644 ui8 buf[4];
645 bool result = true;
646
647 *(ui16*)buf = JP2K_MARKER::SIZ;
648 *(ui16*)buf = swap_byte(*(ui16*)buf);
649 result &= file->write(&buf, 2) == 2;
650 *(ui16*)buf = swap_byte(Lsiz);
651 result &= file->write(&buf, 2) == 2;
652 *(ui16*)buf = swap_byte(Rsiz);
653 result &= file->write(&buf, 2) == 2;
654 *(ui32*)buf = swap_byte(Xsiz);
655 result &= file->write(&buf, 4) == 4;
656 *(ui32*)buf = swap_byte(Ysiz);
657 result &= file->write(&buf, 4) == 4;
658 *(ui32*)buf = swap_byte(XOsiz);
659 result &= file->write(&buf, 4) == 4;
660 *(ui32*)buf = swap_byte(YOsiz);
661 result &= file->write(&buf, 4) == 4;
662 *(ui32*)buf = swap_byte(XTsiz);
663 result &= file->write(&buf, 4) == 4;
664 *(ui32*)buf = swap_byte(YTsiz);
665 result &= file->write(&buf, 4) == 4;
666 *(ui32*)buf = swap_byte(XTOsiz);
667 result &= file->write(&buf, 4) == 4;
668 *(ui32*)buf = swap_byte(YTOsiz);
669 result &= file->write(&buf, 4) == 4;
670 *(ui16*)buf = swap_byte(Csiz);
671 result &= file->write(&buf, 2) == 2;
672 for (int c = 0; c < Csiz; ++c)
673 {
674 buf[0] = cptr[c].SSiz;
675 buf[1] = cptr[c].XRsiz;
676 buf[2] = cptr[c].YRsiz;
677 result &= file->write(&buf, 3) == 3;
678 }
679
680 return result;
681 }
682
684 void param_siz::read(infile_base *file)
685 {
686 if (file->read(&Lsiz, 2) != 2)
687 OJPH_ERROR(0x00050041, "error reading SIZ marker");
688 Lsiz = swap_byte(Lsiz);
689 int num_comps = (Lsiz - 38) / 3;
690 if (Lsiz != 38 + 3 * num_comps)
691 OJPH_ERROR(0x00050042, "error in SIZ marker length");
692 if (file->read(&Rsiz, 2) != 2)
693 OJPH_ERROR(0x00050043, "error reading SIZ marker");
694 Rsiz = swap_byte(Rsiz);
695 if ((Rsiz & 0x4000) == 0)
696 OJPH_ERROR(0x00050044,
697 "Rsiz bit 14 is not set (this is not a JPH file)");
698 if ((Rsiz & 0x8000) != 0 && (Rsiz & 0xD5F) != 0)
699 OJPH_WARN(0x00050001, "Rsiz in SIZ has unimplemented fields");
700 if (file->read(&Xsiz, 4) != 4)
701 OJPH_ERROR(0x00050045, "error reading SIZ marker");
702 Xsiz = swap_byte(Xsiz);
703 if (file->read(&Ysiz, 4) != 4)
704 OJPH_ERROR(0x00050046, "error reading SIZ marker");
705 Ysiz = swap_byte(Ysiz);
706 if (file->read(&XOsiz, 4) != 4)
707 OJPH_ERROR(0x00050047, "error reading SIZ marker");
708 XOsiz = swap_byte(XOsiz);
709 if (file->read(&YOsiz, 4) != 4)
710 OJPH_ERROR(0x00050048, "error reading SIZ marker");
711 YOsiz = swap_byte(YOsiz);
712 if (file->read(&XTsiz, 4) != 4)
713 OJPH_ERROR(0x00050049, "error reading SIZ marker");
714 XTsiz = swap_byte(XTsiz);
715 if (file->read(&YTsiz, 4) != 4)
716 OJPH_ERROR(0x0005004A, "error reading SIZ marker");
717 YTsiz = swap_byte(YTsiz);
718 if (file->read(&XTOsiz, 4) != 4)
719 OJPH_ERROR(0x0005004B, "error reading SIZ marker");
720 XTOsiz = swap_byte(XTOsiz);
721 if (file->read(&YTOsiz, 4) != 4)
722 OJPH_ERROR(0x0005004C, "error reading SIZ marker");
723 YTOsiz = swap_byte(YTOsiz);
724 if (file->read(&Csiz, 2) != 2)
725 OJPH_ERROR(0x0005004D, "error reading SIZ marker");
726 Csiz = swap_byte(Csiz);
727 if (Csiz != num_comps)
728 OJPH_ERROR(0x0005004E, "Csiz does not match the SIZ marker size");
729 set_num_components(Csiz);
730 for (int c = 0; c < Csiz; ++c)
731 {
732 if (file->read(&cptr[c].SSiz, 1) != 1)
733 OJPH_ERROR(0x00050051, "error reading SIZ marker");
734 if (file->read(&cptr[c].XRsiz, 1) != 1)
735 OJPH_ERROR(0x00050052, "error reading SIZ marker");
736 if (file->read(&cptr[c].YRsiz, 1) != 1)
737 OJPH_ERROR(0x00050053, "error reading SIZ marker");
738 if ((cptr[c].SSiz & 0x7F) > 37)
739 OJPH_ERROR(0x00050054, "Wrong SIZ-SSiz value of %d", cptr[c].SSiz);
740 if (cptr[c].XRsiz == 0)
741 OJPH_ERROR(0x00050055, "Wrong SIZ-XRsiz value of %d", cptr[c].XRsiz);
742 if (cptr[c].YRsiz == 0)
743 OJPH_ERROR(0x00050056, "Wrong SIZ-YRsiz value of %d", cptr[c].YRsiz);
744 }
745
746 ws_kern_support_needed = (Rsiz & 0x20) != 0;
747 dfs_support_needed = (Rsiz & 0x80) != 0;
748 }
749
751 point param_siz::get_recon_downsampling(ui32 comp_num) const
752 {
753 assert(comp_num < get_num_components());
754
755 point factor(1u << skipped_resolutions, 1u << skipped_resolutions);
756 const param_cod* cdp = cod->get_coc(comp_num);
757 if (dfs && cdp && cdp->is_dfs_defined()) {
758 const param_dfs* d = dfs->get_dfs(cdp->get_dfs_index());
759 factor = d->get_res_downsamp(skipped_resolutions);
760 }
761 factor.x *= (ui32)cptr[comp_num].XRsiz;
762 factor.y *= (ui32)cptr[comp_num].YRsiz;
763 return factor;
764 }
765
767 point param_siz::get_recon_size(ui32 comp_num) const
768 {
769 assert(comp_num < get_num_components());
770
771 point factor = get_recon_downsampling(comp_num);
772 point r;
773 r.x = ojph_div_ceil(Xsiz, factor.x) - ojph_div_ceil(XOsiz, factor.x);
774 r.y = ojph_div_ceil(Ysiz, factor.y) - ojph_div_ceil(YOsiz, factor.y);
775 return r;
776 }
777
778
780 //
781 //
782 //
783 //
784 //
786
788 bool param_cap::write(outfile_base *file)
789 {
790 //marker size excluding header
791 Lcap = 8;
792
793 char buf[4];
794 bool result = true;
795
796 *(ui16*)buf = JP2K_MARKER::CAP;
797 *(ui16*)buf = swap_byte(*(ui16*)buf);
798 result &= file->write(&buf, 2) == 2;
799 *(ui16*)buf = swap_byte(Lcap);
800 result &= file->write(&buf, 2) == 2;
801 *(ui32*)buf = swap_byte(Pcap);
802 result &= file->write(&buf, 4) == 4;
803
804 *(ui16*)buf = swap_byte(Ccap[0]);
805 result &= file->write(&buf, 2) == 2;
806
807 return result;
808 }
809
811 void param_cap::read(infile_base *file)
812 {
813 if (file->read(&Lcap, 2) != 2)
814 OJPH_ERROR(0x00050061, "error reading CAP marker");
815 Lcap = swap_byte(Lcap);
816 if (file->read(&Pcap, 4) != 4)
817 OJPH_ERROR(0x00050062, "error reading CAP marker");
818 Pcap = swap_byte(Pcap);
819 ui32 count = population_count(Pcap);
820 if (Pcap & 0xFFFDFFFF)
821 OJPH_ERROR(0x00050063,
822 "error Pcap in CAP has options that are not supported");
823 if ((Pcap & 0x00020000) == 0)
824 OJPH_ERROR(0x00050064,
825 "error Pcap should have its 15th MSB set, Pcap^15. "
826 " This is not a JPH file");
827 for (ui32 i = 0; i < count; ++i)
828 if (file->read(Ccap+i, 2) != 2)
829 OJPH_ERROR(0x00050065, "error reading CAP marker");
830 if (Lcap != 6 + 2 * count)
831 OJPH_ERROR(0x00050066, "error in CAP marker length");
832 }
833
835 //
836 //
837 //
838 //
839 //
841
843 bool param_cod::is_reversible() const
844 {
845 if (SPcod.wavelet_trans <= 1)
846 return get_wavelet_kern() == local::param_cod::DWT_REV53;
847 else {
848 assert(atk != NULL);
849 return atk->is_reversible();
850 }
851 }
852
854 bool param_cod::write(outfile_base *file)
855 {
856 assert(type == COD_MAIN);
857
858 //marker size excluding header
859 Lcod = 12;
860 Lcod = (ui16)(Lcod + (Scod & 1 ? 1 + SPcod.num_decomp : 0));
861
862 ui8 buf[4];
863 bool result = true;
864
865 *(ui16*)buf = JP2K_MARKER::COD;
866 *(ui16*)buf = swap_byte(*(ui16*)buf);
867 result &= file->write(&buf, 2) == 2;
868 *(ui16*)buf = swap_byte(Lcod);
869 result &= file->write(&buf, 2) == 2;
870 *(ui8*)buf = Scod;
871 result &= file->write(&buf, 1) == 1;
872 *(ui8*)buf = SGCod.prog_order;
873 result &= file->write(&buf, 1) == 1;
874 *(ui16*)buf = swap_byte(SGCod.num_layers);
875 result &= file->write(&buf, 2) == 2;
876 *(ui8*)buf = SGCod.mc_trans;
877 result &= file->write(&buf, 1) == 1;
878 buf[0] = SPcod.num_decomp;
879 buf[1] = SPcod.block_width;
880 buf[2] = SPcod.block_height;
881 buf[3] = SPcod.block_style;
882 result &= file->write(&buf, 4) == 4;
883 *(ui8*)buf = SPcod.wavelet_trans;
884 result &= file->write(&buf, 1) == 1;
885 if (Scod & 1)
886 for (int i = 0; i <= SPcod.num_decomp; ++i)
887 {
888 *(ui8*)buf = SPcod.precinct_size[i];
889 result &= file->write(&buf, 1) == 1;
890 }
891
892 return result;
893 }
894
896 bool param_cod::write_coc(outfile_base *file, ui32 num_comps)
897 {
898 assert(type == COD_MAIN);
899 bool result = true;
900 param_cod *p = this->next;
901 while (p)
902 {
903 if (p->comp_idx < num_comps)
904 result &= p->internal_write_coc(file, num_comps);
905 p = p->next;
906 }
907 return result;
908 }
909
911 bool param_cod::internal_write_coc(outfile_base *file, ui32 num_comps)
912 {
913 assert(type == COC_MAIN);
914
915 //marker size excluding header
916 Lcod = num_comps < 257 ? 9 : 10;
917 Lcod = (ui16)(Lcod + (Scod & 1 ? 1 + SPcod.num_decomp : 0));
918
919 ui8 buf[4];
920 bool result = true;
921
922 *(ui16*)buf = JP2K_MARKER::COC;
923 *(ui16*)buf = swap_byte(*(ui16*)buf);
924 result &= file->write(&buf, 2) == 2;
925 *(ui16*)buf = swap_byte(Lcod);
926 result &= file->write(&buf, 2) == 2;
927 if (num_comps < 257)
928 {
929 *(ui8*)buf = (ui8)comp_idx;
930 result &= file->write(&buf, 1) == 1;
931 }
932 else
933 {
934 *(ui16*)buf = swap_byte(comp_idx);
935 result &= file->write(&buf, 2) == 2;
936 }
937 *(ui8*)buf = Scod;
938 result &= file->write(&buf, 1) == 1;
939 buf[0] = SPcod.num_decomp;
940 buf[1] = SPcod.block_width;
941 buf[2] = SPcod.block_height;
942 buf[3] = SPcod.block_style;
943 result &= file->write(&buf, 4) == 4;
944 *(ui8*)buf = SPcod.wavelet_trans;
945 result &= file->write(&buf, 1) == 1;
946 if (Scod & 1)
947 for (int i = 0; i <= SPcod.num_decomp; ++i)
948 {
949 *(ui8*)buf = SPcod.precinct_size[i];
950 result &= file->write(&buf, 1) == 1;
951 }
952
953 return result;
954 }
955
957 void param_cod::read(infile_base *file)
958 {
959 assert(type == COD_MAIN);
960
961 if (file->read(&Lcod, 2) != 2)
962 OJPH_ERROR(0x00050071, "error reading COD segment");
963 Lcod = swap_byte(Lcod);
964 if (file->read(&Scod, 1) != 1)
965 OJPH_ERROR(0x00050072, "error reading COD segment");
966 if (file->read(&SGCod.prog_order, 1) != 1)
967 OJPH_ERROR(0x00050073, "error reading COD segment");
968 if (file->read(&SGCod.num_layers, 2) != 2)
969 { OJPH_ERROR(0x00050074, "error reading COD segment"); }
970 else
971 SGCod.num_layers = swap_byte(SGCod.num_layers);
972 if (file->read(&SGCod.mc_trans, 1) != 1)
973 OJPH_ERROR(0x00050075, "error reading COD segment");
974 if (file->read(&SPcod.num_decomp, 1) != 1)
975 OJPH_ERROR(0x00050076, "error reading COD segment");
976 if (file->read(&SPcod.block_width, 1) != 1)
977 OJPH_ERROR(0x00050077, "error reading COD segment");
978 if (file->read(&SPcod.block_height, 1) != 1)
979 OJPH_ERROR(0x00050078, "error reading COD segment");
980 if (file->read(&SPcod.block_style, 1) != 1)
981 OJPH_ERROR(0x00050079, "error reading COD segment");
982 if (file->read(&SPcod.wavelet_trans, 1) != 1)
983 OJPH_ERROR(0x0005007A, "error reading COD segment");
984
985 if (get_num_decompositions() > 32
986 || SPcod.block_width > 8
987 || SPcod.block_height > 8
988 || SPcod.block_width + SPcod.block_height > 8
989 || (SPcod.block_style & 0x40) != 0x40
990 || (SPcod.block_style & 0xB7) != 0x00)
991 OJPH_ERROR(0x0005007D, "wrong settings in a COD-SPcod parameter");
992 if ((SPcod.block_style & 0x40) != 0x40
993 || (SPcod.block_style & 0xB7) != 0x00)
994 OJPH_ERROR(0x0005007E, "unsupported settings in a COD-SPcod parameter");
995
996 ui8 num_decompositions = get_num_decompositions();
997 if (Scod & 1)
998 for (int i = 0; i <= num_decompositions; ++i)
999 if (file->read(&SPcod.precinct_size[i], 1) != 1)
1000 OJPH_ERROR(0x0005007B, "error reading COD segment");
1001 if (Lcod != 12 + ((Scod & 1) ? 1 + SPcod.num_decomp : 0))
1002 OJPH_ERROR(0x0005007C, "error in COD segment length");
1003 }
1004
1006 void param_cod::read_coc(infile_base* file, ui32 num_comps,
1007 param_cod *top_cod)
1008 {
1009 assert(type == COC_MAIN);
1010 assert(top_cod != NULL);
1011
1012 this->SGCod = top_cod->SGCod;
1013 this->top_cod = top_cod;
1014 if (file->read(&Lcod, 2) != 2)
1015 OJPH_ERROR(0x00050121, "error reading COC segment");
1016 Lcod = swap_byte(Lcod);
1017 if (num_comps < 257) {
1018 ui8 t;
1019 if (file->read(&t, 1) != 1)
1020 OJPH_ERROR(0x00050122, "error reading COC segment");
1021 comp_idx = t;
1022 }
1023 else {
1024 if (file->read(&comp_idx, 2) != 2)
1025 OJPH_ERROR(0x00050123, "error reading COC segment");
1026 comp_idx = swap_byte(comp_idx);
1027 }
1028 if (file->read(&Scod, 1) != 1)
1029 OJPH_ERROR(0x00050124, "error reading COC segment");
1030 if (Scod & 0xF8)
1031 OJPH_WARN(0x00050011,
1032 "Unsupported options in Scoc field of the COC segment");
1033 if (file->read(&SPcod.num_decomp, 1) != 1)
1034 OJPH_ERROR(0x00050125, "error reading COC segment");
1035 if (file->read(&SPcod.block_width, 1) != 1)
1036 OJPH_ERROR(0x00050126, "error reading COC segment");
1037 if (file->read(&SPcod.block_height, 1) != 1)
1038 OJPH_ERROR(0x00050127, "error reading COC segment");
1039 if (file->read(&SPcod.block_style, 1) != 1)
1040 OJPH_ERROR(0x00050128, "error reading COC segment");
1041 if (file->read(&SPcod.wavelet_trans, 1) != 1)
1042 OJPH_ERROR(0x00050129, "error reading COC segment");
1043
1044 if (get_num_decompositions() > 32
1045 || SPcod.block_width > 8
1046 || SPcod.block_height > 8
1047 || SPcod.block_width + SPcod.block_height > 8
1048 || (SPcod.block_style & 0x40) != 0x40
1049 || (SPcod.block_style & 0xB7) != 0x00)
1050 OJPH_ERROR(0x0005012C, "wrong settings in a COC-SPcoc parameter");
1051 if ((SPcod.block_style & 0x40) != 0x40
1052 || (SPcod.block_style & 0xB7) != 0x00)
1053 OJPH_ERROR(0x0005012D, "unsupported settings in a COC-SPcoc parameter");
1054
1055 ui8 num_decompositions = get_num_decompositions();
1056 if (Scod & 1)
1057 for (int i = 0; i <= num_decompositions; ++i)
1058 if (file->read(&SPcod.precinct_size[i], 1) != 1)
1059 OJPH_ERROR(0x0005012A, "error reading COC segment");
1060 ui32 t = 9;
1061 t += num_comps < 257 ? 0 : 1;
1062 t += (Scod & 1) ? 1 + num_decompositions : 0;
1063 if (Lcod != t)
1064 OJPH_ERROR(0x0005012B, "error in COC segment length");
1065 }
1066
1068 void param_cod::update_atk(param_atk* atk)
1069 {
1070 assert(type == COD_MAIN);
1071 this->atk = atk->get_atk(SPcod.wavelet_trans);
1072 if (this->atk == NULL)
1073 OJPH_ERROR(0x00050131, "A COD segment employs the DWT kernel "
1074 "atk = %d, but a corresponding ATK segment cannot be found.",
1075 SPcod.wavelet_trans);
1076 param_cod *p = next;
1077 while (p)
1078 {
1079 p->atk = atk->get_atk(p->SPcod.wavelet_trans);
1080 if (p->atk == NULL)
1081 OJPH_ERROR(0x00050132, "A COC segment employs the DWT kernel "
1082 "atk = %d, but a corresponding ATK segment cannot be found",
1083 SPcod.wavelet_trans);
1084 p = p->next;
1085 }
1086 }
1087
1089 const param_cod* param_cod::get_coc(ui32 comp_idx) const
1090 {
1091 assert(this->type == COD_MAIN || this->top_cod->type == COD_MAIN);
1092 const param_cod *p, *q;
1093 if (this->type == COD_MAIN)
1094 q = p = this;
1095 else
1096 q = p = this->top_cod;
1097 while (p && p->comp_idx != comp_idx)
1098 p = p->next;
1099 return p ? p : q;
1100 }
1101
1103 param_cod* param_cod::get_coc(ui32 comp_idx)
1104 {
1105 // cast object to constant
1106 const param_cod* const_p = const_cast<const param_cod*>(this);
1107 // call using the constant object, then cast to non-const
1108 return const_cast<param_cod*>(const_p->get_coc(comp_idx));
1109 }
1110
1112 param_cod* param_cod::add_coc_object(ui32 comp_idx)
1113 {
1114 assert(type == COD_MAIN);
1115 param_cod *p = this;
1116 while (p->next != NULL)
1117 p = p->next;
1118 if (avail)
1119 {
1120 p->next = avail;
1121 avail = avail->next;
1122 p->next->init(this, (ui16)comp_idx);
1123 }
1124 else
1125 p->next = new param_cod(this, (ui16)comp_idx);
1126 return p->next;
1127 }
1128
1130 //
1131 //
1132 //
1133 //
1134 //
1136
1138 void param_qcd::check_validity(const param_siz& siz, const param_cod& cod)
1139 {
1140 ui32 num_comps = siz.get_num_components();
1141 trim_non_existing_components(num_comps);
1142
1143 // first check that all the component captured by QCD have the same
1144 // bit_depth and signedness
1145 bool all_same = true;
1146 bool other_comps_exist = false;
1147 ui32 first_comp = 0xFFFF; // an impossible component
1148 {
1149 ui32 num_decompositions = 0;
1150 ui32 bit_depth = 0;
1151 bool is_signed = false;
1152 ui32 wavelet_kern = param_cod::DWT_IRV97;
1153
1154 for (ui32 c = 0; c < num_comps; ++c)
1155 {
1156 if (get_qcc(c) == this) // no qcc defined for component c
1157 {
1158 const param_cod *p = cod.get_coc(c);
1159 if (bit_depth == 0) // first component captured by QCD
1160 {
1161 num_decompositions = p->get_num_decompositions();
1162 bit_depth = siz.get_bit_depth(c);
1163 is_signed = siz.is_signed(c);
1164 wavelet_kern = p->get_wavelet_kern();
1165 first_comp = c;
1166 }
1167 else
1168 {
1169 all_same = all_same
1170 && (num_decompositions == p->get_num_decompositions())
1171 && (bit_depth == siz.get_bit_depth(c))
1172 && (is_signed == siz.is_signed(c))
1173 && (wavelet_kern == p->get_wavelet_kern());
1174 }
1175 }
1176 else
1177 other_comps_exist = true;
1178 }
1179 }
1180
1181 // configure QCD according COD
1182 ui32 qcd_num_decompositions;
1183 ui32 qcd_bit_depth;
1184 bool qcd_is_signed;
1185 ui32 qcd_wavelet_kern;
1186 {
1187 ui32 qcd_component = first_comp != 0xFFFF ? first_comp : 0;
1188 bool employing_color_transform = cod.is_employing_color_transform();
1189 qcd_num_decompositions = cod.get_num_decompositions();
1190 qcd_bit_depth = siz.get_bit_depth(qcd_component);
1191 qcd_is_signed = siz.is_signed(qcd_component);
1192 qcd_wavelet_kern = cod.get_wavelet_kern();
1193 this->num_subbands = 1 + 3 * qcd_num_decompositions;
1194 if (qcd_wavelet_kern == param_cod::DWT_REV53)
1195 set_rev_quant(qcd_num_decompositions, qcd_bit_depth,
1196 qcd_component < 3 ? employing_color_transform : false);
1197 else if (qcd_wavelet_kern == param_cod::DWT_IRV97)
1198 {
1199 if (this->base_delta == -1.0f)
1200 this->base_delta = 1.0f / (float)(1 << qcd_bit_depth);
1201 set_irrev_quant(qcd_num_decompositions);
1202 }
1203 else
1204 assert(0);
1205 }
1206
1207 // if not all the same and captured by QCD, then create QCC for them
1208 if (!all_same)
1209 {
1210 bool employing_color_transform = cod.is_employing_color_transform();
1211 for (ui32 c = 0; c < num_comps; ++c)
1212 {
1213 const param_cod *cp = cod.get_coc(c);
1214 if (qcd_num_decompositions == cp->get_num_decompositions()
1215 && qcd_bit_depth == siz.get_bit_depth(c)
1216 && qcd_is_signed == siz.is_signed(c)
1217 && qcd_wavelet_kern == cp->get_wavelet_kern())
1218 continue; // captured by QCD
1219
1220 // Does not match QCD, must have QCC
1221 param_qcd *qp = get_qcc(c);
1222 if (qp == this) // no QCC was defined, create QCC
1223 qp = this->add_qcc_object(c);
1224
1225 ui32 num_decompositions = cp->get_num_decompositions();
1226 qp->num_subbands = 1 + 3 * num_decompositions;
1227 ui32 bit_depth = siz.get_bit_depth(c);
1228 if (cp->get_wavelet_kern() == param_cod::DWT_REV53)
1229 qp->set_rev_quant(num_decompositions, bit_depth,
1230 c < 3 ? employing_color_transform : false);
1231 else if (cp->get_wavelet_kern() == param_cod::DWT_IRV97)
1232 {
1233 if (qp->base_delta == -1.0f)
1234 qp->base_delta = 1.0f / (float)(1 << bit_depth);
1235 qp->set_irrev_quant(num_decompositions);
1236 }
1237 else
1238 assert(0);
1239 }
1240 }
1241 else if (other_comps_exist) // Some are captured by QCD
1242 {
1243 bool employing_color_transform = cod.is_employing_color_transform();
1244 for (ui32 c = 0; c < num_comps; ++c)
1245 {
1246 param_qcd *qp = get_qcc(c);
1247 if (qp == this) // if captured by QCD continue
1248 continue;
1249 const param_cod *cp = cod.get_coc(c);
1250 ui32 num_decompositions = cp->get_num_decompositions();
1251 qp->num_subbands = 1 + 3 * num_decompositions;
1252 ui32 bit_depth = siz.get_bit_depth(c);
1253 if (cp->get_wavelet_kern() == param_cod::DWT_REV53)
1254 qp->set_rev_quant(num_decompositions, bit_depth,
1255 c < 3 ? employing_color_transform : false);
1256 else if (cp->get_wavelet_kern() == param_cod::DWT_IRV97)
1257 {
1258 if (qp->base_delta == -1.0f)
1259 qp->base_delta = 1.0f / (float)(1 << bit_depth);
1260 qp->set_irrev_quant(num_decompositions);
1261 }
1262 else
1263 assert(0);
1264 }
1265 }
1266 }
1267
1269 void param_qcd::set_delta(ui32 comp_idx, float delta)
1270 {
1271 assert(type == QCD_MAIN);
1272 param_qcd *p = get_qcc(comp_idx);
1273 if (p == NULL)
1274 p = add_qcc_object(comp_idx);
1275 p->set_delta(delta);
1276 }
1277
1279 void param_qcd::set_rev_quant(ui32 num_decomps, ui32 bit_depth,
1280 bool is_employing_color_transform)
1281 {
1282 ui32 B = bit_depth;
1283 B += is_employing_color_transform ? 1 : 0; //1 bit for RCT
1284 int s = 0;
1285 double bibo_l = bibo_gains::get_bibo_gain_l(num_decomps, true);
1286 ui32 X = (ui32) ceil(log(bibo_l * bibo_l) / M_LN2);
1287 SPqcd.u8[s++] = (ui8)(B + X);
1288 ui32 max_B_plus_X = (ui32)(B + X);
1289 for (ui32 d = num_decomps; d > 0; --d)
1290 {
1291 double bibo_l = bibo_gains::get_bibo_gain_l(d, true);
1292 double bibo_h = bibo_gains::get_bibo_gain_h(d - 1, true);
1293 X = (ui32) ceil(log(bibo_h * bibo_l) / M_LN2);
1294 SPqcd.u8[s++] = (ui8)(B + X);
1295 max_B_plus_X = ojph_max(max_B_plus_X, B + X);
1296 SPqcd.u8[s++] = (ui8)(B + X);
1297 max_B_plus_X = ojph_max(max_B_plus_X, B + X);
1298 X = (ui32) ceil(log(bibo_h * bibo_h) / M_LN2);
1299 SPqcd.u8[s++] = (ui8)(B + X);
1300 max_B_plus_X = ojph_max(max_B_plus_X, B + X);
1301 }
1302
1303 if (max_B_plus_X > 38)
1304 OJPH_ERROR(0x00050151, "The specified combination of bit_depth, "
1305 "colour transform, and type of wavelet transform requires more than "
1306 "38 bits; it requires %d bits. This is beyond what is allowed in "
1307 "the JPEG2000 image coding format.", max_B_plus_X);
1308
1309 int guard_bits = ojph_max(1, (si32)max_B_plus_X - 31);
1310 Sqcd = (ui8)(guard_bits << 5);
1311 s = 0;
1312 SPqcd.u8[s] = encode_SPqcd((ui8)(SPqcd.u8[s] - guard_bits));
1313 s++;
1314 for (ui32 d = num_decomps; d > 0; --d)
1315 {
1316 SPqcd.u8[s] = encode_SPqcd((ui8)(SPqcd.u8[s] - guard_bits));
1317 s++;
1318 SPqcd.u8[s] = encode_SPqcd((ui8)(SPqcd.u8[s] - guard_bits));
1319 s++;
1320 SPqcd.u8[s] = encode_SPqcd((ui8)(SPqcd.u8[s] - guard_bits));
1321 s++;
1322 }
1323 }
1324
1326 void param_qcd::set_irrev_quant(ui32 num_decomps)
1327 {
1328 int guard_bits = 1;
1329 Sqcd = (ui8)((guard_bits<<5)|0x2);//one guard bit, scalar quantization
1330 int s = 0;
1331 float gain_l = sqrt_energy_gains::get_gain_l(num_decomps, false);
1332 float delta_b = base_delta / (gain_l * gain_l);
1333 int exp = 0, mantissa;
1334 while (delta_b < 1.0f)
1335 { exp++; delta_b *= 2.0f; }
1336 //with rounding, there is a risk of becoming equal to 1<<12
1337 // but that should not happen in reality
1338 mantissa = (int)round(delta_b * (float)(1<<11)) - (1<<11);
1339 mantissa = mantissa < (1<<11) ? mantissa : 0x7FF;
1340 SPqcd.u16[s++] = (ui16)((exp << 11) | mantissa);
1341 for (ui32 d = num_decomps; d > 0; --d)
1342 {
1343 float gain_l = sqrt_energy_gains::get_gain_l(d, false);
1344 float gain_h = sqrt_energy_gains::get_gain_h(d - 1, false);
1345
1346 delta_b = base_delta / (gain_l * gain_h);
1347
1348 int exp = 0, mantissa;
1349 while (delta_b < 1.0f)
1350 { exp++; delta_b *= 2.0f; }
1351 mantissa = (int)round(delta_b * (float)(1<<11)) - (1<<11);
1352 mantissa = mantissa < (1<<11) ? mantissa : 0x7FF;
1353 SPqcd.u16[s++] = (ui16)((exp << 11) | mantissa);
1354 SPqcd.u16[s++] = (ui16)((exp << 11) | mantissa);
1355
1356 delta_b = base_delta / (gain_h * gain_h);
1357
1358 exp = 0;
1359 while (delta_b < 1)
1360 { exp++; delta_b *= 2.0f; }
1361 mantissa = (int)round(delta_b * (float)(1<<11)) - (1<<11);
1362 mantissa = mantissa < (1<<11) ? mantissa : 0x7FF;
1363 SPqcd.u16[s++] = (ui16)((exp << 11) | mantissa);
1364 }
1365 }
1366
1368 ui32 param_qcd::get_MAGB() const
1369 {
1370 ui32 B = 0;
1371
1372 const param_qcd *p = this;
1373 while (p)
1374 {
1375 //this can be written better, but it is only executed once
1376 // this assumes a bi-directional wavelet (conventional DWT)
1377 ui32 num_decomps = (p->num_subbands - 1) / 3;
1378
1379 int irrev = p->Sqcd & 0x1F;
1380 if (irrev == 0) //reversible
1381 for (ui32 i = 0; i < p->num_subbands; ++i) {
1382 ui32 t = p->decode_SPqcd(p->SPqcd.u8[i]);
1383 t += p->get_num_guard_bits() - 1u;
1384 B = ojph_max(B, t);
1385 }
1386 else if (irrev == 2) //scalar expounded
1387 for (ui32 i = 0; i < p->num_subbands; ++i)
1388 {
1389 ui32 nb = num_decomps - (i ? (i - 1) / 3 : 0); //decompsition level
1390 ui32 t = (p->SPqcd.u16[i] >> 11) + p->get_num_guard_bits() - nb;
1391 B = ojph_max(B, t);
1392 }
1393 else
1394 assert(0);
1395
1396 p = p->next;
1397 }
1398
1399 return B;
1400 }
1401
1403 float param_qcd::get_irrev_delta(const param_dfs* dfs,
1404 ui32 num_decompositions,
1405 ui32 resolution, ui32 subband) const
1406 {
1407 float arr[] = { 1.0f, 2.0f, 2.0f, 4.0f };
1408 assert((Sqcd & 0x1F) == 2);
1409
1410 ui32 idx;
1411 if (dfs != NULL && dfs->exists())
1412 idx = dfs->get_subband_idx(num_decompositions, resolution, subband);
1413 else
1414 idx = resolution ? (resolution - 1) * 3 + subband : 0;
1415 if (idx >= num_subbands) {
1416 OJPH_INFO(0x00050101, "Trying to access quantization step size for "
1417 "subband %d when the QCD/QCC marker segment specifies "
1418 "quantization step sizes for %d subbands only. To continue "
1419 "decoding, we are using the step size for subband %d, which can "
1420 "produce incorrect results",
1421 idx + 1, num_subbands, num_subbands - 1);
1422 idx = num_subbands - 1;
1423 }
1424 int eps = SPqcd.u16[idx] >> 11;
1425 float mantissa;
1426 mantissa = (float)((SPqcd.u16[idx] & 0x7FF) | 0x800) * arr[subband];
1427 mantissa /= (float)(1 << 11);
1428 mantissa /= (float)(1u << eps);
1429 return mantissa;
1430 }
1431
1433 ui32 param_qcd::propose_precision(const param_cod* cod) const
1434 {
1435 ui32 comp_idx = cod->get_comp_idx();
1436 ui32 precision = 0;
1437 const param_cod *main =
1438 cod->get_coc(param_cod::OJPH_COD_DEFAULT);
1439 if (main->is_employing_color_transform() && comp_idx < 3)
1440 {
1441 for (ui32 i = 0; i < 3; ++i) {
1442 const param_qcd* p = this->get_qcc(i);
1443 precision = ojph_max(precision, p->get_largest_Kmax());
1444 }
1445 }
1446 else {
1447 precision = get_largest_Kmax();
1448 }
1449 // ``precision'' now holds the largest K_max, which excludes the sign
1450 // bit.
1451 // + 1 for the sign bit
1452 // + 1 because my block decoder/encoder does not supports up to 30
1453 // bits (not 31), so we bump it by one more bit.
1454 return precision + 1 + 1;
1455 }
1456
1458 ui32 param_qcd::get_num_guard_bits() const
1459 {
1460 return (Sqcd >> 5);
1461 }
1462
1464 ui32 param_qcd::get_Kmax(const param_dfs* dfs, ui32 num_decompositions,
1465 ui32 resolution, ui32 subband) const
1466 {
1467 ui32 idx;
1468 if (dfs != NULL && dfs->exists())
1469 idx = dfs->get_subband_idx(num_decompositions, resolution, subband);
1470 else
1471 idx = resolution ? (resolution - 1) * 3 + subband : 0;
1472 if (idx >= num_subbands) {
1473 OJPH_INFO(0x00050111, "Trying to access quantization step size for "
1474 "subband %d when the QCD/QCC marker segment specifies "
1475 "quantization step sizes for %d subbands only. To continue "
1476 "decoding, we are using the step size for subband %d, which can "
1477 "produce incorrect results",
1478 idx + 1, num_subbands, num_subbands - 1);
1479 idx = num_subbands - 1;
1480 }
1481
1482 int irrev = Sqcd & 0x1F;
1483 ui32 num_bits = 0;
1484 if (irrev == 0) // reversible; this is (10.22) from the J2K book
1485 {
1486 num_bits = decode_SPqcd(SPqcd.u8[idx]);
1487 num_bits = num_bits == 0 ? 0 : num_bits - 1;
1488 }
1489 else if (irrev == 1)
1490 assert(0);
1491 else if (irrev == 2) //scalar expounded
1492 num_bits = (SPqcd.u16[idx] >> 11) - 1;
1493 else
1494 assert(0);
1495
1496 return num_bits + get_num_guard_bits();
1497 }
1498
1500 ui32 param_qcd::get_largest_Kmax() const
1501 {
1502 int irrev = Sqcd & 0x1F;
1503 ui32 num_bits = 0;
1504 if (irrev == 0) // reversible; this is (10.22) from the J2K book
1505 {
1506 for (ui32 i = 0; i < num_subbands; ++i) {
1507 ui32 t = decode_SPqcd(SPqcd.u8[i]);
1508 num_bits = ojph_max(num_bits, t == 0 ? 0 : t - 1);
1509 }
1510 }
1511 else if (irrev == 1)
1512 assert(0);
1513 else if (irrev == 2) //scalar expounded
1514 {
1515 for (ui32 i = 0; i < num_subbands; ++i) {
1516 ui32 t = (SPqcd.u16[i] >> 11) - 1;
1517 num_bits = ojph_max(num_bits, t);
1518 }
1519 }
1520 else
1521 assert(0);
1522
1523 return num_bits + get_num_guard_bits();
1524 }
1525
1527 bool param_qcd::write(outfile_base *file)
1528 {
1529 int irrev = Sqcd & 0x1F;
1530
1531 //marker size excluding header
1532 Lqcd = 3;
1533 if (irrev == 0)
1534 Lqcd = (ui16)(Lqcd + num_subbands);
1535 else if (irrev == 2)
1536 Lqcd = (ui16)(Lqcd + 2 * num_subbands);
1537 else
1538 assert(0);
1539
1540 char buf[4];
1541 bool result = true;
1542
1543 *(ui16*)buf = JP2K_MARKER::QCD;
1544 *(ui16*)buf = swap_byte(*(ui16*)buf);
1545 result &= file->write(&buf, 2) == 2;
1546 *(ui16*)buf = swap_byte(Lqcd);
1547 result &= file->write(&buf, 2) == 2;
1548 *(ui8*)buf = Sqcd;
1549 result &= file->write(&buf, 1) == 1;
1550
1551 if (irrev == 0)
1552 for (ui32 i = 0; i < num_subbands; ++i)
1553 {
1554 *(ui8*)buf = SPqcd.u8[i];
1555 result &= file->write(&buf, 1) == 1;
1556 }
1557 else if (irrev == 2)
1558 for (ui32 i = 0; i < num_subbands; ++i)
1559 {
1560 *(ui16*)buf = swap_byte(SPqcd.u16[i]);
1561 result &= file->write(&buf, 2) == 2;
1562 }
1563 else
1564 assert(0);
1565
1566 return result;
1567 }
1568
1570 bool param_qcd::write_qcc(outfile_base *file, ui32 num_comps)
1571 {
1572 assert(type == QCD_MAIN);
1573 bool result = true;
1574 param_qcd *p = this->next;
1575 while (p)
1576 {
1577 if (p->enabled)
1578 result &= p->internal_write_qcc(file, num_comps);
1579 p = p->next;
1580 }
1581 return result;
1582 }
1583
1585 bool param_qcd::internal_write_qcc(outfile_base *file, ui32 num_comps)
1586 {
1587 int irrev = Sqcd & 0x1F;
1588
1589 //marker size excluding header
1590 Lqcd = (ui16)(4 + (num_comps < 257 ? 0 : 1));
1591 if (irrev == 0)
1592 Lqcd = (ui16)(Lqcd + num_subbands);
1593 else if (irrev == 2)
1594 Lqcd = (ui16)(Lqcd + 2 * num_subbands);
1595 else
1596 assert(0);
1597
1598 char buf[4];
1599 bool result = true;
1600
1601 *(ui16*)buf = JP2K_MARKER::QCC;
1602 *(ui16*)buf = swap_byte(*(ui16*)buf);
1603 result &= file->write(&buf, 2) == 2;
1604 *(ui16*)buf = swap_byte(Lqcd);
1605 result &= file->write(&buf, 2) == 2;
1606 if (num_comps < 257)
1607 {
1608 *(ui8*)buf = (ui8)comp_idx;
1609 result &= file->write(&buf, 1) == 1;
1610 }
1611 else
1612 {
1613 *(ui16*)buf = swap_byte(comp_idx);
1614 result &= file->write(&buf, 2) == 2;
1615 }
1616 *(ui8*)buf = Sqcd;
1617 result &= file->write(&buf, 1) == 1;
1618 if (irrev == 0)
1619 for (ui32 i = 0; i < num_subbands; ++i)
1620 {
1621 *(ui8*)buf = SPqcd.u8[i];
1622 result &= file->write(&buf, 1) == 1;
1623 }
1624 else if (irrev == 2)
1625 for (ui32 i = 0; i < num_subbands; ++i)
1626 {
1627 *(ui16*)buf = swap_byte(SPqcd.u16[i]);
1628 result &= file->write(&buf, 2) == 2;
1629 }
1630 else
1631 assert(0);
1632
1633 return result;
1634 }
1635
1637 void param_qcd::trim_non_existing_components(ui32 num_comps)
1638 {
1639 assert(type == QCD_MAIN && comp_idx == OJPH_QCD_DEFAULT);
1640 param_qcd *p = this->next;
1641 while (p)
1642 {
1643 assert(p->type == QCC_MAIN);
1644 p->enabled = p->comp_idx < num_comps;
1645 p = p->next;
1646 }
1647 }
1648
1650 void param_qcd::read(infile_base *file)
1651 {
1652 if (file->read(&Lqcd, 2) != 2)
1653 OJPH_ERROR(0x00050081, "error reading QCD marker");
1654 Lqcd = swap_byte(Lqcd);
1655 if (file->read(&Sqcd, 1) != 1)
1656 OJPH_ERROR(0x00050082, "error reading QCD marker");
1657 if ((Sqcd & 0x1F) == 0)
1658 {
1659 num_subbands = (Lqcd - 3);
1660 if (num_subbands > 97 || Lqcd != 3 + num_subbands)
1661 OJPH_ERROR(0x00050083, "wrong Lqcd value of %d in QCD marker", Lqcd);
1662 for (ui32 i = 0; i < num_subbands; ++i)
1663 if (file->read(&SPqcd.u8[i], 1) != 1)
1664 OJPH_ERROR(0x00050084, "error reading QCD marker");
1665 }
1666 else if ((Sqcd & 0x1F) == 1)
1667 {
1668 num_subbands = 0;
1669 OJPH_ERROR(0x00050089,
1670 "Scalar derived quantization is not supported yet in QCD marker");
1671 if (Lqcd != 5)
1672 OJPH_ERROR(0x00050085, "wrong Lqcd value in QCD marker");
1673 }
1674 else if ((Sqcd & 0x1F) == 2)
1675 {
1676 num_subbands = (Lqcd - 3) / 2;
1677 if (num_subbands > 97 || Lqcd != 3 + 2 * num_subbands)
1678 OJPH_ERROR(0x00050086, "wrong Lqcd value of %d in QCD marker", Lqcd);
1679 for (ui32 i = 0; i < num_subbands; ++i)
1680 {
1681 if (file->read(&SPqcd.u16[i], 2) != 2)
1682 OJPH_ERROR(0x00050087, "error reading QCD marker");
1683 SPqcd.u16[i] = swap_byte(SPqcd.u16[i]);
1684 }
1685 }
1686 else
1687 OJPH_ERROR(0x00050088, "wrong Sqcd value in QCD marker");
1688 }
1689
1691 void param_qcd::read_qcc(infile_base *file, ui32 num_comps)
1692 {
1693 if (file->read(&Lqcd, 2) != 2)
1694 OJPH_ERROR(0x000500A1, "error reading QCC marker");
1695 Lqcd = swap_byte(Lqcd);
1696 if (num_comps < 257)
1697 {
1698 ui8 v;
1699 if (file->read(&v, 1) != 1)
1700 OJPH_ERROR(0x000500A2, "error reading QCC marker");
1701 comp_idx = v;
1702 }
1703 else
1704 {
1705 if (file->read(&comp_idx, 2) != 2)
1706 OJPH_ERROR(0x000500A3, "error reading QCC marker");
1707 comp_idx = swap_byte(comp_idx);
1708 }
1709 if (file->read(&Sqcd, 1) != 1)
1710 OJPH_ERROR(0x000500A4, "error reading QCC marker");
1711 ui32 offset = num_comps < 257 ? 4 : 5;
1712 if ((Sqcd & 0x1F) == 0)
1713 {
1714 num_subbands = (Lqcd - offset);
1715 if (num_subbands > 97 || Lqcd != offset + num_subbands)
1716 OJPH_ERROR(0x000500A5, "wrong Lqcd value of %d in QCC marker", Lqcd);
1717 for (ui32 i = 0; i < num_subbands; ++i)
1718 if (file->read(&SPqcd.u8[i], 1) != 1)
1719 OJPH_ERROR(0x000500A6, "error reading QCC marker");
1720 }
1721 else if ((Sqcd & 0x1F) == 1)
1722 {
1723 num_subbands = 0;
1724 OJPH_ERROR(0x000500AB,
1725 "Scalar derived quantization is not supported yet in QCC marker");
1726 if (Lqcd != offset)
1727 OJPH_ERROR(0x000500A7, "wrong Lqcc value in QCC marker");
1728 }
1729 else if ((Sqcd & 0x1F) == 2)
1730 {
1731 num_subbands = (Lqcd - offset) / 2;
1732 if (num_subbands > 97 || Lqcd != offset + 2 * num_subbands)
1733 OJPH_ERROR(0x000500A8, "wrong Lqcc value of %d in QCC marker", Lqcd);
1734 for (ui32 i = 0; i < num_subbands; ++i)
1735 {
1736 if (file->read(&SPqcd.u16[i], 2) != 2)
1737 OJPH_ERROR(0x000500A9, "error reading QCC marker");
1738 SPqcd.u16[i] = swap_byte(SPqcd.u16[i]);
1739 }
1740 }
1741 else
1742 OJPH_ERROR(0x000500AA, "wrong Sqcc value in QCC marker");
1743 }
1744
1746 param_qcd* param_qcd::get_qcc(ui32 comp_idx)
1747 {
1748 // cast object to constant
1749 const param_qcd* const_p = const_cast<const param_qcd*>(this);
1750 // call using the constant object, then cast to non-const
1751 return const_cast<param_qcd*>(const_p->get_qcc(comp_idx));
1752 }
1753
1755 const param_qcd* param_qcd::get_qcc(ui32 comp_idx) const
1756 {
1757 assert(this->type == QCD_MAIN || this->top_qcd->type == QCD_MAIN);
1758 const param_qcd *p, *q;
1759 if (this->type == QCD_MAIN)
1760 q = p = this;
1761 else
1762 q = p = this->top_qcd;
1763 while (p && p->comp_idx != comp_idx)
1764 p = p->next;
1765 return p ? p : q;
1766 }
1767
1769 param_qcd* param_qcd::add_qcc_object(ui32 comp_idx)
1770 {
1771 assert(type == QCD_MAIN);
1772 param_qcd *p = this;
1773 while (p->next != NULL)
1774 p = p->next;
1775 if (avail)
1776 {
1777 p->next = avail;
1778 avail = avail->next;
1779 p->next->init(this, (ui16)comp_idx);
1780 }
1781 else
1782 p->next = new param_qcd(this, (ui16)comp_idx);
1783 return p->next;
1784 }
1785
1787 //
1788 //
1789 //
1790 //
1791 //
1793
1795 void param_nlt::check_validity(param_siz& siz)
1796 {
1797 if (is_any_enabled() == false)
1798 return;
1799
1800 if (this->enabled && this->Tnlt == nonlinearity::OJPH_NLT_NO_NLT)
1801 this->enabled = false;
1802
1803 if (this->enabled &&
1804 this->Tnlt == nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT)
1805 {
1806 bool all_same = true;
1807 ui32 num_comps = siz.get_num_components();
1808
1809 // first stage; find out if all components captured by the default
1810 // entry (ALL_COMPS) has the same bit_depth/signedness,
1811 // while doing this, set the BDnlt for components not captured by the
1812 // default entry (ALL_COMPS)
1813 ui32 bit_depth = 0; // unknown yet
1814 bool is_signed = false; // unknown yet
1815 for (ui32 c = 0; c < num_comps; ++c)
1816 { // captured by ALL_COMPS
1817 param_nlt* p = get_nlt_object(c);
1818 if (p == NULL || !p->enabled)
1819 {
1820 if (bit_depth != 0)
1821 {
1822 // we have seen an undefined component previously
1823 all_same = all_same && (bit_depth == siz.get_bit_depth(c));
1824 all_same = all_same && (is_signed == siz.is_signed(c));
1825 }
1826 else
1827 {
1828 // this is the first component which has not type 3 nlt definition
1829 bit_depth = siz.get_bit_depth(c);
1830 is_signed = siz.is_signed(c);
1831 }
1832 }
1833 else
1834 { // can be type 0 or type 3
1835 p->BDnlt = (ui8)(siz.get_bit_depth(c) - 1);
1836 p->BDnlt = (ui8)(p->BDnlt | (siz.is_signed(c) ? 0x80 : 0));
1837 }
1838 }
1839
1840 if (all_same && bit_depth != 0)
1841 { // all the same, and some components are captured by ALL_COMPS
1842 this->BDnlt = (ui8)(bit_depth - 1);
1843 this->BDnlt = (ui8)(this->BDnlt | (is_signed ? 0x80 : 0));
1844 }
1845 else if (!all_same)
1846 { // have different settings or no component is captured by ALL_COMPS
1847 this->enabled = false;
1848 for (ui32 c = 0; c < num_comps; ++c)
1849 {
1850 param_nlt* p = get_nlt_object(c);
1851 if (p == NULL || !p->enabled)
1852 { // captured by ALL_COMPS
1853 if (p == NULL)
1854 p = add_object(c);
1855 p->enabled = true;
1856 p->Tnlt = nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT;
1857 p->BDnlt = (ui8)(siz.get_bit_depth(c) - 1);
1858 p->BDnlt = (ui8)(p->BDnlt | (siz.is_signed(c) ? 0x80 : 0));
1859 }
1860 }
1861 }
1862 }
1863 else {
1864 // fill NLT segment markers with correct information
1865 ui32 num_comps = siz.get_num_components();
1866 for (ui32 c = 0; c < num_comps; ++c)
1867 { // captured by ALL_COMPS
1868 param_nlt* p = get_nlt_object(c);
1869 if (p != NULL && p->enabled)
1870 { // can be type 0 or type 3
1871 p->BDnlt = (ui8)(siz.get_bit_depth(c) - 1);
1872 p->BDnlt = (ui8)(p->BDnlt | (siz.is_signed(c) ? 0x80 : 0));
1873 }
1874 }
1875 }
1876
1877 trim_non_existing_components(siz.get_num_components());
1878
1879 if (is_any_enabled() == true)
1880 siz.set_Rsiz_flag(param_siz::RSIZ_EXT_FLAG | param_siz::RSIZ_NLT_FLAG);
1881 }
1882
1884 void param_nlt::set_nonlinear_transform(ui32 comp_num, ui8 nl_type)
1885 {
1886 if (nl_type != ojph::param_nlt::OJPH_NLT_NO_NLT &&
1887 nl_type != ojph::param_nlt::OJPH_NLT_BINARY_COMPLEMENT_NLT)
1888 OJPH_ERROR(0x00050171, "Nonliearities other than type 0 "
1889 "(No Nonlinearity) or type 3 (Binary Binary Complement to Sign "
1890 "Magnitude Conversion) are not supported yet");
1891 param_nlt* p = get_nlt_object(comp_num);
1892 if (p == NULL)
1893 p = add_object(comp_num);
1894 p->Tnlt = nl_type;
1895 p->enabled = true;
1896 }
1897
1899 bool
1900 param_nlt::get_nonlinear_transform(ui32 comp_num, ui8& bit_depth,
1901 bool& is_signed, ui8& nl_type) const
1902 {
1903 assert(Cnlt == special_comp_num::ALL_COMPS);
1904 const param_nlt* p = get_nlt_object(comp_num);
1905 p = (p && p->enabled) ? p : this;
1906 if (p->enabled)
1907 {
1908 bit_depth = (ui8)((p->BDnlt & 0x7F) + 1);
1909 bit_depth = bit_depth <= 38 ? bit_depth : 38;
1910 is_signed = (p->BDnlt & 0x80) == 0x80;
1911 nl_type = (nonlinearity)p->Tnlt;
1912 return true;
1913 }
1914 return false;
1915 }
1916
1918 bool param_nlt::write(outfile_base* file) const
1919 {
1920 if (is_any_enabled() == false)
1921 return true;
1922
1923 char buf[2];
1924 bool result = true;
1925 const param_nlt* p = this;
1926 while (p)
1927 {
1928 if (p->enabled)
1929 {
1930 *(ui16*)buf = JP2K_MARKER::NLT;
1931 *(ui16*)buf = swap_byte(*(ui16*)buf);
1932 result &= file->write(&buf, 2) == 2;
1933 *(ui16*)buf = swap_byte(p->Lnlt);
1934 result &= file->write(&buf, 2) == 2;
1935 *(ui16*)buf = swap_byte(p->Cnlt);
1936 result &= file->write(&buf, 2) == 2;
1937 result &= file->write(&p->BDnlt, 1) == 1;
1938 result &= file->write(&p->Tnlt, 1) == 1;
1939 }
1940 p = p->next;
1941 }
1942 return result;
1943 }
1944
1946 void param_nlt::read(infile_base* file)
1947 {
1948 ui8 buf[6];
1949
1950 if (file->read(buf, 6) != 6)
1951 OJPH_ERROR(0x00050141, "error reading NLT marker segment");
1952
1953 ui16 length = swap_byte(*(ui16*)buf);
1954 if (length != 6 || (buf[5] != 3 && buf[5] != 0)) // wrong length or type
1955 OJPH_ERROR(0x00050142, "Unsupported NLT type %d\n", buf[5]);
1956
1957 ui16 comp = swap_byte(*(ui16*)(buf + 2));
1958 param_nlt* p = get_nlt_object(comp);
1959 if (p == NULL)
1960 p = add_object(comp);
1961 p->enabled = true;
1962 p->Cnlt = comp;
1963 p->BDnlt = buf[4];
1964 p->Tnlt = buf[5];
1965 }
1966
1968 param_nlt* param_nlt::get_nlt_object(ui32 comp_num)
1969 {
1970 // cast object to constant
1971 const param_nlt* const_p = const_cast<const param_nlt*>(this);
1972 // call using the constant object, then cast to non-const
1973 return const_cast<param_nlt*>(const_p->get_nlt_object(comp_num));
1974 }
1975
1977 const param_nlt* param_nlt::get_nlt_object(ui32 comp_num) const
1978 {
1979 const param_nlt* p = this;
1980 while (p && p->Cnlt != comp_num)
1981 p = p->next;
1982 return p;
1983 }
1984
1986 param_nlt* param_nlt::add_object(ui32 comp_num)
1987 {
1988 assert(comp_num != special_comp_num::ALL_COMPS);
1989 assert(Cnlt == special_comp_num::ALL_COMPS);
1990 param_nlt* p = this;
1991 while (p->next != NULL) {
1992 assert(p->Cnlt != comp_num);
1993 p = p->next;
1994 }
1995 if (avail)
1996 {
1997 p->next = avail;
1998 avail = avail->next;
1999 p->next->init();
2000 }
2001 else
2002 p->next = new param_nlt;
2003 p = p->next;
2004 p->Cnlt = (ui16)comp_num;
2005 return p;
2006 }
2007
2009 bool param_nlt::is_any_enabled() const
2010 {
2011 // check if any field is enabled
2012 const param_nlt* p = this;
2013 while (p && p->enabled == false)
2014 p = p->next;
2015 return (p != NULL);
2016 }
2017
2019 void param_nlt::trim_non_existing_components(ui32 num_comps)
2020 {
2021 param_nlt* p = this->next;
2022 while (p) {
2023 if (p->enabled == true && p->Cnlt >= num_comps) {
2024 p->enabled = false;
2025 OJPH_INFO(0x00050161, "The NLT marker segment for the "
2026 "non-existing component %d has been removed.", p->Cnlt);
2027 }
2028 p = p->next;
2029 }
2030 }
2031
2032
2034 //
2035 //
2036 //
2037 //
2038 //
2040
2042 bool param_sot::write(outfile_base *file, ui32 payload_len)
2043 {
2044 char buf[4];
2045 bool result = true;
2046
2047 this->Psot = payload_len + 14; //inc. SOT marker, field & SOD
2048
2049 *(ui16*)buf = JP2K_MARKER::SOT;
2050 *(ui16*)buf = swap_byte(*(ui16*)buf);
2051 result &= file->write(&buf, 2) == 2;
2052 *(ui16*)buf = swap_byte(Lsot);
2053 result &= file->write(&buf, 2) == 2;
2054 *(ui16*)buf = swap_byte(Isot);
2055 result &= file->write(&buf, 2) == 2;
2056 *(ui32*)buf = swap_byte(Psot);
2057 result &= file->write(&buf, 4) == 4;
2058 result &= file->write(&TPsot, 1) == 1;
2059 result &= file->write(&TNsot, 1) == 1;
2060
2061 return result;
2062 }
2063
2065 bool param_sot::write(outfile_base *file, ui32 payload_len,
2066 ui8 TPsot, ui8 TNsot)
2067 {
2068 char buf[4];
2069 bool result = true;
2070
2071 *(ui16*)buf = JP2K_MARKER::SOT;
2072 *(ui16*)buf = swap_byte(*(ui16*)buf);
2073 result &= file->write(&buf, 2) == 2;
2074 *(ui16*)buf = swap_byte(Lsot);
2075 result &= file->write(&buf, 2) == 2;
2076 *(ui16*)buf = swap_byte(Isot);
2077 result &= file->write(&buf, 2) == 2;
2078 *(ui32*)buf = swap_byte(payload_len + 14);
2079 result &= file->write(&buf, 4) == 4;
2080 result &= file->write(&TPsot, 1) == 1;
2081 result &= file->write(&TNsot, 1) == 1;
2082
2083 return result;
2084 }
2085
2087 bool param_sot::read(infile_base *file, bool resilient)
2088 {
2089 if (resilient)
2090 {
2091 if (file->read(&Lsot, 2) != 2)
2092 {
2093 OJPH_INFO(0x00050091, "error reading SOT marker");
2094 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
2095 return false;
2096 }
2097 Lsot = swap_byte(Lsot);
2098 if (Lsot != 10)
2099 {
2100 OJPH_INFO(0x00050092, "error in SOT length");
2101 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
2102 return false;
2103 }
2104 if (file->read(&Isot, 2) != 2)
2105 {
2106 OJPH_INFO(0x00050093, "error reading tile index");
2107 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
2108 return false;
2109 }
2110 Isot = swap_byte(Isot);
2111 if (Isot == 0xFFFF)
2112 {
2113 OJPH_INFO(0x00050094, "tile index in SOT marker cannot be 0xFFFF");
2114 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
2115 return false;
2116 }
2117 if (file->read(&Psot, 4) != 4)
2118 {
2119 OJPH_INFO(0x00050095, "error reading SOT marker");
2120 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
2121 return false;
2122 }
2123 Psot = swap_byte(Psot);
2124 if (file->read(&TPsot, 1) != 1)
2125 {
2126 OJPH_INFO(0x00050096, "error reading SOT marker");
2127 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
2128 return false;
2129 }
2130 if (file->read(&TNsot, 1) != 1)
2131 {
2132 OJPH_INFO(0x00050097, "error reading SOT marker");
2133 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
2134 return false;
2135 }
2136 }
2137 else
2138 {
2139 if (file->read(&Lsot, 2) != 2)
2140 OJPH_ERROR(0x00050091, "error reading SOT marker");
2141 Lsot = swap_byte(Lsot);
2142 if (Lsot != 10)
2143 OJPH_ERROR(0x00050092, "error in SOT length");
2144 if (file->read(&Isot, 2) != 2)
2145 OJPH_ERROR(0x00050093, "error reading SOT tile index");
2146 Isot = swap_byte(Isot);
2147 if (Isot == 0xFFFF)
2148 OJPH_ERROR(0x00050094, "tile index in SOT marker cannot be 0xFFFF");
2149 if (file->read(&Psot, 4) != 4)
2150 OJPH_ERROR(0x00050095, "error reading SOT marker");
2151 Psot = swap_byte(Psot);
2152 if (file->read(&TPsot, 1) != 1)
2153 OJPH_ERROR(0x00050096, "error reading SOT marker");
2154 if (file->read(&TNsot, 1) != 1)
2155 OJPH_ERROR(0x00050097, "error reading SOT marker");
2156 }
2157 return true;
2158 }
2159
2161 //
2162 //
2163 //
2164 //
2165 //
2167
2169 void param_tlm::init(ui32 num_pairs, Ttlm_Ptlm_pair *store)
2170 {
2171 if (4 + 6 * num_pairs > 65535)
2172 OJPH_ERROR(0x000500B1, "Trying to allocate more than 65535 bytes for "
2173 "a TLM marker; this can be resolved by having more than "
2174 "one TLM marker, but the code does not support this. "
2175 "In any case, this limit means that we have 10922 "
2176 "tileparts or more, which is a huge number.");
2177 this->num_pairs = num_pairs;
2178 pairs = store;
2179 Ltlm = (ui16)(4 + 6 * num_pairs);
2180 Ztlm = 0;
2181 Stlm = 0x60;
2182 }
2183
2185 void param_tlm::set_next_pair(ui16 Ttlm, ui32 Ptlm)
2186 {
2187 assert(next_pair_index < num_pairs);
2188 pairs[next_pair_index].Ttlm = Ttlm;
2189 pairs[next_pair_index].Ptlm = Ptlm + 14;
2190 ++next_pair_index;
2191 }
2192
2194 bool param_tlm::write(outfile_base *file)
2195 {
2196 assert(next_pair_index == num_pairs);
2197 char buf[4];
2198 bool result = true;
2199
2200 *(ui16*)buf = JP2K_MARKER::TLM;
2201 *(ui16*)buf = swap_byte(*(ui16*)buf);
2202 result &= file->write(&buf, 2) == 2;
2203 *(ui16*)buf = swap_byte(Ltlm);
2204 result &= file->write(&buf, 2) == 2;
2205 result &= file->write(&Ztlm, 1) == 1;
2206 result &= file->write(&Stlm, 1) == 1;
2207 for (ui32 i = 0; i < num_pairs; ++i)
2208 {
2209 *(ui16*)buf = swap_byte(pairs[i].Ttlm);
2210 result &= file->write(&buf, 2) == 2;
2211 *(ui32*)buf = swap_byte(pairs[i].Ptlm);
2212 result &= file->write(&buf, 4) == 4;
2213 }
2214 return result;
2215 }
2216
2218 //
2219 //
2220 //
2221 //
2222 //
2224
2226 const param_dfs* param_dfs::get_dfs(int index) const
2227 {
2228 const param_dfs* p = this;
2229 while (p && p->Sdfs != index)
2230 p = p->next;
2231 return p;
2232 }
2233
2235 param_dfs::dfs_dwt_type param_dfs::get_dwt_type(ui32 decomp_level) const
2236 {
2237 decomp_level = ojph_min(decomp_level, Ids);
2238 ui32 d = decomp_level - 1; // decomp_level starts from 1
2239 ui32 idx = d >> 2; // complete bytes
2240 ui32 bits = d & 0x3; // bit within the bytes
2241 ui32 val = (Ddfs[idx] >> (6 - 2 * bits)) & 0x3;
2242 return (dfs_dwt_type)val;
2243 }
2244
2246 ui32 param_dfs::get_subband_idx(ui32 num_decompositions, ui32 resolution,
2247 ui32 subband) const
2248 {
2249 assert((resolution == 0 && subband == 0) ||
2250 (resolution > 0 && subband > 0 && subband < 4));
2251
2252 ui32 ns[4] = { 0, 3, 1, 1 };
2253
2254 ui32 idx = 0;
2255 if (resolution > 0)
2256 {
2257 idx = 0;
2258 ui32 i = 1;
2259 for (; i < resolution; ++i)
2260 idx += ns[get_dwt_type(num_decompositions - i + 1)];
2261 dfs_dwt_type t = get_dwt_type(num_decompositions - i + 1);
2262 idx += subband;
2263 if (t == VERT_DWT && subband == 2)
2264 --idx;
2265 }
2266
2267 return idx;
2268 }
2269
2271 point param_dfs::get_res_downsamp(ui32 skipped_resolutions) const
2272 {
2273 point factor(1, 1);
2274 ui32 decomp_level = 1;
2275 while (skipped_resolutions > 0)
2276 {
2277 param_dfs::dfs_dwt_type type = get_dwt_type(decomp_level);
2278 if (type == BIDIR_DWT)
2279 { factor.x *= 2; factor.y *= 2; }
2280 else if (type == HORZ_DWT)
2281 factor.x *= 2;
2282 else if (type == VERT_DWT)
2283 factor.y *= 2;
2284
2285 ++decomp_level;
2286 --skipped_resolutions;
2287 }
2288 return factor;
2289 }
2290
2292 bool param_dfs::read(infile_base *file)
2293 {
2294 if (Ldfs != 0) { // this param_dfs is used
2295 param_dfs* p = this;
2296 while (p->next != NULL)
2297 p = p->next;
2298 if (avail)
2299 {
2300 p->next = avail;
2301 avail = avail->next;
2302 p->next->init();
2303 }
2304 else
2305 p->next = new param_dfs;
2306 p = p->next;
2307 return p->read(file);
2308 }
2309
2310 if (file->read(&Ldfs, 2) != 2)
2311 OJPH_ERROR(0x000500D1, "error reading DFS-Ldfs parameter");
2312 Ldfs = swap_byte(Ldfs);
2313 if (file->read(&Sdfs, 2) != 2)
2314 OJPH_ERROR(0x000500D2, "error reading DFS-Sdfs parameter");
2315 Sdfs = swap_byte(Sdfs);
2316 if (Sdfs > 15)
2317 OJPH_ERROR(0x000500D3, "The DFS-Sdfs parameter is %d, which is "
2318 "larger than the permissible 15", Sdfs);
2319 ui8 t, l_Ids = 0;
2320 if (file->read(&l_Ids, 1) != 1)
2321 OJPH_ERROR(0x000500D4, "error reading DFS-Ids parameter");
2322 constexpr int max_Ddfs = sizeof(Ddfs) * 4;
2323 if (l_Ids > max_Ddfs)
2324 OJPH_INFO(0x000500D5, "The DFS-Ids parameter is %d; while this is "
2325 "valid, the number is unnessarily large -- you do not need more "
2326 "than %d. Please contact me regarding this issue.",
2327 l_Ids, max_Ddfs);
2328 Ids = l_Ids < max_Ddfs ? l_Ids : max_Ddfs;
2329 for (int i = 0; i < Ids; i += 4)
2330 if (file->read(&Ddfs[i / 4], 1) != 1)
2331 OJPH_ERROR(0x000500D6, "error reading DFS-Ddfs parameters");
2332 for (int i = Ids; i < l_Ids; i += 4)
2333 if (file->read(&t, 1) != 1)
2334 OJPH_ERROR(0x000500D7, "error reading DFS-Ddfs parameters");
2335 return true;
2336 }
2337
2339 //
2340 //
2341 //
2342 //
2343 //
2345
2347 param_atk* param_atk::get_atk(int index)
2348 {
2349 assert(top_atk == NULL);
2350
2351 if (Latk == 0)
2352 {
2353 // This atk object is not used, initialize it to either 0 (irv97)
2354 // or 1 (rev53), and use it. If index is not 0 nor 1, then index
2355 // must have been read from file previously, otherwise it is an
2356 // error.
2357 if (index == 0) { this->init_irv97(); return this; }
2358 else if (index == 1) { this->init_rev53(); return this; }
2359 }
2360
2361 param_atk* p = this;
2362 while (p && p->get_index() != index)
2363 p = p->next;
2364
2365 if (p == NULL && (index == 0 || index == 1))
2366 {
2367 // The index was not found, add an atk object only if the index is
2368 // either 0 or 1
2369 p = add_object();
2370 if (index == 0)
2371 p->init_irv97();
2372 else if (index == 1)
2373 p->init_rev53();
2374 }
2375
2376 return p;
2377 }
2378
2380 bool param_atk::read_coefficient(infile_base *file, float &K, si32& bytes)
2381 {
2382 int coeff_type = get_coeff_type();
2383 if (coeff_type == 0) { // 8bit
2384 ui8 v;
2385 if (file->read(&v, 1) != 1) return false;
2386 bytes -= 1;
2387 K = v;
2388 }
2389 else if (coeff_type == 1) { // 16bit
2390 ui16 v;
2391 if (file->read(&v, 2) != 2) return false;
2392 bytes -= 2;
2393 K = swap_byte(v);
2394 }
2395 else if (coeff_type == 2) { // float
2396 union {
2397 float f;
2398 ui32 i;
2399 } v;
2400 if (file->read(&v.i, 4) != 4) return false;
2401 bytes -= 4;
2402 v.i = swap_byte(v.i);
2403 K = v.f;
2404 }
2405 else if (coeff_type == 3) { // double
2406 union {
2407 double d;
2408 ui64 i;
2409 } v;
2410 if (file->read(&v.i, 8) != 8) return false;
2411 bytes -= 8;
2412 v.i = swap_byte(v.i);
2413 K = (float)v.d;
2414 }
2415 else if (coeff_type == 4) { // 128 bit float
2416 ui64 v, v1;
2417 if (file->read(&v, 8) != 8) return false;
2418 bytes -= 8;
2419 if (file->read(&v1, 8) != 8) return false; // v1 not needed
2420 bytes -= 8;
2421 v = swap_byte(v);
2422
2423 union {
2424 float f;
2425 ui32 i;
2426 } s;
2427 // convert the MSB of 128b float to 32b float
2428 // 32b float has 1 sign bit, 8 exponent (offset 127), 23 mantissa
2429 // 128b float has 1 sign bit, 15 exponent (offset 16383), 112 mantissa
2430 si32 e = (si32)((v >> 48) & 0x7FFF); // exponent
2431 e -= 16383;
2432 e += 127;
2433 e = e & 0xFF; // removes MSBs if negative
2434 e <<= 23; // move bits to their location
2435 s.i = 0;
2436 s.i |= ((ui32)(v >> 32) & 0x80000000); // copy sign bit
2437 s.i |= (ui32)e; // copy exponent
2438 s.i |= (ui32)((v >> 25) & 0x007FFFFF); // copy 23 mantissa
2439 K = s.f;
2440 }
2441 return true;
2442 }
2443
2444
2446 bool param_atk::read_coefficient(infile_base *file, si16 &K, si32& bytes)
2447 {
2448 int coeff_type = get_coeff_type();
2449 if (coeff_type == 0) {
2450 si8 v;
2451 if (file->read(&v, 1) != 1) return false;
2452 bytes -= 1;
2453 K = v;
2454 }
2455 else if (coeff_type == 1) {
2456 si16 v;
2457 if (file->read(&v, 2) != 2) return false;
2458 bytes -= 2;
2459 K = (si16)swap_byte((ui16)v);
2460 }
2461 else
2462 return false;
2463 return true;
2464 }
2465
2467 bool param_atk::read(infile_base *file)
2468 {
2469 if (Latk != 0) // this param_atk is used
2470 return add_object()->read(file);
2471
2472 if (file->read(&Latk, 2) != 2)
2473 OJPH_ERROR(0x000500E1, "error reading ATK-Latk parameter");
2474 Latk = swap_byte(Latk);
2475 si32 bytes = Latk - 2;
2476 ojph::ui16 temp_Satk;
2477 if (file->read(&temp_Satk, 2) != 2)
2478 OJPH_ERROR(0x000500E2, "error reading ATK-Satk parameter");
2479 bytes -= 2;
2480 temp_Satk = swap_byte(temp_Satk);
2481 int tmp_idx = temp_Satk & 0xFF;
2482 if ((top_atk && top_atk->get_atk(tmp_idx) != NULL)
2483 || tmp_idx == 0 || tmp_idx == 1)
2484 OJPH_ERROR(0x000500F3, "ATK-Satk parameter sets ATK marker index to "
2485 "the illegal value of %d. ATK-Satk should be in (2-255) and, I "
2486 "believe, must not be repeated; otherwise, it would be unclear "
2487 "what marker segment must be employed when an index is repeated.",
2488 tmp_idx);
2489 Satk = temp_Satk;
2490 if (is_m_init0() == false) // only even-indexed is supported
2491 OJPH_ERROR(0x000500E3, "ATK-Satk parameter sets m_init to 1, "
2492 "requiring odd-indexed subsequence in first reconstruction step, "
2493 "which is not supported yet.");
2494 if (is_whole_sample() == false) // ARB filter not supported
2495 OJPH_ERROR(0x000500E4, "ATK-Satk parameter specified ARB filter, "
2496 "which is not supported yet.");
2497 if (is_reversible() && get_coeff_type() >= 2) // reversible & float
2498 OJPH_ERROR(0x000500E5, "ATK-Satk parameter does not make sense. "
2499 "It employs floats with reversible filtering.");
2500 if (is_using_ws_extension() == false) // only sym. ext is supported
2501 OJPH_ERROR(0x000500E6, "ATK-Satk parameter requires constant "
2502 "boundary extension, which is not supported yet.");
2503 if (is_reversible() == false)
2504 if (read_coefficient(file, Katk, bytes) == false)
2505 OJPH_ERROR(0x000500E7, "error reading ATK-Katk parameter");
2506 if (file->read(&Natk, 1) != 1)
2507 OJPH_ERROR(0x000500E8, "error reading ATK-Natk parameter");
2508 bytes -= 1;
2509 if (Natk > max_steps) {
2510 if (d != d_store) // was this allocated -- very unlikely
2511 delete[] d;
2512 d = new lifting_step[Natk];
2513 max_steps = Natk;
2514 }
2515
2516 if (is_reversible())
2517 {
2518 for (int s = 0; s < Natk; ++s)
2519 {
2520 if (file->read(&d[s].rev.Eatk, 1) != 1)
2521 OJPH_ERROR(0x000500E9, "error reading ATK-Eatk parameter");
2522 bytes -= 1;
2523 if (file->read(&d[s].rev.Batk, 2) != 2)
2524 OJPH_ERROR(0x000500EA, "error reading ATK-Batk parameter");
2525 bytes -= 2;
2526 d[s].rev.Batk = (si16)swap_byte((ui16)d[s].rev.Batk);
2527 ui8 LCatk;
2528 if (file->read(&LCatk, 1) != 1)
2529 OJPH_ERROR(0x000500EB, "error reading ATK-LCatk parameter");
2530 bytes -= 1;
2531 if (LCatk == 0)
2532 OJPH_ERROR(0x000500EC, "Encountered a ATK-LCatk value of zero; "
2533 "something is wrong.");
2534 if (LCatk > 1)
2535 OJPH_ERROR(0x000500ED, "ATK-LCatk value greater than 1; "
2536 "that is, a multitap filter is not supported");
2537 if (read_coefficient(file, d[s].rev.Aatk, bytes) == false)
2538 OJPH_ERROR(0x000500EE, "Error reding ATK-Aatk parameter");
2539 }
2540 }
2541 else
2542 {
2543 for (int s = 0; s < Natk; ++s)
2544 {
2545 ui8 LCatk;
2546 if (file->read(&LCatk, 1) != 1)
2547 OJPH_ERROR(0x000500EF, "error reading ATK-LCatk parameter");
2548 bytes -= 1;
2549 if (LCatk == 0)
2550 OJPH_ERROR(0x000500F0, "Encountered a ATK-LCatk value of zero; "
2551 "something is wrong.");
2552 if (LCatk > 1)
2553 OJPH_ERROR(0x000500F1, "ATK-LCatk value greater than 1; "
2554 "that is, a multitap filter is not supported.");
2555 if (read_coefficient(file, d[s].irv.Aatk, bytes) == false)
2556 OJPH_ERROR(0x000500F2, "Error reding ATK-Aatk parameter");
2557 }
2558 }
2559 if (bytes != 0)
2560 OJPH_ERROR(0x000500F3, "The length of an ATK marker segment "
2561 "(ATK-Latk) is not correct");
2562
2563 return true;
2564 }
2565
2567 void param_atk::init_irv97()
2568 {
2569 Satk = 0x4a00; // illegal because ATK = 0
2570 Katk = (float)1.230174104914001;
2571 Natk = 4;
2572 // next is (A-4) in T.801 second line
2573 Latk = (ui16)(5 + Natk + sizeof(float) * (1 + Natk));
2574 d[0].irv.Aatk = (float)0.443506852043971;
2575 d[1].irv.Aatk = (float)0.882911075530934;
2576 d[2].irv.Aatk = (float)-0.052980118572961;
2577 d[3].irv.Aatk = (float)-1.586134342059924;
2578 }
2579
2581 void param_atk::init_rev53()
2582 {
2583 Satk = 0x5801; // illegal because ATK = 1
2584 Natk = 2;
2585 // next is (A-4) in T.801 fourth line
2586 Latk = (ui16)(5 + 2 * Natk + sizeof(ui8) * (Natk + Natk));
2587 d[0].rev.Aatk = 1;
2588 d[0].rev.Batk = 2;
2589 d[0].rev.Eatk = 2;
2590 d[1].rev.Aatk = -1;
2591 d[1].rev.Batk = 1;
2592 d[1].rev.Eatk = 1;
2593 }
2594
2596 param_atk* param_atk::add_object()
2597 {
2598 assert(top_atk = NULL);
2599 param_atk *p = this;
2600 while (p->next != NULL)
2601 p = p->next;
2602 if (avail)
2603 {
2604 p->next = avail;
2605 avail = avail->next;
2606 }
2607 else
2608 p->next = new param_atk;
2609 p = p->next;
2610 p->init(this);
2611 return p;
2612 }
2613
2614 } // !local namespace
2615} // !ojph namespace
ojph::comment_exchange::len
ui16 len
Definition ojph_params.h:300
ojph::comment_exchange::Rcom
ui16 Rcom
Definition ojph_params.h:301
ojph::comment_exchange::set_string
void set_string(const char *str)
Definition ojph_params.cpp:460
ojph::comment_exchange::set_data
void set_data(const char *data, ui16 len)
Definition ojph_params.cpp:472
ojph::comment_exchange::data
const char * data
Definition ojph_params.h:299
ojph::infile_base
Definition ojph_file.h:247
ojph::infile_base::read
virtual size_t read(void *ptr, size_t size)=0
ojph::local::bibo_gains
Definition ojph_params.cpp:581
ojph::local::bibo_gains::gain_5x3_l
static const float gain_5x3_l[34]
Definition ojph_params.cpp:591
ojph::local::bibo_gains::get_bibo_gain_l
static float get_bibo_gain_l(ui32 num_decomp, bool reversible)
Definition ojph_params.cpp:583
ojph::local::bibo_gains::gain_5x3_h
static const float gain_5x3_h[34]
Definition ojph_params.cpp:592
ojph::local::bibo_gains::get_bibo_gain_h
static float get_bibo_gain_h(ui32 num_decomp, bool reversible)
Definition ojph_params.cpp:585
ojph::local::bibo_gains::gain_9x7_h
static const float gain_9x7_h[34]
Definition ojph_params.cpp:590
ojph::local::bibo_gains::gain_9x7_l
static const float gain_9x7_l[34]
Definition ojph_params.cpp:589
ojph::local::resolution
Definition ojph_resolution.h:62
ojph::local::sqrt_energy_gains
Definition ojph_params.cpp:530
ojph::local::sqrt_energy_gains::gain_5x3_l
static const float gain_5x3_l[34]
Definition ojph_params.cpp:540
ojph::local::sqrt_energy_gains::gain_5x3_h
static const float gain_5x3_h[34]
Definition ojph_params.cpp:541
ojph::local::sqrt_energy_gains::get_gain_l
static float get_gain_l(ui32 num_decomp, bool reversible)
Definition ojph_params.cpp:532
ojph::local::sqrt_energy_gains::gain_9x7_l
static const float gain_9x7_l[34]
Definition ojph_params.cpp:538
ojph::local::sqrt_energy_gains::get_gain_h
static float get_gain_h(ui32 num_decomp, bool reversible)
Definition ojph_params.cpp:534
ojph::local::sqrt_energy_gains::gain_9x7_h
static const float gain_9x7_h[34]
Definition ojph_params.cpp:539
ojph::local::subband
Definition ojph_subband.h:63
ojph::outfile_base
Definition ojph_file.h:75
ojph::outfile_base::write
virtual size_t write(const void *ptr, size_t size)=0
ojph::param_coc
Definition ojph_params.h:136
ojph::param_coc::is_reversible
bool is_reversible() const
Definition ojph_params.cpp:393
ojph::param_coc::set_precinct_size
void set_precinct_size(int num_levels, size *precinct_size)
Definition ojph_params.cpp:373
ojph::param_coc::get_block_dims
size get_block_dims() const
Definition ojph_params.cpp:385
ojph::param_coc::set_reversible
void set_reversible(bool reversible)
Definition ojph_params.cpp:377
ojph::param_coc::get_precinct_size
size get_precinct_size(ui32 level_num) const
Definition ojph_params.cpp:397
ojph::param_coc::get_num_decompositions
ui32 get_num_decompositions() const
Definition ojph_params.cpp:381
ojph::param_coc::state
local::param_cod * state
Definition ojph_params.h:154
ojph::param_coc::get_log_block_dims
size get_log_block_dims() const
Definition ojph_params.cpp:389
ojph::param_coc::get_log_precinct_size
size get_log_precinct_size(ui32 level_num) const
Definition ojph_params.cpp:401
ojph::param_coc::set_num_decomposition
void set_num_decomposition(ui32 num_decompositions)
Definition ojph_params.cpp:365
ojph::param_coc::get_block_vertical_causality
bool get_block_vertical_causality() const
Definition ojph_params.cpp:405
ojph::param_coc::set_block_dims
void set_block_dims(ui32 width, ui32 height)
Definition ojph_params.cpp:369
ojph::param_cod
Definition ojph_params.h:104
ojph::param_cod::get_block_dims
size get_block_dims() const
Definition ojph_params.cpp:273
ojph::param_cod::get_progression_order
int get_progression_order() const
Definition ojph_params.cpp:303
ojph::param_cod::is_using_color_transform
bool is_using_color_transform() const
Definition ojph_params.cpp:333
ojph::param_cod::get_coc
param_coc get_coc(ui32 component_idx)
Definition ojph_params.cpp:258
ojph::param_cod::set_num_decomposition
void set_num_decomposition(ui32 num_decompositions)
Definition ojph_params.cpp:168
ojph::param_cod::get_num_decompositions
ui32 get_num_decompositions() const
Definition ojph_params.cpp:267
ojph::param_cod::get_log_block_dims
size get_log_block_dims() const
Definition ojph_params.cpp:279
ojph::param_cod::packets_may_use_sop
bool packets_may_use_sop() const
Definition ojph_params.cpp:339
ojph::param_cod::get_precinct_size
size get_precinct_size(ui32 level_num) const
Definition ojph_params.cpp:291
ojph::param_cod::get_progression_order_as_string
const char * get_progression_order_as_string() const
Definition ojph_params.cpp:309
ojph::param_cod::set_precinct_size
void set_precinct_size(int num_levels, size *precinct_size)
Definition ojph_params.cpp:191
ojph::param_cod::packets_use_eph
bool packets_use_eph() const
Definition ojph_params.cpp:345
ojph::param_cod::state
local::param_cod * state
Definition ojph_params.h:131
ojph::param_cod::is_reversible
bool is_reversible() const
Definition ojph_params.cpp:285
ojph::param_cod::set_progression_order
void set_progression_order(const char *name)
Definition ojph_params.cpp:219
ojph::param_cod::get_block_vertical_causality
bool get_block_vertical_causality() const
Definition ojph_params.cpp:351
ojph::param_cod::set_block_dims
void set_block_dims(ui32 width, ui32 height)
Definition ojph_params.cpp:177
ojph::param_cod::get_log_precinct_size
size get_log_precinct_size(ui32 level_num) const
Definition ojph_params.cpp:297
ojph::param_cod::get_num_layers
int get_num_layers() const
Definition ojph_params.cpp:327
ojph::param_cod::set_color_transform
void set_color_transform(bool color_transform)
Definition ojph_params.cpp:246
ojph::param_cod::set_reversible
void set_reversible(bool reversible)
Definition ojph_params.cpp:252
ojph::param_nlt::OJPH_NLT_NO_NLT
@ OJPH_NLT_NO_NLT
Definition ojph_params.h:249
ojph::param_nlt::OJPH_NLT_BINARY_COMPLEMENT_NLT
@ OJPH_NLT_BINARY_COMPLEMENT_NLT
Definition ojph_params.h:252
ojph::param_nlt::get_nonlinear_transform
bool get_nonlinear_transform(ui32 comp_num, ui8 &bit_depth, bool &is_signed, ui8 &nl_type) const
get the nonlinearity type associated with comp_num, which should be one from enum nonlinearity
Definition ojph_params.cpp:444
ojph::param_nlt::state
local::param_nlt * state
Definition ojph_params.h:286
ojph::param_nlt::set_nonlinear_transform
void set_nonlinear_transform(ui32 comp_num, ui8 nl_type)
enables or disables type 3 nonlinearity for a component or the default setting
Definition ojph_params.cpp:438
ojph::param_qcd::set_irrev_quant
void set_irrev_quant(float delta)
Set the irreversible quantization base delta.
Definition ojph_params.cpp:418
ojph::param_qcd::state
local::param_qcd * state
Definition ojph_params.h:191
ojph::param_siz::set_tile_size
void set_tile_size(size s)
Definition ojph_params.cpp:66
ojph::param_siz::get_image_extent
point get_image_extent() const
Definition ojph_params.cpp:100
ojph::param_siz::set_component
void set_component(ui32 comp_num, const point &downsampling, ui32 bit_depth, bool is_signed)
Definition ojph_params.cpp:93
ojph::param_siz::set_num_components
void set_num_components(ui32 num_comps)
Definition ojph_params.cpp:87
ojph::param_siz::get_bit_depth
ui32 get_bit_depth(ui32 comp_num) const
Definition ojph_params.cpp:130
ojph::param_siz::set_tile_offset
void set_tile_offset(point offset)
Definition ojph_params.cpp:80
ojph::param_siz::get_image_offset
point get_image_offset() const
Definition ojph_params.cpp:106
ojph::param_siz::state
local::param_siz * state
Definition ojph_params.h:99
ojph::param_siz::set_image_offset
void set_image_offset(point offset)
Definition ojph_params.cpp:73
ojph::param_siz::get_tile_size
size get_tile_size() const
Definition ojph_params.cpp:112
ojph::param_siz::get_recon_height
ui32 get_recon_height(ui32 comp_num) const
Definition ojph_params.cpp:154
ojph::param_siz::get_downsampling
point get_downsampling(ui32 comp_num) const
Definition ojph_params.cpp:142
ojph::param_siz::set_image_extent
void set_image_extent(point extent)
Definition ojph_params.cpp:59
ojph::param_siz::get_tile_offset
point get_tile_offset() const
Definition ojph_params.cpp:118
ojph::param_siz::get_recon_width
ui32 get_recon_width(ui32 comp_num) const
Definition ojph_params.cpp:148
ojph::param_siz::is_signed
bool is_signed(ui32 comp_num) const
Definition ojph_params.cpp:136
ojph::param_siz::get_num_components
ui32 get_num_components() const
Definition ojph_params.cpp:124
ojph::local
Definition ojph_bitbuffer_read.h:52
ojph::local::SIZ
@ SIZ
Definition ojph_params_local.h:123
ojph::local::NLT
@ NLT
Definition ojph_params_local.h:141
ojph::local::TLM
@ TLM
Definition ojph_params_local.h:126
ojph::local::QCC
@ QCC
Definition ojph_params_local.h:132
ojph::local::QCD
@ QCD
Definition ojph_params_local.h:131
ojph::local::COC
@ COC
Definition ojph_params_local.h:125
ojph::local::COD
@ COD
Definition ojph_params_local.h:124
ojph::local::CAP
@ CAP
Definition ojph_params_local.h:122
ojph::local::SOT
@ SOT
Definition ojph_params_local.h:143
ojph::local::swap_byte
static ui16 swap_byte(ui16 t)
Definition ojph_codestream_local.h:58
ojph
Definition ojph_img_io.h:52
ojph::OJPH_PO_STRING_PCRL
const char OJPH_PO_STRING_PCRL[]
Definition ojph_params_local.h:70
ojph::OJPH_PO_LRCP
@ OJPH_PO_LRCP
Definition ojph_params_local.h:59
ojph::OJPH_PO_RLCP
@ OJPH_PO_RLCP
Definition ojph_params_local.h:60
ojph::OJPH_PO_CPRL
@ OJPH_PO_CPRL
Definition ojph_params_local.h:63
ojph::OJPH_PO_PCRL
@ OJPH_PO_PCRL
Definition ojph_params_local.h:62
ojph::OJPH_PO_RPCL
@ OJPH_PO_RPCL
Definition ojph_params_local.h:61
ojph::si8
int8_t si8
Definition ojph_defs.h:51
ojph::ui64
uint64_t ui64
Definition ojph_defs.h:56
ojph::ui16
uint16_t ui16
Definition ojph_defs.h:52
ojph::population_count
static ui32 population_count(ui32 val)
Definition ojph_arch.h:156
ojph::OJPH_PO_STRING_RLCP
const char OJPH_PO_STRING_RLCP[]
Definition ojph_params_local.h:68
ojph::OJPH_PO_STRING_RPCL
const char OJPH_PO_STRING_RPCL[]
Definition ojph_params_local.h:69
ojph::OJPH_PO_STRING_CPRL
const char OJPH_PO_STRING_CPRL[]
Definition ojph_params_local.h:71
ojph::count_leading_zeros
static ui32 count_leading_zeros(ui32 val)
Definition ojph_arch.h:177
ojph::si32
int32_t si32
Definition ojph_defs.h:55
ojph::si16
int16_t si16
Definition ojph_defs.h:53
ojph::ui32
uint32_t ui32
Definition ojph_defs.h:54
ojph::ui8
uint8_t ui8
Definition ojph_defs.h:50
ojph::OJPH_PO_STRING_LRCP
const char OJPH_PO_STRING_LRCP[]
Definition ojph_params_local.h:67
ojph_base.h
main
int main(int argc, char *argv[])
Definition ojph_compress.cpp:487
ojph_max
#define ojph_max(a, b)
Definition ojph_defs.h:73
ojph_div_ceil
#define ojph_div_ceil(a, b)
Definition ojph_defs.h:70
ojph_min
#define ojph_min(a, b)
Definition ojph_defs.h:76
ojph_file.h
ojph_message.h
OJPH_INFO
#define OJPH_INFO(t,...)
MACROs to insert file and line number for info, warning, and error.
Definition ojph_message.h:284
OJPH_ERROR
#define OJPH_ERROR(t,...)
Definition ojph_message.h:288
OJPH_WARN
#define OJPH_WARN(t,...)
Definition ojph_message.h:286
ojph_params.h
ojph_params_local.h
ojph::local::cod_SPcod::wavelet_trans
ui8 wavelet_trans
Definition ojph_params_local.h:345
ojph::local::param_atk
Definition ojph_params_local.h:1071
ojph::local::param_atk::Natk
ui8 Natk
Definition ojph_params_local.h:1165
ojph::local::param_atk::read_coefficient
bool read_coefficient(infile_base *file, float &K, si32 &bytes)
Definition ojph_params.cpp:2380
ojph::local::param_atk::Katk
float Katk
Definition ojph_params_local.h:1164
ojph::local::param_atk::d
lifting_step * d
Definition ojph_params_local.h:1166
ojph::local::param_atk::is_m_init0
bool is_m_init0() const
Definition ojph_params_local.h:1129
ojph::local::param_atk::Satk
ui16 Satk
Definition ojph_params_local.h:1163
ojph::local::param_atk::d_store
lifting_step d_store[6]
Definition ojph_params_local.h:1168
ojph::local::param_atk::top_atk
param_atk * top_atk
Definition ojph_params_local.h:1171
ojph::local::param_atk::init
void init(param_atk *top_atk)
Definition ojph_params_local.h:1139
ojph::local::param_atk::param_atk
param_atk()
Definition ojph_params_local.h:1078
ojph::local::param_atk::is_reversible
bool is_reversible() const
Definition ojph_params_local.h:1128
ojph::local::param_atk::read
bool read(infile_base *file)
Definition ojph_params.cpp:2467
ojph::local::param_atk::add_object
param_atk * add_object()
Definition ojph_params.cpp:2596
ojph::local::param_atk::get_coeff_type
int get_coeff_type() const
Definition ojph_params_local.h:1126
ojph::local::param_atk::get_index
ui8 get_index() const
Definition ojph_params_local.h:1125
ojph::local::param_atk::Latk
ui16 Latk
Definition ojph_params_local.h:1162
ojph::local::param_atk::avail
param_atk * avail
Definition ojph_params_local.h:1175
ojph::local::param_atk::next
param_atk * next
Definition ojph_params_local.h:1169
ojph::local::param_atk::get_atk
param_atk * get_atk(int index)
Definition ojph_params.cpp:2347
ojph::local::param_atk::is_whole_sample
bool is_whole_sample() const
Definition ojph_params_local.h:1127
ojph::local::param_atk::max_steps
ui32 max_steps
Definition ojph_params_local.h:1167
ojph::local::param_atk::init_rev53
void init_rev53()
Definition ojph_params.cpp:2581
ojph::local::param_atk::init_irv97
void init_irv97()
Definition ojph_params.cpp:2567
ojph::local::param_atk::is_using_ws_extension
bool is_using_ws_extension() const
Definition ojph_params_local.h:1130
ojph::local::param_cap::read
void read(infile_base *file)
Definition ojph_params.cpp:811
ojph::local::param_cap::Pcap
ui32 Pcap
Definition ojph_params_local.h:898
ojph::local::param_cap::write
bool write(outfile_base *file)
Definition ojph_params.cpp:788
ojph::local::param_cap::Ccap
ui16 Ccap[32]
Definition ojph_params_local.h:899
ojph::local::param_cap::Lcap
ui16 Lcap
Definition ojph_params_local.h:897
ojph::local::param_cod
Definition ojph_params_local.h:371
ojph::local::param_cod::comp_idx
ui16 comp_idx
Definition ojph_params_local.h:649
ojph::local::param_cod::COD_MAIN
@ COD_MAIN
Definition ojph_params_local.h:387
ojph::local::param_cod::COC_MAIN
@ COC_MAIN
Definition ojph_params_local.h:388
ojph::local::param_cod::write
bool write(outfile_base *file)
Definition ojph_params.cpp:854
ojph::local::param_cod::get_coc
const param_cod * get_coc(ui32 comp_idx) const
Definition ojph_params.cpp:1089
ojph::local::param_cod::internal_write_coc
bool internal_write_coc(outfile_base *file, ui32 num_comps)
Definition ojph_params.cpp:911
ojph::local::param_cod::get_dfs_index
ui16 get_dfs_index() const
Definition ojph_params_local.h:600
ojph::local::param_cod::write_coc
bool write_coc(outfile_base *file, ui32 num_comps)
Definition ojph_params.cpp:896
ojph::local::param_cod::SGCod
cod_SGcod SGCod
Definition ojph_params_local.h:642
ojph::local::param_cod::atk
const param_atk * atk
Definition ojph_params_local.h:645
ojph::local::param_cod::is_employing_color_transform
bool is_employing_color_transform() const
Definition ojph_params_local.h:523
ojph::local::param_cod::get_comp_idx
ui32 get_comp_idx() const
Definition ojph_params_local.h:604
ojph::local::param_cod::avail
param_cod * avail
Definition ojph_params_local.h:652
ojph::local::param_cod::SPcod
cod_SPcod SPcod
Definition ojph_params_local.h:643
ojph::local::param_cod::OJPH_COD_DEFAULT
@ OJPH_COD_DEFAULT
Definition ojph_params_local.h:376
ojph::local::param_cod::top_cod
param_cod * top_cod
Definition ojph_params_local.h:648
ojph::local::param_cod::DWT_REV53
@ DWT_REV53
Definition ojph_params_local.h:395
ojph::local::param_cod::DWT_IRV97
@ DWT_IRV97
Definition ojph_params_local.h:394
ojph::local::param_cod::read
void read(infile_base *file)
Definition ojph_params.cpp:957
ojph::local::param_cod::init
void init(param_cod *top_cod, ui16 comp_idx)
Definition ojph_params_local.h:613
ojph::local::param_cod::read_coc
void read_coc(infile_base *file, ui32 num_comps, param_cod *top_cod)
Definition ojph_params.cpp:1006
ojph::local::param_cod::Lcod
ui16 Lcod
Definition ojph_params_local.h:640
ojph::local::param_cod::type
cod_type type
Definition ojph_params_local.h:639
ojph::local::param_cod::update_atk
void update_atk(param_atk *atk)
Definition ojph_params.cpp:1068
ojph::local::param_cod::Scod
ui8 Scod
Definition ojph_params_local.h:641
ojph::local::param_cod::is_dfs_defined
bool is_dfs_defined() const
Definition ojph_params_local.h:596
ojph::local::param_cod::get_num_decompositions
ui8 get_num_decompositions() const
Definition ojph_params_local.h:490
ojph::local::param_cod::is_reversible
bool is_reversible() const
Definition ojph_params.cpp:843
ojph::local::param_cod::param_cod
param_cod(param_cod *top_cod=NULL, ui16 comp_idx=OJPH_COD_DEFAULT)
Definition ojph_params_local.h:399
ojph::local::param_cod::get_wavelet_kern
ui8 get_wavelet_kern() const
Definition ojph_params_local.h:516
ojph::local::param_cod::add_coc_object
param_cod * add_coc_object(ui32 comp_idx)
Definition ojph_params.cpp:1112
ojph::local::param_cod::next
param_cod * next
Definition ojph_params_local.h:644
ojph::local::param_dfs
Definition ojph_params_local.h:979
ojph::local::param_dfs::read
bool read(infile_base *file)
Definition ojph_params.cpp:2292
ojph::local::param_dfs::get_dwt_type
dfs_dwt_type get_dwt_type(ui32 decomp_level) const
Definition ojph_params.cpp:2235
ojph::local::param_dfs::get_res_downsamp
point get_res_downsamp(ui32 skipped_resolutions) const
Definition ojph_params.cpp:2271
ojph::local::param_dfs::dfs_dwt_type
dfs_dwt_type
Definition ojph_params_local.h:981
ojph::local::param_dfs::HORZ_DWT
@ HORZ_DWT
Definition ojph_params_local.h:984
ojph::local::param_dfs::BIDIR_DWT
@ BIDIR_DWT
Definition ojph_params_local.h:983
ojph::local::param_dfs::VERT_DWT
@ VERT_DWT
Definition ojph_params_local.h:985
ojph::local::param_dfs::param_dfs
param_dfs()
Definition ojph_params_local.h:989
ojph::local::param_dfs::next
param_dfs * next
Definition ojph_params_local.h:1036
ojph::local::param_dfs::Ddfs
ui8 Ddfs[8]
Definition ojph_params_local.h:1034
ojph::local::param_dfs::Sdfs
ui16 Sdfs
Definition ojph_params_local.h:1032
ojph::local::param_dfs::Ldfs
ui16 Ldfs
Definition ojph_params_local.h:1031
ojph::local::param_dfs::avail
param_dfs * avail
Definition ojph_params_local.h:1039
ojph::local::param_dfs::get_subband_idx
ui32 get_subband_idx(ui32 num_decompositions, ui32 resolution, ui32 subband) const
Definition ojph_params.cpp:2246
ojph::local::param_dfs::init
void init()
Definition ojph_params_local.h:1016
ojph::local::param_dfs::Ids
ui8 Ids
Definition ojph_params_local.h:1033
ojph::local::param_dfs::get_dfs
const param_dfs * get_dfs(int index) const
Definition ojph_params.cpp:2226
ojph::local::param_dfs::exists
bool exists() const
Definition ojph_params_local.h:1003
ojph::local::param_nlt::param_nlt
param_nlt()
Definition ojph_params_local.h:792
ojph::local::param_nlt::BDnlt
ui8 BDnlt
Definition ojph_params_local.h:844
ojph::local::param_nlt::write
bool write(outfile_base *file) const
Definition ojph_params.cpp:1918
ojph::local::param_nlt::add_object
param_nlt * add_object(ui32 comp_num)
Definition ojph_params.cpp:1986
ojph::local::param_nlt::avail
param_nlt * avail
Definition ojph_params_local.h:855
ojph::local::param_nlt::Tnlt
ui8 Tnlt
Definition ojph_params_local.h:845
ojph::local::param_nlt::trim_non_existing_components
void trim_non_existing_components(ui32 num_comps)
Definition ojph_params.cpp:2019
ojph::local::param_nlt::Lnlt
ui16 Lnlt
Definition ojph_params_local.h:842
ojph::local::param_nlt::read
void read(infile_base *file)
Definition ojph_params.cpp:1946
ojph::local::param_nlt::nonlinearity
ojph::param_nlt::nonlinearity nonlinearity
Definition ojph_params_local.h:790
ojph::local::param_nlt::next
param_nlt * next
Definition ojph_params_local.h:847
ojph::local::param_nlt::init
void init()
Definition ojph_params_local.h:814
ojph::local::param_nlt::get_nonlinear_transform
bool get_nonlinear_transform(ui32 comp_num, ui8 &bit_depth, bool &is_signed, ui8 &nl_type) const
Definition ojph_params.cpp:1900
ojph::local::param_nlt::Cnlt
ui16 Cnlt
Definition ojph_params_local.h:843
ojph::local::param_nlt::get_nlt_object
const param_nlt * get_nlt_object(ui32 comp_num) const
Definition ojph_params.cpp:1977
ojph::local::param_nlt::check_validity
void check_validity(param_siz &siz)
Definition ojph_params.cpp:1795
ojph::local::param_nlt::enabled
bool enabled
Definition ojph_params_local.h:846
ojph::local::param_nlt::is_any_enabled
bool is_any_enabled() const
Definition ojph_params.cpp:2009
ojph::local::param_nlt::set_nonlinear_transform
void set_nonlinear_transform(ui32 comp_num, ui8 nl_type)
Definition ojph_params.cpp:1884
ojph::local::param_qcd::encode_SPqcd
ui8 encode_SPqcd(ui8 v) const
Definition ojph_params_local.h:753
ojph::local::param_qcd::u16
ui16 u16[97]
Definition ojph_params_local.h:763
ojph::local::param_qcd::write_qcc
bool write_qcc(outfile_base *file, ui32 num_comps)
Definition ojph_params.cpp:1570
ojph::local::param_qcd::u8
ui8 u8[97]
Definition ojph_params_local.h:762
ojph::local::param_qcd::set_rev_quant
void set_rev_quant(ui32 num_decomps, ui32 bit_depth, bool is_employing_color_transform)
Definition ojph_params.cpp:1279
ojph::local::param_qcd::set_irrev_quant
void set_irrev_quant(ui32 num_decomps)
Definition ojph_params.cpp:1326
ojph::local::param_qcd::get_largest_Kmax
ui32 get_largest_Kmax() const
Definition ojph_params.cpp:1500
ojph::local::param_qcd::get_num_guard_bits
ui32 get_num_guard_bits() const
Definition ojph_params.cpp:1458
ojph::local::param_qcd::get_irrev_delta
float get_irrev_delta(const param_dfs *dfs, ui32 num_decompositions, ui32 resolution, ui32 subband) const
Definition ojph_params.cpp:1403
ojph::local::param_qcd::enabled
bool enabled
Definition ojph_params_local.h:768
ojph::local::param_qcd::set_delta
void set_delta(float delta)
Definition ojph_params_local.h:696
ojph::local::param_qcd::read_qcc
void read_qcc(infile_base *file, ui32 num_comps)
Definition ojph_params.cpp:1691
ojph::local::param_qcd::check_validity
void check_validity(const param_siz &siz, const param_cod &cod)
Definition ojph_params.cpp:1138
ojph::local::param_qcd::write
bool write(outfile_base *file)
Definition ojph_params.cpp:1527
ojph::local::param_qcd::propose_precision
ui32 propose_precision(const param_cod *cod) const
Definition ojph_params.cpp:1433
ojph::local::param_qcd::read
void read(infile_base *file)
Definition ojph_params.cpp:1650
ojph::local::param_qcd::init
void init(param_qcd *top_qcd, ui16 comp_idx)
Definition ojph_params_local.h:718
ojph::local::param_qcd::base_delta
float base_delta
Definition ojph_params_local.h:766
ojph::local::param_qcd::add_qcc_object
param_qcd * add_qcc_object(ui32 comp_idx)
Definition ojph_params.cpp:1769
ojph::local::param_qcd::type
qcd_type type
Definition ojph_params_local.h:757
ojph::local::param_qcd::top_qcd
param_qcd * top_qcd
Definition ojph_params_local.h:770
ojph::local::param_qcd::num_subbands
ui32 num_subbands
Definition ojph_params_local.h:765
ojph::local::param_qcd::QCD_MAIN
@ QCD_MAIN
Definition ojph_params_local.h:674
ojph::local::param_qcd::QCC_MAIN
@ QCC_MAIN
Definition ojph_params_local.h:675
ojph::local::param_qcd::get_MAGB
ui32 get_MAGB() const
Definition ojph_params.cpp:1368
ojph::local::param_qcd::avail
param_qcd * avail
Definition ojph_params_local.h:776
ojph::local::param_qcd::get_Kmax
ui32 get_Kmax(const param_dfs *dfs, ui32 num_decompositions, ui32 resolution, ui32 subband) const
Definition ojph_params.cpp:1464
ojph::local::param_qcd::Lqcd
ui16 Lqcd
Definition ojph_params_local.h:758
ojph::local::param_qcd::comp_idx
ui16 comp_idx
Definition ojph_params_local.h:773
ojph::local::param_qcd::decode_SPqcd
ui8 decode_SPqcd(ui8 v) const
Definition ojph_params_local.h:751
ojph::local::param_qcd::get_qcc
param_qcd * get_qcc(ui32 comp_idx)
Definition ojph_params.cpp:1746
ojph::local::param_qcd::param_qcd
param_qcd(param_qcd *top_qcd=NULL, ui16 comp_idx=OJPH_QCD_DEFAULT)
Definition ojph_params_local.h:681
ojph::local::param_qcd::next
param_qcd * next
Definition ojph_params_local.h:769
ojph::local::param_qcd::OJPH_QCD_DEFAULT
@ OJPH_QCD_DEFAULT
Definition ojph_params_local.h:668
ojph::local::param_qcd::trim_non_existing_components
void trim_non_existing_components(ui32 num_comps)
Definition ojph_params.cpp:1637
ojph::local::param_qcd::internal_write_qcc
bool internal_write_qcc(outfile_base *file, ui32 num_comps)
Definition ojph_params.cpp:1585
ojph::local::param_qcd::SPqcd
union ojph::local::param_qcd::@140013103227173134364232343330020031205064137337 SPqcd
ojph::local::param_qcd::Sqcd
ui8 Sqcd
Definition ojph_params_local.h:759
ojph::local::param_siz
Definition ojph_params_local.h:166
ojph::local::param_siz::skipped_resolutions
ui32 skipped_resolutions
Definition ojph_params_local.h:312
ojph::local::param_siz::cptr
siz_comp_info * cptr
Definition ojph_params_local.h:309
ojph::local::param_siz::YOsiz
ui32 YOsiz
Definition ojph_params_local.h:303
ojph::local::param_siz::YTsiz
ui32 YTsiz
Definition ojph_params_local.h:305
ojph::local::param_siz::get_bit_depth
ui32 get_bit_depth(ui32 comp_num) const
Definition ojph_params_local.h:238
ojph::local::param_siz::ws_kern_support_needed
bool ws_kern_support_needed
Definition ojph_params_local.h:315
ojph::local::param_siz::is_signed
bool is_signed(ui32 comp_num) const
Definition ojph_params_local.h:243
ojph::local::param_siz::XTOsiz
ui32 XTOsiz
Definition ojph_params_local.h:306
ojph::local::param_siz::write
bool write(outfile_base *file)
Definition ojph_params.cpp:639
ojph::local::param_siz::get_num_components
ui16 get_num_components() const
Definition ojph_params_local.h:237
ojph::local::param_siz::cod
const param_cod * cod
Definition ojph_params_local.h:317
ojph::local::param_siz::get_recon_downsampling
point get_recon_downsampling(ui32 comp_num) const
Definition ojph_params.cpp:751
ojph::local::param_siz::set_Rsiz_flag
void set_Rsiz_flag(ui16 flag)
Definition ojph_params_local.h:292
ojph::local::param_siz::XOsiz
ui32 XOsiz
Definition ojph_params_local.h:302
ojph::local::param_siz::Csiz
ui16 Csiz
Definition ojph_params_local.h:308
ojph::local::param_siz::get_recon_size
point get_recon_size(ui32 comp_num) const
Definition ojph_params.cpp:767
ojph::local::param_siz::Xsiz
ui32 Xsiz
Definition ojph_params_local.h:300
ojph::local::param_siz::RSIZ_NLT_FLAG
@ RSIZ_NLT_FLAG
Definition ojph_params_local.h:171
ojph::local::param_siz::RSIZ_EXT_FLAG
@ RSIZ_EXT_FLAG
Definition ojph_params_local.h:173
ojph::local::param_siz::dfs
const param_dfs * dfs
Definition ojph_params_local.h:318
ojph::local::param_siz::dfs_support_needed
bool dfs_support_needed
Definition ojph_params_local.h:316
ojph::local::param_siz::YTOsiz
ui32 YTOsiz
Definition ojph_params_local.h:307
ojph::local::param_siz::Rsiz
ui16 Rsiz
Definition ojph_params_local.h:299
ojph::local::param_siz::Lsiz
ui16 Lsiz
Definition ojph_params_local.h:298
ojph::local::param_siz::XTsiz
ui32 XTsiz
Definition ojph_params_local.h:304
ojph::local::param_siz::read
void read(infile_base *file)
Definition ojph_params.cpp:684
ojph::local::param_siz::Ysiz
ui32 Ysiz
Definition ojph_params_local.h:301
ojph::local::param_siz::set_num_components
void set_num_components(ui32 num_comps)
Definition ojph_params_local.h:197
ojph::local::param_sot::TPsot
ui8 TPsot
Definition ojph_params_local.h:936
ojph::local::param_sot::read
bool read(infile_base *file, bool resilient)
Definition ojph_params.cpp:2087
ojph::local::param_sot::TNsot
ui8 TNsot
Definition ojph_params_local.h:937
ojph::local::param_sot::Lsot
ui16 Lsot
Definition ojph_params_local.h:933
ojph::local::param_sot::write
bool write(outfile_base *file, ui32 payload_len)
Definition ojph_params.cpp:2042
ojph::local::param_sot::Isot
ui16 Isot
Definition ojph_params_local.h:934
ojph::local::param_sot::Psot
ui32 Psot
Definition ojph_params_local.h:935
ojph::local::param_tlm::Ttlm_Ptlm_pair
Definition ojph_params_local.h:950
ojph::local::param_tlm::next_pair_index
ui32 next_pair_index
Definition ojph_params_local.h:968
ojph::local::param_tlm::Ltlm
ui16 Ltlm
Definition ojph_params_local.h:963
ojph::local::param_tlm::set_next_pair
void set_next_pair(ui16 Ttlm, ui32 Ptlm)
Definition ojph_params.cpp:2185
ojph::local::param_tlm::write
bool write(outfile_base *file)
Definition ojph_params.cpp:2194
ojph::local::param_tlm::Ztlm
ui8 Ztlm
Definition ojph_params_local.h:964
ojph::local::param_tlm::pairs
Ttlm_Ptlm_pair * pairs
Definition ojph_params_local.h:966
ojph::local::param_tlm::Stlm
ui8 Stlm
Definition ojph_params_local.h:965
ojph::local::param_tlm::num_pairs
ui32 num_pairs
Definition ojph_params_local.h:967
ojph::local::param_tlm::init
void init(ui32 num_pairs, Ttlm_Ptlm_pair *store)
Definition ojph_params.cpp:2169
ojph::point
Definition ojph_base.h:58
ojph::point::y
ui32 y
Definition ojph_base.h:60
ojph::point::x
ui32 x
Definition ojph_base.h:60
ojph::size
Definition ojph_base.h:48
ojph::size::w
ui32 w
Definition ojph_base.h:50
ojph::size::h
ui32 h
Definition ojph_base.h:51
ojph::local::lifting_step
Definition ojph_params_local.h:1051