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 48 //////////////////////////////////////////////////////////////////////////// 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 58 ////////////////////////////////////////////////////////////////////////// 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 68 ////////////////////////////////////////////////////////////////////////// 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 access_siz()80 ojph::param_siz access_siz() //return externally wrapped siz 81 { return ojph::param_siz(&siz); } get_siz()82 const param_siz* get_siz() //return internal siz 83 { return &siz; } access_cod()84 ojph::param_cod access_cod() //return externally wrapped cod 85 { return ojph::param_cod(&cod); } get_cod()86 const param_cod* get_cod() //return internal code 87 { return &cod; } access_qcd(int comp_num)88 param_qcd* access_qcd(int comp_num) 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 } get_allocator()96 mem_fixed_allocator* get_allocator() { return allocator; } get_elastic_alloc()97 mem_elastic_allocator* get_elastic_alloc() { return elastic_alloc; } get_file()98 outfile_base* get_file() { return outfile; } 99 100 line_buf* exchange(line_buf* line, int& next_component); 101 void write_headers(outfile_base *file); 102 void enable_resilience(); is_resilient()103 bool is_resilient() { return resilient; } 104 void read_headers(infile_base *file); 105 void restrict_input_resolution(int skipped_res_for_data, 106 int skipped_res_for_recon); 107 void read(); 108 void set_planar(int planar); 109 void set_profile(const char *s); 110 line_buf* pull(int &comp_num); 111 void flush(); 112 void close(); 113 is_planar()114 bool is_planar() const { return planar != 0; } get_profile()115 si32 get_profile() const { return profile; }; 116 117 void check_imf_validity(); 118 void check_broadcast_validity(); 119 get_precinct_scratch()120 ui8* get_precinct_scratch() { return precinct_scratch; } get_skipped_res_for_recon()121 int get_skipped_res_for_recon() 122 { return skipped_res_for_recon; } get_skipped_res_for_read()123 int get_skipped_res_for_read() 124 { return skipped_res_for_read; } 125 126 private: 127 int precinct_scratch_needed_bytes; 128 ui8* precinct_scratch; 129 130 private: 131 int cur_line; 132 int cur_comp; 133 int cur_tile_row; 134 bool resilient; 135 int skipped_res_for_read, skipped_res_for_recon; 136 137 private: 138 size num_tiles; 139 tile *tiles; 140 line_buf* line; 141 int num_comps; 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 144 bool employ_color_transform; 145 int planar; 146 int profile; 147 148 private: 149 param_siz siz; 150 param_cod cod; 151 param_cap cap; 152 param_qcd qcd; 153 param_tlm tlm; 154 155 private: // this is to handle qcc 156 int used_qcc_fields; 157 param_qcc qcc_store[4], *qcc; // we allocate 4, 158 // if not enough, we allocate more 159 160 private: 161 mem_fixed_allocator *allocator; 162 mem_elastic_allocator *elastic_alloc; 163 outfile_base *outfile; 164 infile_base *infile; 165 }; 166 167 ////////////////////////////////////////////////////////////////////////// 168 class tile 169 { 170 public: 171 static void pre_alloc(codestream *codestream, const rect& tile_rect, 172 const rect& recon_tile_rect); 173 void finalize_alloc(codestream *codestream, const rect& tile_rect, 174 const rect& recon_tile_rect, 175 int tile_idx, int offset); 176 177 bool push(line_buf *line, int 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 *, int comp_num); 184 185 private: 186 codestream *parent; 187 rect tile_rect, recon_tile_rect; 188 int num_comps; 189 tile_comp *comps; 190 int num_lines; 191 line_buf* lines; 192 bool reversible, employ_color_transform, resilient; 193 rect *comp_rects, *recon_comp_rects; 194 int *line_offsets; 195 int skipped_res_for_read; 196 197 int *num_bits; 198 bool *is_signed; 199 int *cur_line; 200 int prog_order; 201 202 private: 203 param_sot sot; 204 int next_tile_part; 205 206 private: 207 int profile; 208 int *num_comp_bytes; //this for use with TLM 209 }; 210 211 ////////////////////////////////////////////////////////////////////////// 212 class tile_comp 213 { 214 public: 215 static void pre_alloc(codestream *codestream, const rect& comp_rect, 216 const rect& recon_comp_rect); 217 void finalize_alloc(codestream *codestream, tile *parent, 218 int comp_num, const rect& comp_rect, 219 const rect& recon_comp_rect); 220 get_num_resolutions()221 int get_num_resolutions() { return num_decomps + 1; } get_num_decompositions()222 int get_num_decompositions() { return num_decomps; } 223 line_buf* get_line(); 224 void push_line(); 225 line_buf* pull_line(); 226 227 ui32 prepare_precincts(); 228 void write_precincts(int res_num, outfile_base *file); 229 bool get_top_left_precinct(int res_num, point &top_left); 230 void write_one_precinct(int res_num, outfile_base *file); 231 void parse_precincts(int res_num, ui32& data_left, infile_base *file); 232 void parse_one_precinct(int res_num, ui32& data_left, infile_base *file); 233 234 private: 235 tile *parent_tile; 236 resolution *res; 237 rect comp_rect; 238 ojph::point comp_downsamp; 239 int num_decomps; 240 int comp_num; 241 }; 242 243 ////////////////////////////////////////////////////////////////////////// 244 class resolution 245 { 246 public: 247 248 public: 249 static void pre_alloc(codestream *codestream, const rect& res_rect, 250 const rect& recon_res_rect, int res_num); 251 void finalize_alloc(codestream *codestream, const rect& res_rect, 252 const rect& recon_res_rect, int comp_num, 253 int res_num, point comp_downsamp, 254 tile_comp *parent_tile, 255 resolution *parent_res); 256 get_line()257 line_buf* get_line() { return lines + 0; } 258 void push_line(); 259 line_buf* pull_line(); get_rect()260 rect get_rect() { return res_rect; } get_comp_num()261 int get_comp_num() { return comp_num; } 262 263 ui32 prepare_precinct(); 264 void write_precincts(outfile_base *file); 265 bool get_top_left_precinct(point &top_left); 266 void write_one_precinct(outfile_base *file); next_resolution()267 resolution *next_resolution() { return child_res; } 268 void parse_all_precincts(ui32& data_left, infile_base *file); 269 void parse_one_precinct(ui32& data_left, infile_base *file); 270 271 private: 272 bool reversible, skipped_res_for_read, skipped_res_for_recon; 273 int num_lines, num_bands, res_num; 274 int comp_num; 275 point comp_downsamp; 276 rect res_rect; 277 line_buf *lines; 278 subband *bands; 279 tile_comp *parent; 280 resolution *parent_res, *child_res; 281 //precincts stuff 282 precinct *precincts; 283 size num_precincts; 284 size log_PP; 285 int max_num_levels; 286 int tag_tree_size; 287 si32 level_index[20]; //more than enough 288 point cur_precinct_loc; //used for progressing spatial modes (2, 3, 4) 289 //wavelet machinery 290 int cur_line, available_lines; 291 bool vert_even, horz_even; 292 mem_elastic_allocator *elastic; 293 }; 294 295 ////////////////////////////////////////////////////////////////////////// 296 struct precinct 297 { 298 ui32 prepare_precinct(int tag_tree_size, si32* lev_idx, 299 mem_elastic_allocator *elastic); 300 void write(outfile_base *file); 301 void parse(int tag_tree_size, si32* lev_idx, 302 mem_elastic_allocator *elastic, 303 ui32& data_left, infile_base *file, bool skipped); 304 305 ui8 *scratch; 306 point img_point; //the precinct projected to full resolution 307 rect cb_idxs[4]; //indices of codeblocks 308 subband *bands; //the subbands 309 coded_lists* coded; 310 int num_bands; 311 bool special_x, special_y; 312 bool may_use_sop, uses_eph; 313 }; 314 315 ////////////////////////////////////////////////////////////////////////// 316 class subband 317 { 318 friend struct precinct; 319 public: 320 static void pre_alloc(codestream *codestream, const rect& band_rect, 321 int res_num); 322 void finalize_alloc(codestream *codestream, const rect& band_rect, 323 resolution* res, int res_num, int subband_num); 324 325 void exchange_buf(line_buf* l); get_line()326 line_buf* get_line() { return lines; } 327 void push_line(); 328 329 void get_cb_indices(const size& num_precincts, precinct *precincts); 330 331 line_buf* pull_line(); 332 333 private: 334 int res_num, band_num; 335 bool reversible; 336 rect band_rect; 337 line_buf *lines; 338 resolution* parent; 339 codeblock* blocks; 340 size num_blocks; 341 size log_PP; 342 int xcb_prime, ycb_prime; 343 int cur_cb_row; 344 int cur_line; 345 int cur_cb_height; 346 float delta, delta_inv; 347 int K_max; 348 coded_cb_header *coded_cbs; 349 mem_elastic_allocator *elastic; 350 }; 351 352 ////////////////////////////////////////////////////////////////////////// 353 class codeblock 354 { 355 friend struct precinct; 356 public: 357 static void pre_alloc(codestream *codestream, const size& nominal); 358 void finalize_alloc(codestream *codestream, subband* parent, 359 const size& nominal, const size& cb_size, 360 coded_cb_header* coded_cb, 361 int K_max, int tbx0); 362 void push(line_buf *line); 363 void encode(mem_elastic_allocator *elastic); 364 void recreate(const size& cb_size, coded_cb_header* coded_cb); 365 366 void decode(); 367 void pull_line(line_buf *line); 368 369 private: 370 si32* buf; 371 size nominal_size; 372 size cb_size; 373 subband* parent; 374 int line_offset; 375 int cur_line; 376 int K_max; 377 int max_val; 378 bool resilient; 379 coded_cb_header* coded_cb; 380 }; 381 382 ////////////////////////////////////////////////////////////////////////// 383 struct coded_cb_header 384 { 385 int pass_length[2]; 386 int num_passes; 387 int Kmax; 388 int missing_msbs; 389 coded_lists *next_coded; 390 391 static const int prefix_buf_size = 8; 392 static const int suffix_buf_size = 8; 393 }; 394 395 } 396 } 397 398 399 #endif // !OJPH_CODESTREAM_LOCAL_H 400