OpenJPH
Open-source implementation of JPEG2000 Part-15
Loading...
Searching...
No Matches
ojph_codeblock.cpp
Go to the documentation of this file.
1
2//***************************************************************************/
3// This software is released under the 2-Clause BSD license, included
4// below.
5//
6// Copyright (c) 2019, Aous Naman
7// Copyright (c) 2019, Kakadu Software Pty Ltd, Australia
8// Copyright (c) 2019, The University of New South Wales, Australia
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//***************************************************************************/
33// This file is part of the OpenJPH software implementation.
34// File: ojph_codeblock.cpp
35// Author: Aous Naman
36// Date: 28 August 2019
37//***************************************************************************/
38
39
40#include <climits>
41#include <cmath>
42
43#include "ojph_mem.h"
44#include "ojph_params.h"
46#include "ojph_codeblock.h"
47#include "ojph_subband.h"
48#include "ojph_resolution.h"
49
50namespace ojph {
51
52 namespace local
53 {
54
57 const size& nominal)
58 {
60
61 assert(byte_alignment / sizeof(ui32) > 1);
62 const ui32 f = byte_alignment / sizeof(ui32) - 1;
63 ui32 stride = (nominal.w + f) & ~f; // a multiple of 8
64
65 const param_siz* sz = codestream->get_siz();
66 const param_cod* cd = codestream->get_cod(comp_num);
67 ui32 precision = cd->propose_precision(sz, comp_num);
68 if (precision <= 32)
69 allocator->pre_alloc_data<ui32>(nominal.h * (size_t)stride, 0);
70 else
71 allocator->pre_alloc_data<ui64>(nominal.h * (size_t)stride, 0);
72 }
73
76 subband *parent, const size& nominal,
77 const size& cb_size,
78 coded_cb_header* coded_cb,
79 ui32 K_max, int line_offset)
80 {
82
83 const ui32 f = byte_alignment / sizeof(ui32) - 1;
84 this->stride = (nominal.w + f) & ~f; // a multiple of 8
85 this->buf_size = this->stride * nominal.h;
86
87 ui32 comp_num = parent->get_parent()->get_comp_num();
88 const param_siz* sz = codestream->get_siz();
89 const param_cod* cd = codestream->get_cod(comp_num);
90 ui32 bit_depth = cd->propose_precision(sz, comp_num);
91 if (bit_depth <= 32) {
93 this->buf32 = allocator->post_alloc_data<ui32>(this->buf_size, 0);
94 }
95 else {
97 this->buf64 = allocator->post_alloc_data<ui64>(this->buf_size, 0);
98 }
99
100 this->nominal_size = nominal;
101 this->cb_size = cb_size;
102 this->parent = parent;
103 this->line_offset = line_offset;
104 this->cur_line = 0;
105 this->delta = parent->get_delta();
106 this->delta_inv = 1.0f / this->delta;
107 this->K_max = K_max;
108 for (int i = 0; i < 4; ++i)
109 this->max_val64[i] = 0;
111 this->reversible = cod.is_reversible();
112 this->resilient = codestream->is_resilient();
114 this->zero_block = false;
115 this->coded_cb = coded_cb;
116
118 }
119
122 {
123 // convert to sign and magnitude and keep max_val
124 if (precision == BUF32)
125 {
126 assert(line->flags & line_buf::LFT_32BIT);
127 const si32 *sp = line->i32 + line_offset;
128 ui32 *dp = buf32 + cur_line * stride;
131 ++cur_line;
132 }
133 else
134 {
135 assert(precision == BUF64);
136 assert(line->flags & line_buf::LFT_64BIT);
137 const si64 *sp = line->i64 + line_offset;
138 ui64 *dp = buf64 + cur_line * stride;
141 ++cur_line;
142 }
143 }
144
147 {
148 if (precision == BUF32)
149 {
151 if (mv >= 1u << (31 - K_max))
152 {
154 assert(coded_cb->missing_msbs > 0);
155 assert(coded_cb->missing_msbs < K_max);
156 coded_cb->num_passes = 1;
157
160 elastic, coded_cb->next_coded);
161 }
162 }
163 else
164 {
165 assert(precision == BUF64);
167 if (mv >= 1ULL << (63 - K_max))
168 {
170 assert(coded_cb->missing_msbs > 0);
171 assert(coded_cb->missing_msbs < K_max);
172 coded_cb->num_passes = 1;
173
176 elastic, coded_cb->next_coded);
177 }
178 }
179 }
180
182 void codeblock::recreate(const size &cb_size, coded_cb_header* coded_cb)
183 {
184 assert(cb_size.h * stride <= buf_size && cb_size.w <= stride);
185 this->cb_size = cb_size;
186 this->coded_cb = coded_cb;
187 this->cur_line = 0;
188 for (int i = 0; i < 4; ++i)
189 this->max_val64[i] = 0;
190 this->zero_block = false;
191 }
192
195 {
196 if (coded_cb->pass_length[0] > 0 && coded_cb->num_passes > 0 &&
197 coded_cb->next_coded != NULL)
198 {
199 bool result;
200 if (precision == BUF32)
201 {
202 result = this->codeblock_functions.decode_cb32(
207 }
208 else
209 {
210 assert(precision == BUF64);
211 result = this->codeblock_functions.decode_cb64(
216 }
217
218 if (result == false)
219 {
220 if (resilient == true) {
221 OJPH_INFO(0x000300A1, "Error decoding a codeblock.");
222 zero_block = true;
223 }
224 else
225 OJPH_ERROR(0x000300A1, "Error decoding a codeblock.");
226 }
227 }
228 else
229 zero_block = true;
230 }
231
232
235 {
236 //convert to sign and magnitude
237 if (precision == BUF32)
238 {
239 assert(line->flags & line_buf::LFT_32BIT);
240 si32 *dp = line->i32 + line_offset;
241 if (!zero_block)
242 {
243 const ui32 *sp = buf32 + cur_line * stride;
245 cb_size.w);
246 }
247 else
248 this->codeblock_functions.mem_clear(dp, cb_size.w * sizeof(ui32));
249 }
250 else
251 {
252 assert(precision == BUF64);
253 assert(line->flags & line_buf::LFT_64BIT);
254 si64 *dp = line->i64 + line_offset;
255 if (!zero_block)
256 {
257 const ui64 *sp = buf64 + cur_line * stride;
259 cb_size.w);
260 }
261 else
262 this->codeblock_functions.mem_clear(dp, cb_size.w * sizeof(*dp));
263 }
264
265 ++cur_line;
266 assert(cur_line <= cb_size.h);
267 }
268
269 }
270}
coded_cb_header * coded_cb
void push(line_buf *line)
static void pre_alloc(codestream *codestream, ui32 comp_num, const size &nominal)
void encode(mem_elastic_allocator *elastic)
void recreate(const size &cb_size, coded_cb_header *coded_cb)
void finalize_alloc(codestream *codestream, subband *parent, const size &nominal, const size &cb_size, coded_cb_header *coded_cb, ui32 K_max, int tbx0)
codeblock_fun codeblock_functions
void pull_line(line_buf *line)
mem_fixed_allocator * get_allocator()
resolution * get_parent()
void pre_alloc_data(size_t num_ele, ui32 pre_size)
Definition ojph_mem.h:66
T * post_alloc_data(size_t num_ele, ui32 pre_size)
Definition ojph_mem.h:89
bool is_reversible() const
bool get_block_vertical_causality() const
const ui32 byte_alignment
Definition ojph_arch.h:290
int64_t si64
Definition ojph_defs.h:57
uint64_t ui64
Definition ojph_defs.h:56
int32_t si32
Definition ojph_defs.h:55
uint32_t ui32
Definition ojph_defs.h:54
#define OJPH_INFO(t,...)
MACROs to insert file and line number for info, warning, and error.
#define OJPH_ERROR(t,...)
find_max_val_fun32 find_max_val32
find_max_val_fun64 find_max_val64
ui32 propose_precision(const param_siz *siz, ui32 comp_num) const