OpenJPH
Open-source implementation of JPEG2000 Part-15
Loading...
Searching...
No Matches
ojph_block_common.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) 2022, Aous Naman
6// Copyright (c) 2022, Kakadu Software Pty Ltd, Australia
7// Copyright (c) 2022, The University of New South Wales, Australia
8// Copyright (c) 2026, Osamu Watanabe
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_block_common.cpp
35// Author: Aous Naman
36// Author: Osamu Watanabe
37// Date: 13 May 2022
38//***************************************************************************/
39
40#include <cassert>
41#include <cstddef>
42#include <cstring>
43#include "ojph_block_common.h"
44
45//***************************************************************************/
49
50namespace ojph {
51 namespace local {
52
53 //************************************************************************/
69
71 ui16 vlc_tbl0[1024] = { 0 };
74 ui16 vlc_tbl1[1024] = { 0 };
76
77 //************************************************************************/
104
106 ui16 uvlc_tbl0[256+64] = { 0 };
109 ui16 uvlc_tbl1[256] = { 0 };
114 ui32 uvlc_tbl1_wide[4096] = { 0 };
116 ui8 uvlc_bias[256+64] = { 0 };
118
119 //************************************************************************/
124 static bool vlc_init_tables()
125 {
126 const bool debug = false; //useful for checking
127
128 //Data in the table is arranged in this format (taken from the standard)
129 // c_q is the context for a quad
130 // rho is the significance pattern for a quad
131 // u_off indicate if u value is 0 (u_off is 0), or communicated
132 // e_k, e_1 EMB patterns
133 // cwd VLC codeword
134 // cwd VLC codeword length
135 struct vlc_src_table { int c_q, rho, u_off, e_k, e_1, cwd, cwd_len; };
136 // initial quad rows
137 vlc_src_table tbl0[] = {
138 #include "table0.h"
139 };
140 // number of entries in the table
141 size_t tbl0_size = sizeof(tbl0) / sizeof(vlc_src_table);
142
143 // nono-initial quad rows
144 vlc_src_table tbl1[] = {
145 #include "table1.h"
146 };
147 // number of entries in the table
148 size_t tbl1_size = sizeof(tbl1) / sizeof(vlc_src_table);
149
150 if (debug) memset(vlc_tbl0, 0, sizeof(vlc_tbl0)); //unnecessary
151
152 // this is to convert table entries into values for decoder look up
153 // There can be at most 1024 possibilities, not all of them are valid.
154 //
155 for (int i = 0; i < 1024; ++i)
156 {
157 int cwd = i & 0x7F; // from i extract codeword
158 int c_q = i >> 7; // from i extract context
159 // See if this case exist in the table, if so then set the entry in
160 // vlc_tbl0
161 for (size_t j = 0; j < tbl0_size; ++j)
162 if (tbl0[j].c_q == c_q) // this is an and operation
163 if (tbl0[j].cwd == (cwd & ((1 << tbl0[j].cwd_len) - 1)))
164 {
165 if (debug) assert(vlc_tbl0[i] == 0);
166 // Put this entry into the table
167 vlc_tbl0[i] = (ui16)((tbl0[j].rho << 4) | (tbl0[j].u_off << 3)
168 | (tbl0[j].e_k << 12) | (tbl0[j].e_1 << 8) | tbl0[j].cwd_len);
169 }
170 }
171
172 if (debug) memset(vlc_tbl1, 0, sizeof(vlc_tbl1)); //unnecessary
173
174 // this the same as above but for non-initial rows
175 for (int i = 0; i < 1024; ++i)
176 {
177 int cwd = i & 0x7F; //7 bits
178 int c_q = i >> 7;
179 for (size_t j = 0; j < tbl1_size; ++j)
180 if (tbl1[j].c_q == c_q) // this is an and operation
181 if (tbl1[j].cwd == (cwd & ((1 << tbl1[j].cwd_len) - 1)))
182 {
183 if (debug) assert(vlc_tbl1[i] == 0);
184 vlc_tbl1[i] = (ui16)((tbl1[j].rho << 4) | (tbl1[j].u_off << 3)
185 | (tbl1[j].e_k << 12) | (tbl1[j].e_1 << 8) | tbl1[j].cwd_len);
186 }
187 }
188
189 return true;
190 }
191
192 //************************************************************************/
196 static bool uvlc_init_tables()
197 {
198 // table stores possible decoding three bits from vlc
199 // there are 8 entries for xx1, x10, 100, 000, where x means do not
200 // care table value is made up of
201 // 2 bits in the LSB for prefix length
202 // 3 bits for suffix length
203 // 3 bits in the MSB for prefix value (u_pfx in Table 3 of ITU T.814)
204 static const ui8 dec[8] = { // the index is the prefix codeword
205 3 | (5 << 2) | (5 << 5), //000 == 000, prefix codeword "000"
206 1 | (0 << 2) | (1 << 5), //001 == xx1, prefix codeword "1"
207 2 | (0 << 2) | (2 << 5), //010 == x10, prefix codeword "01"
208 1 | (0 << 2) | (1 << 5), //011 == xx1, prefix codeword "1"
209 3 | (1 << 2) | (3 << 5), //100 == 100, prefix codeword "001"
210 1 | (0 << 2) | (1 << 5), //101 == xx1, prefix codeword "1"
211 2 | (0 << 2) | (2 << 5), //110 == x10, prefix codeword "01"
212 1 | (0 << 2) | (1 << 5) //111 == xx1, prefix codeword "1"
213 };
214
215 for (ui32 i = 0; i < 256 + 64; ++i)
216 {
217 ui32 mode = i >> 6;
218 ui32 vlc = i & 0x3F;
219
220 if (mode == 0) { // both u_off are 0
221 uvlc_tbl0[i] = 0;
222 uvlc_bias[i] = 0;
223 }
224 else if (mode <= 2) // u_off are either 01 or 10
225 {
226 ui32 d = dec[vlc & 0x7]; //look at the least significant 3 bits
227
228 ui32 total_prefix = d & 0x3;
229 ui32 total_suffix = (d >> 2) & 0x7;
230 ui32 u0_suffix_len = (mode == 1) ? total_suffix : 0;
231 ui32 u0 = (mode == 1) ? (d >> 5) : 0;
232 ui32 u1 = (mode == 1) ? 0 : (d >> 5);
233
234 uvlc_tbl0[i] = (ui16)(total_prefix |
235 (total_suffix << 3) |
236 (u0_suffix_len << 7) |
237 (u0 << 10) |
238 (u1 << 13));
239
240 }
241 else if (mode == 3) // both u_off are 1, and MEL event is 0
242 {
243 ui32 d0 = dec[vlc & 0x7]; // LSBs of VLC are prefix codeword
244 vlc >>= d0 & 0x3; // Consume bits
245 ui32 d1 = dec[vlc & 0x7]; // LSBs of VLC are prefix codeword
246
247 ui32 total_prefix, u0_suffix_len, total_suffix, u0, u1;
248 if ((d0 & 0x3) == 3)
249 {
250 total_prefix = (d0 & 0x3) + 1;
251 u0_suffix_len = (d0 >> 2) & 0x7;
252 total_suffix = u0_suffix_len;
253 u0 = d0 >> 5;
254 u1 = (vlc & 1) + 1;
255 uvlc_bias[i] = 4; // 0b00 for u0 and 0b01 for u1
256 }
257 else
258 {
259 total_prefix = (d0 & 0x3) + (d1 & 0x3);
260 u0_suffix_len = (d0 >> 2) & 0x7;
261 total_suffix = u0_suffix_len + ((d1 >> 2) & 0x7);
262 u0 = d0 >> 5;
263 u1 = d1 >> 5;
264 uvlc_bias[i] = 0;
265 }
266
267 uvlc_tbl0[i] = (ui16)(total_prefix |
268 (total_suffix << 3) |
269 (u0_suffix_len << 7) |
270 (u0 << 10) |
271 (u1 << 13));
272 }
273 else if (mode == 4) // both u_off are 1, and MEL event is 1
274 {
275 ui32 d0 = dec[vlc & 0x7]; // LSBs of VLC are prefix codeword
276 vlc >>= d0 & 0x3; // Consume bits
277 ui32 d1 = dec[vlc & 0x7]; // LSBs of VLC are prefix codeword
278
279 ui32 total_prefix = (d0 & 0x3) + (d1 & 0x3);
280 ui32 u0_suffix_len = (d0 >> 2) & 0x7;
281 ui32 total_suffix = u0_suffix_len + ((d1 >> 2) & 0x7);
282 ui32 u0 = (d0 >> 5) + 2;
283 ui32 u1 = (d1 >> 5) + 2;
284
285 uvlc_tbl0[i] = (ui16)(total_prefix |
286 (total_suffix << 3) |
287 (u0_suffix_len << 7) |
288 (u0 << 10) |
289 (u1 << 13));
290 uvlc_bias[i] = 10; // 0b10 for u0 and 0b10 for u1
291 }
292 }
293
294 for (ui32 i = 0; i < 256; ++i)
295 {
296 ui32 mode = i >> 6;
297 ui32 vlc = i & 0x3F;
298
299 if (mode == 0) // both u_off are 0
300 uvlc_tbl1[i] = 0;
301 else if (mode <= 2) // u_off are either 01 or 10
302 {
303 ui32 d = dec[vlc & 0x7]; // look at the 3 LSB bits
304
305 ui32 total_prefix = d & 0x3;
306 ui32 total_suffix = (d >> 2) & 0x7;
307 ui32 u0_suffix_len = (mode == 1) ? total_suffix : 0;
308 ui32 u0 = (mode == 1) ? (d >> 5) : 0;
309 ui32 u1 = (mode == 1) ? 0 : (d >> 5);
310
311 uvlc_tbl1[i] = (ui16)(total_prefix |
312 (total_suffix << 3) |
313 (u0_suffix_len << 7) |
314 (u0 << 10) |
315 (u1 << 13));
316 }
317 else if (mode == 3) // both u_off are 1
318 {
319 ui32 d0 = dec[vlc & 0x7]; // LSBs of VLC are prefix codeword
320 vlc >>= d0 & 0x3; // Consume bits
321 ui32 d1 = dec[vlc & 0x7]; // LSBs of VLC are prefix codeword
322
323 ui32 total_prefix = (d0 & 0x3) + (d1 & 0x3);
324 ui32 u0_suffix_len = (d0 >> 2) & 0x7;
325 ui32 total_suffix = u0_suffix_len + ((d1 >> 2) & 0x7);
326 ui32 u0 = d0 >> 5;
327 ui32 u1 = d1 >> 5;
328
329 uvlc_tbl1[i] = (ui16)(total_prefix |
330 (total_suffix << 3) |
331 (u0_suffix_len << 7) |
332 (u0 << 10) |
333 (u1 << 13));
334 }
335 }
336 return true;
337 }
338
339 //************************************************************************/
347 {
348 static const ui8 dec[8] = {
349 3 | (5 << 2) | (5 << 5), //000
350 1 | (0 << 2) | (1 << 5), //xx1
351 2 | (0 << 2) | (2 << 5), //x10
352 1 | (0 << 2) | (1 << 5), //xx1
353 3 | (1 << 2) | (3 << 5), //100
354 1 | (0 << 2) | (1 << 5), //xx1
355 2 | (0 << 2) | (2 << 5), //x10
356 1 | (0 << 2) | (1 << 5) //xx1
357 };
358
359 for (ui32 idx = 0; idx < 4096; ++idx)
360 {
361 ui32 mode = idx >> 10; // 2 bits
362 ui32 vlc = idx & 0x3FF; // 10 bits
363
364 if (mode == 0) {
365 uvlc_tbl1_wide[idx] = 0;
366 continue;
367 }
368
369 if (mode <= 2) // single UVLC (one u_off set)
370 {
371 ui32 d = dec[vlc & 0x7];
372 ui32 prefix_len = d & 0x3;
373 ui32 suffix_len = (d >> 2) & 0x7;
374 ui32 u_pfx = d >> 5;
375 ui32 suffix_val = (vlc >> prefix_len) & ((1u << suffix_len) - 1);
376 ui32 u_val = u_pfx + suffix_val;
377 ui32 total = prefix_len + suffix_len;
378 ui32 u_q0 = (mode == 1) ? u_val : 0;
379 ui32 u_q1 = (mode == 2) ? u_val : 0;
380 uvlc_tbl1_wide[idx] = total | (u_q0 << 5) | (u_q1 << 13);
381 continue;
382 }
383
384 // mode == 3: both u_off set
385 // Bitstream layout: [prefix0][prefix1][suffix0][suffix1]
386 ui32 d0 = dec[vlc & 0x7];
387 ui32 p0_len = d0 & 0x3;
388 ui32 s0_len = (d0 >> 2) & 0x7;
389 ui32 u0_pfx = d0 >> 5;
390
391 ui32 vlc1 = vlc >> p0_len; // consume prefix0
392 ui32 d1 = dec[vlc1 & 0x7];
393 ui32 p1_len = d1 & 0x3;
394 ui32 s1_len = (d1 >> 2) & 0x7;
395 ui32 u1_pfx = d1 >> 5;
396
397 ui32 total_prefix = p0_len + p1_len;
398 ui32 total_suffix = s0_len + s1_len;
399 ui32 total = total_prefix + total_suffix;
400
401 if (total > 10) {
402 uvlc_tbl1_wide[idx] = 0x1F; // fallback sentinel
403 continue;
404 }
405
406 // suffixes follow both prefixes in the bitstream
407 ui32 suffix_bits = vlc >> total_prefix;
408 ui32 s0_val = suffix_bits & ((1u << s0_len) - 1);
409 ui32 s1_val = (suffix_bits >> s0_len) & ((1u << s1_len) - 1);
410
411 ui32 u_q0 = u0_pfx + s0_val;
412 ui32 u_q1 = u1_pfx + s1_val;
413 uvlc_tbl1_wide[idx] = total | (u_q0 << 5) | (u_q1 << 13);
414 }
415 return true;
416 }
417
418 //************************************************************************/
423
424 //************************************************************************/
429
430 //************************************************************************/
435
436 } // !namespace local
437} // !namespace ojph
ui8 uvlc_bias[256+64]
uvlc_bias contains decoding info. for initial row of quads
static bool uvlc_tables_initialized
Initializes UVLC tables uvlc_tbl0 and uvlc_tbl1.
static bool uvlc_init_tables()
Initializes uvlc_tbl0 and uvlc_tbl1 tables.
ui32 uvlc_tbl1_wide[4096]
uvlc_tbl1_wide: wider UVLC table for non-initial rows. Index = mode(2 bits) * 1024 + vlc_data(10 bits...
static bool uvlc_wide_initialized
Initializes wide UVLC table uvlc_tbl1_wide.
ui16 uvlc_tbl0[256+64]
uvlc_tbl0 contains decoding information for initial row of quads
ui16 uvlc_tbl1[256]
uvlc_tbl1 contains decoding information for non-initial row of quads
static bool uvlc_init_wide_table()
Initializes uvlc_tbl1_wide: wider UVLC table for non-initial rows. Index = mode(2b) * 1024 + vlc(10b)...
static bool vlc_tables_initialized
Initializes VLC tables vlc_tbl0 and vlc_tbl1.
static bool vlc_init_tables()
Initializes vlc_tbl0 and vlc_tbl1 tables, from table0.h and table1.h.
ui16 vlc_tbl1[1024]
vlc_tbl1 contains decoding information for non-initial row of quads
ui16 vlc_tbl0[1024]
vlc_tbl0 contains decoding information for initial row of quads
uint16_t ui16
Definition ojph_defs.h:52
uint32_t ui32
Definition ojph_defs.h:54
uint8_t ui8
Definition ojph_defs.h:50