OpenJPH
Open-source implementation of JPEG2000 Part-15
ojph_codestream_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_codestream_local.h
34 // Author: Aous Naman
35 // Date: 28 August 2019
36 //***************************************************************************/
37 
38 
39 #ifndef OJPH_CODESTREAM_LOCAL_H
40 #define OJPH_CODESTREAM_LOCAL_H
41 
42 #include "ojph_defs.h"
43 #include "ojph_file.h"
44 #include "ojph_params_local.h"
45 
46 namespace ojph {
47 
49  //defined elsewhere
50  struct line_buf;
51  class mem_fixed_allocator;
52  class mem_elastic_allocator;
53  class codestream;
54  struct coded_lists;
55 
56  namespace local {
57 
59  //defined here
60  class tile;
61  class tile_comp;
62  class resolution;
63  struct precinct;
64  class subband;
65  class codeblock;
66  struct coded_cb_header;
67 
69  class codestream
70  {
71  friend ::ojph::codestream;
72 
73  public:
74  codestream();
75  ~codestream();
76 
77  void pre_alloc();
78  void finalize_alloc();
79 
80  ojph::param_siz access_siz() //return externally wrapped siz
81  { return ojph::param_siz(&siz); }
82  const param_siz* get_siz() //return internal siz
83  { return &siz; }
84  ojph::param_cod access_cod() //return externally wrapped cod
85  { return ojph::param_cod(&cod); }
86  const param_cod* get_cod() //return internal code
87  { return &cod; }
89  {
90  if (used_qcc_fields > 0)
91  for (int v = 0; v < used_qcc_fields; ++v)
92  if (qcc[v].get_comp_num() == comp_num)
93  return qcc + v;
94  return &qcd;
95  }
98  outfile_base* get_file() { return outfile; }
99 
100  line_buf* exchange(line_buf* line, ui32& next_component);
101  void write_headers(outfile_base *file);
102  void enable_resilience();
103  bool is_resilient() { return resilient; }
104  void read_headers(infile_base *file);
105  void restrict_input_resolution(ui32 skipped_res_for_data,
107  void read();
108  void set_planar(int planar);
109  void set_profile(const char *s);
110  line_buf* pull(ui32 &comp_num);
111  void flush();
112  void close();
113 
114  bool is_planar() const { return planar != 0; }
115  si32 get_profile() const { return profile; };
116 
117  void check_imf_validity();
119 
122  { return skipped_res_for_recon; }
124  { return skipped_res_for_read; }
125 
126  private:
129 
130  private:
134  bool resilient;
136 
137  private:
142  size *comp_size; //stores full resolution no. of lines and width
143  size *recon_comp_size; //stores number of lines and width of each comp
145  int planar;
146  int profile;
147 
148  private:
154 
155  private: // this is to handle qcc
157  param_qcc qcc_store[4], *qcc; // we allocate 4,
158  // if not enough, we allocate more
159 
160  private:
165  };
166 
168  class tile
169  {
170  public:
171  static void pre_alloc(codestream *codestream, const rect& tile_rect,
172  const rect& recon_tile_rect);
174  const rect& recon_tile_rect,
175  ui32 tile_idx, ui32 offset);
176 
177  bool push(line_buf *line, ui32 comp_num);
178  void prepare_for_flush();
179  void fill_tlm(param_tlm* tlm);
180  void flush(outfile_base *file);
181  void parse_tile_header(const param_sot& sot, infile_base *file,
182  const ui64& tile_start_location);
183  bool pull(line_buf *, ui32 comp_num);
185 
186  private:
187  //codestream *parent;
197 
199  bool *is_signed;
202 
203  private:
206 
207  private:
208  int profile;
209  ui32 *num_comp_bytes; //this for use with TLM
210  };
211 
213  class tile_comp
214  {
215  public:
216  static void pre_alloc(codestream *codestream, const rect& comp_rect,
217  const rect& recon_comp_rect);
218  void finalize_alloc(codestream *codestream, tile *parent,
219  ui32 comp_num, const rect& comp_rect,
220  const rect& recon_comp_rect);
221 
224  tile* get_tile() { return parent_tile; }
225  line_buf* get_line();
226  void push_line();
227  line_buf* pull_line();
228 
230  void write_precincts(ui32 res_num, outfile_base *file);
231  bool get_top_left_precinct(ui32 res_num, point &top_left);
232  void write_one_precinct(ui32 res_num, outfile_base *file);
233  void parse_precincts(ui32 res_num, ui32& data_left, infile_base *file);
234  void parse_one_precinct(ui32 res_num, ui32& data_left,
235  infile_base *file);
236 
237  private:
244  };
245 
248  {
249  public:
250 
251  public:
252  static void pre_alloc(codestream *codestream, const rect& res_rect,
253  const rect& recon_res_rect, ui32 res_num);
255  const rect& recon_res_rect, ui32 comp_num,
257  tile_comp *parent_tile_comp,
259 
260  line_buf* get_line() { return lines + 0; }
261  void push_line();
262  line_buf* pull_line();
263  rect get_rect() { return res_rect; }
264  ui32 get_comp_num() { return comp_num; }
265 
267  void write_precincts(outfile_base *file);
268  bool get_top_left_precinct(point &top_left);
269  void write_one_precinct(outfile_base *file);
271  void parse_all_precincts(ui32& data_left, infile_base *file);
272  void parse_one_precinct(ui32& data_left, infile_base *file);
273 
274  private:
285  //precincts stuff
291  ui32 level_index[20]; //more than enough
292  point cur_precinct_loc; //used for progressing spatial modes (2, 3, 4)
293  //wavelet machinery
297  };
298 
300  struct precinct
301  {
303  scratch = NULL; bands = NULL; coded = NULL;
304  num_bands = 0; may_use_sop = uses_eph = false;
305  }
306  ui32 prepare_precinct(int tag_tree_size, ui32* lev_idx,
307  mem_elastic_allocator *elastic);
308  void write(outfile_base *file);
309  void parse(int tag_tree_size, ui32* lev_idx,
310  mem_elastic_allocator *elastic,
311  ui32& data_left, infile_base *file, bool skipped);
312 
314  point img_point; //the precinct projected to full resolution
315  rect cb_idxs[4]; //indices of codeblocks
316  subband *bands; //the subbands
320  };
321 
323  class subband
324  {
325  friend struct precinct;
326  public:
327  static void pre_alloc(codestream *codestream, const rect& band_rect,
328  ui32 res_num);
330  resolution* res, ui32 res_num, ui32 subband_num);
331 
332  void exchange_buf(line_buf* l);
333  line_buf* get_line() { return lines; }
334  void push_line();
335 
336  void get_cb_indices(const size& num_precincts, precinct *precincts);
337  float get_delta() { return delta; }
338 
339  line_buf* pull_line();
340 
341  private:
344  bool empty;
353  int cur_line;
355  float delta, delta_inv;
359  };
360 
362  class codeblock
363  {
364  friend struct precinct;
365  public:
366  static void pre_alloc(codestream *codestream, const size& nominal);
368  const size& nominal, const size& cb_size,
370  ui32 K_max, int tbx0);
371  void push(line_buf *line);
372  void encode(mem_elastic_allocator *elastic);
374 
375  void decode();
376  void pull_line(line_buf *line);
377 
378  private:
387  float delta, delta_inv;
390  bool resilient;
392  bool zero_block; // true when the decoded block is all zero
393  ui32 max_val[8]; // supports up to 256 bits
395 
396  private:
397  // define function signature simple memory clearing
398  typedef void (*mem_clear_fun)(void* addr, size_t count);
399  // a pointer to the max value finding function
401  static void gen_mem_clear(void* addr, size_t count);
402 
403  // define function signature for max value finding
404  typedef ui32 (*find_max_val_fun)(ui32* addr);
405  // a pointer to the max value finding function
407  static ui32 gen_find_max_val(ui32* addr) { return addr[0]; }
408 
409  // define line transfer function signature from subbands to codeblocks
410  typedef void (*tx_to_cb_fun)(const void *sp, ui32 *dp, ui32 K_max,
411  float delta_inv, ui32 count, ui32* max_val);
412  // a pointer to function transferring samples from subbands to codeblocks
414  static void gen_rev_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max,
415  float delta_inv, ui32 count, ui32* max_val);
416  static void gen_irv_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max,
417  float delta_inv, ui32 count, ui32* max_val);
418 
419  // define line transfer function signature from codeblock to subband
420  typedef void (*tx_from_cb_fun)(const ui32 *sp, void *dp, ui32 K_max,
421  float delta, ui32 count);
422  // a pointer to function transferring samples from codeblocks to subbands
424  static void gen_rev_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max,
425  float delta, ui32 count);
426  static void gen_irv_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max,
427  float delta, ui32 count);
428 
429  // define the block decoder function signature
430  typedef bool (*cb_decoder_fun)(ui8* coded_data, ui32* decoded_data,
431  ui32 missing_msbs, ui32 num_passes, ui32 lengths1, ui32 lengths2,
432  ui32 width, ui32 height, ui32 stride, bool stripe_causal);
433  // a pointer to the decoder function
435  };
436 
439  {
445 
446  static const int prefix_buf_size = 8;
447  static const int suffix_buf_size = 16;
448  };
449 
451  void sse_mem_clear(void* addr, size_t count);
452  void avx_mem_clear(void* addr, size_t count);
453  void wasm_mem_clear(void* addr, size_t count);
454 
456  ui32 sse2_find_max_val(ui32* address);
457  ui32 avx2_find_max_val(ui32* address);
458  ui32 wasm_find_max_val(ui32* address);
459 
461  void sse2_rev_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max,
462  float delta_inv, ui32 count, ui32* max_val);
463  void avx2_rev_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max,
464  float delta_inv, ui32 count, ui32* max_val);
465  void sse2_irv_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max,
466  float delta_inv, ui32 count, ui32* max_val);
467  void avx2_irv_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max,
468  float delta_inv, ui32 count, ui32* max_val);
469  void wasm_rev_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max,
470  float delta_inv, ui32 count, ui32* max_val);
471  void wasm_irv_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max,
472  float delta_inv, ui32 count, ui32* max_val);
473 
475  void sse2_rev_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max,
476  float delta, ui32 count);
477  void avx2_rev_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max,
478  float delta, ui32 count);
479  void sse2_irv_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max,
480  float delta, ui32 count);
481  void avx2_irv_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max,
482  float delta, ui32 count);
483  void wasm_rev_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max,
484  float delta, ui32 count);
485  void wasm_irv_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max,
486  float delta, ui32 count);
487 
488  }
489 }
490 
491 
492 #endif // !OJPH_CODESTREAM_LOCAL_H
bool(* cb_decoder_fun)(ui8 *coded_data, ui32 *decoded_data, ui32 missing_msbs, ui32 num_passes, ui32 lengths1, ui32 lengths2, ui32 width, ui32 height, ui32 stride, bool stripe_causal)
static void gen_mem_clear(void *addr, size_t count)
ui32(* find_max_val_fun)(ui32 *addr)
static void gen_rev_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
static ui32 gen_find_max_val(ui32 *addr)
static void pre_alloc(codestream *codestream, const size &nominal)
void(* mem_clear_fun)(void *addr, size_t count)
static void gen_irv_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
void(* tx_to_cb_fun)(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
void push(line_buf *line)
void(* tx_from_cb_fun)(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
static cb_decoder_fun decode_cb
void encode(mem_elastic_allocator *elastic)
void recreate(const size &cb_size, coded_cb_header *coded_cb)
static void gen_irv_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
void finalize_alloc(codestream *codestream, subband *parent, const size &nominal, const size &cb_size, coded_cb_header *coded_cb, ui32 K_max, int tbx0)
static void gen_rev_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
void pull_line(line_buf *line)
mem_elastic_allocator * get_elastic_alloc()
line_buf * exchange(line_buf *line, ui32 &next_component)
const param_siz * get_siz()
void restrict_input_resolution(ui32 skipped_res_for_data, ui32 skipped_res_for_recon)
mem_elastic_allocator * elastic_alloc
mem_fixed_allocator * allocator
mem_fixed_allocator * get_allocator()
param_qcd * access_qcd(ui32 comp_num)
void read_headers(infile_base *file)
const param_cod * get_cod()
void set_profile(const char *s)
void write_headers(outfile_base *file)
line_buf * pull(ui32 &comp_num)
bool get_top_left_precinct(point &top_left)
void parse_one_precinct(ui32 &data_left, infile_base *file)
mem_elastic_allocator * elastic
void write_precincts(outfile_base *file)
void finalize_alloc(codestream *codestream, const rect &res_rect, const rect &recon_res_rect, ui32 comp_num, ui32 res_num, point comp_downsamp, tile_comp *parent_tile_comp, resolution *parent_res)
void parse_all_precincts(ui32 &data_left, infile_base *file)
static void pre_alloc(codestream *codestream, const rect &res_rect, const rect &recon_res_rect, ui32 res_num)
void write_one_precinct(outfile_base *file)
void exchange_buf(line_buf *l)
coded_cb_header * coded_cbs
void get_cb_indices(const size &num_precincts, precinct *precincts)
mem_elastic_allocator * elastic
static void pre_alloc(codestream *codestream, const rect &band_rect, ui32 res_num)
void finalize_alloc(codestream *codestream, const rect &band_rect, resolution *res, ui32 res_num, ui32 subband_num)
static void pre_alloc(codestream *codestream, const rect &comp_rect, const rect &recon_comp_rect)
bool get_top_left_precinct(ui32 res_num, point &top_left)
void write_one_precinct(ui32 res_num, outfile_base *file)
void finalize_alloc(codestream *codestream, tile *parent, ui32 comp_num, const rect &comp_rect, const rect &recon_comp_rect)
void parse_one_precinct(ui32 res_num, ui32 &data_left, infile_base *file)
void write_precincts(ui32 res_num, outfile_base *file)
void parse_precincts(ui32 res_num, ui32 &data_left, infile_base *file)
bool pull(line_buf *, ui32 comp_num)
void finalize_alloc(codestream *codestream, const rect &tile_rect, const rect &recon_tile_rect, ui32 tile_idx, ui32 offset)
void fill_tlm(param_tlm *tlm)
static void pre_alloc(codestream *codestream, const rect &tile_rect, const rect &recon_tile_rect)
void flush(outfile_base *file)
bool push(line_buf *line, ui32 comp_num)
void parse_tile_header(const param_sot &sot, infile_base *file, const ui64 &tile_start_location)
ui32 avx2_find_max_val(ui32 *address)
void avx2_irv_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
void sse2_irv_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
void avx_mem_clear(void *addr, size_t count)
void wasm_irv_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
void avx2_rev_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
void wasm_irv_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
void sse2_irv_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
void sse_mem_clear(void *addr, size_t count)
void wasm_rev_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
void sse2_rev_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
void sse2_rev_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
void wasm_mem_clear(void *addr, size_t count)
ui32 sse2_find_max_val(ui32 *address)
void wasm_rev_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
void avx2_rev_tx_from_cb(const ui32 *sp, void *dp, ui32 K_max, float delta, ui32 count)
void avx2_irv_tx_to_cb(const void *sp, ui32 *dp, ui32 K_max, float delta_inv, ui32 count, ui32 *max_val)
ui32 wasm_find_max_val(ui32 *address)
uint64_t ui64
Definition: ojph_defs.h:56
int32_t si32
Definition: ojph_defs.h:55
uint32_t ui32
Definition: ojph_defs.h:54
uint8_t ui8
Definition: ojph_defs.h:50
void write(outfile_base *file)
ui32 prepare_precinct(int tag_tree_size, ui32 *lev_idx, mem_elastic_allocator *elastic)
void parse(int tag_tree_size, ui32 *lev_idx, mem_elastic_allocator *elastic, ui32 &data_left, infile_base *file, bool skipped)