OpenJPH: /build/openjph/src/OpenJPH/src/core/codestream/ojph_precinct.cpp Source File

OpenJPH Open-source implementation of JPEG2000 Part-15

Loading...
Searching...
No Matches
ojph_precinct.cpp
Go to the documentation of this file.
1//***************************************************************************/
2// This software is released under the 2-Clause BSD license, included
3// below.
4//
5// Copyright (c) 2019, Aous Naman
6// Copyright (c) 2019, Kakadu Software Pty Ltd, Australia
7// Copyright (c) 2019, The University of New South Wales, Australia
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// 1. Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15//
16// 2. Redistributions in binary form must reproduce the above copyright
17// notice, this list of conditions and the following disclaimer in the
18// documentation and/or other materials provided with the distribution.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31//***************************************************************************/
32// This file is part of the OpenJPH software implementation.
33// File: ojph_precinct.cpp
34// Author: Aous Naman
35// Date: 28 August 2019
36//***************************************************************************/
37
38
39#include <climits>
40#include <cmath>
41
42#include "ojph_mem.h"
43#include "ojph_params.h"
44#include "ojph_codestream_local.h"
45#include "ojph_precinct.h"
46#include "ojph_subband.h"
47#include "ojph_codeblock.h" // for coded_cb_header
48#include "ojph_bitbuffer_write.h"
49#include "ojph_bitbuffer_read.h"
50
51
52namespace ojph {
53
54 namespace local
55 {
56
58 struct tag_tree
59 {
60 void init(ui8* buf, ui32 *lev_idx, ui32 num_levels, size s, int init_val)
61 {
62 for (ui32 i = 0; i <= num_levels; ++i) //on extra level
63 levs[i] = buf + lev_idx[i];
64 for (ui32 i = num_levels + 1; i < 16; ++i)
65 levs[i] = (ui8*)INT_MAX; //make it crash on error
66 width = s.w;
67 height = s.h;
68 for (ui32 i = 0; i < num_levels; ++i)
69 {
70 ui32 size = 1u << ((num_levels - 1 - i) << 1);
71 memset(levs[i], init_val, size);
72 }
73 *levs[num_levels] = 0;
74 this->num_levels = num_levels;
75 }
76
77 ui8* get(ui32 x, ui32 y, ui32 lev)
78 {
79 return levs[lev] + (x + y * ((width + (1 << lev) - 1) >> lev));
80 }
81
82 ui32 width, height, num_levels;
83 ui8* levs[16]; // you cannot have this high number of levels
84 };
85
87 static inline ui32 log2ceil(ui32 x)
88 {
89 ui32 t = 31 - count_leading_zeros(x);
90 return t + (x & (x - 1) ? 1 : 0);
91 }
92
94 ui32 precinct::prepare_precinct(int tag_tree_size, ui32* lev_idx,
95 mem_elastic_allocator* elastic)
96 {
97 bit_write_buf bb;
98 coded_lists *cur_coded_list = NULL;
99 ui32 cb_bytes = 0; //cb_bytes;
100 ui32 ph_bytes = 0; //precinct header size
101 int num_skipped_subbands = 0;
102 for (int s = 0; s < 4; ++s)
103 {
104 if (bands[s].empty)
105 continue;
106
107 if (cb_idxs[s].siz.w == 0 || cb_idxs[s].siz.h == 0)
108 continue;
109
110 ui32 num_levels = 1 +
111 ojph_max(log2ceil(cb_idxs[s].siz.w), log2ceil(cb_idxs[s].siz.h));
112
113 //create quad trees for inclusion and missing msbs
114 tag_tree inc_tag, inc_tag_flags, mmsb_tag, mmsb_tag_flags;
115 inc_tag.init(scratch, lev_idx, num_levels, cb_idxs[s].siz, 255);
116 inc_tag_flags.init(scratch + tag_tree_size,
117 lev_idx, num_levels, cb_idxs[s].siz, 0);
118 mmsb_tag.init(scratch + (tag_tree_size<<1),
119 lev_idx, num_levels, cb_idxs[s].siz, 255);
120 mmsb_tag_flags.init(scratch + (tag_tree_size<<1) + tag_tree_size,
121 lev_idx, num_levels, cb_idxs[s].siz, 0);
122 ui32 band_width = bands[s].num_blocks.w;
123 coded_cb_header *cp = bands[s].coded_cbs;
124 cp += cb_idxs[s].org.x + cb_idxs[s].org.y * band_width;
125 for (ui32 y = 0; y < cb_idxs[s].siz.h; ++y)
126 {
127 for (ui32 x = 0; x < cb_idxs[s].siz.w; ++x)
128 {
129 coded_cb_header *p = cp + x;
130 *inc_tag.get(x, y, 0) = (p->next_coded == NULL); //1 if true
131 *mmsb_tag.get(x, y, 0) = (ui8)p->missing_msbs;
132 }
133 cp += band_width;
134 }
135 for (ui32 lev = 1; lev < num_levels; ++lev)
136 {
137 ui32 height = (cb_idxs[s].siz.h + (1<<lev) - 1) >> lev;
138 ui32 width = (cb_idxs[s].siz.w + (1<<lev) - 1) >> lev;
139 for (ui32 y = 0; y < height; ++y)
140 {
141 for (ui32 x = 0; x < width; ++x)
142 {
143 ui8 t1, t2;
144 t1 = ojph_min(*inc_tag.get(x<<1, y<<1, lev-1),
145 *inc_tag.get((x<<1) + 1, y<<1, lev-1));
146 t2 = ojph_min(*inc_tag.get(x<<1, (y<<1) + 1, lev-1),
147 *inc_tag.get((x<<1) + 1, (y<<1) + 1, lev-1));
148 *inc_tag.get(x, y, lev) = ojph_min(t1, t2);
149 *inc_tag_flags.get(x, y, lev) = 0;
150 t1 = ojph_min(*mmsb_tag.get(x<<1, y<<1, lev-1),
151 *mmsb_tag.get((x<<1) + 1, y<<1, lev-1));
152 t2 = ojph_min(*mmsb_tag.get(x<<1, (y<<1) + 1, lev-1),
153 *mmsb_tag.get((x<<1) + 1, (y<<1) + 1, lev-1));
154 *mmsb_tag.get(x, y, lev) = ojph_min(t1, t2);
155 *mmsb_tag_flags.get(x, y, lev) = 0;
156 }
157 }
158 }
159 *inc_tag.get(0,0,num_levels) = 0;
160 *inc_tag_flags.get(0,0,num_levels) = 0;
161 *mmsb_tag.get(0,0,num_levels) = 0;
162 *mmsb_tag_flags.get(0,0,num_levels) = 0;
163 if (*inc_tag.get(0, 0, num_levels-1) != 0) //empty subband
164 {
165 if (coded) //non empty precinct, tag tree top is 0
166 bb_put_bits(&bb, 0, 1, elastic, cur_coded_list, ph_bytes);
167 else
168 ++num_skipped_subbands;
169 continue;
170 }
171 //now we are in a position to code
172 if (coded == NULL)
173 {
174 bb_init(&bb, elastic, cur_coded_list);
175 coded = cur_coded_list;
176 //store non empty packet
177 bb_put_bit(&bb, 1, elastic, cur_coded_list, ph_bytes);
178
179 // if the first one or two subbands are empty (has codeblocks but
180 // no data in them), we need to code them here.
181 bb_put_bits(&bb, 0, num_skipped_subbands, elastic, cur_coded_list,
182 ph_bytes);
183 num_skipped_subbands = 0; //this line is not needed
184 }
185
186 ui32 width = cb_idxs[s].siz.w;
187 ui32 height = cb_idxs[s].siz.h;
188 for (ui32 y = 0; y < height; ++y)
189 {
190 cp = bands[s].coded_cbs;
191 cp += cb_idxs[s].org.x + (y + cb_idxs[s].org.y) * band_width;
192 for (ui32 x = 0; x < width; ++x, ++cp)
193 {
194 //inclusion bits
195 for (ui32 cur_lev = num_levels; cur_lev > 0; --cur_lev)
196 {
197 ui32 levm1 = cur_lev - 1;
198 //check sent
199 if (*inc_tag_flags.get(x>>levm1, y>>levm1, levm1) == 0)
200 {
201 ui32 skipped = *inc_tag.get(x>>levm1, y>>levm1, levm1);
202 skipped -= *inc_tag.get(x>>cur_lev, y>>cur_lev, cur_lev);
203 assert(skipped <= 1); // for HTJ2K, this should 0 or 1
204 bb_put_bits(&bb, 1 - skipped, 1,
205 elastic, cur_coded_list, ph_bytes);
206 *inc_tag_flags.get(x>>levm1, y>>levm1, levm1) = 1;
207 }
208 if (*inc_tag.get(x>>levm1, y>>levm1, levm1) > 0)
209 break;
210 }
211
212 if (cp->num_passes == 0) //empty codeblock
213 continue;
214
215 //missing msbs
216 for (ui32 cur_lev = num_levels; cur_lev > 0; --cur_lev)
217 {
218 ui32 levm1 = cur_lev - 1;
219 //check sent
220 if (*mmsb_tag_flags.get(x>>levm1, y>>levm1, levm1) == 0)
221 {
222 int num_zeros = *mmsb_tag.get(x>>levm1, y>>levm1, levm1);
223 num_zeros -= *mmsb_tag.get(x>>cur_lev, y>>cur_lev, cur_lev);
224 bb_put_zeros(&bb, num_zeros,
225 elastic, cur_coded_list, ph_bytes);
226 bb_put_bits(&bb, 1, 1,
227 elastic, cur_coded_list, ph_bytes);
228 *mmsb_tag_flags.get(x>>levm1, y>>levm1, levm1) = 1;
229 }
230 }
231
232 //number of coding passes
233 switch (cp->num_passes)
234 {
235 case 3:
236 bb_put_bits(&bb, 12, 4, elastic, cur_coded_list, ph_bytes);
237 break;
238 case 2:
239 bb_put_bits(&bb, 2, 2, elastic, cur_coded_list, ph_bytes);
240 break;
241 case 1:
242 bb_put_bits(&bb, 0, 1, elastic, cur_coded_list, ph_bytes);
243 break;
244 default:
245 assert(0);
246 }
247
248 //pass lengths
249 //either one, two, or three passes, but only one or two lengths
250 int bits1 = 32 - (int)count_leading_zeros(cp->pass_length[0]);
251 int extra_bit = cp->num_passes > 2 ? 1 : 0; //for 2nd length
252 int bits2 = 0;
253 if (cp->num_passes > 1)
254 bits2 = 32 - (int)count_leading_zeros(cp->pass_length[1]);
255 int bits = ojph_max(bits1, bits2 - extra_bit) - 3;
256 bits = ojph_max(bits, 0);
257 bb_put_bits(&bb, 0xFFFFFFFEu, bits+1,
258 elastic, cur_coded_list, ph_bytes);
259
260 bb_put_bits(&bb, cp->pass_length[0], bits+3,
261 elastic, cur_coded_list, ph_bytes);
262 if (cp->num_passes > 1)
263 bb_put_bits(&bb, cp->pass_length[1], bits+3+extra_bit,
264 elastic, cur_coded_list, ph_bytes);
265
266 cb_bytes += cp->pass_length[0] + cp->pass_length[1];
267 }
268 }
269 }
270
271 if (coded)
272 {
273 bb_terminate(&bb);
274 ph_bytes += cur_coded_list->buf_size - cur_coded_list->avail_size;
275 }
276
277 return coded ? cb_bytes + ph_bytes : 1; // 1 for empty packet
278 }
279
281 void precinct::write(outfile_base *file)
282 {
283 if (coded)
284 {
285 //write packet header
286 coded_lists *ccl = coded;
287 while (ccl)
288 {
289 file->write(ccl->buf, ccl->buf_size - ccl->avail_size);
290 ccl = ccl->next_list;
291 }
292
293 //write codeblocks
294 for (int s = 0; s < 4; ++s)
295 {
296 if (bands[s].empty)
297 continue;
298
299 ui32 band_width = bands[s].num_blocks.w;
300 ui32 width = cb_idxs[s].siz.w;
301 ui32 height = cb_idxs[s].siz.h;
302 for (ui32 y = 0; y < height; ++y)
303 {
304 coded_cb_header *cp = bands[s].coded_cbs;
305 cp += cb_idxs[s].org.x + (y + cb_idxs[s].org.y) * band_width;
306 for (ui32 x = 0; x < width; ++x, ++cp)
307 {
308 coded_lists *ccl = cp->next_coded;
309 while (ccl)
310 {
311 file->write(ccl->buf, ccl->buf_size - ccl->avail_size);
312 ccl = ccl->next_list;
313 }
314 }
315 }
316 }
317 }
318 else
319 {
320 //empty packet
321 char buf = 0x00;
322 file->write(&buf, 1);
323 }
324 }
325
326
328 void precinct::parse(int tag_tree_size, ui32* lev_idx,
329 mem_elastic_allocator *elastic,
330 ui32 &data_left, infile_base *file,
331 bool skipped)
332 {
333 assert(data_left > 0);
334 bit_read_buf bb;
335 bb_init(&bb, data_left, file);
336 if (may_use_sop)
337 bb_skip_sop(&bb);
338
339 bool empty_packet = true;
340 for (int s = 0; s < 4; ++s)
341 {
342 if (bands[s].empty)
343 continue;
344
345 if (cb_idxs[s].siz.w == 0 || cb_idxs[s].siz.h == 0)
346 continue;
347
348 if (empty_packet) //one bit to check if the packet is empty
349 {
350 ui32 bit;
351 bb_read_bit(&bb, bit);
352 if (bit == 0) //empty packet
353 { bb_terminate(&bb, uses_eph); data_left = bb.bytes_left; return; }
354 empty_packet = false;
355 }
356
357 ui32 num_levels = 1 +
358 ojph_max(log2ceil(cb_idxs[s].siz.w), log2ceil(cb_idxs[s].siz.h));
359
360 //create quad trees for inclusion and missing msbs
361 tag_tree inc_tag, inc_tag_flags, mmsb_tag, mmsb_tag_flags;
362 inc_tag.init(scratch, lev_idx, num_levels, cb_idxs[s].siz, 0);
363 *inc_tag.get(0, 0, num_levels) = 0;
364 inc_tag_flags.init(scratch + tag_tree_size, lev_idx, num_levels,
365 cb_idxs[s].siz, 0);
366 *inc_tag_flags.get(0, 0, num_levels) = 0;
367 mmsb_tag.init(scratch + (tag_tree_size<<1), lev_idx, num_levels,
368 cb_idxs[s].siz, 0);
369 *mmsb_tag.get(0, 0, num_levels) = 0;
370 mmsb_tag_flags.init(scratch + (tag_tree_size<<1) + tag_tree_size,
371 lev_idx, num_levels, cb_idxs[s].siz, 0);
372 *mmsb_tag_flags.get(0, 0, num_levels) = 0;
373
374 //
375 ui32 band_width = bands[s].num_blocks.w;
376 ui32 width = cb_idxs[s].siz.w;
377 ui32 height = cb_idxs[s].siz.h;
378 for (ui32 y = 0; y < height; ++y)
379 {
380 coded_cb_header *cp = bands[s].coded_cbs;
381 cp += cb_idxs[s].org.x + (y + cb_idxs[s].org.y) * band_width;
382 for (ui32 x = 0; x < width; ++x, ++cp)
383 {
384 //process inclusion
385 bool empty_cb = false;
386 for (ui32 cl = num_levels; cl > 0; --cl)
387 {
388 ui32 cur_lev = cl - 1;
389 empty_cb = *inc_tag.get(x>>cur_lev, y>>cur_lev, cur_lev) == 1;
390 if (empty_cb)
391 break;
392 //check received
393 if (*inc_tag_flags.get(x>>cur_lev, y>>cur_lev, cur_lev) == 0)
394 {
395 ui32 bit;
396 if (bb_read_bit(&bb, bit) == false)
397 { data_left = 0; throw "error reading from file p1"; }
398 empty_cb = (bit == 0);
399 *inc_tag.get(x>>cur_lev, y>>cur_lev, cur_lev) = (ui8)(1 - bit);
400 *inc_tag_flags.get(x>>cur_lev, y>>cur_lev, cur_lev) = 1;
401 }
402 if (empty_cb)
403 break;
404 }
405
406 if (empty_cb)
407 continue;
408
409 //process missing msbs
410 ui32 mmsbs = 0;
411 for (ui32 levp1 = num_levels; levp1 > 0; --levp1)
412 {
413 ui32 cur_lev = levp1 - 1;
414 mmsbs = *mmsb_tag.get(x>>levp1, y>>levp1, levp1);
415 //check received
416 if (*mmsb_tag_flags.get(x>>cur_lev, y>>cur_lev, cur_lev) == 0)
417 {
418 ui32 bit = 0;
419 while (bit == 0)
420 {
421 if (bb_read_bit(&bb, bit) == false)
422 { data_left = 0; throw "error reading from file p2"; }
423 mmsbs += 1 - bit;
424 }
425 *mmsb_tag.get(x>>cur_lev, y>>cur_lev, cur_lev) = (ui8)mmsbs;
426 *mmsb_tag_flags.get(x>>cur_lev, y>>cur_lev, cur_lev) = 1;
427 }
428 }
429
430 if (mmsbs > cp->Kmax)
431 throw "error in parsing a tile header; "
432 "missing msbs are larger or equal to Kmax. The most likely "
433 "cause is a corruption in the bitstream.";
434 cp->missing_msbs = mmsbs;
435
436 //get number of passes
437 ui32 bit, num_passes = 1;
438 if (bb_read_bit(&bb, bit) == false)
439 { data_left = 0; throw "error reading from file p3"; }
440 if (bit)
441 {
442 num_passes = 2;
443 if (bb_read_bit(&bb, bit) == false)
444 { data_left = 0; throw "error reading from file p4"; }
445 if (bit)
446 {
447 if (bb_read_bits(&bb, 2, bit) == false)
448 { data_left = 0; throw "error reading from file p5"; }
449 num_passes = 3 + bit;
450 if (bit == 3)
451 {
452 if (bb_read_bits(&bb, 5, bit) == false)
453 { data_left = 0; throw "error reading from file p6"; }
454 num_passes = 6 + bit;
455 if (bit == 31)
456 {
457 if (bb_read_bits(&bb, 7, bit) == false)
458 { data_left = 0; throw "error reading from file p7"; }
459 num_passes = 37 + bit;
460 }
461 }
462 }
463 }
464 cp->num_passes = num_passes;
465
466 // Parse pass lengths
467 // When number of passes is one, one length.
468 // When number of passes is two or three, two lengths.
469 // When number of passes > 3, we have place holder passes;
470 // In this case, subtract multiples of 3 from the number of
471 // passes; for example, if we have 10 passes, we subtract 9,
472 // producing 1 pass.
473
474 // 1 => 1, 2 => 2, 3 => 3, 4 => 1, 5 => 2, 6 => 3
475 ui32 num_phld_passes = (num_passes - 1) / 3;
476 cp->missing_msbs += num_phld_passes;
477
478 num_phld_passes *= 3;
479 cp->num_passes = num_passes - num_phld_passes;
480 cp->pass_length[0] = cp->pass_length[1] = 0;
481
482 int Lblock = 3;
483 bit = 1;
484 while (bit)
485 {
486 // add any extra bits here
487 if (bb_read_bit(&bb, bit) == false)
488 { data_left = 0; throw "error reading from file p8"; }
489 Lblock += bit;
490 }
491
492 int bits = Lblock + 31 -
493 (int)count_leading_zeros(num_phld_passes + 1);
494 if (bb_read_bits(&bb, bits, bit) == false)
495 { data_left = 0; throw "error reading from file p9"; }
496 if (bit < 2)
497 throw "The cleanup segment of an HT codeblock cannot contain "
498 "less than 2 bytes";
499 if (bit >= 65535)
500 throw "The cleanup segment of an HT codeblock must contain "
501 "less than 65535 bytes";
502 cp->pass_length[0] = bit;
503
504 if (cp->num_passes > 1)
505 {
506 //bits = Lblock + 31 - count_leading_zeros(cp->num_passes - 1);
507 // The following is simpler than the above, I think?
508 bits = Lblock + (cp->num_passes > 2 ? 1 : 0);
509 if (bb_read_bits(&bb, bits, bit) == false)
510 { data_left = 0; throw "error reading from file p10"; }
511 if (bit >= 2047)
512 throw "The refinement segment (SigProp and MagRep passes) of "
513 "an HT codeblock must contain less than 2047 bytes";
514 cp->pass_length[1] = bit;
515 }
516 }
517 }
518 }
519 if (empty_packet)
520 { // all subbands are empty
521 ui32 bit = 0;
522 bb_read_bit(&bb, bit);
523 //assert(bit == 0);
524 }
525 bb_terminate(&bb, uses_eph);
526 //read codeblock data
527 for (int s = 0; s < 4; ++s)
528 {
529 if (bands[s].empty)
530 continue;
531
532 ui32 band_width = bands[s].num_blocks.w;
533 ui32 width = cb_idxs[s].siz.w;
534 ui32 height = cb_idxs[s].siz.h;
535 for (ui32 y = 0; y < height; ++y)
536 {
537 coded_cb_header *cp = bands[s].coded_cbs;
538 cp += cb_idxs[s].org.x + (y + cb_idxs[s].org.y) * band_width;
539 for (ui32 x = 0; x < width; ++x, ++cp)
540 {
541 ui32 num_bytes = cp->pass_length[0] + cp->pass_length[1];
542 if (data_left)
543 {
544 if (num_bytes)
545 {
546 if (skipped)
547 { //no need to read
548 si64 cur_loc = file->tell();
549 ui32 t = ojph_min(num_bytes, bb.bytes_left);
550 file->seek(t, infile_base::OJPH_SEEK_CUR);
551 ui32 bytes_read = (ui32)(file->tell() - cur_loc);
552 cp->pass_length[0] = cp->pass_length[1] = 0;
553 bb.bytes_left -= bytes_read;
554 assert(bytes_read == t || bb.bytes_left == 0);
555 }
556 else
557 {
558 if (!bb_read_chunk(&bb, num_bytes, cp->next_coded, elastic))
559 {
560 //no need to decode a broken codeblock
561 cp->pass_length[0] = cp->pass_length[1] = 0;
562 data_left = 0;
563 }
564 }
565 }
566 }
567 else
568 cp->pass_length[0] = cp->pass_length[1] = 0;
569 }
570 }
571 }
572 data_left = bb.bytes_left;
573 }
574
575 }
576}
ojph::infile_base
Definition ojph_file.h:267
ojph::infile_base::seek
seek
Definition ojph_file.h:269
ojph::infile_base::OJPH_SEEK_CUR
@ OJPH_SEEK_CUR
Definition ojph_file.h:271
ojph::infile_base::tell
virtual si64 tell()=0
ojph::mem_elastic_allocator
Definition ojph_mem.h:218
ojph::outfile_base
Definition ojph_file.h:75
ojph::outfile_base::write
virtual size_t write(const void *ptr, size_t size)=0
ojph::local
Definition ojph_bitbuffer_read.h:53
ojph::local::bb_read_chunk
static bool bb_read_chunk(bit_read_buf *bbp, ui32 num_bytes, coded_lists *&cur_coded_list, mem_elastic_allocator *elastic)
Definition ojph_bitbuffer_read.h:134
ojph::local::bb_read_bit
static bool bb_read_bit(bit_read_buf *bbp, ui32 &bit)
Definition ojph_bitbuffer_read.h:103
ojph::local::bb_read_bits
static bool bb_read_bits(bit_read_buf *bbp, int num_bits, ui32 &bits)
Definition ojph_bitbuffer_read.h:114
ojph::local::bb_skip_sop
static bool bb_skip_sop(bit_read_buf *bbp)
Definition ojph_bitbuffer_read.h:184
ojph::local::bb_terminate
static bool bb_terminate(bit_read_buf *bbp, bool uses_eph)
Definition ojph_bitbuffer_read.h:169
ojph::local::log2ceil
static ui32 log2ceil(ui32 x)
Definition ojph_precinct.cpp:87
ojph::local::bb_put_zeros
static void bb_put_zeros(bit_write_buf *bbp, int num_zeros, mem_elastic_allocator *elastic, coded_lists *&cur_coded_list, ui32 &ph_bytes)
Definition ojph_bitbuffer_write.h:114
ojph::local::bb_put_bits
static void bb_put_bits(bit_write_buf *bbp, ui32 data, int num_bits, mem_elastic_allocator *elastic, coded_lists *&cur_coded_list, ui32 &ph_bytes)
Definition ojph_bitbuffer_write.h:124
ojph::local::bb_init
static void bb_init(bit_read_buf *bbp, ui32 bytes_left, infile_base *file)
Definition ojph_bitbuffer_read.h:68
ojph::local::bb_put_bit
static void bb_put_bit(bit_write_buf *bbp, ui32 bit, mem_elastic_allocator *elastic, coded_lists *&cur_coded_list, ui32 &ph_bytes)
Definition ojph_bitbuffer_write.h:90
ojph
Definition ojph_img_io.h:52
ojph::si64
int64_t si64
Definition ojph_defs.h:57
ojph::count_leading_zeros
static ui32 count_leading_zeros(ui32 val)
Definition ojph_arch.h:206
ojph::ui32
uint32_t ui32
Definition ojph_defs.h:54
ojph::ui8
uint8_t ui8
Definition ojph_defs.h:50
ojph_bitbuffer_read.h
ojph_bitbuffer_write.h
ojph_codeblock.h
ojph_codestream_local.h
ojph_max
#define ojph_max(a, b)
Definition ojph_defs.h:73
ojph_min
#define ojph_min(a, b)
Definition ojph_defs.h:76
ojph_mem.h
ojph_params.h
ojph_precinct.h
ojph_subband.h
ojph::coded_lists
Definition ojph_mem.h:202
ojph::coded_lists::buf_size
ui32 buf_size
Definition ojph_mem.h:211
ojph::coded_lists::buf
ui8 * buf
Definition ojph_mem.h:213
ojph::coded_lists::next_list
coded_lists * next_list
Definition ojph_mem.h:210
ojph::coded_lists::avail_size
ui32 avail_size
Definition ojph_mem.h:212
ojph::local::bit_read_buf
Definition ojph_bitbuffer_read.h:58
ojph::local::bit_read_buf::bytes_left
ui32 bytes_left
Definition ojph_bitbuffer_read.h:63
ojph::local::bit_write_buf
Definition ojph_bitbuffer_write.h:56
ojph::local::coded_cb_header
Definition ojph_codeblock.h:116
ojph::local::coded_cb_header::next_coded
coded_lists * next_coded
Definition ojph_codeblock.h:121
ojph::local::coded_cb_header::pass_length
ui32 pass_length[2]
Definition ojph_codeblock.h:117
ojph::local::coded_cb_header::missing_msbs
ui32 missing_msbs
Definition ojph_codeblock.h:120
ojph::local::coded_cb_header::Kmax
ui32 Kmax
Definition ojph_codeblock.h:119
ojph::local::coded_cb_header::num_passes
ui32 num_passes
Definition ojph_codeblock.h:118
ojph::local::precinct::may_use_sop
bool may_use_sop
Definition ojph_precinct.h:76
ojph::local::precinct::write
void write(outfile_base *file)
Definition ojph_precinct.cpp:281
ojph::local::precinct::coded
coded_lists * coded
Definition ojph_precinct.h:75
ojph::local::precinct::bands
subband * bands
Definition ojph_precinct.h:74
ojph::local::precinct::scratch
ui8 * scratch
Definition ojph_precinct.h:71
ojph::local::precinct::prepare_precinct
ui32 prepare_precinct(int tag_tree_size, ui32 *lev_idx, mem_elastic_allocator *elastic)
Definition ojph_precinct.cpp:94
ojph::local::precinct::parse
void parse(int tag_tree_size, ui32 *lev_idx, mem_elastic_allocator *elastic, ui32 &data_left, infile_base *file, bool skipped)
Definition ojph_precinct.cpp:328
ojph::local::precinct::uses_eph
bool uses_eph
Definition ojph_precinct.h:76
ojph::local::precinct::cb_idxs
rect cb_idxs[4]
Definition ojph_precinct.h:73
ojph::local::tag_tree
Definition ojph_precinct.cpp:59
ojph::local::tag_tree::levs
ui8 * levs[16]
Definition ojph_precinct.cpp:83
ojph::local::tag_tree::get
ui8 * get(ui32 x, ui32 y, ui32 lev)
Definition ojph_precinct.cpp:77
ojph::local::tag_tree::width
ui32 width
Definition ojph_precinct.cpp:82
ojph::local::tag_tree::num_levels
ui32 num_levels
Definition ojph_precinct.cpp:82
ojph::local::tag_tree::height
ui32 height
Definition ojph_precinct.cpp:82
ojph::local::tag_tree::init
void init(ui8 *buf, ui32 *lev_idx, ui32 num_levels, size s, int init_val)
Definition ojph_precinct.cpp:60
ojph::size
Definition ojph_base.h:48
ojph::size::w
ui32 w
Definition ojph_base.h:50
ojph::size::h
ui32 h
Definition ojph_base.h:51