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
60 {
61 state->Xsiz = dims.x;
62 state->Ysiz = dims.y;
63 }
64
67 {
68 state->XTsiz = s.w;
69 state->YTsiz = s.h;
70 }
71
74 { // WARNING need to check if these are valid
75 state->XOsiz = offset.x;
76 state->YOsiz = offset.y;
77 }
78
81 { // WARNING need to check if these are valid
82 state->XTOsiz = offset.x;
83 state->YTOsiz = offset.y;
84 }
85
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
101 {
102 return point(state->Xsiz, state->Ysiz);
103 }
104
107 {
108 return point(state->XOsiz, state->YOsiz);
109 }
110
113 {
114 return size(state->XTsiz, state->YTsiz);
115 }
116
119 {
120 return point(state->XTOsiz, state->YTOsiz);
121 }
122
125 {
126 return state->Csiz;
127 }
128
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
143 {
144 return state->get_downsampling(comp_num);
145 }
146
149 {
150 return state->get_recon_width(comp_num);
151 }
152
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
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
262
265 {
266 return state->get_block_dims();
267 }
268
271 {
272 return state->get_log_block_dims();
273 }
274
277 {
278 if (state->SPcod.wavelet_trans <= 1)
280 else {
281 assert(state->atk != NULL);
282 return state->access_atk()->is_reversible();
283 }
284 }
285
288 {
289 return state->get_precinct_size(level_num);
290 }
291
294 {
295 return state->get_log_precinct_size(level_num);
296 }
297
300 {
301 return state->SGCod.prog_order;
302 }
303
306 {
308 return OJPH_PO_STRING_LRCP;
309 else if (state->SGCod.prog_order == OJPH_PO_RLCP)
310 return OJPH_PO_STRING_RLCP;
311 else if (state->SGCod.prog_order == OJPH_PO_RPCL)
312 return OJPH_PO_STRING_RPCL;
313 else if (state->SGCod.prog_order == OJPH_PO_PCRL)
314 return OJPH_PO_STRING_PCRL;
315 else if (state->SGCod.prog_order == OJPH_PO_CPRL)
316 return OJPH_PO_STRING_CPRL;
317 else
318 assert(0);
319 return "";
320 }
321
324 {
325 return state->SGCod.num_layers;
326 }
327
333
336 {
337 return state->packets_may_use_sop();
338 }
339
342 {
343 return state->packets_use_eph();
344 }
345
351
352
354 //
355 //
356 //
357 //
358 //
360
363 {
364 state->set_delta(delta);
365 }
366
368 //
369 //
370 //
371 //
372 //
374
376 void param_nlt::set_type3_transformation(ui32 comp_num, bool enable)
377 {
378 state->set_type3_transformation(comp_num, enable);
379 }
380
383 bool& is_signed)
384 {
385 return state->get_type3_transformation(comp_num, bit_depth, is_signed);
386 }
387
389 //
390 //
391 //
392 //
393 //
395
397 void comment_exchange::set_string(const char* str)
398 {
399 size_t t = strlen(str);
400 if (len > 65531)
401 OJPH_ERROR(0x000500C1,
402 "COM marker string length cannot be larger than 65531");
403 this->data = str;
404 this->len = (ui16)t;
405 this->Rcom = 1;
406 }
407
409 void comment_exchange::set_data(const char* data, ui16 len)
410 {
411 if (len > 65531)
412 OJPH_ERROR(0x000500C2,
413 "COM marker string length cannot be larger than 65531");
414 this->data = data;
415 this->len = len;
416 this->Rcom = 0;
417 }
418
420 //
421 //
422 // LOCAL
423 //
424 //
426
427 namespace local {
428
430 static inline
432 {
433 return (ui16)((t << 8) | (t >> 8));
434 }
435
437 static inline
439 {
440 ui32 u = swap_byte((ui16)(t & 0xFFFFu));
441 u <<= 16;
442 u |= swap_byte((ui16)(t >> 16));
443 return u;
444 }
445
447 static inline
449 {
450 ui64 u = swap_byte((ui32)(t & 0xFFFFFFFFu));
451 u <<= 32;
452 u |= swap_byte((ui32)(t >> 32));
453 return u;
454 }
455
457 //
458 //
459 //
460 //
461 //
463
465 //static
467 {
468 public:
469 static float get_gain_l(ui32 num_decomp, bool reversible)
470 { return reversible ? gain_5x3_l[num_decomp] : gain_9x7_l[num_decomp]; }
471 static float get_gain_h(ui32 num_decomp, bool reversible)
472 { return reversible ? gain_5x3_h[num_decomp] : gain_9x7_h[num_decomp]; }
473
474 private:
475 static const float gain_9x7_l[34];
476 static const float gain_9x7_h[34];
477 static const float gain_5x3_l[34];
478 static const float gain_5x3_h[34];
479 };
480
482 const float sqrt_energy_gains::gain_9x7_l[34] = { 1.0000e+00f,
483 1.4021e+00f, 2.0304e+00f, 2.9012e+00f, 4.1153e+00f, 5.8245e+00f,
484 8.2388e+00f, 1.1652e+01f, 1.6479e+01f, 2.3304e+01f, 3.2957e+01f,
485 4.6609e+01f, 6.5915e+01f, 9.3217e+01f, 1.3183e+02f, 1.8643e+02f,
486 2.6366e+02f, 3.7287e+02f, 5.2732e+02f, 7.4574e+02f, 1.0546e+03f,
487 1.4915e+03f, 2.1093e+03f, 2.9830e+03f, 4.2185e+03f, 5.9659e+03f,
488 8.4371e+03f, 1.1932e+04f, 1.6874e+04f, 2.3864e+04f, 3.3748e+04f,
489 4.7727e+04f, 6.7496e+04f, 9.5454e+04f };
490 const float sqrt_energy_gains::gain_9x7_h[34] = { 1.4425e+00f,
491 1.9669e+00f, 2.8839e+00f, 4.1475e+00f, 5.8946e+00f, 8.3472e+00f,
492 1.1809e+01f, 1.6701e+01f, 2.3620e+01f, 3.3403e+01f, 4.7240e+01f,
493 6.6807e+01f, 9.4479e+01f, 1.3361e+02f, 1.8896e+02f, 2.6723e+02f,
494 3.7792e+02f, 5.3446e+02f, 7.5583e+02f, 1.0689e+03f, 1.5117e+03f,
495 2.1378e+03f, 3.0233e+03f, 4.2756e+03f, 6.0467e+03f, 8.5513e+03f,
496 1.2093e+04f, 1.7103e+04f, 2.4187e+04f, 3.4205e+04f, 4.8373e+04f,
497 6.8410e+04f, 9.6747e+04f, 1.3682e+05f };
498 const float sqrt_energy_gains::gain_5x3_l[34] = { 1.0000e+00f,
499 1.2247e+00f, 1.3229e+00f, 1.5411e+00f, 1.7139e+00f, 1.9605e+00f,
500 2.2044e+00f, 2.5047e+00f, 2.8277e+00f, 3.2049e+00f, 3.6238e+00f,
501 4.1033e+00f, 4.6423e+00f, 5.2548e+00f, 5.9462e+00f, 6.7299e+00f,
502 7.6159e+00f, 8.6193e+00f, 9.7544e+00f, 1.1039e+01f, 1.2493e+01f,
503 1.4139e+01f, 1.6001e+01f, 1.8108e+01f, 2.0493e+01f, 2.3192e+01f,
504 2.6246e+01f, 2.9702e+01f, 3.3614e+01f, 3.8041e+01f, 4.3051e+01f,
505 4.8721e+01f, 5.5138e+01f, 6.2399e+01f };
506 const float sqrt_energy_gains::gain_5x3_h[34] = { 1.0458e+00f,
507 1.3975e+00f, 1.4389e+00f, 1.7287e+00f, 1.8880e+00f, 2.1841e+00f,
508 2.4392e+00f, 2.7830e+00f, 3.1341e+00f, 3.5576e+00f, 4.0188e+00f,
509 4.5532e+00f, 5.1494e+00f, 5.8301e+00f, 6.5963e+00f, 7.4663e+00f,
510 8.4489e+00f, 9.5623e+00f, 1.0821e+01f, 1.2247e+01f, 1.3860e+01f,
511 1.5685e+01f, 1.7751e+01f, 2.0089e+01f, 2.2735e+01f, 2.5729e+01f,
512 2.9117e+01f, 3.2952e+01f, 3.7292e+01f, 4.2203e+01f, 4.7761e+01f,
513 5.4051e+01f, 6.1170e+01f, 6.9226e+01f };
514
516 //static
518 {
519 public:
520 static float get_bibo_gain_l(ui32 num_decomp, bool reversible)
521 { return reversible ? gain_5x3_l[num_decomp] : gain_9x7_l[num_decomp]; }
522 static float get_bibo_gain_h(ui32 num_decomp, bool reversible)
523 { return reversible ? gain_5x3_h[num_decomp] : gain_9x7_h[num_decomp]; }
524
525 private:
526 static const float gain_9x7_l[34];
527 static const float gain_9x7_h[34];
528 static const float gain_5x3_l[34];
529 static const float gain_5x3_h[34];
530 };
531
533 const float bibo_gains::gain_9x7_l[34] = { 1.0000e+00f, 1.3803e+00f,
534 1.3328e+00f, 1.3067e+00f, 1.3028e+00f, 1.3001e+00f, 1.2993e+00f,
535 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
536 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
537 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
538 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
539 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
540 1.2992e+00f, 1.2992e+00f };
541 const float bibo_gains::gain_9x7_h[34] = { 1.2976e+00f, 1.3126e+00f,
542 1.2757e+00f, 1.2352e+00f, 1.2312e+00f, 1.2285e+00f, 1.2280e+00f,
543 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
544 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
545 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
546 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
547 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
548 1.2278e+00f, 1.2278e+00f };
549 const float bibo_gains::gain_5x3_l[34] = { 1.0000e+00f, 1.5000e+00f,
550 1.6250e+00f, 1.6875e+00f, 1.6963e+00f, 1.7067e+00f, 1.7116e+00f,
551 1.7129e+00f, 1.7141e+00f, 1.7145e+00f, 1.7151e+00f, 1.7152e+00f,
552 1.7155e+00f, 1.7155e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
553 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
554 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
555 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
556 1.7156e+00f, 1.7156e+00f };
557 const float bibo_gains::gain_5x3_h[34] = { 2.0000e+00f, 2.5000e+00f,
558 2.7500e+00f, 2.8047e+00f, 2.8198e+00f, 2.8410e+00f, 2.8558e+00f,
559 2.8601e+00f, 2.8628e+00f, 2.8656e+00f, 2.8662e+00f, 2.8667e+00f,
560 2.8669e+00f, 2.8670e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
561 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
562 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
563 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
564 2.8671e+00f, 2.8671e+00f };
565
566
568 //
569 //
570 //
571 //
572 //
574
577 {
578 //marker size excluding header
579 Lsiz = (ui16)(38 + 3 * Csiz);
580
581 ui8 buf[4];
582 bool result = true;
583
584 *(ui16*)buf = JP2K_MARKER::SIZ;
585 *(ui16*)buf = swap_byte(*(ui16*)buf);
586 result &= file->write(&buf, 2) == 2;
587 *(ui16*)buf = swap_byte(Lsiz);
588 result &= file->write(&buf, 2) == 2;
589 *(ui16*)buf = swap_byte(Rsiz);
590 result &= file->write(&buf, 2) == 2;
591 *(ui32*)buf = swap_byte(Xsiz);
592 result &= file->write(&buf, 4) == 4;
593 *(ui32*)buf = swap_byte(Ysiz);
594 result &= file->write(&buf, 4) == 4;
595 *(ui32*)buf = swap_byte(XOsiz);
596 result &= file->write(&buf, 4) == 4;
597 *(ui32*)buf = swap_byte(YOsiz);
598 result &= file->write(&buf, 4) == 4;
599 *(ui32*)buf = swap_byte(XTsiz);
600 result &= file->write(&buf, 4) == 4;
601 *(ui32*)buf = swap_byte(YTsiz);
602 result &= file->write(&buf, 4) == 4;
603 *(ui32*)buf = swap_byte(XTOsiz);
604 result &= file->write(&buf, 4) == 4;
605 *(ui32*)buf = swap_byte(YTOsiz);
606 result &= file->write(&buf, 4) == 4;
607 *(ui16*)buf = swap_byte(Csiz);
608 result &= file->write(&buf, 2) == 2;
609 for (int c = 0; c < Csiz; ++c)
610 {
611 buf[0] = cptr[c].SSiz;
612 buf[1] = cptr[c].XRsiz;
613 buf[2] = cptr[c].YRsiz;
614 result &= file->write(&buf, 3) == 3;
615 }
616
617 return result;
618 }
619
622 {
623 if (file->read(&Lsiz, 2) != 2)
624 OJPH_ERROR(0x00050041, "error reading SIZ marker");
626 int num_comps = (Lsiz - 38) / 3;
627 if (Lsiz != 38 + 3 * num_comps)
628 OJPH_ERROR(0x00050042, "error in SIZ marker length");
629 if (file->read(&Rsiz, 2) != 2)
630 OJPH_ERROR(0x00050043, "error reading SIZ marker");
632 if ((Rsiz & 0x4000) == 0)
633 OJPH_ERROR(0x00050044,
634 "Rsiz bit 14 is not set (this is not a JPH file)");
635 if ((Rsiz & 0x8000) != 0 && (Rsiz & 0xD5F) != 0)
636 OJPH_WARN(0x00050001, "Rsiz in SIZ has unimplemented fields");
637 if (file->read(&Xsiz, 4) != 4)
638 OJPH_ERROR(0x00050045, "error reading SIZ marker");
640 if (file->read(&Ysiz, 4) != 4)
641 OJPH_ERROR(0x00050046, "error reading SIZ marker");
643 if (file->read(&XOsiz, 4) != 4)
644 OJPH_ERROR(0x00050047, "error reading SIZ marker");
646 if (file->read(&YOsiz, 4) != 4)
647 OJPH_ERROR(0x00050048, "error reading SIZ marker");
649 if (file->read(&XTsiz, 4) != 4)
650 OJPH_ERROR(0x00050049, "error reading SIZ marker");
652 if (file->read(&YTsiz, 4) != 4)
653 OJPH_ERROR(0x0005004A, "error reading SIZ marker");
655 if (file->read(&XTOsiz, 4) != 4)
656 OJPH_ERROR(0x0005004B, "error reading SIZ marker");
658 if (file->read(&YTOsiz, 4) != 4)
659 OJPH_ERROR(0x0005004C, "error reading SIZ marker");
661 if (file->read(&Csiz, 2) != 2)
662 OJPH_ERROR(0x0005004D, "error reading SIZ marker");
664 if (Csiz != num_comps)
665 OJPH_ERROR(0x0005004E, "Csiz does not match the SIZ marker size");
666 if (Csiz > old_Csiz)
667 {
668 if (cptr != store)
669 delete[] cptr;
670 cptr = new siz_comp_info[(ui32)num_comps];
671 old_Csiz = Csiz;
672 }
673 for (int c = 0; c < Csiz; ++c)
674 {
675 if (file->read(&cptr[c].SSiz, 1) != 1)
676 OJPH_ERROR(0x00050051, "error reading SIZ marker");
677 if (file->read(&cptr[c].XRsiz, 1) != 1)
678 OJPH_ERROR(0x00050052, "error reading SIZ marker");
679 if (file->read(&cptr[c].YRsiz, 1) != 1)
680 OJPH_ERROR(0x00050053, "error reading SIZ marker");
681 }
682
683 ws_kern_support_needed = (Rsiz & 0x20) != 0;
684 dfs_support_needed = (Rsiz & 0x80) != 0;
685 }
686
689 {
690 assert(comp_num < get_num_components());
691
692 point factor(1u << skipped_resolutions, 1u << skipped_resolutions);
693 const param_cod* cdp = cod->get_cod(comp_num);
694 if (dfs && cdp && cdp->is_dfs_defined()) {
695 const param_dfs* d = dfs->get_dfs(cdp->get_dfs_index());
697 }
698 factor.x *= (ui32)cptr[comp_num].XRsiz;
699 factor.y *= (ui32)cptr[comp_num].YRsiz;
700 return factor;
701 }
702
705 {
706 assert(comp_num < get_num_components());
707
708 point factor = get_recon_downsampling(comp_num);
709 point r;
710 r.x = ojph_div_ceil(Xsiz, factor.x) - ojph_div_ceil(XOsiz, factor.x);
711 r.y = ojph_div_ceil(Ysiz, factor.y) - ojph_div_ceil(YOsiz, factor.y);
712 return r;
713 }
714
715
717 //
718 //
719 //
720 //
721 //
723
726 {
727 //marker size excluding header
728 Lcap = 8;
729
730 char buf[4];
731 bool result = true;
732
733 *(ui16*)buf = JP2K_MARKER::CAP;
734 *(ui16*)buf = swap_byte(*(ui16*)buf);
735 result &= file->write(&buf, 2) == 2;
736 *(ui16*)buf = swap_byte(Lcap);
737 result &= file->write(&buf, 2) == 2;
738 *(ui32*)buf = swap_byte(Pcap);
739 result &= file->write(&buf, 4) == 4;
740
741 *(ui16*)buf = swap_byte(Ccap[0]);
742 result &= file->write(&buf, 2) == 2;
743
744 return result;
745 }
746
749 {
750 if (file->read(&Lcap, 2) != 2)
751 OJPH_ERROR(0x00050061, "error reading CAP marker");
753 if (file->read(&Pcap, 4) != 4)
754 OJPH_ERROR(0x00050062, "error reading CAP marker");
756 ui32 count = population_count(Pcap);
757 if (Pcap & 0xFFFDFFFF)
758 OJPH_ERROR(0x00050063,
759 "error Pcap in CAP has options that are not supported");
760 if ((Pcap & 0x00020000) == 0)
761 OJPH_ERROR(0x00050064,
762 "error Pcap should have its 15th MSB set, Pcap^15. "
763 " This is not a JPH file");
764 for (ui32 i = 0; i < count; ++i)
765 if (file->read(Ccap+i, 2) != 2)
766 OJPH_ERROR(0x00050065, "error reading CAP marker");
767 if (Lcap != 6 + 2 * count)
768 OJPH_ERROR(0x00050066, "error in CAP marker length");
769 }
770
772 //
773 //
774 //
775 //
776 //
778
780 ui32
781 param_cod::propose_precision(const param_siz* siz, ui32 comp_num) const
782 {
783 bool employing_color_transform = is_employing_color_transform() ? 1 : 0;
784 bool reversible = atk->is_reversible();
785
786 ui32 bit_depth = 32;
787 if (reversible) {
788 bit_depth = siz->get_bit_depth(comp_num);
789 bit_depth += comp_num < 3 ? employing_color_transform : 0;
790 // 3 or 4 is how many extra bits are needed for the HH band at the
791 // bottom most level of decomposition.
792 bit_depth += get_num_decompositions() > 5 ? 4 : 3;
793 }
794
795 return bit_depth;
796 }
797
800 {
801 assert(type == COD_MAIN);
802
803 //marker size excluding header
804 Lcod = 12;
805 Lcod = (ui16)(Lcod + (Scod & 1 ? 1 + SPcod.num_decomp : 0));
806
807 ui8 buf[4];
808 bool result = true;
809
810 *(ui16*)buf = JP2K_MARKER::COD;
811 *(ui16*)buf = swap_byte(*(ui16*)buf);
812 result &= file->write(&buf, 2) == 2;
813 *(ui16*)buf = swap_byte(Lcod);
814 result &= file->write(&buf, 2) == 2;
815 *(ui8*)buf = Scod;
816 result &= file->write(&buf, 1) == 1;
817 *(ui8*)buf = SGCod.prog_order;
818 result &= file->write(&buf, 1) == 1;
819 *(ui16*)buf = swap_byte(SGCod.num_layers);
820 result &= file->write(&buf, 2) == 2;
821 *(ui8*)buf = SGCod.mc_trans;
822 result &= file->write(&buf, 1) == 1;
823 buf[0] = SPcod.num_decomp;
824 buf[1] = SPcod.block_width;
825 buf[2] = SPcod.block_height;
826 buf[3] = SPcod.block_style;
827 result &= file->write(&buf, 4) == 4;
828 *(ui8*)buf = SPcod.wavelet_trans;
829 result &= file->write(&buf, 1) == 1;
830 if (Scod & 1)
831 for (int i = 0; i <= SPcod.num_decomp; ++i)
832 {
833 *(ui8*)buf = SPcod.precinct_size[i];
834 result &= file->write(&buf, 1) == 1;
835 }
836
837 return result;
838 }
839
842 {
843 assert(this->type == UNDEFINED);
844 assert(type == COD_MAIN);
845
846 this->type = type;
847 if (file->read(&Lcod, 2) != 2)
848 OJPH_ERROR(0x00050071, "error reading COD segment");
850 if (file->read(&Scod, 1) != 1)
851 OJPH_ERROR(0x00050072, "error reading COD segment");
852 if (file->read(&SGCod.prog_order, 1) != 1)
853 OJPH_ERROR(0x00050073, "error reading COD segment");
854 if (file->read(&SGCod.num_layers, 2) != 2)
855 { OJPH_ERROR(0x00050074, "error reading COD segment"); }
856 else
858 if (file->read(&SGCod.mc_trans, 1) != 1)
859 OJPH_ERROR(0x00050075, "error reading COD segment");
860 if (file->read(&SPcod.num_decomp, 1) != 1)
861 OJPH_ERROR(0x00050076, "error reading COD segment");
862 if (file->read(&SPcod.block_width, 1) != 1)
863 OJPH_ERROR(0x00050077, "error reading COD segment");
864 if (file->read(&SPcod.block_height, 1) != 1)
865 OJPH_ERROR(0x00050078, "error reading COD segment");
866 if (file->read(&SPcod.block_style, 1) != 1)
867 OJPH_ERROR(0x00050079, "error reading COD segment");
868 if (file->read(&SPcod.wavelet_trans, 1) != 1)
869 OJPH_ERROR(0x0005007A, "error reading COD segment");
870 if (Scod & 1)
871 for (int i = 0; i <= SPcod.num_decomp; ++i)
872 if (file->read(&SPcod.precinct_size[i], 1) != 1)
873 OJPH_ERROR(0x0005007B, "error reading COD segment");
874 if (Lcod != 12 + ((Scod & 1) ? 1 + SPcod.num_decomp : 0))
875 OJPH_ERROR(0x0005007C, "error in COD segment length");
876 }
877
880 ui32 num_comps, param_cod *cod)
881 {
882 assert(this->type == UNDEFINED);
883 assert(type == COC_MAIN);
884 assert(cod != NULL);
885
886 this->type = type;
887 this->SGCod = cod->SGCod;
888 this->parent = cod;
889 if (file->read(&Lcod, 2) != 2)
890 OJPH_ERROR(0x00050121, "error reading COC segment");
892 if (num_comps < 257) {
893 ui8 t;
894 if (file->read(&t, 1) != 1)
895 OJPH_ERROR(0x00050122, "error reading COC segment");
896 comp_num = t;
897 }
898 else {
899 if (file->read(&comp_num, 2) != 2)
900 OJPH_ERROR(0x00050123, "error reading COC segment");
902 }
903 if (file->read(&Scod, 1) != 1)
904 OJPH_ERROR(0x00050124, "error reading COC segment");
905 if (Scod & 0xF8)
906 OJPH_WARN(0x00050011,
907 "Unsupported options in Scoc field of the COC segment");
908 if (file->read(&SPcod.num_decomp, 1) != 1)
909 OJPH_ERROR(0x00050125, "error reading COC segment");
910 if (file->read(&SPcod.block_width, 1) != 1)
911 OJPH_ERROR(0x00050126, "error reading COC segment");
912 if (file->read(&SPcod.block_height, 1) != 1)
913 OJPH_ERROR(0x00050127, "error reading COC segment");
914 if (file->read(&SPcod.block_style, 1) != 1)
915 OJPH_ERROR(0x00050128, "error reading COC segment");
916 if (file->read(&SPcod.wavelet_trans, 1) != 1)
917 OJPH_ERROR(0x00050129, "error reading COC segment");
918 if (Scod & 1)
919 for (int i = 0; i <= get_num_decompositions(); ++i)
920 if (file->read(&SPcod.precinct_size[i], 1) != 1)
921 OJPH_ERROR(0x0005012A, "error reading COC segment");
922 ui32 t = 9;
923 t += num_comps < 257 ? 0 : 1;
924 t += (Scod & 1) ? 1 + get_num_decompositions() : 0;
925 if (Lcod != t)
926 OJPH_ERROR(0x0005012B, "error in COC segment length");
927 }
928
931 {
932 this->atk = atk->get_atk(SPcod.wavelet_trans);
933 if (this->atk == NULL)
934 OJPH_ERROR(0x00050131, "A COD/COC segment employs the DWT kernel "
935 "atk=%d, but a corresponding ATK segment cannot be found",
937 }
938
940 //
941 //
942 //
943 //
944 //
946
948 void param_qcd::set_rev_quant(ui32 num_decomps, ui32 bit_depth,
949 bool is_employing_color_transform)
950 {
951 ui32 B = bit_depth;
952 B += is_employing_color_transform ? 1 : 0; //1 bit for RCT
953 int s = 0;
954 double bibo_l = bibo_gains::get_bibo_gain_l(num_decomps, true);
955 ui32 X = (ui32) ceil(log(bibo_l * bibo_l) / M_LN2);
956 u8_SPqcd[s++] = (ui8)(B + X);
957 ui32 max_B_plus_X = (ui32)(B + X);
958 for (ui32 d = num_decomps; d > 0; --d)
959 {
960 double bibo_l = bibo_gains::get_bibo_gain_l(d, true);
961 double bibo_h = bibo_gains::get_bibo_gain_h(d - 1, true);
962 X = (ui32) ceil(log(bibo_h * bibo_l) / M_LN2);
963 u8_SPqcd[s++] = (ui8)(B + X);
964 max_B_plus_X = ojph_max(max_B_plus_X, B + X);
965 u8_SPqcd[s++] = (ui8)(B + X);
966 max_B_plus_X = ojph_max(max_B_plus_X, B + X);
967 X = (ui32) ceil(log(bibo_h * bibo_h) / M_LN2);
968 u8_SPqcd[s++] = (ui8)(B + X);
969 max_B_plus_X = ojph_max(max_B_plus_X, B + X);
970 }
971
972 if (max_B_plus_X > 38)
973 OJPH_ERROR(0x00050151, "The specified combination of bit_depth, "
974 "colour transform, and type of wavelet transform requires more than "
975 "38 bits; it requires %d bits. This is beyond what is allowed in "
976 "the JPEG2000 image coding format.", max_B_plus_X);
977
978 int guard_bits = ojph_max(1, (si32)max_B_plus_X - 31);
979 Sqcd = (ui8)(guard_bits << 5);
980 s = 0;
981 u8_SPqcd[s] = encode_SPqcd((ui8)(u8_SPqcd[s] - guard_bits));
982 s++;
983 for (ui32 d = num_decomps; d > 0; --d)
984 {
985 u8_SPqcd[s] = encode_SPqcd((ui8)(u8_SPqcd[s] - guard_bits));
986 s++;
987 u8_SPqcd[s] = encode_SPqcd((ui8)(u8_SPqcd[s] - guard_bits));
988 s++;
989 u8_SPqcd[s] = encode_SPqcd((ui8)(u8_SPqcd[s] - guard_bits));
990 s++;
991 }
992 }
993
996 {
997 int guard_bits = 1;
998 Sqcd = (ui8)((guard_bits<<5)|0x2);//one guard bit, scalar quantization
999 int s = 0;
1000 float gain_l = sqrt_energy_gains::get_gain_l(num_decomps, false);
1001 float delta_b = base_delta / (gain_l * gain_l);
1002 int exp = 0, mantissa;
1003 while (delta_b < 1.0f)
1004 { exp++; delta_b *= 2.0f; }
1005 //with rounding, there is a risk of becoming equal to 1<<12
1006 // but that should not happen in reality
1007 mantissa = (int)round(delta_b * (float)(1<<11)) - (1<<11);
1008 mantissa = mantissa < (1<<11) ? mantissa : 0x7FF;
1009 u16_SPqcd[s++] = (ui16)((exp << 11) | mantissa);
1010 for (ui32 d = num_decomps; d > 0; --d)
1011 {
1012 float gain_l = sqrt_energy_gains::get_gain_l(d, false);
1013 float gain_h = sqrt_energy_gains::get_gain_h(d - 1, false);
1014
1015 delta_b = base_delta / (gain_l * gain_h);
1016
1017 int exp = 0, mantissa;
1018 while (delta_b < 1.0f)
1019 { exp++; delta_b *= 2.0f; }
1020 mantissa = (int)round(delta_b * (float)(1<<11)) - (1<<11);
1021 mantissa = mantissa < (1<<11) ? mantissa : 0x7FF;
1022 u16_SPqcd[s++] = (ui16)((exp << 11) | mantissa);
1023 u16_SPqcd[s++] = (ui16)((exp << 11) | mantissa);
1024
1025 delta_b = base_delta / (gain_h * gain_h);
1026
1027 exp = 0;
1028 while (delta_b < 1)
1029 { exp++; delta_b *= 2.0f; }
1030 mantissa = (int)round(delta_b * (float)(1<<11)) - (1<<11);
1031 mantissa = mantissa < (1<<11) ? mantissa : 0x7FF;
1032 u16_SPqcd[s++] = (ui16)((exp << 11) | mantissa);
1033 }
1034 }
1035
1038 { //this can be written better, but it is only executed once
1039
1040 // this assumes a bi-directional wavelet (conventional DWT)
1041 ui32 num_decomps = (num_subbands - 1) / 3;
1042
1043 ui32 B = 0;
1044 int irrev = Sqcd & 0x1F;
1045 if (irrev == 0) //reversible
1046 for (ui32 i = 0; i < num_subbands; ++i) {
1047 ui32 t = decode_SPqcd(u8_SPqcd[i]);
1048 t += get_num_guard_bits() - 1u;
1049 B = ojph_max(B, t);
1050 }
1051 else if (irrev == 2) //scalar expounded
1052 for (ui32 i = 0; i < num_subbands; ++i)
1053 {
1054 ui32 nb = num_decomps - (i ? (i - 1) / 3 : 0); //decompsition level
1055 B = ojph_max(B, (u16_SPqcd[i] >> 11) + get_num_guard_bits() - nb);
1056 }
1057 else
1058 assert(0);
1059
1060 return B;
1061 }
1062
1065 ui32 num_decompositions,
1066 ui32 resolution, ui32 subband) const
1067 {
1068 float arr[] = { 1.0f, 2.0f, 2.0f, 4.0f };
1069 assert((Sqcd & 0x1F) == 2);
1070
1071 ui32 idx;
1072 if (dfs != NULL && dfs->exists())
1073 idx = dfs->get_subband_idx(num_decompositions, resolution, subband);
1074 else
1075 idx = resolution ? (resolution - 1) * 3 + subband : 0;
1076 if (idx >= num_subbands) {
1077 OJPH_INFO(0x00050101, "Trying to access quantization step size for "
1078 "subband %d when the QCD/QCC marker segment specifies "
1079 "quantization step sizes for %d subbands only. To continue "
1080 "decoding, we are using the step size for subband %d, which can "
1081 "produce incorrect results",
1082 idx + 1, num_subbands, num_subbands - 1);
1083 idx = num_subbands - 1;
1084 }
1085 int eps = u16_SPqcd[idx] >> 11;
1086 float mantissa;
1087 mantissa = (float)((u16_SPqcd[idx] & 0x7FF) | 0x800) * arr[subband];
1088 mantissa /= (float)(1 << 11);
1089 mantissa /= (float)(1u << eps);
1090 return mantissa;
1091 }
1092
1095 {
1096 return (Sqcd >> 5);
1097 }
1098
1100 ui32 param_qcd::get_Kmax(const param_dfs* dfs, ui32 num_decompositions,
1101 ui32 resolution, ui32 subband) const
1102 {
1103 ui32 num_bits = get_num_guard_bits();
1104 ui32 idx;
1105 if (dfs != NULL && dfs->exists())
1106 idx = dfs->get_subband_idx(num_decompositions, resolution, subband);
1107 else
1108 idx = resolution ? (resolution - 1) * 3 + subband : 0;
1109 if (idx >= num_subbands) {
1110 OJPH_INFO(0x00050111, "Trying to access quantization step size for "
1111 "subband %d when the QCD/QCC marker segment specifies "
1112 "quantization step sizes for %d subbands only. To continue "
1113 "decoding, we are using the step size for subband %d, which can "
1114 "produce incorrect results",
1115 idx + 1, num_subbands, num_subbands - 1);
1116 idx = num_subbands - 1;
1117 }
1118
1119 int irrev = Sqcd & 0x1F;
1120 if (irrev == 0) // reversible; this is (10.22) from the J2K book
1121 {
1122 num_bits += decode_SPqcd(u8_SPqcd[idx]);
1123 num_bits = num_bits == 0 ? 0 : num_bits - 1;
1124 }
1125 else if (irrev == 1)
1126 assert(0);
1127 else if (irrev == 2) //scalar expounded
1128 num_bits += (u16_SPqcd[idx] >> 11) - 1;
1129 else
1130 assert(0);
1131
1132 return num_bits;
1133 }
1134
1137 {
1138 int irrev = Sqcd & 0x1F;
1139
1140 //marker size excluding header
1141 Lqcd = 3;
1142 if (irrev == 0)
1143 Lqcd = (ui16)(Lqcd + num_subbands);
1144 else if (irrev == 2)
1145 Lqcd = (ui16)(Lqcd + 2 * num_subbands);
1146 else
1147 assert(0);
1148
1149 char buf[4];
1150 bool result = true;
1151
1152 *(ui16*)buf = JP2K_MARKER::QCD;
1153 *(ui16*)buf = swap_byte(*(ui16*)buf);
1154 result &= file->write(&buf, 2) == 2;
1155 *(ui16*)buf = swap_byte(Lqcd);
1156 result &= file->write(&buf, 2) == 2;
1157 *(ui8*)buf = Sqcd;
1158 result &= file->write(&buf, 1) == 1;
1159
1160 if (irrev == 0)
1161 for (ui32 i = 0; i < num_subbands; ++i)
1162 {
1163 *(ui8*)buf = u8_SPqcd[i];
1164 result &= file->write(&buf, 1) == 1;
1165 }
1166 else if (irrev == 2)
1167 for (ui32 i = 0; i < num_subbands; ++i)
1168 {
1169 *(ui16*)buf = swap_byte(u16_SPqcd[i]);
1170 result &= file->write(&buf, 2) == 2;
1171 }
1172 else
1173 assert(0);
1174
1175
1176 return result;
1177 }
1180 {
1181 if (file->read(&Lqcd, 2) != 2)
1182 OJPH_ERROR(0x00050081, "error reading QCD marker");
1183 Lqcd = swap_byte(Lqcd);
1184 if (file->read(&Sqcd, 1) != 1)
1185 OJPH_ERROR(0x00050082, "error reading QCD marker");
1186 if ((Sqcd & 0x1F) == 0)
1187 {
1188 num_subbands = (Lqcd - 3);
1189 if (Lqcd != 3 + num_subbands)
1190 OJPH_ERROR(0x00050083, "wrong Lqcd value in QCD marker");
1191 for (ui32 i = 0; i < num_subbands; ++i)
1192 if (file->read(&u8_SPqcd[i], 1) != 1)
1193 OJPH_ERROR(0x00050084, "error reading QCD marker");
1194 }
1195 else if ((Sqcd & 0x1F) == 1)
1196 {
1197 num_subbands = 0;
1198 OJPH_ERROR(0x00050089,
1199 "Scalar derived quantization is not supported yet in QCD marker");
1200 if (Lqcd != 5)
1201 OJPH_ERROR(0x00050085, "wrong Lqcd value in QCD marker");
1202 }
1203 else if ((Sqcd & 0x1F) == 2)
1204 {
1205 num_subbands = (Lqcd - 3) / 2;
1206 if (Lqcd != 3 + 2 * num_subbands)
1207 OJPH_ERROR(0x00050086, "wrong Lqcd value in QCD marker");
1208 for (ui32 i = 0; i < num_subbands; ++i)
1209 {
1210 if (file->read(&u16_SPqcd[i], 2) != 2)
1211 OJPH_ERROR(0x00050087, "error reading QCD marker");
1212 u16_SPqcd[i] = swap_byte(u16_SPqcd[i]);
1213 }
1214 }
1215 else
1216 OJPH_ERROR(0x00050088, "wrong Sqcd value in QCD marker");
1217 }
1218
1220 //
1221 //
1222 //
1223 //
1224 //
1226
1228 void param_qcc::read(infile_base *file, ui32 num_comps)
1229 {
1230 if (file->read(&Lqcd, 2) != 2)
1231 OJPH_ERROR(0x000500A1, "error reading QCC marker");
1232 Lqcd = swap_byte(Lqcd);
1233 if (num_comps < 257)
1234 {
1235 ui8 v;
1236 if (file->read(&v, 1) != 1)
1237 OJPH_ERROR(0x000500A2, "error reading QCC marker");
1238 comp_idx = v;
1239 }
1240 else
1241 {
1242 if (file->read(&comp_idx, 2) != 2)
1243 OJPH_ERROR(0x000500A3, "error reading QCC marker");
1245 }
1246 if (file->read(&Sqcd, 1) != 1)
1247 OJPH_ERROR(0x000500A4, "error reading QCC marker");
1248 ui32 offset = num_comps < 257 ? 4 : 5;
1249 if ((Sqcd & 0x1F) == 0)
1250 {
1251 num_subbands = (Lqcd - offset);
1252 if (Lqcd != offset + num_subbands)
1253 OJPH_ERROR(0x000500A5, "wrong Lqcd value in QCC marker");
1254 for (ui32 i = 0; i < num_subbands; ++i)
1255 if (file->read(&u8_SPqcd[i], 1) != 1)
1256 OJPH_ERROR(0x000500A6, "error reading QCC marker");
1257 }
1258 else if ((Sqcd & 0x1F) == 1)
1259 {
1260 num_subbands = 0;
1261 OJPH_ERROR(0x000500AB,
1262 "Scalar derived quantization is not supported yet in QCC marker");
1263 if (Lqcd != offset)
1264 OJPH_ERROR(0x000500A7, "wrong Lqcc value in QCC marker");
1265 }
1266 else if ((Sqcd & 0x1F) == 2)
1267 {
1268 num_subbands = (Lqcd - offset) / 2;
1269 if (Lqcd != offset + 2 * num_subbands)
1270 OJPH_ERROR(0x000500A8, "wrong Lqcc value in QCC marker");
1271 for (ui32 i = 0; i < num_subbands; ++i)
1272 {
1273 if (file->read(&u16_SPqcd[i], 2) != 2)
1274 OJPH_ERROR(0x000500A9, "error reading QCC marker");
1275 u16_SPqcd[i] = swap_byte(u16_SPqcd[i]);
1276 }
1277 }
1278 else
1279 OJPH_ERROR(0x000500AA, "wrong Sqcc value in QCC marker");
1280 }
1281
1283 //
1284 //
1285 //
1286 //
1287 //
1289
1292 {
1293 if (is_any_enabled() == false)
1294 return;
1295
1296 bool all_same = true;
1297 ui32 num_comps = siz.get_num_components();
1298
1299 // first stage; find out if all components captured by the default
1300 // entry (ALL_COMPS) has the same bit_depth/signedness,
1301 // while doing this, set the BDnlt for components not captured but the
1302 // default entry (ALL_COMPS)
1303 ui32 bit_depth = 0; // unknown yet
1304 bool is_signed = false; // unknown yet
1305 for (ui32 c = 0; c < num_comps; ++c)
1306 {
1307 param_nlt* p = get_comp_object(c);
1308 if (p == NULL || !p->enabled) // comp is not in list or not enabled
1309 {
1310 if (bit_depth == 0)
1311 { // this is the first component which has not type 3 nlt definition
1312 bit_depth = siz.get_bit_depth(c);
1313 is_signed = siz.is_signed(c);
1314 }
1315 else
1316 { // we have seen an undefined component previously
1317 all_same = all_same && (bit_depth == siz.get_bit_depth(c));
1318 all_same = all_same && (is_signed == siz.is_signed(c));
1319 }
1320 }
1321 else
1322 {
1323 p->BDnlt = (ui8)(siz.get_bit_depth(c) - 1);
1324 p->BDnlt = (ui8)(p->BDnlt | (siz.is_signed(c) ? 0x80 : 0));
1325 }
1326 }
1327
1328 // If the default entry is enabled/used, then if the components captured
1329 // by it are not the same, we need to create entries for these
1330 // components
1331 if (this->enabled)
1332 {
1333 if (bit_depth != 0) // default captures some components
1334 {
1335 // captures at least one of the componets in the default entry
1336 this->BDnlt = (ui8)((bit_depth - 1) | (is_signed ? 0x80 : (ui8)0));
1337
1338 if (!all_same)
1339 {
1340 // We cannot use the default for all components in it, so we
1341 // will keep the first one, and we will also define other
1342 // components on their own.
1343
1344 for (ui32 c = 0; c < num_comps; ++c)
1345 {
1346 ui32 bd = siz.get_bit_depth(c);
1347 bool is = siz.is_signed(c);
1348 if (bd != bit_depth || is != is_signed)
1349 {
1350 // this component has different bit_depth/signedness than the
1351 // default (ALL_COMPS) entry
1352 param_nlt* p = get_comp_object(c);
1353 if (p == NULL || !p->enabled)
1354 {
1355 // this component is captured by the default (ALL_COMPS)
1356 // entry (because it is either not in the list, or
1357 // not enabled
1358 if (p == NULL)
1359 p = add_object(c);
1360 p->enabled = true;
1361 p->BDnlt = (ui8)((bd - 1) | (is ? 0x80 : 0));
1362 }
1363 }
1364 }
1365 }
1366 }
1367 else
1368 this->enabled = false;
1369 }
1370
1372
1373 if (is_any_enabled() == false)
1374 return;
1376 }
1377
1379 void param_nlt::set_type3_transformation(ui32 comp_num, bool enable)
1380 {
1381 param_nlt* p = get_comp_object(comp_num);
1382 if (p == NULL)
1383 p = add_object(comp_num);
1384 p->enabled = enable;
1385 }
1386
1389 bool& is_signed) const
1390 {
1391 const param_nlt* p = get_comp_object(comp_num);
1392 p = p ? p : this;
1393 if (p->enabled)
1394 {
1395 bit_depth = (ui8)((p->BDnlt & 0x7F) + 1);
1396 bit_depth = bit_depth <= 38 ? bit_depth : 38;
1397 is_signed = (p->BDnlt & 0x80) == 0x80;
1398 }
1399 return p->enabled;
1400 }
1401
1404 {
1405 if (is_any_enabled() == false)
1406 return true;
1407
1408 char buf[2];
1409 bool result = true;
1410 const param_nlt* p = this;
1411 while (p)
1412 {
1413 if (p->enabled)
1414 {
1415 *(ui16*)buf = JP2K_MARKER::NLT;
1416 *(ui16*)buf = swap_byte(*(ui16*)buf);
1417 result &= file->write(&buf, 2) == 2;
1418 *(ui16*)buf = swap_byte(p->Lnlt);
1419 result &= file->write(&buf, 2) == 2;
1420 *(ui16*)buf = swap_byte(p->Cnlt);
1421 result &= file->write(&buf, 2) == 2;
1422 result &= file->write(&p->BDnlt, 1) == 1;
1423 result &= file->write(&p->Tnlt, 1) == 1;
1424 }
1425 p = p->next;
1426 }
1427 return result;
1428 }
1429
1432 {
1433 ui8 buf[6];
1434
1435 if (file->read(buf, 6) != 6)
1436 OJPH_ERROR(0x00050141, "error reading NLT marker segment");
1437
1438 ui16 length = swap_byte(*(ui16*)buf);
1439 if (length != 6 || buf[5] != 3) // wrong length or type
1440 OJPH_ERROR(0x00050142, "Unsupported NLT type %d\n", buf[5]);
1441
1442 ui16 comp = swap_byte(*(ui16*)(buf + 2));
1443 param_nlt* p = this;
1444 if (comp != special_comp_num::ALL_COMPS)
1445 {
1446 p = get_comp_object(comp);
1447 if (p == NULL)
1448 p = add_object(comp);
1449 }
1450 p->enabled = true;
1451 p->Cnlt = comp;
1452 p->BDnlt = buf[4];
1453 }
1454
1457 {
1458 // cast object to constant
1459 const param_nlt* const_p = const_cast<const param_nlt*>(this);
1460 // call using the constant object, then cast to non-const
1461 return const_cast<param_nlt*>(const_p->get_comp_object(comp_num));
1462 }
1463
1466 {
1467 if (Cnlt == comp_num)
1468 return this;
1469 else {
1470 param_nlt* p = next;
1471 while (p && p->Cnlt != comp_num)
1472 p = p->next;
1473 return p;
1474 }
1475 }
1476
1479 {
1480 assert(Cnlt != comp_num);
1481 param_nlt* p = this;
1482 while (p->next != NULL) {
1483 assert(p->Cnlt != comp_num);
1484 p = p->next;
1485 }
1486 p->next = new param_nlt;
1487 p->alloced_next = true;
1488 p = p->next;
1489 p->Cnlt = (ui16)comp_num;
1490 return p;
1491 }
1492
1495 {
1496 // check if any field is enabled
1497 const param_nlt* p = this;
1498 while (p && p->enabled == false)
1499 p = p->next;
1500 return (p != NULL);
1501 }
1502
1505 {
1506 param_nlt* p = this->next;
1507 while (p) {
1508 if (p->enabled == true && p->Cnlt >= num_comps)
1509 p->enabled = false;
1510 p = p->next;
1511 }
1512 }
1513
1514
1516 //
1517 //
1518 //
1519 //
1520 //
1522
1524 bool param_sot::write(outfile_base *file, ui32 payload_len)
1525 {
1526 char buf[4];
1527 bool result = true;
1528
1529 this->Psot = payload_len + 14; //inc. SOT marker, field & SOD
1530
1531 *(ui16*)buf = JP2K_MARKER::SOT;
1532 *(ui16*)buf = swap_byte(*(ui16*)buf);
1533 result &= file->write(&buf, 2) == 2;
1534 *(ui16*)buf = swap_byte(Lsot);
1535 result &= file->write(&buf, 2) == 2;
1536 *(ui16*)buf = swap_byte(Isot);
1537 result &= file->write(&buf, 2) == 2;
1538 *(ui32*)buf = swap_byte(Psot);
1539 result &= file->write(&buf, 4) == 4;
1540 result &= file->write(&TPsot, 1) == 1;
1541 result &= file->write(&TNsot, 1) == 1;
1542
1543 return result;
1544 }
1545
1547 bool param_sot::write(outfile_base *file, ui32 payload_len,
1548 ui8 TPsot, ui8 TNsot)
1549 {
1550 char buf[4];
1551 bool result = true;
1552
1553 *(ui16*)buf = JP2K_MARKER::SOT;
1554 *(ui16*)buf = swap_byte(*(ui16*)buf);
1555 result &= file->write(&buf, 2) == 2;
1556 *(ui16*)buf = swap_byte(Lsot);
1557 result &= file->write(&buf, 2) == 2;
1558 *(ui16*)buf = swap_byte(Isot);
1559 result &= file->write(&buf, 2) == 2;
1560 *(ui32*)buf = swap_byte(payload_len + 14);
1561 result &= file->write(&buf, 4) == 4;
1562 result &= file->write(&TPsot, 1) == 1;
1563 result &= file->write(&TNsot, 1) == 1;
1564
1565 return result;
1566 }
1567
1569 bool param_sot::read(infile_base *file, bool resilient)
1570 {
1571 if (resilient)
1572 {
1573 if (file->read(&Lsot, 2) != 2)
1574 {
1575 OJPH_INFO(0x00050091, "error reading SOT marker");
1576 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
1577 return false;
1578 }
1579 Lsot = swap_byte(Lsot);
1580 if (Lsot != 10)
1581 {
1582 OJPH_INFO(0x00050092, "error in SOT length");
1583 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
1584 return false;
1585 }
1586 if (file->read(&Isot, 2) != 2)
1587 {
1588 OJPH_INFO(0x00050093, "error reading tile index");
1589 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
1590 return false;
1591 }
1592 Isot = swap_byte(Isot);
1593 if (Isot == 0xFFFF)
1594 {
1595 OJPH_INFO(0x00050094, "tile index in SOT marker cannot be 0xFFFF");
1596 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
1597 return false;
1598 }
1599 if (file->read(&Psot, 4) != 4)
1600 {
1601 OJPH_INFO(0x00050095, "error reading SOT marker");
1602 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
1603 return false;
1604 }
1605 Psot = swap_byte(Psot);
1606 if (file->read(&TPsot, 1) != 1)
1607 {
1608 OJPH_INFO(0x00050096, "error reading SOT marker");
1609 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
1610 return false;
1611 }
1612 if (file->read(&TNsot, 1) != 1)
1613 {
1614 OJPH_INFO(0x00050097, "error reading SOT marker");
1615 Lsot = 0; Isot = 0; Psot = 0; TPsot = 0; TNsot = 0;
1616 return false;
1617 }
1618 }
1619 else
1620 {
1621 if (file->read(&Lsot, 2) != 2)
1622 OJPH_ERROR(0x00050091, "error reading SOT marker");
1623 Lsot = swap_byte(Lsot);
1624 if (Lsot != 10)
1625 OJPH_ERROR(0x00050092, "error in SOT length");
1626 if (file->read(&Isot, 2) != 2)
1627 OJPH_ERROR(0x00050093, "error reading SOT tile index");
1628 Isot = swap_byte(Isot);
1629 if (Isot == 0xFFFF)
1630 OJPH_ERROR(0x00050094, "tile index in SOT marker cannot be 0xFFFF");
1631 if (file->read(&Psot, 4) != 4)
1632 OJPH_ERROR(0x00050095, "error reading SOT marker");
1633 Psot = swap_byte(Psot);
1634 if (file->read(&TPsot, 1) != 1)
1635 OJPH_ERROR(0x00050096, "error reading SOT marker");
1636 if (file->read(&TNsot, 1) != 1)
1637 OJPH_ERROR(0x00050097, "error reading SOT marker");
1638 }
1639 return true;
1640 }
1641
1643 //
1644 //
1645 //
1646 //
1647 //
1649
1651 void param_tlm::init(ui32 num_pairs, Ttlm_Ptlm_pair *store)
1652 {
1653 if (4 + 6 * num_pairs > 65535)
1654 OJPH_ERROR(0x000500B1, "Trying to allocate more than 65535 bytes for "
1655 "a TLM marker; this can be resolved by having more than "
1656 "one TLM marker, but the code does not support this. "
1657 "In any case, this limit means that we have 10922 "
1658 "tileparts or more, which is a huge number.");
1659 this->num_pairs = num_pairs;
1660 pairs = store;
1661 Ltlm = (ui16)(4 + 6 * num_pairs);
1662 Ztlm = 0;
1663 Stlm = 0x60;
1664 }
1665
1668 {
1669 assert(next_pair_index < num_pairs);
1670 pairs[next_pair_index].Ttlm = Ttlm;
1671 pairs[next_pair_index].Ptlm = Ptlm + 14;
1673 }
1674
1677 {
1678 assert(next_pair_index == num_pairs);
1679 char buf[4];
1680 bool result = true;
1681
1682 *(ui16*)buf = JP2K_MARKER::TLM;
1683 *(ui16*)buf = swap_byte(*(ui16*)buf);
1684 result &= file->write(&buf, 2) == 2;
1685 *(ui16*)buf = swap_byte(Ltlm);
1686 result &= file->write(&buf, 2) == 2;
1687 result &= file->write(&Ztlm, 1) == 1;
1688 result &= file->write(&Stlm, 1) == 1;
1689 for (ui32 i = 0; i < num_pairs; ++i)
1690 {
1691 *(ui16*)buf = swap_byte(pairs[i].Ttlm);
1692 result &= file->write(&buf, 2) == 2;
1693 *(ui32*)buf = swap_byte(pairs[i].Ptlm);
1694 result &= file->write(&buf, 4) == 4;
1695 }
1696 return result;
1697 }
1698
1700 //
1701 //
1702 //
1703 //
1704 //
1706
1708 const param_dfs* param_dfs::get_dfs(int index) const
1709 {
1710 const param_dfs* p = this;
1711 while (p && p->Sdfs != index)
1712 p = p->next;
1713 return p;
1714 }
1715
1718 {
1719 decomp_level = ojph_min(decomp_level, Ids);
1720 ui32 d = decomp_level - 1; // decomp_level starts from 1
1721 ui32 idx = d >> 2; // complete bytes
1722 ui32 bits = d & 0x3; // bit within the bytes
1723 ui32 val = (Ddfs[idx] >> (6 - 2 * bits)) & 0x3;
1724 return (dfs_dwt_type)val;
1725 }
1726
1729 ui32 subband) const
1730 {
1731 assert((resolution == 0 && subband == 0) ||
1732 (resolution > 0 && subband > 0 && subband < 4));
1733
1734 ui32 ns[4] = { 0, 3, 1, 1 };
1735
1736 ui32 idx = 0;
1737 if (resolution > 0)
1738 {
1739 idx = 0;
1740 ui32 i = 1;
1741 for (; i < resolution; ++i)
1742 idx += ns[get_dwt_type(num_decompositions - i + 1)];
1743 dfs_dwt_type t = get_dwt_type(num_decompositions - i + 1);
1744 idx += subband;
1745 if (t == VERT_DWT && subband == 2)
1746 --idx;
1747 }
1748
1749 return idx;
1750 }
1751
1753 point param_dfs::get_res_downsamp(ui32 skipped_resolutions) const
1754 {
1755 point factor(1, 1);
1756 ui32 decomp_level = 1;
1757 while (skipped_resolutions > 0)
1758 {
1759 param_dfs::dfs_dwt_type type = get_dwt_type(decomp_level);
1760 if (type == BIDIR_DWT)
1761 { factor.x *= 2; factor.y *= 2; }
1762 else if (type == HORZ_DWT)
1763 factor.x *= 2;
1764 else if (type == VERT_DWT)
1765 factor.y *= 2;
1766
1767 ++decomp_level;
1768 --skipped_resolutions;
1769 }
1770 return factor;
1771 }
1772
1775 {
1776 if (Ldfs != 0) { // this param_dfs is used
1777 param_dfs* p = this;
1778 while (p->next != NULL)
1779 p = p->next;
1780 p->next = new param_dfs;
1781 p = p->next;
1782 return p->read(file);
1783 }
1784
1785 if (file->read(&Ldfs, 2) != 2)
1786 OJPH_ERROR(0x000500D1, "error reading DFS-Ldfs parameter");
1787 Ldfs = swap_byte(Ldfs);
1788 if (file->read(&Sdfs, 2) != 2)
1789 OJPH_ERROR(0x000500D2, "error reading DFS-Sdfs parameter");
1790 Sdfs = swap_byte(Sdfs);
1791 if (Sdfs > 15)
1792 OJPH_ERROR(0x000500D3, "The DFS-Sdfs parameter is %d, which is "
1793 "larger than the permissible 15", Sdfs);
1794 ui8 t, l_Ids = 0;
1795 if (file->read(&l_Ids, 1) != 1)
1796 OJPH_ERROR(0x000500D4, "error reading DFS-Ids parameter");
1797 constexpr int max_Ddfs = sizeof(Ddfs) * 4;
1798 if (l_Ids > max_Ddfs)
1799 OJPH_INFO(0x000500D5, "The DFS-Ids parameter is %d; while this is "
1800 "valid, the number is unnessarily large -- you do not need more "
1801 "than %d. Please contact me regarding this issue.",
1802 l_Ids, max_Ddfs);
1803 Ids = l_Ids < max_Ddfs ? l_Ids : max_Ddfs;
1804 for (int i = 0; i < Ids; i += 4)
1805 if (file->read(&Ddfs[i / 4], 1) != 1)
1806 OJPH_ERROR(0x000500D6, "error reading DFS-Ddfs parameters");
1807 for (int i = Ids; i < l_Ids; i += 4)
1808 if (file->read(&t, 1) != 1)
1809 OJPH_ERROR(0x000500D7, "error reading DFS-Ddfs parameters");
1810 return true;
1811 }
1812
1814 //
1815 //
1816 //
1817 //
1818 //
1820
1822 const param_atk* param_atk::get_atk(int index) const
1823 {
1824 const param_atk* p = this;
1825 while (p && p->get_index() != index)
1826 p = p->next;
1827 return p;
1828 }
1829
1832 {
1833 int coeff_type = get_coeff_type();
1834 if (coeff_type == 0) { // 8bit
1835 ui8 v;
1836 if (file->read(&v, 1) != 1) return false;
1837 K = v;
1838 }
1839 else if (coeff_type == 1) { // 16bit
1840 ui16 v;
1841 if (file->read(&v, 2) != 2) return false;
1842 K = swap_byte(v);
1843 }
1844 else if (coeff_type == 2) { // float
1845 union {
1846 float f;
1847 ui32 i;
1848 } v;
1849 if (file->read(&v.i, 4) != 4) return false;
1850 v.i = swap_byte(v.i);
1851 K = v.f;
1852 }
1853 else if (coeff_type == 3) { // double
1854 union {
1855 double d;
1856 ui64 i;
1857 } v;
1858 if (file->read(&v.i, 8) != 8) return false;
1859 v.i = swap_byte(v.i);
1860 K = (float)v.d;
1861 }
1862 else if (coeff_type == 4) { // 128 bit float
1863 ui64 v, v1;
1864 if (file->read(&v, 8) != 8) return false;
1865 if (file->read(&v1, 8) != 8) return false; // v1 not needed
1866 v = swap_byte(v);
1867
1868 union {
1869 float f;
1870 ui32 i;
1871 } s;
1872 // convert the MSB of 128b float to 32b float
1873 // 32b float has 1 sign bit, 8 exponent (offset 127), 23 mantissa
1874 // 128b float has 1 sign bit, 15 exponent (offset 16383), 112 mantissa
1875 si32 e = (si32)((v >> 48) & 0x7FFF); // exponent
1876 e -= 16383;
1877 e += 127;
1878 e = e & 0xFF; // removes MSBs if negative
1879 e <<= 23; // move bits to their location
1880 s.i = 0;
1881 s.i |= ((ui32)(v >> 32) & 0x80000000); // copy sign bit
1882 s.i |= (ui32)e; // copy exponent
1883 s.i |= (ui32)((v >> 25) & 0x007FFFFF); // copy 23 mantissa
1884 K = s.f;
1885 }
1886 return true;
1887 }
1888
1889
1892 {
1893 int coeff_type = get_coeff_type();
1894 if (coeff_type == 0) {
1895 si8 v;
1896 if (file->read(&v, 1) != 1) return false;
1897 K = v;
1898 }
1899 else if (coeff_type == 1) {
1900 si16 v;
1901 if (file->read(&v, 2) != 2) return false;
1902 K = (si16)swap_byte((ui16)v);
1903 }
1904 else
1905 return false;
1906 return true;
1907 }
1908
1911 {
1912 if (Latk != 0) { // this param_atk is used
1913 param_atk *p = this;
1914 while (p->next != NULL)
1915 p = p->next;
1916 p->next = new param_atk;
1917 p->alloced_next = true;
1918 p = p->next;
1919 return p->read(file);
1920 }
1921
1922 if (file->read(&Latk, 2) != 2)
1923 OJPH_ERROR(0x000500E1, "error reading ATK-Latk parameter");
1924 Latk = swap_byte(Latk);
1925 if (file->read(&Satk, 2) != 2)
1926 OJPH_ERROR(0x000500E2, "error reading ATK-Satk parameter");
1927 Satk = swap_byte(Satk);
1928 if (is_m_init0() == false) // only even-indexed is supported
1929 OJPH_ERROR(0x000500E3, "ATK-Satk parameter sets m_init to 1, "
1930 "requiring odd-indexed subsequence in first reconstruction step, "
1931 "which is not supported yet.");
1932 if (is_whole_sample() == false) // ARB filter not supported
1933 OJPH_ERROR(0x000500E4, "ATK-Satk parameter specified ARB filter, "
1934 "which is not supported yet.");
1935 if (is_reversible() && get_coeff_type() >= 2) // reversible & float
1936 OJPH_ERROR(0x000500E5, "ATK-Satk parameter does not make sense. "
1937 "It employs floats with reversible filtering.");
1938 if (is_using_ws_extension() == false) // only sym. ext is supported
1939 OJPH_ERROR(0x000500E6, "ATK-Satk parameter requires constant "
1940 "boundary extension, which is not supported yet.");
1941 if (is_reversible() == false)
1942 if (read_coefficient(file, Katk) == false)
1943 OJPH_ERROR(0x000500E7, "error reading ATK-Katk parameter");
1944 if (file->read(&Natk, 1) != 1)
1945 OJPH_ERROR(0x000500E8, "error reading ATK-Natk parameter");
1946 if (Natk > max_steps) {
1947 if (d != d_store) // was this allocated -- very unlikely
1948 delete[] d;
1949 d = new lifting_step[Natk];
1950 max_steps = Natk;
1951 }
1952
1953 if (is_reversible())
1954 {
1955 for (int s = 0; s < Natk; ++s)
1956 {
1957 if (file->read(&d[s].rev.Eatk, 1) != 1)
1958 OJPH_ERROR(0x000500E9, "error reading ATK-Eatk parameter");
1959 if (file->read(&d[s].rev.Batk, 2) != 2)
1960 OJPH_ERROR(0x000500EA, "error reading ATK-Batk parameter");
1961 d[s].rev.Batk = (si16)swap_byte((ui16)d[s].rev.Batk);
1962 ui8 LCatk;
1963 if (file->read(&LCatk, 1) != 1)
1964 OJPH_ERROR(0x000500EB, "error reading ATK-LCatk parameter");
1965 if (LCatk == 0)
1966 OJPH_ERROR(0x000500EC, "Encountered a ATK-LCatk value of zero; "
1967 "something is wrong.");
1968 if (LCatk > 1)
1969 OJPH_ERROR(0x000500ED, "ATK-LCatk value greater than 1; "
1970 "that is, a multitap filter is not supported");
1971 if (read_coefficient(file, d[s].rev.Aatk) == false)
1972 OJPH_ERROR(0x000500EE, "Error reding ATK-Aatk parameter");
1973 }
1974 }
1975 else
1976 {
1977 for (int s = 0; s < Natk; ++s)
1978 {
1979 ui8 LCatk;
1980 if (file->read(&LCatk, 1) != 1)
1981 OJPH_ERROR(0x000500EF, "error reading ATK-LCatk parameter");
1982 if (LCatk == 0)
1983 OJPH_ERROR(0x000500F0, "Encountered a ATK-LCatk value of zero; "
1984 "something is wrong.");
1985 if (LCatk > 1)
1986 OJPH_ERROR(0x000500F1, "ATK-LCatk value greater than 1; "
1987 "that is, a multitap filter is not supported.");
1988 if (read_coefficient(file, d[s].irv.Aatk) == false)
1989 OJPH_ERROR(0x000500F2, "Error reding ATK-Aatk parameter");
1990 }
1991 }
1992
1993 return true;
1994 }
1995
1998 {
1999 Satk = 0x4a00; // illegal because ATK = 0
2000 Katk = (float)1.230174104914001;
2001 Natk = 4;
2002 // next is (A-4) in T.801 second line
2003 Latk = (ui16)(5 + Natk + sizeof(float) * (1 + Natk));
2004 d[0].irv.Aatk = (float)0.443506852043971;
2005 d[1].irv.Aatk = (float)0.882911075530934;
2006 d[2].irv.Aatk = (float)-0.052980118572961;
2007 d[3].irv.Aatk = (float)-1.586134342059924;
2008 }
2009
2012 {
2013 Satk = 0x5801; // illegal because ATK = 1
2014 Natk = 2;
2015 // next is (A-4) in T.801 fourth line
2016 Latk = (ui16)(5 + 2 * Natk + sizeof(ui8) * (Natk + Natk));
2017 d[0].rev.Aatk = 1;
2018 d[0].rev.Batk = 2;
2019 d[0].rev.Eatk = 2;
2020 d[1].rev.Aatk = -1;
2021 d[1].rev.Batk = 1;
2022 d[1].rev.Eatk = 1;
2023 }
2024
2025 } // !local namespace
2026} // !ojph namespace
void set_string(const char *str)
void set_data(const char *data, ui16 len)
virtual size_t read(void *ptr, size_t size)=0
static const float gain_5x3_l[34]
static float get_bibo_gain_l(ui32 num_decomp, bool reversible)
static const float gain_5x3_h[34]
static float get_bibo_gain_h(ui32 num_decomp, bool reversible)
static const float gain_9x7_h[34]
static const float gain_9x7_l[34]
static const float gain_5x3_l[34]
static const float gain_5x3_h[34]
static float get_gain_l(ui32 num_decomp, bool reversible)
static const float gain_9x7_l[34]
static float get_gain_h(ui32 num_decomp, bool reversible)
static const float gain_9x7_h[34]
virtual size_t write(const void *ptr, size_t size)=0
size get_block_dims() const
int get_progression_order() const
bool is_using_color_transform() const
void set_num_decomposition(ui32 num_decompositions)
ui32 get_num_decompositions() const
size get_log_block_dims() const
bool packets_may_use_sop() const
size get_precinct_size(ui32 level_num) const
const char * get_progression_order_as_string() const
void set_precinct_size(int num_levels, size *precinct_size)
bool packets_use_eph() const
local::param_cod * state
bool is_reversible() const
void set_progression_order(const char *name)
bool get_block_vertical_causality() const
void set_block_dims(ui32 width, ui32 height)
size get_log_precinct_size(ui32 level_num) const
int get_num_layers() const
void set_color_transform(bool color_transform)
void set_reversible(bool reversible)
void set_type3_transformation(ui32 comp_num, bool enable)
enables or disables type 3 nonlinearity for a component or the default setting
bool get_type3_transformation(ui32 comp_num, ui8 &bit_depth, bool &is_signed)
get the state (enabled or disabled) of type 3 nonlinearity for a component or the default setting
local::param_nlt * state
void set_irrev_quant(float delta)
local::param_qcd * state
void set_tile_size(size s)
point get_image_extent() const
void set_component(ui32 comp_num, const point &downsampling, ui32 bit_depth, bool is_signed)
void set_num_components(ui32 num_comps)
ui32 get_bit_depth(ui32 comp_num) const
void set_tile_offset(point offset)
point get_image_offset() const
local::param_siz * state
Definition ojph_params.h:89
void set_image_offset(point offset)
size get_tile_size() const
ui32 get_recon_height(ui32 comp_num) const
point get_downsampling(ui32 comp_num) const
void set_image_extent(point extent)
point get_tile_offset() const
ui32 get_recon_width(ui32 comp_num) const
bool is_signed(ui32 comp_num) const
ui32 get_num_components() const
static ui16 swap_byte(ui16 t)
const char OJPH_PO_STRING_PCRL[]
int8_t si8
Definition ojph_defs.h:51
uint64_t ui64
Definition ojph_defs.h:56
uint16_t ui16
Definition ojph_defs.h:52
static ui32 population_count(ui32 val)
Definition ojph_arch.h:152
const char OJPH_PO_STRING_RLCP[]
const char OJPH_PO_STRING_RPCL[]
const char OJPH_PO_STRING_CPRL[]
static ui32 count_leading_zeros(ui32 val)
Definition ojph_arch.h:199
int32_t si32
Definition ojph_defs.h:55
int16_t si16
Definition ojph_defs.h:53
uint32_t ui32
Definition ojph_defs.h:54
uint8_t ui8
Definition ojph_defs.h:50
const char OJPH_PO_STRING_LRCP[]
#define ojph_max(a, b)
Definition ojph_defs.h:73
#define ojph_div_ceil(a, b)
Definition ojph_defs.h:70
#define ojph_min(a, b)
Definition ojph_defs.h:76
#define OJPH_INFO(t,...)
MACROs to insert file and line number for info, warning, and error.
#define OJPH_ERROR(t,...)
#define OJPH_WARN(t,...)
const param_atk * get_atk(int index) const
bool read(infile_base *file)
bool read_coefficient(infile_base *file, float &K)
void read(infile_base *file)
bool write(outfile_base *file)
bool write(outfile_base *file)
void set_reversible(bool reversible)
const param_cod * get_cod(ui32 comp_num) const
bool is_employing_color_transform() const
void employ_color_transform(ui8 val)
const param_atk * access_atk() const
size get_log_precinct_size(ui32 res_num) const
void read(infile_base *file, cod_type type)
void update_atk(const param_atk *atk)
size get_precinct_size(ui32 res_num) const
ui32 propose_precision(const param_siz *siz, ui32 comp_num) const
bool read(infile_base *file)
dfs_dwt_type get_dwt_type(ui32 decomp_level) const
point get_res_downsamp(ui32 skipped_resolutions) const
ui32 get_subband_idx(ui32 num_decompositions, ui32 resolution, ui32 subband) const
const param_dfs * get_dfs(int index) const
void set_type3_transformation(ui32 comp_num, bool enable)
bool get_type3_transformation(ui32 comp_num, ui8 &bit_depth, bool &is_signed) const
bool write(outfile_base *file) const
param_nlt * add_object(ui32 comp_num)
void trim_non_existing_components(ui32 num_comps)
void read(infile_base *file)
const param_nlt * get_comp_object(ui32 comp_num) const
void check_validity(param_siz &siz)
void read(infile_base *file, ui32 num_comps)
float irrev_get_delta(const param_dfs *dfs, ui32 num_decompositions, ui32 resolution, ui32 subband) const
ui8 encode_SPqcd(ui8 v) const
void set_rev_quant(ui32 num_decomps, ui32 bit_depth, bool is_employing_color_transform)
void set_irrev_quant(ui32 num_decomps)
ui32 get_num_guard_bits() const
void set_delta(float delta)
bool write(outfile_base *file)
void read(infile_base *file)
ui32 get_Kmax(const param_dfs *dfs, ui32 num_decompositions, ui32 resolution, ui32 subband) const
ui8 decode_SPqcd(ui8 v) const
ui32 get_bit_depth(ui32 comp_num) const
ui32 get_recon_height(ui32 comp_num) const
bool is_signed(ui32 comp_num) const
bool write(outfile_base *file)
point get_recon_downsampling(ui32 comp_num) const
void set_Rsiz_flag(ui16 flag)
point get_recon_size(ui32 comp_num) const
void set_comp_info(ui32 comp_num, const point &downsampling, ui32 bit_depth, bool is_signed)
point get_downsampling(ui32 comp_num) const
void read(infile_base *file)
void set_num_components(ui32 num_comps)
ui32 get_recon_width(ui32 comp_num) const
bool read(infile_base *file, bool resilient)
bool write(outfile_base *file, ui32 payload_len)
void set_next_pair(ui16 Ttlm, ui32 Ptlm)
bool write(outfile_base *file)
void init(ui32 num_pairs, Ttlm_Ptlm_pair *store)