OpenJPH
Open-source implementation of JPEG2000 Part-15
ojph_params_local.h
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_local.h
34// Author: Aous Naman
35// Date: 28 August 2019
36//***************************************************************************/
37
38
39#ifndef OJPH_PARAMS_LOCAL_H
40#define OJPH_PARAMS_LOCAL_H
41
42#include <cstring>
43#include <cassert>
44
45#include "ojph_defs.h"
46#include "ojph_base.h"
47#include "ojph_arch.h"
48#include "ojph_message.h"
49
50namespace ojph {
51
53 class outfile_base;
54 class infile_base;
55
58 {
63 OJPH_PO_CPRL = 4
64 };
65
67 const char OJPH_PO_STRING_LRCP[] = "LRCP";
68 const char OJPH_PO_STRING_RLCP[] = "RLCP";
69 const char OJPH_PO_STRING_RPCL[] = "RPCL";
70 const char OJPH_PO_STRING_PCRL[] = "PCRL";
71 const char OJPH_PO_STRING_CPRL[] = "CPRL";
72
75 {
84 OJPH_PN_IMF = 8
85 };
86
88 const char OJPH_PN_STRING_PROFILE0[] = "PROFILE0";
89 const char OJPH_PN_STRING_PROFILE1[] = "PROFILE1";
90 const char OJPH_PN_STRING_CINEMA2K[] = "CINEMA2K";
91 const char OJPH_PN_STRING_CINEMA4K[] = "CINEMA4K";
92 const char OJPH_PN_STRING_CINEMAS2K[] = "CINEMAS2K";
93 const char OJPH_PN_STRING_CINEMAS4K[] = "CINEMAS4K";
94 const char OJPH_PN_STRING_BROADCAST[] = "BROADCAST";
95 const char OJPH_PN_STRING_IMF[] = "IMF";
96
99 OJPH_TILEPART_NO_DIVISIONS = 0x0, // no divisions to tile parts
102 OJPH_TILEPART_LAYERS = 0x4, // these are meaningless with HTJ2K
103 OJPH_TILEPART_MASK = 0x3, // mask used for testing
104 };
105
106 namespace local {
107
108 //defined here
109 struct param_siz;
110 struct param_cod;
111 struct param_qcd;
112 struct param_cap;
113 struct param_sot;
114 struct param_tlm;
115 struct param_dfs;
116 struct param_atk;
117
120 {
121 SOC = 0xFF4F, //start of codestream (required)
122 CAP = 0xFF50, //extended capability
123 SIZ = 0xFF51, //image and tile size (required)
124 COD = 0xFF52, //coding style default (required)
125 COC = 0xFF53, //coding style component
126 TLM = 0xFF55, //tile-part lengths
127 PRF = 0xFF56, //profile
128 PLM = 0xFF57, //packet length, main header
129 PLT = 0xFF58, //packet length, tile-part header
130 CPF = 0xFF59, //corresponding profile values
131 QCD = 0xFF5C, //qunatization default (required)
132 QCC = 0xFF5D, //quantization component
133 RGN = 0xFF5E, //region of interest
134 POC = 0xFF5F, //progression order change
135 PPM = 0xFF60, //packed packet headers, main header
136 PPT = 0xFF61, //packed packet headers, tile-part header
137 CRG = 0xFF63, //component registration
138 COM = 0xFF64, //comment
139 DFS = 0xFF72, //downsampling factor styles
140 ADS = 0xFF73, //arbitrary decomposition styles
141 NLT = 0xFF76, //non-linearity point transformation
142 ATK = 0xFF79, //arbitrary transformation kernels
143 SOT = 0xFF90, //start of tile-part
144 SOP = 0xFF91, //start of packet
145 EPH = 0xFF92, //end of packet
146 SOD = 0xFF93, //start of data
147 EOC = 0xFFD9, //end of codestream (required)
148 };
149
151 //
152 //
153 //
154 //
155 //
158 {
162 };
163
166 {
167 friend ::ojph::param_siz;
168
169 public:
170 enum : ui16 {
172 RSIZ_HT_FLAG = 0x4000,
174 };
175
176 public:
178 {
179 Lsiz = Csiz = 0;
180 Xsiz = Ysiz = XOsiz = YOsiz = XTsiz = YTsiz = XTOsiz = YTOsiz = 0;
182 memset(store, 0, sizeof(store));
184 cod = NULL;
185 dfs = NULL;
187 cptr = store;
188 old_Csiz = 4;
189 }
190
192 {
193 if (cptr != store) delete[] cptr;
194 }
195
196 void set_num_components(ui32 num_comps)
197 {
198 Csiz = (ui16)num_comps;
199 if (Csiz > old_Csiz)
200 {
201 if (cptr != store)
202 delete[] cptr;
203 cptr = new siz_comp_info[num_comps];
204 old_Csiz = Csiz;
205 }
206 memset(cptr, 0, sizeof(local::siz_comp_info) * num_comps);
207 }
208
209 void set_comp_info(ui32 comp_num, const point& downsampling,
210 ui32 bit_depth, bool is_signed)
211 {
212 assert(comp_num < Csiz);
213 assert(downsampling.x != 0 && downsampling.y != 0);
214 cptr[comp_num].SSiz = (ui8)(bit_depth - 1 + (is_signed ? 0x80 : 0));
215 cptr[comp_num].XRsiz = (ui8)downsampling.x;
216 cptr[comp_num].YRsiz = (ui8)downsampling.y;
217 }
218
220 {
221 this->cod = &cod;
222
223 if (XTsiz == 0 && YTsiz == 0)
224 { XTsiz = Xsiz + XOsiz; YTsiz = Ysiz + YOsiz; }
225 if (Xsiz == 0 || Ysiz == 0 || XTsiz == 0 || YTsiz == 0)
226 OJPH_ERROR(0x00040001,
227 "You cannot set image extent nor tile size to zero");
228 if (XTOsiz > XOsiz || YTOsiz > YOsiz)
229 OJPH_ERROR(0x00040002,
230 "tile offset has to be smaller than image offset");
231 if (XTsiz + XTOsiz <= XOsiz || YTsiz + YTOsiz <= YOsiz)
232 OJPH_ERROR(0x00040003,
233 "the top left tile must intersect with the image");
234 }
235
236 ui16 get_num_components() const { return Csiz; }
237 ui32 get_bit_depth(ui32 comp_num) const
238 {
239 assert(comp_num < Csiz);
240 return (cptr[comp_num].SSiz & 0x7F) + 1u;
241 }
242 bool is_signed(ui32 comp_num) const
243 {
244 assert(comp_num < Csiz);
245 return (cptr[comp_num].SSiz & 0x80) != 0;
246 }
248 {
249 assert(comp_num < Csiz);
250 return point(cptr[comp_num].XRsiz, cptr[comp_num].YRsiz);
251 }
252
253 bool write(outfile_base *file);
254 void read(infile_base *file);
255
256 void link(const param_cod* cod)
257 { this->cod = cod; }
258
259 void link(const param_dfs* dfs)
260 { this->dfs = dfs; }
261
263 { this->skipped_resolutions = skipped_resolutions; }
264
265 ui32 get_width(ui32 comp_num) const
266 {
267 assert(comp_num < get_num_components());
268 ui32 ds = (ui32)cptr[comp_num].XRsiz;
269 ui32 t = ojph_div_ceil(Xsiz, ds) - ojph_div_ceil(XOsiz, ds);
270 return t;
271 }
272
273 ui32 get_height(ui32 comp_num) const
274 {
275 assert(comp_num < get_num_components());
276 ui32 ds = (ui32)cptr[comp_num].YRsiz;
277 ui32 t = ojph_div_ceil(Ysiz, ds) - ojph_div_ceil(YOsiz, ds);
278 return t;
279 }
280
281 point get_recon_downsampling(ui32 comp_num) const;
282 point get_recon_size(ui32 comp_num) const;
283 ui32 get_recon_width(ui32 comp_num) const
284 { return get_recon_size(comp_num).x; }
285 ui32 get_recon_height(ui32 comp_num) const
286 { return get_recon_size(comp_num).y; }
287
290
292 { Rsiz |= flag; }
294 { Rsiz = (ui16)(Rsiz & ~flag); }
295
296 private:
309
310 private:
318 param_siz(const param_siz&) = delete; //prevent copy constructor
319 param_siz& operator=(const param_siz&) = delete; //prevent copy
320 };
321
323 //
324 //
325 //
326 //
327 //
330 {
332 num_decomp = 5;
333 block_width = 4; // 64
334 block_height = 4; // 64
335 block_style = 0x40; // HT mode
336 wavelet_trans = 0; // reversible 5 / 3
337 memset(precinct_size, 0, sizeof(precinct_size));
338 }
339
345 ui8 precinct_size[33]; //num_decomp is in [0,32]
346
348 { return size(block_width + 2, block_height + 2); }
350 { size t = get_log_block_dims(); return size(1 << t.w, 1 << t.h); }
352 {
353 assert(res_num <= num_decomp);
354 size ps(precinct_size[res_num] & 0xF, precinct_size[res_num] >> 4);
355 return ps;
356 }
357 };
358
361 {
366 };
367
370 {
371 // serves for both COD and COC markers
372 friend ::ojph::param_cod;
375 OJPH_COD_DEFAULT = 65535
376 };
377
381 HT_MODE = 0x40
382 };
384 enum cod_type : ui8 {
388 COD_TILE = 3, // not implemented
389 COC_TILE = 4 // not implemented
390 };
392 enum dwt_type : ui8 {
395 };
396
397 public: // COD_MAIN and COC_MAIN common functions
400 {
402 Lcod = 0;
403 Scod = 0;
404 next = NULL;
405 atk = NULL;
406 this->top_cod = top_cod;
407 this->comp_idx = comp_idx;
408 }
409
412 if (next) {
413 delete next;
414 next = NULL;
415 }
416 }
417
419 void set_reversible(bool reversible)
420 {
421 assert(type == UNDEFINED || type == COD_MAIN || type == COC_MAIN);
422 SPcod.wavelet_trans = reversible ? DWT_REV53 : DWT_IRV97;
423 }
424
427 {
428 assert(val == 0 || val == 1);
429 assert(type == UNDEFINED || type == COD_MAIN);
430 SGCod.mc_trans = val;
431 }
432
434 void check_validity(const param_siz& siz)
435 {
436 assert(type == COD_MAIN);
437
438 //check that colour transform and match number of components and
439 // downsampling
440 int num_comps = siz.get_num_components();
441 if (SGCod.mc_trans == 1 && num_comps < 3)
442 OJPH_ERROR(0x00040011,
443 "color transform can only be employed when the image has 3 or "
444 "more color components");
445
446 if (SGCod.mc_trans == 1)
447 {
448 bool test_signedness = false;
449 bool test_bit_depth = false;
450 bool test_downsampling = false;
451 point p = siz.get_downsampling(0);
452 ui32 bit_depth = siz.get_bit_depth(0);
453 bool is_signed = siz.is_signed(0);
454 for (ui32 i = 1; i < 3; ++i)
455 {
456 point p1 = siz.get_downsampling(i);
457 test_downsampling = test_downsampling
458 || (p.x != p1.x || p.y != p1.y);
459 test_bit_depth = test_bit_depth
460 || (bit_depth != siz.get_bit_depth(i));
461 test_signedness = test_signedness
462 || (is_signed != siz.is_signed(i));
463 }
464 if (test_downsampling)
465 OJPH_ERROR(0x00040012,
466 "when color transform is used, the first 3 colour components "
467 "must have the same downsampling factor.");
468 if (test_bit_depth)
469 OJPH_ERROR(0x00040014,
470 "when color transform is used, the first 3 colour components "
471 "must have the same bit depth.");
472 if (test_signedness)
473 OJPH_ERROR(0x00040015,
474 "when color transform is used, the first 3 colour components "
475 "must have the same signedness (signed or unsigned).");
476
477 }
478
479 //check the progression order matches downsampling
482 {
483 ui32 num_comps = siz.get_num_components();
484 for (ui32 i = 0; i < num_comps; ++i)
485 {
486 point r = siz.get_downsampling(i);
487 if (r.x & (r.x - 1) || r.y & (r.y - 1))
488 OJPH_ERROR(0x00040013, "For RPCL and PCRL progression orders,"
489 "component downsampling factors have to be powers of 2");
490 }
491 }
492 }
493
496 {
497 if (type == COD_MAIN)
498 return SPcod.num_decomp;
499 else if (type == COC_MAIN)
500 {
501 if (is_dfs_defined())
503 else
504 return SPcod.num_decomp;
505 }
506 else {
507 assert(0);
508 return 0; // just in case
509 }
510 }
511
514 { return SPcod.get_block_dims(); }
515
518 { return SPcod.get_log_block_dims(); }
519
522 { return SPcod.wavelet_trans; }
523
525 bool is_reversible() const;
526
529 {
530 if (type == COD_MAIN || type == COD_TILE)
531 return (SGCod.mc_trans == 1);
532 else
534 }
535
538 {
539 size t = get_log_precinct_size(res_num);
540 return size(1 << t.w, 1 << t.h);
541 }
542
545 {
546 if (Scod & 1)
547 return SPcod.get_log_precinct_size(res_num);
548 else
549 return size(15, 15);
550 }
551
554 {
555 if (type == COD_MAIN || type == COD_TILE)
556 return (Scod & 2) == 2;
557 return false;
558 }
559
561 bool packets_use_eph() const
562 {
563 if (type == COD_MAIN || type == COD_TILE)
564 return (Scod & 4) == 4;
565 return false;
566 }
567
571
573 bool write(outfile_base *file);
574
576 bool write_coc(outfile_base *file, ui32 num_comps);
577
579 void read(infile_base *file);
580
582 void read_coc(infile_base* file, ui32 num_comps, param_cod* top_cod);
583
585 void update_atk(const param_atk* atk);
586
588 const param_cod* get_coc(ui32 comp_idx) const;
589
592
595
597 const param_atk* access_atk() const { return atk; }
598
599 public: // COC_MAIN only functions
601 bool is_dfs_defined() const
602 { return (SPcod.num_decomp & 0x80) != 0; }
603
605 ui16 get_dfs_index() const // cannot be more than 15
606 { return SPcod.num_decomp & 0xF; }
607
610 {
611 assert((type == COC_MAIN && comp_idx != OJPH_COD_DEFAULT) ||
613 return comp_idx;
614 }
615
616 private:
617 bool internal_write_coc(outfile_base *file, ui32 num_comps);
618
620 private: // Common variables
621 cod_type type; // The type of this cod structure
622 ui16 Lcod; // serves as Lcod and Scod
623 ui8 Scod; // serves as Scod and Scoc
624 cod_SGcod SGCod; // Used in COD and copied to COC
625 cod_SPcod SPcod; // serves as SPcod and SPcoc
626 param_cod* next; // to chain coc parameters to cod
627 const param_atk* atk; // used to read transform information
628
629 private: // COC only variables
630 param_cod* top_cod; // parent COD structure
631 ui16 comp_idx; // component index of this COC structure
632 };
633
635 //
636 //
637 //
638 //
639 //
642 {
643 // serves for both QCD and QCC markers
644 friend ::ojph::param_qcd;
647 OJPH_QCD_DEFAULT = 65535
648 };
649
651 enum qcd_type : ui8 {
655 QCD_TILE = 3, // not implemented
656 QCC_TILE = 4 // not implemented
657 };
658
659 public:
661 {
663 Lqcd = 0;
664 Sqcd = 0;
665 memset(&SPqcd, 0, sizeof(SPqcd));
666 num_subbands = 0;
667 base_delta = -1.0f;
668 enabled = true;
669 next = NULL;
670 this->top_qcd = top_qcd;
671 this->comp_idx = comp_idx;
672 }
674 if (next)
675 {
676 delete next;
677 next = NULL;
678 }
679 }
680
681 void check_validity(const param_siz& siz, const param_cod& cod);
682 void set_delta(float delta) { base_delta = delta; }
683 void set_delta(ui32 comp_idx, float delta);
684 ui32 get_num_guard_bits() const;
685 ui32 get_MAGB() const;
686 ui32 get_Kmax(const param_dfs* dfs, ui32 num_decompositions,
687 ui32 resolution, ui32 subband) const;
688 ui32 propose_precision(const param_cod* cod) const;
689 float get_irrev_delta(const param_dfs* dfs,
690 ui32 num_decompositions,
691 ui32 resolution, ui32 subband) const;
692 bool write(outfile_base *file);
693 bool write_qcc(outfile_base *file, ui32 num_comps);
694 void read(infile_base *file);
695 void read_qcc(infile_base *file, ui32 num_comps);
696
698 const param_qcd* get_qcc(ui32 comp_idx) const;
700 ui16 get_comp_idx() const { return comp_idx; }
701
702 private:
703 void set_rev_quant(ui32 num_decomps, ui32 bit_depth,
704 bool is_employing_color_transform);
705 void set_irrev_quant(ui32 num_decomps);
706 ui32 get_largest_Kmax() const;
707 bool internal_write_qcc(outfile_base *file, ui32 num_comps);
708 void trim_non_existing_components(ui32 num_comps);
709
711 { return (ui8)(v >> 3); }
713 { return (ui8)(v << 3); }
714
715 private: // QCD variables
719 union
720 {
721 ui8 u8[97];
724 ui32 num_subbands; // number of subbands
725 float base_delta; // base quantization step size -- all other
726 // step sizes are derived from it.
727 bool enabled; // enabled if two, and ignored if false
728 param_qcd *next; // pointer to create chains of qcc marker segments
729 param_qcd *top_qcd; // pointer to the top QCD (this is the default)
730
731 private: // QCC only variables
733 };
734
736 //
737 //
738 //
739 //
740 //
742 // data structures used by param_nlt
744 {
747 public:
749 Lnlt = 6;
750 Cnlt = special_comp_num::ALL_COMPS; // default
751 BDnlt = 0;
752 Tnlt = nonlinearity::OJPH_NLT_UNDEFINED;
753 enabled = false; next = NULL; alloced_next = false;
754 }
755
757 if (next && alloced_next) {
758 delete next;
759 alloced_next = false;
760 next = NULL;
761 }
762 }
763
764 void check_validity(param_siz& siz);
765 void set_nonlinear_transform(ui32 comp_num, ui8 nl_type);
766 bool get_nonlinear_transform(ui32 comp_num, ui8& bit_depth,
767 bool& is_signed, ui8& nl_type) const;
768 bool write(outfile_base* file) const;
769 void read(infile_base* file);
770
771 private:
772 const param_nlt* get_nlt_object(ui32 comp_num) const;
773 param_nlt* get_nlt_object(ui32 comp_num);
774 param_nlt* add_object(ui32 comp_num);
775 bool is_any_enabled() const;
776 void trim_non_existing_components(ui32 num_comps);
777
778 private:
779 ui16 Lnlt; // length of the marker segment excluding marker
780 ui16 Cnlt; // Component involved in the transformation
781 ui8 BDnlt; // Decoded image component bit depth parameter
782 ui8 Tnlt; // Type of non-linearity
783 bool enabled; // true if this object is used
784 param_nlt* next; // for chaining NLT markers
785 bool alloced_next; // true if next was allocated, not just set to an
786 // existing object
787
788 // The top level param_nlt object is not allocated, but as part of
789 // codestream, and is used to manage allocated next objects.
790 // next holds a list of param_nlt objects, which are managed by the top
791 // param_nlt object.
792 };
793
795 //
796 //
797 //
798 //
799 //
802 {
803 public:
805 {
806 memset(this, 0, sizeof(param_cap));
807 Lcap = 8;
808 Pcap = 0x00020000; //for jph, Pcap^15 must be set, the 15th MSB
809 }
810
811 void check_validity(const param_cod& cod, const param_qcd& qcd)
812 {
814 Ccap[0] &= 0xFFDF;
815 else
816 Ccap[0] |= 0x0020;
817 Ccap[0] &= 0xFFE0;
818 ui32 Bp = 0;
819 ui32 B = qcd.get_MAGB();
820 if (B <= 8)
821 Bp = 0;
822 else if (B < 28)
823 Bp = B - 8;
824 else
825 Bp = 13 + (B >> 2);
826 Ccap[0] = (ui16)(Ccap[0] | (ui16)Bp);
827 }
828
829 bool write(outfile_base *file);
830 void read(infile_base *file);
831
832 private:
835 ui16 Ccap[32]; //a maximum of 32
836 };
837
838
840 //
841 //
842 //
843 //
844 //
847 {
848 public:
849 void init(ui32 payload_length = 0, ui16 tile_idx = 0,
850 ui8 tile_part_index = 0, ui8 num_tile_parts = 0)
851 {
852 Lsot = 10;
853 Psot = payload_length + 12; //total = payload + SOT marker
854 Isot = tile_idx;
855 TPsot = tile_part_index;
856 TNsot = num_tile_parts;
857 }
858
859 bool write(outfile_base *file, ui32 payload_len);
860 bool write(outfile_base *file, ui32 payload_len, ui8 TPsot, ui8 TNsot);
861 bool read(infile_base *file, bool resilient);
862
863 ui16 get_tile_index() const { return Isot; }
864 ui32 get_payload_length() const { return Psot > 0 ? Psot - 12 : 0; }
865 ui8 get_tile_part_index() const { return TPsot; }
866 ui8 get_num_tile_parts() const { return TNsot; }
867
868 private:
874 };
875
877 //
878 //
879 //
880 //
881 //
884 {
886 {
889 };
890
891 public:
892 param_tlm() { pairs = NULL; num_pairs = 0; next_pair_index = 0; };
893 void init(ui32 num_pairs, Ttlm_Ptlm_pair* store);
894
895 void set_next_pair(ui16 Ttlm, ui32 Ptlm);
896 bool write(outfile_base *file);
897
898 private:
905 };
906
908 //
909 //
910 //
911 //
912 //
915 {
916 public:
918 NO_DWT = 0, // no wavelet transform
919 BIDIR_DWT = 1, // bidirectional DWT (this the conventional DWT)
920 HORZ_DWT = 2, // horizontal only DWT transform
921 VERT_DWT = 3, // vertical only DWT transform
922 };
923
924 public: // member functions
926 ~param_dfs() { if (next) delete next; }
927 void init()
928 { Ldfs = Sdfs = Ids = 0; memset(Ddfs, 0, sizeof(Ddfs)); next = NULL; }
929 bool read(infile_base *file);
930 bool exists() const { return Ldfs != 0; }
931
932 // get_dfs return a dfs structure Sdfs == index, or NULL if not found
933 const param_dfs* get_dfs(int index) const;
934 // decomp_level is the decomposition level, starting from 1 for highest
935 // resolution to num_decomps for the coarsest resolution
936 dfs_dwt_type get_dwt_type(ui32 decomp_level) const;
937 ui32 get_subband_idx(ui32 num_decompositions, ui32 resolution,
938 ui32 subband) const;
939 point get_res_downsamp(ui32 skipped_resolutions) const;
940
941 private: // member variables
942 ui16 Ldfs; // length of the segment marker
943 ui16 Sdfs; // index of this DFS marker segment
944 ui8 Ids; // number of elements in Ddfs, 2 bits per sub-level
945 ui8 Ddfs[8]; // a string defining number of decomposition sub-levels
946 // 8 bytes should be enough for 32 levels
947 param_dfs* next; // used for linking other dfs segments
948 };
949
951 //
952 //
953 //
954 //
955 //
957 // data structures used by param_atk
958
960 struct irv_data {
961 // si8 Oatk; // only for arbitrary filter
962 // ui8 LCatk; // number of lifting coefficients in a step
963 float Aatk; // lifting coefficient
964 };
965
966 struct rev_data {
967 // si8 Oatk; // only for arbitrary filter, offset of filter
968 ui8 Eatk; // only for reversible, epsilon, the power of 2
969 si16 Batk; // only for reversible, beta, the additive residue
970 // ui8 LCatk; // number of lifting coefficients in a step
971 si16 Aatk; // lifting coefficient
972 };
973
976 };
977
979 {
980 // Limitations:
981 // Arbitrary filters (ARB) are not supported
982 // Up to 6 steps are supported -- more than 6 are not supported
983 // Only one coefficient per step -- first order filter
984 // Only even-indexed subsequence in first reconstruction step,
985 // m_init = 0 is supported
986
987 public: // member functions
990 if (next && alloced_next) {
991 delete next;
992 next = NULL;
993 }
994 if (d != NULL && d != d_store) {
995 delete[] d;
996 init(false);
997 }
998 }
999 bool read(infile_base *file);
1000 bool read_coefficient(infile_base *file, float &K);
1001 bool read_coefficient(infile_base *file, si16 &K);
1002 void init(bool clear_all = true) {
1003 if (clear_all)
1004 {
1005 Latk = Satk = 0;
1006 Katk = 0.0f;
1007 Natk = 0;
1008 d = NULL;
1009 max_steps = 0;
1010 memset(d_store, 0, sizeof(d_store));
1011 next = NULL;
1012 alloced_next = false;
1013 }
1014 d = d_store; max_steps = sizeof(d_store) / sizeof(lifting_step);
1015 }
1016 void init_irv97();
1017 void init_rev53();
1019 { assert(this->next == NULL); this->next = next; alloced_next = false; }
1020
1021 ui8 get_index() const { return (ui8)(Satk & 0xFF); }
1022 int get_coeff_type() const { return (Satk >> 8) & 0x7; }
1023 bool is_whole_sample() const { return (Satk & 0x800) != 0; }
1024 bool is_reversible() const { return (Satk & 0x1000) != 0; }
1025 bool is_m_init0() const { return (Satk & 0x2000) == 0; }
1026 bool is_using_ws_extension() const { return (Satk & 0x4000) != 0; }
1027 const param_atk* get_atk(int index) const;
1028 const lifting_step* get_step(ui32 s) const
1029 { assert(s < Natk); return d + s; }
1030 ui32 get_num_steps() const { return Natk; }
1031 float get_K() const { return Katk; }
1032
1033 private: // member variables
1034 ui16 Latk; // structure length
1035 ui16 Satk; // carries a variety of information
1036 float Katk; // only for irreversible scaling factor K
1037 ui8 Natk; // number of lifting steps
1038 lifting_step* d; // pointer to data, initialized to d_store
1039 int max_steps; // maximum number of steps without memory allocation
1040 lifting_step d_store[6]; // lifting step coefficient
1041 param_atk* next; // used for chaining if more than one atk segment
1042 // exist in the codestream
1043 bool alloced_next; // true if next was allocated, not just set to an
1044 // existing object
1045 };
1046 } // !local namespace
1047} // !ojph namespace
1048
1049#endif // !OJPH_PARAMS_LOCAL_H
const char OJPH_PN_STRING_BROADCAST[]
const char OJPH_PN_STRING_CINEMAS4K[]
const char OJPH_PO_STRING_PCRL[]
const char OJPH_PN_STRING_IMF[]
const char OJPH_PN_STRING_CINEMA4K[]
uint16_t ui16
Definition: ojph_defs.h:52
const char OJPH_PO_STRING_RLCP[]
const char OJPH_PN_STRING_CINEMA2K[]
const char OJPH_PO_STRING_RPCL[]
OJPH_TILEPART_DIVISIONS
@ OJPH_TILEPART_RESOLUTIONS
@ OJPH_TILEPART_NO_DIVISIONS
@ OJPH_TILEPART_LAYERS
@ OJPH_TILEPART_COMPONENTS
@ OJPH_TILEPART_MASK
const char OJPH_PO_STRING_CPRL[]
@ OJPH_PN_PROFILE1
@ OJPH_PN_BROADCAST
@ OJPH_PN_CINEMA4K
@ OJPH_PN_CINEMA2K
@ OJPH_PN_CINEMAS4K
@ OJPH_PN_UNDEFINED
@ OJPH_PN_CINEMAS2K
@ OJPH_PN_PROFILE0
int32_t si32
Definition: ojph_defs.h:55
const char OJPH_PN_STRING_PROFILE0[]
int16_t si16
Definition: ojph_defs.h:53
const char OJPH_PN_STRING_CINEMAS2K[]
uint32_t ui32
Definition: ojph_defs.h:54
uint8_t ui8
Definition: ojph_defs.h:50
const char OJPH_PO_STRING_LRCP[]
const char OJPH_PN_STRING_PROFILE1[]
#define ojph_div_ceil(a, b)
Definition: ojph_defs.h:70
#define OJPH_ERROR(t,...)
Definition: ojph_message.h:287
size get_log_precinct_size(ui32 res_num) const
const param_atk * get_atk(int index) const
bool read(infile_base *file)
void init(bool clear_all=true)
bool read_coefficient(infile_base *file, float &K)
const lifting_step * get_step(ui32 s) const
void link(param_atk *next)
bool is_using_ws_extension() const
void check_validity(const param_cod &cod, const param_qcd &qcd)
void read(infile_base *file)
bool write(outfile_base *file)
void check_validity(const param_siz &siz)
bool write(outfile_base *file)
const param_cod * get_coc(ui32 comp_idx) const
bool internal_write_coc(outfile_base *file, ui32 num_comps)
bool write_coc(outfile_base *file, ui32 num_comps)
void set_reversible(bool reversible)
bool is_employing_color_transform() const
void employ_color_transform(ui8 val)
bool get_block_vertical_causality() const
const param_atk * access_atk() const
void read(infile_base *file)
size get_log_precinct_size(ui32 res_num) const
void read_coc(infile_base *file, ui32 num_comps, param_cod *top_cod)
ui8 get_num_decompositions() const
void update_atk(const param_atk *atk)
bool packets_may_use_sop() const
bool is_reversible() const
size get_precinct_size(ui32 res_num) const
param_cod(param_cod *top_cod=NULL, ui16 comp_idx=OJPH_COD_DEFAULT)
param_cod * add_coc_object(ui32 comp_idx)
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
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)
bool get_nonlinear_transform(ui32 comp_num, ui8 &bit_depth, bool &is_signed, ui8 &nl_type) const
const param_nlt * get_nlt_object(ui32 comp_num) const
void check_validity(param_siz &siz)
bool is_any_enabled() const
void set_nonlinear_transform(ui32 comp_num, ui8 nl_type)
ui8 encode_SPqcd(ui8 v) const
bool write_qcc(outfile_base *file, ui32 num_comps)
void set_rev_quant(ui32 num_decomps, ui32 bit_depth, bool is_employing_color_transform)
void set_irrev_quant(ui32 num_decomps)
ui32 get_largest_Kmax() const
ui32 get_num_guard_bits() const
float get_irrev_delta(const param_dfs *dfs, ui32 num_decompositions, ui32 resolution, ui32 subband) const
void set_delta(float delta)
void read_qcc(infile_base *file, ui32 num_comps)
void check_validity(const param_siz &siz, const param_cod &cod)
bool write(outfile_base *file)
ui32 propose_precision(const param_cod *cod) const
void read(infile_base *file)
param_qcd * add_qcc_object(ui32 comp_idx)
ui32 get_Kmax(const param_dfs *dfs, ui32 num_decompositions, ui32 resolution, ui32 subband) const
ui8 decode_SPqcd(ui8 v) const
param_qcd * get_qcc(ui32 comp_idx)
param_qcd(param_qcd *top_qcd=NULL, ui16 comp_idx=OJPH_QCD_DEFAULT)
union ojph::local::param_qcd::@6 SPqcd
void trim_non_existing_components(ui32 num_comps)
bool internal_write_qcc(outfile_base *file, ui32 num_comps)
void set_skipped_resolutions(ui32 skipped_resolutions)
ui32 get_bit_depth(ui32 comp_num) const
ui32 get_recon_height(ui32 comp_num) const
bool is_signed(ui32 comp_num) const
void check_validity(const param_cod &cod)
bool write(outfile_base *file)
param_siz(const param_siz &)=delete
point get_recon_downsampling(ui32 comp_num) const
void set_Rsiz_flag(ui16 flag)
point get_recon_size(ui32 comp_num) const
ui32 get_height(ui32 comp_num) const
void set_comp_info(ui32 comp_num, const point &downsampling, ui32 bit_depth, bool is_signed)
void link(const param_cod *cod)
point get_downsampling(ui32 comp_num) const
void reset_Rsiz_flag(ui16 flag)
void read(infile_base *file)
param_siz & operator=(const param_siz &)=delete
void link(const param_dfs *dfs)
void set_num_components(ui32 num_comps)
ui32 get_width(ui32 comp_num) const
ui32 get_recon_width(ui32 comp_num) const
void init(ui32 payload_length=0, ui16 tile_idx=0, ui8 tile_part_index=0, ui8 num_tile_parts=0)
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)
ui32 w
Definition: ojph_base.h:50
ui32 h
Definition: ojph_base.h:51