OpenJPH
Open-source implementation of JPEG2000 Part-15
Loading...
Searching...
No Matches
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
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
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 //
163
166 {
167 friend ::ojph::param_siz;
168
169 public:
170 enum : ui16 {
172 RSIZ_HT_FLAG = 0x4000,
174 };
175
176 public:
179
180 void init()
181 {
182 Lsiz = Csiz = 0;
183 Xsiz = Ysiz = XOsiz = YOsiz = XTsiz = YTsiz = XTOsiz = YTOsiz = 0;
185 memset(store, 0, sizeof(store));
187 cod = NULL;
188 dfs = NULL;
190 cptr = store;
191 old_Csiz = sizeof(store) / sizeof(siz_comp_info);
192 }
193
194 void destroy()
195 { if (cptr != store) { delete[] cptr; cptr = NULL; } }
196
197 void set_num_components(ui32 num_comps)
198 {
199 Csiz = (ui16)num_comps;
200 if (Csiz > old_Csiz)
201 {
202 if (cptr != store)
203 delete[] cptr;
204 cptr = new siz_comp_info[num_comps];
205 old_Csiz = Csiz;
206 }
207 memset(cptr, 0, sizeof(local::siz_comp_info) * num_comps);
208 }
209
210 void set_comp_info(ui32 comp_num, const point& downsampling,
211 ui32 bit_depth, bool is_signed)
212 {
213 assert(comp_num < Csiz);
214 assert(downsampling.x != 0 && downsampling.y != 0);
215 cptr[comp_num].SSiz = (ui8)(bit_depth - 1 + (is_signed ? 0x80 : 0));
216 cptr[comp_num].XRsiz = (ui8)downsampling.x;
217 cptr[comp_num].YRsiz = (ui8)downsampling.y;
218 }
219
220 void set_image_extent(point dims) { Xsiz = dims.x; Ysiz = dims.y; }
221 point get_image_extent() const { return point(Xsiz, Ysiz); }
222 void set_tile_size(size s) { XTsiz = s.w; YTsiz = s.h; }
223 size get_tile_size() const { return size(XTsiz, YTsiz); }
225 { XOsiz = offset.x; YOsiz = offset.y; }
227 { return point(XOsiz, YOsiz); }
229 { XTOsiz = offset.x; YTOsiz = offset.y; }
231 { return point(XTOsiz, YTOsiz); }
232
233 void set_cod(const param_cod& cod) { this->cod = &cod; }
234
236 {
237 if (Xsiz == 0 || Ysiz == 0 || XTsiz == 0 || YTsiz == 0)
238 OJPH_ERROR(0x00040001,
239 "Image extent and/or tile size cannot be zero");
240 if (XTOsiz > XOsiz || YTOsiz > YOsiz)
241 OJPH_ERROR(0x00040002,
242 "Tile offset has to be smaller than the image offset");
243 if (XTsiz + XTOsiz <= XOsiz || YTsiz + YTOsiz <= YOsiz)
244 OJPH_ERROR(0x00040003,
245 "The top left tile must intersect with the image");
246 if (Xsiz <= XOsiz || Ysiz <= YOsiz)
247 OJPH_ERROR(0x00040004,
248 "The image extent must be larger than the image offset");
249 }
250
251 ui16 get_num_components() const { return Csiz; }
252 ui32 get_bit_depth(ui32 comp_num) const
253 {
254 assert(comp_num < Csiz);
255 return (cptr[comp_num].SSiz & 0x7F) + 1u;
256 }
257 bool is_signed(ui32 comp_num) const
258 {
259 assert(comp_num < Csiz);
260 return (cptr[comp_num].SSiz & 0x80) != 0;
261 }
263 {
264 assert(comp_num < Csiz);
265 return point(cptr[comp_num].XRsiz, cptr[comp_num].YRsiz);
266 }
267
268 bool write(outfile_base *file);
269 void read(infile_base *file);
270
271 void link(const param_cod* cod)
272 { this->cod = cod; }
273
274 void link(const param_dfs* dfs)
275 { this->dfs = dfs; }
276
278 { this->skipped_resolutions = skipped_resolutions; }
279
280 ui32 get_width(ui32 comp_num) const
281 {
282 assert(comp_num < get_num_components());
283 ui32 ds = (ui32)cptr[comp_num].XRsiz;
284 ui32 t = ojph_div_ceil(Xsiz, ds) - ojph_div_ceil(XOsiz, ds);
285 return t;
286 }
287
288 ui32 get_height(ui32 comp_num) const
289 {
290 assert(comp_num < get_num_components());
291 ui32 ds = (ui32)cptr[comp_num].YRsiz;
292 ui32 t = ojph_div_ceil(Ysiz, ds) - ojph_div_ceil(YOsiz, ds);
293 return t;
294 }
295
296 point get_recon_downsampling(ui32 comp_num) const;
297 point get_recon_size(ui32 comp_num) const;
298 ui32 get_recon_width(ui32 comp_num) const
299 { return get_recon_size(comp_num).x; }
300 ui32 get_recon_height(ui32 comp_num) const
301 { return get_recon_size(comp_num).y; }
302
305
307 { Rsiz |= flag; }
309 { Rsiz = (ui16)(Rsiz & ~flag); }
310
311 private:
324
325 private:
333 param_siz(const param_siz&) = delete; //prevent copy constructor
334 param_siz& operator=(const param_siz&) = delete; //prevent copy
335 };
336
338 //
339 //
340 //
341 //
342 //
345 {
347 num_decomp = 5;
348 block_width = 4; // 64
349 block_height = 4; // 64
350 block_style = 0x40; // HT mode
351 wavelet_trans = 0; // reversible 5 / 3
352 memset(precinct_size, 0, sizeof(precinct_size));
353 }
354
360 ui8 precinct_size[33]; //num_decomp is in [0,32]
361
363 { return size(block_width + 2, block_height + 2); }
365 { size t = get_log_block_dims(); return size(1 << t.w, 1 << t.h); }
367 {
368 assert(res_num <= num_decomp);
369 size ps(precinct_size[res_num] & 0xF, precinct_size[res_num] >> 4);
370 return ps;
371 }
372 };
373
382
385 {
386 // serves for both COD and COC markers
387 friend ::ojph::param_cod;
392
398
399 enum cod_type : ui8 {
403 COD_TILE = 3, // not implemented
404 COC_TILE = 4 // not implemented
405 };
406
407 enum dwt_type : ui8 {
410 };
411
412 public: // COD_MAIN and COC_MAIN common functions
416
418 void restart()
419 {
420 param_cod** p = &avail; // move next to the end of avail
421 while (*p != NULL)
422 p = &((*p)->next);
423 *p = next;
425 }
426
428 void set_reversible(bool reversible)
429 {
430 assert(type == UNDEFINED || type == COD_MAIN || type == COC_MAIN);
431 SPcod.wavelet_trans = reversible ? DWT_REV53 : DWT_IRV97;
432 }
433
436 {
437 assert(val == 0 || val == 1);
438 assert(type == UNDEFINED || type == COD_MAIN);
439 SGCod.mc_trans = val;
440 }
441
443 void check_validity(const param_siz& siz)
444 {
445 assert(type == COD_MAIN);
446
447 //check that colour transform and match number of components and
448 // downsampling
449 int num_comps = siz.get_num_components();
450 if (SGCod.mc_trans == 1 && num_comps < 3)
451 OJPH_ERROR(0x00040011,
452 "color transform can only be employed when the image has 3 or "
453 "more color components");
454
455 if (SGCod.mc_trans == 1)
456 {
457 bool test_signedness = false;
458 bool test_bit_depth = false;
459 bool test_downsampling = false;
460 point p = siz.get_downsampling(0);
461 ui32 bit_depth = siz.get_bit_depth(0);
462 bool is_signed = siz.is_signed(0);
463 for (ui32 i = 1; i < 3; ++i)
464 {
465 point p1 = siz.get_downsampling(i);
466 test_downsampling = test_downsampling
467 || (p.x != p1.x || p.y != p1.y);
468 test_bit_depth = test_bit_depth
469 || (bit_depth != siz.get_bit_depth(i));
470 test_signedness = test_signedness
471 || (is_signed != siz.is_signed(i));
472 }
473 if (test_downsampling)
474 OJPH_ERROR(0x00040012,
475 "when color transform is used, the first 3 colour components "
476 "must have the same downsampling factor.");
477 if (test_bit_depth)
478 OJPH_ERROR(0x00040014,
479 "when color transform is used, the first 3 colour components "
480 "must have the same bit depth.");
481 if (test_signedness)
482 OJPH_ERROR(0x00040015,
483 "when color transform is used, the first 3 colour components "
484 "must have the same signedness (signed or unsigned).");
485
486 }
487
488 //check the progression order matches downsampling
491 {
492 ui32 num_comps = siz.get_num_components();
493 for (ui32 i = 0; i < num_comps; ++i)
494 {
495 point r = siz.get_downsampling(i);
496 if (r.x & (r.x - 1) || r.y & (r.y - 1))
497 OJPH_ERROR(0x00040013, "For RPCL and PCRL progression orders,"
498 "component downsampling factors have to be powers of 2");
499 }
500 }
501 }
502
505 {
506 if (type == COD_MAIN)
507 return SPcod.num_decomp;
508 else if (type == COC_MAIN)
509 {
510 if (is_dfs_defined())
512 else
513 return SPcod.num_decomp;
514 }
515 else {
516 assert(0);
517 return 0; // just in case
518 }
519 }
520
523 { return SPcod.get_block_dims(); }
524
528
531 { return SPcod.wavelet_trans; }
532
534 bool is_reversible() const;
535
538 {
539 if (type == COD_MAIN || type == COD_TILE)
540 return (SGCod.mc_trans == 1);
541 else
543 }
544
547 {
548 size t = get_log_precinct_size(res_num);
549 return size(1 << t.w, 1 << t.h);
550 }
551
554 {
555 if (Scod & 1)
556 return SPcod.get_log_precinct_size(res_num);
557 else
558 return size(15, 15);
559 }
560
563 {
564 if (type == COD_MAIN || type == COD_TILE)
565 return (Scod & 2) == 2;
566 return false;
567 }
568
570 bool packets_use_eph() const
571 {
572 if (type == COD_MAIN || type == COD_TILE)
573 return (Scod & 4) == 4;
574 return false;
575 }
576
580
582 bool write(outfile_base *file);
583
585 bool write_coc(outfile_base *file, ui32 num_comps);
586
588 void read(infile_base *file);
589
591 void read_coc(infile_base* file, ui32 num_comps, param_cod* top_cod);
592
594 void update_atk(param_atk* atk);
595
597 const param_cod* get_coc(ui32 comp_idx) const;
598
601
604
607
609 const param_atk* access_atk() const { return atk; }
610
611 public: // COC_MAIN only functions
613 bool is_dfs_defined() const
614 { return (SPcod.num_decomp & 0x80) != 0; }
615
617 ui16 get_dfs_index() const // cannot be more than 15
618 { return SPcod.num_decomp & 0xF; }
619
622 {
623 assert((type == COC_MAIN && comp_idx != OJPH_COD_DEFAULT) ||
625 return comp_idx;
626 }
627
628 private:
631 {
633 Lcod = 0;
634 Scod = 0;
635 SPcod = cod_SPcod(); // SPcod is initialized to default values
636 next = NULL;
637 atk = NULL;
638 // For COC marker segment:
639 // Lcod will be initialized on writing the marker segment to disk
640 // Scod is initialized to 0
641 // SGcod does not exist in COC
642 // SPcoc is initialized to default values
643 // atk is initialized to NULL
644 this->top_cod = top_cod;
645 this->comp_idx = comp_idx;
646 }
647
649 void destroy() {
650 if (avail)
651 delete avail;
652 if (next) {
653 delete next;
654 next = NULL;
655 }
656 }
657
658 private:
659 bool internal_write_coc(outfile_base *file, ui32 num_comps);
660
662 private: // Common variables
663 cod_type type; // The type of this cod structure
664 ui16 Lcod; // serves as Lcod and Scod
665 ui8 Scod; // serves as Scod and Scoc
666 cod_SGcod SGCod; // Used in COD and copied to COC
667 cod_SPcod SPcod; // serves as SPcod and SPcoc
668 param_cod* next; // to chain coc parameters to cod
669 const param_atk* atk; // used to read transform information
670
671 private: // COC only variables
672 param_cod* top_cod; // parent COD structure
673 ui16 comp_idx; // component index of this COC structure
674
675 private: // on restart, already allocated param_cod objs are stored here
677 };
678
680 //
681 //
682 //
683 //
684 //
687 {
688 // serves for both QCD and QCC markers
689 friend ::ojph::param_qcd;
694
696 enum qcd_type : ui8 {
700 QCD_TILE = 3, // not implemented
701 QCC_TILE = 4 // not implemented
702 };
703
705 const float QFACTOR_UNSET = 0.0f;
706 // 1 LL subband + 3 subbands for each of at most 32 decomposition levels
707 static constexpr ui32 MAX_SUBBAND_COUNT = 97;
708
711
712 public:
716
718 void restart()
719 {
720 param_qcd** p = &avail; // move next to the end of avail
721 while (*p != NULL)
722 p = &((*p)->next);
723 *p = next;
725 }
726
727 void check_validity(const param_siz& siz, const param_cod& cod);
728 void make_quant_steps(ui32 comp_num, const param_cod &cod,
729 const param_siz &siz);
730 bool is_qcc_needed(ui32 comp_num, const param_cod &cod,
731 const param_siz &siz);
732 void set_delta(float delta) { base_delta = delta; }
733 void set_delta(float delta, size_t num_weights, const float *weights)
735 void set_qfactor(float qfactor);
736 void set_weights(size_t num_weights, const float *weights);
737 ui32 get_num_guard_bits() const;
738 ui32 get_MAGB() const;
739 ui32 get_Kmax(const param_dfs* dfs, ui32 num_decompositions,
740 ui32 resolution, ui32 subband) const;
741 ui32 propose_precision(const param_cod* cod) const;
742 float get_irrev_delta(const param_dfs* dfs,
743 ui32 num_decompositions, ui32 comp_num,
744 ui32 resolution, ui32 subband) const;
745 bool write(outfile_base *file);
746 bool write_qcc(outfile_base *file, ui32 num_comps);
747 void read(infile_base *file);
748 void read_qcc(infile_base *file, ui32 num_comps);
749
750 void set_delta(ui32 comp_idx, float delta);
751 void set_delta(ui32 comp_idx, float delta,
752 size_t num_weights, const float *weights);
755 const param_qcd* get_qcc(ui32 comp_idx) const;
757 ui16 get_comp_idx() const { return comp_idx; }
758
759 private:
762 {
763 is_init = false;
765 Lqcd = 0;
766 Sqcd = 0;
767 memset(&SPqcd, 0, sizeof(SPqcd));
768 num_subbands = 0;
769 base_delta = -1.0f;
771 num_weights = 0;
772 ctype = comp_type::OJPH_COMP_Y;
773 sampling = ojph::point(1, 1);
774 enabled = true;
775 next = NULL;
776 this->top_qcd = top_qcd;
777 this->comp_idx = comp_idx;
778 }
779
781 void destroy() {
782 if (avail)
783 delete avail;
784 if (next)
785 {
786 delete next;
787 next = NULL;
788 }
789 }
790
791 private:
793 bool is_employing_color_transform);
795 void encode_SPqcd(ui32 subband_index, float delta);
796 ui32 get_largest_Kmax() const;
797 bool internal_write_qcc(outfile_base *file, ui32 num_comps);
798 void trim_non_existing_components(ui32 num_comps);
799
801 { return (ui8)(v >> 3); }
803 { return (ui8)(v << 3); }
804
805 private: // QCD variables
807 bool is_init; // have the quantization steps been generated
810 union
811 {
815 ui32 num_subbands; // number of subbands
816 bool enabled; // enabled if two, and ignored if false
817 param_qcd *next; // pointer to create chains of qcc marker segments
818 param_qcd *top_qcd; // pointer to the top QCD (this is the default)
819
820 // variables used to generate the quantization step sizes
821 float base_delta; // base quantization step size -- all other
822 // step sizes are derived from it.
823 float qfactor;
824 ui32 num_weights; // number of coefficients in `weights`; 0 if none
825 // weight coefficients, in subband order
826 // {LH1, HL1, HH1, ..., LHN, HLN, HHN, LLN}
835
836 private: // QCC only variables
838
839 private: // on restart, already allocated param_qcd objs are stored here
841 };
842
844 //
845 //
846 //
847 //
848 //
850
851 // nlt_rec for easy exchange and processing of NLT types 2 and 4
852 struct nlt_rec {
854
855 static ui8 get_bpp(ui32 t) { return (t <= 8) ? 1 : ((t <= 16) ? 2 : 4); }
856 nlt_rec() { points_store = NULL; store_size = 0; init(); }
857 void init() {
858 BDnlt = 0; Tnlt = nonlinearity::OJPH_NLT_UNDEFINED;
860 marker_points = NULL;
861 // decode
862 dec_points = NULL;
863 fd_min = fd_max = delta = inv_delta = multiplier = 0.0f;
864 // encode
865 approx_encoding_nlt = false;
866 enc_num_points = 0;
867 ft_min = ft_max = 0.0f;
869 approx_enc_points = NULL;
873 precise_dec_lut = NULL;
874 }
875 ui8 get_type() const { return Tnlt; }
876 ui8 get_bit_depth() const { return (ui8)((BDnlt & 0x7F) + 1u); }
877 ui8 get_bpp() const { return get_bpp(pt_val); }
878 bool is_signed() const { return (BDnlt & 0x80) != 0; }
880 { return (ui32)num_points * (ui32)get_bpp(); }
881 ui8 BDnlt; // Decoded image component bit depth parameter
882 ui8 Tnlt; // Type of non-linearity
883 ui32 d_min, d_max; // Dmin and Dmax
884 ui32 pt_val; // Precision of points in bits
885 ui32 num_points; // number of points in LUT points from 2 to 8192
886 void* marker_points; // pointer to marker points
887 ui8 bytes_per_point; // number of bytes per point, derived from pt_val
888
889 // point storage
890 void* points_store;// store for all needed storage
891 ui32 store_size; // storage size in bytes
892
893 // memebers for decoding
894 float* dec_points; // LUT points for decoding -- must be float
895 float fd_min, fd_max; // float d_min and d_max
896 float delta, inv_delta;// delta is (dmax-dmin) / (num_points - 1)
897 float multiplier; // multiplier to convert to final integer
899 { // add 2 extra points, one before the dec_points table and one after
900 return (ui32)(num_points + 2u) * (ui32)sizeof(float)
901 + (ui32)num_points * (ui32)get_bpp();
902 }
904 { // 2 extra points, one before the dec_points table and one after
905 dec_points = (float*)points_store + 1; approx_enc_points = NULL;
906 marker_points = (ui8*)dec_points + (num_points + 1) * sizeof(float);
907 }
909
910 // memebers for encoding -- we also use some from decoding
911 ui32 enc_num_points; // # of points for encoding (larger than decoding)
912 float ft_min, ft_max; // float first and last LUT points
913 bool approx_encoding_nlt; // use approx encoding non-linearity
915 float* approx_enc_points; // LUT points for encoding -- must be float
917 ui32 precise_max_steps; // max needed steps to find LUT data node
918 ui16* precise_enc_dec_indices; // LUT indices into decoder LUT
919 float* precise_dec_lut; // decoder LUT in float
920
922 {
923 this->enc_num_points = enc_num_points;
924
925 // add 4 extra points, two before enc_num_points table and two after
927 return (ui32)(enc_num_points + 4u) * (ui32)sizeof(float)
928 + (ui32)num_points * (ui32)get_bpp();
929 else
930 return (ui32)(enc_num_points + 4u) * (ui32)sizeof(ui16)
931 + (ui32)(num_points + 4u) * (ui32)sizeof(float)
932 + (ui32)num_points * (ui32)get_bpp();
933 }
935 {
936 dec_points = NULL;
937
938 // add 4 extra points, two before enc_num_points table and two after
940 {
941 approx_enc_points = (float*)points_store + 2u;
943 precise_dec_lut = NULL;
945 + (enc_num_points + 4u) * sizeof(float);
946 }
947 else
948 { // add 6 extra points, 3 before enc_num_points table and 3 after
949 approx_enc_points = NULL;
951 precise_dec_lut = (float*)((ui8*)points_store +
952 (ui32)(enc_num_points + 4u) * (ui32)sizeof(ui16)) + 2u;
954 + (ui32)(enc_num_points + 4u) * (ui32)sizeof(ui16)
955 + (ui32)(num_points + 4u) * (ui32)sizeof(float);
956 }
957 }
961 };
962
963 // data structures used by param_nlt
965 {
968
969 public:
971 avail = NULL;
972 init();
973 }
975
977 void restart()
978 {
979 param_nlt** p = &avail; // move next to the end of avail
980 while (*p != NULL)
981 p = &((*p)->next);
982 *p = next;
983 this->init();
984 }
985
986 void check_validity(param_siz& siz, const param_cod& cod);
987
989 // Returns the index of the first component that uses a LUT nonlinearity
990 // type (types 2 or 4) with a reversible wavelet, which is not supported
991 // yet, as it makes no sense, becausse the LUT itself is not reversible.
992 // This function returns the first component that has this problem or
993 // or -1 when there is no such component.
994 int find_unsupported_nlt(const param_siz& siz,
995 const param_cod& cod) const;
996
997 void set_nonlinear_transform(ui32 comp_num, ui8 nl_type);
998
999 void set_nonlinear_transform(ui32 comp_num,
1000 ui8 decoded_bit_depth,
1001 bool decoded_signedness,
1002 ui32 d_min, ui32 d_max, ui8 pt_val,
1003 ui16 num_points, void* points, ui8 nl_type,
1004 bool approx_encoding_nlt,
1005 ui32 num_enc_points);
1006
1007 bool get_nonlinear_transform(ui32 comp_num,
1008 ui8& decoded_bit_depth,
1009 bool& decoded_signedness,
1010 ui8& nl_type) const;
1011
1012 bool write(outfile_base* file) const;
1013 bool read(infile_base* file);
1014
1015 const nlt_rec* get_nlt_rec(ui32 comp_num) const;
1016
1017 private:
1019 void init()
1020 {
1021 Lnlt = 0;
1022 Cnlt = special_comp_num::ALL_COMPS; // default
1023 rec.init();
1024 enabled = false; next = NULL;
1025 }
1026
1028 void destroy()
1029 {
1030 if (rec.points_store) {
1031 delete[] (ui8*)rec.points_store;
1032 rec.points_store = NULL;
1033 }
1034 if (avail)
1035 delete avail;
1036 if (next) {
1037 delete next;
1038 next = NULL;
1039 }
1040 }
1041
1042 private:
1043 const param_nlt* get_nlt_object(ui32 comp_num) const;
1044 param_nlt* get_nlt_object(ui32 comp_num);
1045 param_nlt* add_object(ui32 comp_num);
1046 bool is_any_enabled() const;
1047 void trim_non_existing_components(ui32 num_comps);
1048
1049 private:
1050 ui16 Lnlt; // length of the marker segment excluding marker
1051 ui16 Cnlt; // Component involved in the transformation
1052 nlt_rec rec; // NLT properties
1053
1054 // The top level param_nlt object is not allocated, but as part of
1055 // codestream, and is used to manage allocated next objects.
1056 // next holds a list of param_nlt objects, which are managed by the top
1057 // param_nlt object.
1058
1059 private: // on restart, already allocated param_nlt objs are stored here
1060 bool enabled; // true if this object is used
1061 param_nlt* next; // for chaining NLT markers
1063 };
1064
1066 //
1067 //
1068 //
1069 //
1070 //
1073 {
1074 public:
1076 {
1077 memset(this, 0, sizeof(param_cap));
1078 Lcap = 8;
1079 Pcap = 0x00020000; //for jph, Pcap^15 must be set, the 15th MSB
1080 }
1081
1082 void check_validity(const param_cod& cod, const param_qcd& qcd)
1083 {
1085 Ccap[0] &= 0xFFDF;
1086 else
1087 Ccap[0] |= 0x0020;
1088 Ccap[0] &= 0xFFE0;
1089 ui32 Bp = 0;
1090 ui32 B = qcd.get_MAGB();
1091 if (B <= 8)
1092 Bp = 0;
1093 else if (B < 28)
1094 Bp = B - 8;
1095 else
1096 Bp = 13 + (B >> 2);
1097 Ccap[0] = (ui16)(Ccap[0] | (ui16)Bp);
1098 }
1099
1100 bool write(outfile_base *file);
1101 void read(infile_base *file);
1102
1103 private:
1106 ui16 Ccap[32]; //a maximum of 32
1107 };
1108
1109
1111 //
1112 //
1113 //
1114 //
1115 //
1118 {
1119 public:
1120 void init(ui32 payload_length = 0, ui16 tile_idx = 0,
1121 ui8 tile_part_index = 0, ui8 num_tile_parts = 0)
1122 {
1123 Lsot = 10;
1124 Psot = payload_length + 12; //total = payload + SOT marker
1125 Isot = tile_idx;
1126 TPsot = tile_part_index;
1127 TNsot = num_tile_parts;
1128 }
1129
1130 bool write(outfile_base *file, ui32 payload_len);
1131 bool write(outfile_base *file, ui32 payload_len, ui8 TPsot, ui8 TNsot);
1132 bool read(infile_base *file, bool resilient);
1133
1134 ui16 get_tile_index() const { return Isot; }
1135 ui32 get_payload_length() const { return Psot > 0 ? Psot - 12 : 0; }
1136 ui8 get_tile_part_index() const { return TPsot; }
1137 ui8 get_num_tile_parts() const { return TNsot; }
1138
1139 private:
1145 };
1146
1148 //
1149 //
1150 //
1151 //
1152 //
1155 {
1157 {
1160 };
1161
1162 public:
1163 param_tlm() { pairs = NULL; num_pairs = 0; next_pair_index = 0; };
1164 void init(ui32 num_pairs, Ttlm_Ptlm_pair* store);
1165
1166 void set_next_pair(ui16 Ttlm, ui32 Ptlm);
1167 bool write(outfile_base *file);
1168
1169 private:
1170 enum : ui32 {
1171 // Ltlm is 16 bits and spans itself, Ztlm, Stlm and 6 bytes per entry
1172 MAX_PAIRS_PER_SEG = (65535 - 4) / 6,
1173 MAX_SEGMENTS = 256, // Ztlm is 8 bits
1174 };
1175
1179 };
1180
1182 //
1183 //
1184 //
1185 //
1186 //
1189 {
1190 public:
1192 NO_DWT = 0, // no wavelet transform
1193 BIDIR_DWT = 1, // bidirectional DWT (this the conventional DWT)
1194 HORZ_DWT = 2, // horizontal only DWT transform
1195 VERT_DWT = 3, // vertical only DWT transform
1196 };
1197
1198 public: // member functions
1199 param_dfs() { avail = NULL; init(); }
1201
1203 void restart()
1204 {
1205 param_dfs** p = &avail; // move next to the end of avail
1206 while (*p != NULL)
1207 p = &((*p)->next);
1208 *p = next;
1209 this->init();
1210 }
1211
1212 bool read(infile_base *file);
1213 bool exists() const { return Ldfs != 0; }
1214
1215 // get_dfs return a dfs structure Sdfs == index, or NULL if not found
1216 const param_dfs* get_dfs(int index) const;
1217 // decomp_level is the decomposition level, starting from 1 for highest
1218 // resolution to num_decomps for the coarsest resolution
1219 dfs_dwt_type get_dwt_type(ui32 decomp_level) const;
1220 ui32 get_subband_idx(ui32 num_decompositions, ui32 resolution,
1221 ui32 subband) const;
1222 point get_res_downsamp(ui32 skipped_resolutions) const;
1223
1224 private:
1226 void init()
1227 { Ldfs = Sdfs = Ids = 0; memset(Ddfs, 0, sizeof(Ddfs)); next = NULL; }
1228
1230 void destroy()
1231 {
1232 if (avail)
1233 delete avail;
1234 if (next) {
1235 delete next;
1236 next = NULL;
1237 }
1238 }
1239
1240 private: // member variables
1241 ui16 Ldfs; // length of the segment marker
1242 ui16 Sdfs; // index of this DFS marker segment
1243 ui8 Ids; // number of elements in Ddfs, 2 bits per sub-level
1244 ui8 Ddfs[8]; // a string defining number of decomposition sub-levels
1245 // 8 bytes should be enough for 32 levels
1246 param_dfs* next; // used for linking other dfs segments
1247
1248 private: // on restart, already allocated param_dfs objs are stored here
1250 };
1251
1253 //
1254 //
1255 //
1256 //
1257 //
1259 // data structures used by param_atk
1260
1262 struct irv_data {
1263 // si8 Oatk; // only for arbitrary filter
1264 // ui8 LCatk; // number of lifting coefficients in a step
1265 float Aatk; // lifting coefficient
1266 };
1267
1268 struct rev_data {
1269 // si8 Oatk; // only for arbitrary filter, offset of filter
1270 ui8 Eatk; // only for reversible, epsilon, the power of 2
1271 si16 Batk; // only for reversible, beta, the additive residue
1272 // ui8 LCatk; // number of lifting coefficients in a step
1273 si16 Aatk; // lifting coefficient
1274 };
1275
1278 };
1279
1281 {
1282 // Limitations:
1283 // Arbitrary filters (ARB) are not supported
1284 // Only one coefficient per step -- first order filter
1285 // Only even-indexed subsequence in first reconstruction step,
1286 // m_init = 0 is supported
1287 public: // member functions
1289 {
1290 d = d_store;
1291 max_steps = sizeof(d_store) / sizeof(lifting_step);
1292 init(NULL);
1293 }
1295 {
1296 if (avail) {
1297 delete avail;
1298 avail = NULL;
1299 }
1300 if (next) {
1301 delete next;
1302 next = NULL;
1303 }
1304 if (d != NULL && d != d_store) {
1305 delete[] d;
1306 d = d_store;
1307 max_steps = sizeof(d_store) / sizeof(lifting_step);
1308 }
1309 }
1310
1312 void restart()
1313 {
1314 assert(top_atk == NULL);
1315
1316 Latk = Satk = 0;
1317 Katk = 0.0f;
1318 Natk = 0;
1319 if (d == NULL || d == d_store) {
1320 d = d_store;
1321 max_steps = sizeof(d_store) / sizeof(lifting_step);
1322 }
1323 memset(d, 0, max_steps * sizeof(lifting_step));
1324
1325 param_atk** p = &avail; // move next to the end of avail
1326 while (*p != NULL)
1327 p = &((*p)->next);
1328 *p = next;
1329
1330 next = NULL;
1331 }
1332
1333 bool read(infile_base *file);
1334
1335 ui8 get_index() const { return (ui8)(Satk & 0xFF); }
1336 int get_coeff_type() const { return (Satk >> 8) & 0x7; }
1337 bool is_whole_sample() const { return (Satk & 0x800) != 0; }
1338 bool is_reversible() const { return (Satk & 0x1000) != 0; }
1339 bool is_m_init0() const { return (Satk & 0x2000) == 0; }
1340 bool is_using_ws_extension() const { return (Satk & 0x4000) != 0; }
1341 param_atk* get_atk(int index);
1343 { assert(s < Natk); return d + s; }
1344 ui32 get_num_steps() const { return Natk; }
1345 float get_K() const { return Katk; }
1346
1347 private:
1350 {
1351 Latk = Satk = 0;
1352 Katk = 0.0f;
1353 Natk = 0;
1354 if (d == NULL || d == d_store) {
1355 d = d_store;
1356 max_steps = sizeof(d_store) / sizeof(lifting_step);
1357 }
1358 memset(d, 0, max_steps * sizeof(lifting_step));
1359 next = NULL;
1360 this->top_atk = top_atk;
1361 avail = NULL;
1362 }
1363 private:
1364 bool read_coefficient(infile_base *file, float &K, si32& bytes);
1365 bool read_coefficient(infile_base *file, si16 &K, si32& bytes);
1366
1367 void init_irv97();
1368 void init_rev53();
1370
1371 private: // member variables
1372 ui16 Latk; // structure length
1373 ui16 Satk; // carries a variety of information
1374 float Katk; // only for irreversible scaling factor K
1375 ui8 Natk; // number of lifting steps
1376 lifting_step* d; // pointer to data, initialized to d_store
1377 ui32 max_steps; // maximum number of steps without memory allocation
1378 lifting_step d_store[6]; // lifting step coefficient
1379 param_atk* next; // used for chaining if more than one atk segment
1380 // exist in the codestream
1381 param_atk* top_atk;// This is the top level atk, from which all atk
1382 // objects are derived
1383
1384 private: // on restart, already allocated param_atk objs are stored here
1386 };
1387 } // !local namespace
1388} // !ojph namespace
1389
1390#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
const char OJPH_PO_STRING_CPRL[]
@ OJPH_PN_BROADCAST
@ OJPH_PN_CINEMAS4K
@ OJPH_PN_UNDEFINED
@ OJPH_PN_CINEMAS2K
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,...)
size get_log_precinct_size(ui32 res_num) const
ui32 cal_store_size_for_encoding(ui32 enc_num_points)
ui32 cal_marker_points_size() const
ojph::param_nlt::nonlinearity nonlinearity
static ui8 get_bpp(ui32 t)
bool read_coefficient(infile_base *file, float &K, si32 &bytes)
void init(param_atk *top_atk)
bool read(infile_base *file)
param_atk * get_atk(int index)
const lifting_step * get_step(ui32 s) 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 init(param_cod *top_cod, ui16 comp_idx)
void read_coc(infile_base *file, ui32 num_comps, param_cod *top_cod)
void update_atk(param_atk *atk)
size get_precinct_size(ui32 res_num) const
param_cod * get_or_add_coc(ui32 comp_idx)
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
ojph::param_nlt::special_comp_num special_comp_num
bool write(outfile_base *file) const
param_nlt * add_object(ui32 comp_num)
void trim_non_existing_components(ui32 num_comps)
ojph::param_nlt::nonlinearity nonlinearity
void check_validity(param_siz &siz, const param_cod &cod)
const param_nlt * get_nlt_object(ui32 comp_num) const
bool read(infile_base *file)
int find_unsupported_nlt(const param_siz &siz, const param_cod &cod) const
void set_nonlinear_transform(ui32 comp_num, ui8 nl_type)
const nlt_rec * get_nlt_rec(ui32 comp_num) const
bool get_nonlinear_transform(ui32 comp_num, ui8 &decoded_bit_depth, bool &decoded_signedness, ui8 &nl_type) const
ui8 encode_SPqcd(ui8 v) const
bool write_qcc(outfile_base *file, ui32 num_comps)
float get_irrev_delta(const param_dfs *dfs, ui32 num_decompositions, ui32 comp_num, ui32 resolution, ui32 subband) 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_largest_Kmax() const
ui32 get_num_guard_bits() 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)
bool is_qcc_needed(ui32 comp_num, const param_cod &cod, const param_siz &siz)
void make_quant_steps(ui32 comp_num, const param_cod &cod, const param_siz &siz)
void init(param_qcd *top_qcd, ui16 comp_idx)
param_qcd * add_qcc_object(ui32 comp_idx)
ui32 get_Kmax(const param_dfs *dfs, ui32 num_decompositions, ui32 resolution, ui32 subband) const
void set_weights(size_t num_weights, const float *weights)
ojph::param_qcd::comp_type comp_type
void encode_SPqcd(ui32 subband_index, float delta)
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)
static constexpr ui32 MAX_SUBBAND_COUNT
void trim_non_existing_components(ui32 num_comps)
void set_qfactor(float qfactor)
bool internal_write_qcc(outfile_base *file, ui32 num_comps)
union ojph::local::param_qcd::@140013103227173134364232343330020031205064137337 SPqcd
float weights[MAX_SUBBAND_COUNT]
void set_delta(float delta, size_t num_weights, const float *weights)
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 set_image_offset(point offset)
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
void set_cod(const param_cod &cod)
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 set_tile_offset(point offset)
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)
void set_image_extent(point dims)
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)
point(ui32 x=0, ui32 y=0)
Definition ojph_base.h:59
size(ui32 w=0, ui32 h=0)
Definition ojph_base.h:49