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
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 if (precision <= 32)
66 allocator->pre_alloc_data<ui32>(nominal.h * (size_t)stride, 0);
67 else
68 allocator->pre_alloc_data<ui64>(nominal.h * (size_t)stride, 0);
69 }
70
73 subband *parent, const size& nominal,
74 const size& cb_size,
77 ui32 precision, ui32 comp_idx)
78 {
80
81 const ui32 f = byte_alignment / sizeof(ui32) - 1;
82 this->stride = (nominal.w + f) & ~f; // a multiple of 8
83 this->buf_size = this->stride * nominal.h;
84
85 if (precision <= 32) {
86 this->precision = BUF32;
87 this->buf32 = allocator->post_alloc_data<ui32>(this->buf_size, 0);
88 }
89 else {
90 this->precision = BUF64;
91 this->buf64 = allocator->post_alloc_data<ui64>(this->buf_size, 0);
92 }
93
94 this->nominal_size = nominal;
95 this->cb_size = cb_size;
96 this->parent = parent;
97 this->line_offset = line_offset;
98 this->cur_line = 0;
99 this->delta = parent->get_delta();
100 this->delta_inv = 1.0f / this->delta;
101 this->K_max = K_max;
102 for (int i = 0; i < 4; ++i)
103 this->max_val64[i] = 0;
104 const param_cod* coc = codestream->get_coc(comp_idx);
105 this->reversible = coc->is_reversible();
108 this->zero_block = false;
109 this->coded_cb = coded_cb;
110
112 }
113
116 {
117 // convert to sign and magnitude and keep max_val
118 if (precision == BUF32)
119 {
120 assert(line->flags & line_buf::LFT_32BIT);
121 const void *sp = (line->flags & line_buf::LFT_INTEGER)
122 ? (const void*)(line->i32 + line_offset)
123 : (const void*)(line->f32 + line_offset);
124 ui32 *dp = buf32 + cur_line * stride;
125 this->codeblock_functions.tx_to_cb32(sp, dp, K_max, delta_inv,
126 cb_size.w, max_val32);
127 ++cur_line;
128 }
129 else
130 {
131 assert(precision == BUF64);
132 assert(line->flags & line_buf::LFT_64BIT);
133 const si64 *sp = line->i64 + line_offset;
134 ui64 *dp = buf64 + cur_line * stride;
135 this->codeblock_functions.tx_to_cb64(sp, dp, K_max, delta_inv,
136 cb_size.w, max_val64);
137 ++cur_line;
138 }
139 }
140
143 {
144 if (precision == BUF32)
145 {
146 ui32 mv = this->codeblock_functions.find_max_val32(max_val32);
147 if (mv >= 1u << (31 - K_max))
148 {
149 coded_cb->missing_msbs = K_max - 1;
150 assert(coded_cb->missing_msbs > 0);
151 assert(coded_cb->missing_msbs < K_max);
152 coded_cb->num_passes = 1;
153
154 this->codeblock_functions.encode_cb32(buf32, K_max-1, 1,
155 cb_size.w, cb_size.h, stride, coded_cb->pass_length,
156 elastic, coded_cb->next_coded);
157 }
158 }
159 else
160 {
161 assert(precision == BUF64);
162 ui64 mv = this->codeblock_functions.find_max_val64(max_val64);
163 if (mv >= 1ULL << (63 - K_max))
164 {
165 coded_cb->missing_msbs = K_max - 1;
166 assert(coded_cb->missing_msbs > 0);
167 assert(coded_cb->missing_msbs < K_max);
168 coded_cb->num_passes = 1;
169
170 this->codeblock_functions.encode_cb64(buf64, K_max-1, 1,
171 cb_size.w, cb_size.h, stride, coded_cb->pass_length,
172 elastic, coded_cb->next_coded);
173 }
174 }
175 }
176
179 {
180 assert(cb_size.h * stride <= buf_size && cb_size.w <= stride);
181 this->cb_size = cb_size;
182 this->coded_cb = coded_cb;
183 this->cur_line = 0;
184 for (int i = 0; i < 4; ++i)
185 this->max_val64[i] = 0;
186 this->zero_block = false;
187 }
188
191 {
192 if (coded_cb->pass_length[0] > 0 && coded_cb->num_passes > 0 &&
193 coded_cb->next_coded != NULL)
194 {
195 bool result;
196 if (precision == BUF32)
197 {
198 result = this->codeblock_functions.decode_cb32(
200 buf32, coded_cb->missing_msbs, coded_cb->num_passes,
201 coded_cb->pass_length[0], coded_cb->pass_length[1],
203 }
204 else
205 {
206 assert(precision == BUF64);
207 result = this->codeblock_functions.decode_cb64(
209 buf64, coded_cb->missing_msbs, coded_cb->num_passes,
210 coded_cb->pass_length[0], coded_cb->pass_length[1],
212 }
213
214 if (result == false)
215 {
216 if (resilient == true) {
217 OJPH_INFO(0x000300A1, "Error decoding a codeblock.");
218 zero_block = true;
219 }
220 else
221 OJPH_ERROR(0x000300A1, "Error decoding a codeblock.");
222 }
223 }
224 else
225 zero_block = true;
226 }
227
228
231 {
232 //convert to sign and magnitude
233 if (precision == BUF32)
234 {
235 assert(line->flags & line_buf::LFT_32BIT);
236 void *dp = (line->flags & line_buf::LFT_INTEGER)
237 ? (void*)(line->i32 + line_offset)
238 : (void*)(line->f32 + line_offset);
239 if (!zero_block)
240 {
241 const ui32 *sp = buf32 + cur_line * stride;
242 this->codeblock_functions.tx_from_cb32(sp, dp, K_max, delta,
243 cb_size.w);
244 }
245 else
246 this->codeblock_functions.mem_clear(dp, cb_size.w * sizeof(ui32));
247 }
248 else
249 {
250 assert(precision == BUF64);
251 assert((reversible && (line->flags & line_buf::LFT_64BIT))
252 || (!reversible && (line->flags & line_buf::LFT_32BIT)));
253 si64 *dp = line->i64 + line_offset;
254 if (!zero_block)
255 {
256 const ui64 *sp = buf64 + cur_line * stride;
257 this->codeblock_functions.tx_from_cb64(sp, dp, K_max, delta,
258 cb_size.w);
259 }
260 else
261 this->codeblock_functions.mem_clear(dp, cb_size.w * sizeof(*dp));
262 }
263
264 ++cur_line;
265 assert(cur_line <= cb_size.h);
266 }
267
268 }
269}
float * f32
Definition ojph_mem.h:187
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, ui32 precision, ui32 comp_idx)
void push(line_buf *line)
static void pre_alloc(codestream *codestream, const size &nominal, ui32 precision)
void encode(mem_elastic_allocator *elastic)
void recreate(const size &cb_size, coded_cb_header *coded_cb)
codeblock_fun codeblock_functions
void pull_line(line_buf *line)
const param_cod * get_coc(ui32 comp_num)
mem_fixed_allocator * get_allocator()
void pre_alloc_data(size_t num_ele, ui32 pre_size)
Definition ojph_mem.h:72
T * post_alloc_data(size_t num_ele, ui32 pre_size)
Definition ojph_mem.h:112
const ui32 byte_alignment
Definition ojph_arch.h:344
int64_t si64
Definition ojph_defs.h:57
uint64_t ui64
Definition ojph_defs.h:56
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,...)
bool get_block_vertical_causality() const