OpenJPH
Open-source implementation of JPEG2000 Part-15
Loading...
Searching...
No Matches
ojph_colour.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_colour.cpp
34// Author: Aous Naman
35// Date: 28 August 2019
36//***************************************************************************/
37
38#include <cmath>
39#include <climits>
40#include <mutex>
41
42#include "ojph_defs.h"
43#include "ojph_arch.h"
44#include "ojph_mem.h"
45#include "ojph_colour.h"
46#include "ojph_colour_local.h"
47
48#include "ojph_params.h"
50
51namespace ojph {
52
53 // defined elsewhere
54 class line_buf;
55
56 namespace local {
57
60 (const line_buf *src_line, const ui32 src_line_offset,
61 line_buf *dst_line, const ui32 dst_line_offset,
62 si64 shift, ui32 width) = NULL;
63
66 (const line_buf *src_line, const ui32 src_line_offset,
67 line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width,
68 const nlt_rec *rec) = NULL;
69
72 (const line_buf *src_line, const ui32 src_line_offset,
73 line_buf *dst_line, const ui32 dst_line_offset, ui32 bit_depth,
74 bool is_signed, ui32 width, const nlt_rec *rec) = NULL;
75
78 (const line_buf *src_line, const ui32 src_line_offset,
79 line_buf *dst_line, const ui32 dst_line_offset,
80 si64 shift, ui32 width) = NULL;
81
84 const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset,
85 ui32 bit_depth, bool is_signed, ui32 width) = NULL;
86
89 const line_buf *src_line, ui32 src_line_offset,
90 line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width) = NULL;
91
94 const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset,
95 ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec) = NULL;
96
99 const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset,
100 ui32 bit_depth, bool is_signed, ui32 width) = NULL;
101
104 const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line,
105 ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec) = NULL;
106
109 const line_buf *src_line, ui32 src_line_offset,
110 line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width) = NULL;
111
114 (const line_buf* r, const line_buf* g, const line_buf* b,
115 line_buf* y, line_buf* cb, line_buf* cr, ui32 repeat) = NULL;
116
119 (const line_buf* r, const line_buf* g, const line_buf* b,
120 line_buf* y, line_buf* cb, line_buf* cr, ui32 repeat) = NULL;
121
124 (const float *r, const float *g, const float *b,
125 float *y, float *cb, float *cr, ui32 repeat) = NULL;
126
129 (const float *y, const float *cb, const float *cr,
130 float *r, float *g, float *b, ui32 repeat) = NULL;
131
134 {
135 static std::once_flag colour_transform_functions_init_flag;
136 std::call_once(colour_transform_functions_init_flag, []() {
137#if !defined(OJPH_ENABLE_WASM_SIMD) || !defined(OJPH_EMSCRIPTEN)
138
153
154 #ifndef OJPH_DISABLE_SIMD
155
156 #if (defined(OJPH_ARCH_X86_64) || defined(OJPH_ARCH_I386))
157
158 #ifndef OJPH_DISABLE_SSE
160 {
163 }
164 #endif // !OJPH_DISABLE_SSE
165
166 #ifndef OJPH_DISABLE_SSE2
168 {
181 }
182 #endif // !OJPH_DISABLE_SSE2
183
184 #ifndef OJPH_DISABLE_AVX
186 {
189 }
190 #endif // !OJPH_DISABLE_AVX
191
192 #ifndef OJPH_DISABLE_AVX2
194 {
207 }
208 #endif // !OJPH_DISABLE_AVX2
209
210 #elif defined(OJPH_ARCH_ARM)
211
212 #elif defined(OJPH_ARCH_PPC64LE)
213
215 {
216 // 128-bit VSX kernels; see ojph_simd_vsx.h
229 }
230
231 #endif // !(defined(OJPH_ARCH_X86_64) || defined(OJPH_ARCH_I386))
232
233 #endif // !OJPH_DISABLE_SIMD
234
235#else // OJPH_ENABLE_WASM_SIMD
236
251
252#endif // !OJPH_ENABLE_WASM_SIMD
253 });
254 }
255
257 const float CT_CNST::ALPHA_RF = 0.299f;
258 const float CT_CNST::ALPHA_GF = 0.587f;
259 const float CT_CNST::ALPHA_BF = 0.114f;
260 const float CT_CNST::BETA_CbF = float(0.5/(1-double(CT_CNST::ALPHA_BF)));
261 const float CT_CNST::BETA_CrF = float(0.5/(1-double(CT_CNST::ALPHA_RF)));
262 const float CT_CNST::GAMMA_CB2G =
263 float(2.0*double(ALPHA_BF)*(1.0-double(ALPHA_BF))/double(ALPHA_GF));
264 const float CT_CNST::GAMMA_CR2G =
265 float(2.0*double(ALPHA_RF)*(1.0-double(ALPHA_RF))/double(ALPHA_GF));
266 const float CT_CNST::GAMMA_CB2B = float(2.0 * (1.0 - double(ALPHA_BF)));
267 const float CT_CNST::GAMMA_CR2R = float(2.0 * (1.0 - double(ALPHA_RF)));
268
270
272 template<int NLT_TYPE>
273 static inline
275 line_buf *dst_line, ui32 dst_line_offset,
276 ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec* rec)
277 {
278 assert((src_line->flags & line_buf::LFT_32BIT) &&
279 (src_line->flags & line_buf::LFT_INTEGER) == 0 &&
280 (dst_line->flags & line_buf::LFT_32BIT) &&
281 (dst_line->flags & line_buf::LFT_INTEGER));
282 ojph_unused(bit_depth);
283 ojph_unused(is_signed);
284
285 assert(rec->get_bit_depth() <= 32);
286 const float* sp = src_line->f32;
287 si32* dp = dst_line->i32 + dst_line_offset;
288
289 float mul = rec->multiplier;
290 float d_min = rec->fd_min;
291 float d_max = rec->fd_max;
292 float delta = rec->delta;
293 float inv_delta = rec->inv_delta;
294 float* lut = rec->dec_points;
295
296 if (rec->is_signed())
297 {
298 const ui32 bias = (ui32)(1ULL << (rec->get_bit_depth() - 1)) + 1u;
299 const float half = (float)(1ULL << (rec->get_bit_depth() - 1));
300 for (int i = (int)width; i > 0; --i) {
301 float t = *sp++ + 0.5f; // convert to [0, 1]
302 t = ojph_max(t, d_min);
303 t = ojph_min(t, d_max);
304 ui32 k = (ui32)floorf((t - d_min) * inv_delta);
305 float d_k = d_min + (float)k * delta;
306 float t_k = lut[k];
307 float t_kp1 = lut[k + 1];
308 float z = t_k + (t - d_k) * inv_delta * (t_kp1 - t_k);
309
310 si32 v = ojph_round(z * mul - half);
311 if (NLT_TYPE == 4)
312 v = (v >= 0) ? v : (si32)(-(ui32)v - bias);
313 *dp++ = v;
314 }
315 }
316 else
317 {
318 for (int i = (int)width; i > 0; --i) {
319 float t = *sp++ + 0.5f; // convert to [0, 1]
320 t = ojph_max(t, d_min);
321 t = ojph_min(t, d_max);
322 ui32 k = (ui32)floorf((t - d_min) * inv_delta);
323 float d_k = d_min + (float)k * delta;
324 float t_k = lut[k];
325 float t_kp1 = lut[k + 1];
326 float z = t_k + (t - d_k) * inv_delta * (t_kp1 - t_k);
327
328 si32 v = ojph_round(z * mul);
329 *dp++ = v;
330 }
331 }
332 }
333
336 line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth,
337 bool is_signed, ui32 width, const nlt_rec* rec)
338 {
339 using nl = nlt_rec::nonlinearity;
340 // if (rec->get_type() == nl::OJPH_NLT_NO_NLT)
341 // local_gen_irv_convert_to_integer_nlt0or3<false>(src_line, dst_line,
342 // dst_line_offset, bit_depth, is_signed, width);
343 // else
344 if (rec->get_type() == nl::OJPH_NLT_LUT_STYLE_NLT)
346 dst_line_offset, bit_depth, is_signed, width, rec);
347 // else if (rec->get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_NLT)
348 // local_gen_irv_convert_to_integer_nlt0or3<true>(src_line, dst_line,
349 // dst_line_offset, bit_depth, is_signed, width);
350 else if (rec->get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
352 dst_line_offset, bit_depth, is_signed, width, rec);
353 else
354 assert(0);
355 }
356
358 template<int NLT_TYPE>
359 static inline
361 ui32 src_line_offset, line_buf *dst_line,
362 ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec* rec)
363 {
364 assert((src_line->flags & line_buf::LFT_32BIT) &&
365 (src_line->flags & line_buf::LFT_INTEGER) &&
366 (dst_line->flags & line_buf::LFT_32BIT) &&
367 (dst_line->flags & line_buf::LFT_INTEGER) == 0);
368 ojph_unused(is_signed);
369 ojph_unused(bit_depth);
370
371 assert(bit_depth <= 32);
372 float mul = rec->multiplier;
373 float ft_min = rec->ft_min;
374 float ft_max = rec->ft_max;
375 float delta = rec->delta;
376 float inv_delta = rec->inv_delta;
377 float* lut = rec->approx_enc_points;
378
379 const si32* sp = src_line->i32 + src_line_offset;
380 float* dp = dst_line->f32;
381 if (rec->is_signed())
382 {
383 const ui32 bias = (ui32)(1ULL << (rec->get_bit_depth() - 1)) + 1u;
384 for (int i = (int)width; i > 0; --i) {
385 si32 v = *sp++;
386 if (NLT_TYPE == 4)
387 v = (v >= 0) ? v : (si32)(-(ui32)v - bias);
388 float t = (float)v * mul + 0.5f; // convert to [0, 1]
389
390 t = ojph_max(t, ft_min);
391 t = ojph_min(t, ft_max);
392 ui32 k = (ui32)floorf((t - ft_min) * inv_delta);
393 float d_k = ft_min + (float)k * delta;
394 float t_k = lut[k];
395 float t_kp1 = lut[k + 1];
396 float y = t_k + (t - d_k) * inv_delta * (t_kp1 - t_k);
397
398 *dp++ = y - 0.5f;
399 }
400 }
401 else
402 {
403 for (int i = (int)width; i > 0; --i) {
404 si32 v = *sp++;
405 float t = (float)v * mul; // it is in [0, 1]
406
407 t = ojph_max(t, ft_min);
408 t = ojph_min(t, ft_max);
409 ui32 k = (ui32)floorf((t - ft_min) * inv_delta);
410 float d_k = ft_min + (float)k * delta;
411 float t_k = lut[k];
412 float t_kp1 = lut[k + 1];
413 float y = t_k + (t - d_k) * inv_delta * (t_kp1 - t_k);
414
415 *dp++ = y - 0.5f;
416 }
417 }
418 }
419
421 // The precise inverse of the look-up table, for a table whose derived
422 // version is fine enough that one step of it crosses at most one entry of
423 // the table that was supplied. The entry that a value falls in is found
424 // with the same arithmetic that the approximation above uses, and the
425 // entry after that is looked at as well, to catch the values that fall
426 // past the entry that was found.
428 template<int NLT_TYPE>
429 static inline
431 const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line,
432 ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec* rec)
433 {
434 assert((src_line->flags & line_buf::LFT_32BIT) &&
435 (src_line->flags & line_buf::LFT_INTEGER) &&
436 (dst_line->flags & line_buf::LFT_32BIT) &&
437 (dst_line->flags & line_buf::LFT_INTEGER) == 0);
438 ojph_unused(is_signed);
439 ojph_unused(bit_depth);
440
441 assert(bit_depth <= 32);
442 float mul = rec->multiplier;
443 float ft_min = rec->ft_min;
444 float ft_max = rec->ft_max;
445 float fd_min = rec->fd_min;
446 float delta = rec->delta;
447 float inv_delta = rec->inv_delta;
448 ui16* indices= rec->precise_enc_dec_indices;
449 float* lut = rec->precise_dec_lut;
450
451 const si32* sp = src_line->i32 + src_line_offset;
452 float* dp = dst_line->f32;
453 if (rec->is_signed())
454 {
455 const ui32 bias = (ui32)(1ULL << (rec->get_bit_depth() - 1)) + 1u;
456 for (int i = (int)width; i > 0; --i) {
457 si32 v = *sp++;
458 if (NLT_TYPE == 4)
459 v = (v >= 0) ? v : (si32)(-(ui32)v - bias);
460 float t = (float)v * mul + 0.5f; // convert to [0, 1]
461
462 t = ojph_max(t, ft_min);
463 t = ojph_min(t, ft_max);
464 ui32 k = (ui32)floorf((t - ft_min) * inv_delta);
465 k = indices[k];
466 float y0 = lut[k]; // lookup 0
467 float y1 = lut[k + 1]; // lookup 1
468 float y2 = lut[k + 2]; // lookup 2: one-step search
469 if (t > y1)
470 { y0 = y1; y1 = y2; ++k; }
471 float y = fd_min + (float)k * delta +
472 (y1 > y0 ? (t - y0) * delta / (y1 - y0) : 0.0f);
473
474 *dp++ = y - 0.5f;
475 }
476 }
477 else
478 {
479 for (int i = (int)width; i > 0; --i) {
480 si32 v = *sp++;
481 float t = (float)v * mul; // it is in [0, 1]
482
483 t = ojph_max(t, ft_min);
484 t = ojph_min(t, ft_max);
485 ui32 k = (ui32)floorf((t - ft_min) * inv_delta);
486 k = indices[k];
487 float y0 = lut[k]; // lookup 0
488 float y1 = lut[k + 1]; // lookup 1
489 float y2 = lut[k + 2]; // lookup 2: one-step search
490 if (t > y1)
491 { y0 = y1; y1 = y2; ++k; }
492 float y = fd_min + (float)k * delta +
493 (y1 > y0 ? (t - y0) * delta / (y1 - y0) : 0.0f);
494
495 *dp++ = y - 0.5f;
496 }
497 }
498 }
499
501 // The precise inverse of the look-up table, for a table whose derived
502 // version is coarse enough that one step of it can cross more than one
503 // entry of the table that was supplied. The entry that a value falls in
504 // then has to be found by searching, which does not vectorize. This is
505 // the implementation that the SIMD versions in ojph_colour_sse2.cpp and
506 // ojph_colour_avx2.cpp copy, so keep those in step when this changes.
508 template<int NLT_TYPE>
509 static inline
511 const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line,
512 ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec* rec)
513 {
514 assert((src_line->flags & line_buf::LFT_32BIT) &&
515 (src_line->flags & line_buf::LFT_INTEGER) &&
516 (dst_line->flags & line_buf::LFT_32BIT) &&
517 (dst_line->flags & line_buf::LFT_INTEGER) == 0);
518 ojph_unused(is_signed);
519 ojph_unused(bit_depth);
520
521 assert(bit_depth <= 32);
522 assert(rec->precise_max_steps > 1);
523 float mul = rec->multiplier;
524 float ft_min = rec->ft_min;
525 float ft_max = rec->ft_max;
526 float fd_min = rec->fd_min;
527 float delta = rec->delta;
528 float inv_delta = rec->inv_delta;
529 ui16* indices= rec->precise_enc_dec_indices;
530 float* lut = rec->precise_dec_lut;
531 ui32 num_points = rec->num_points;
532
533 const si32* sp = src_line->i32 + src_line_offset;
534 float* dp = dst_line->f32;
535 if (rec->is_signed())
536 {
537 const ui32 bias = (ui32)(1ULL << (rec->get_bit_depth() - 1)) + 1u;
538 for (int i = (int)width; i > 0; --i) {
539 si32 v = *sp++;
540 if (NLT_TYPE == 4)
541 v = (v >= 0) ? v : (si32)(-(ui32)v - bias);
542 float t = (float)v * mul + 0.5f; // convert to [0, 1]
543
544 t = ojph_max(t, ft_min);
545 t = ojph_min(t, ft_max);
546 ui32 k = (ui32)floorf((t - ft_min) * inv_delta);
547 k = indices[k];
548
549 ui32 lo = k;
550 ui32 hi = ojph_min(k + rec->precise_max_steps + 1, num_points);
551 while (hi - lo > 1)
552 {
553 ui32 mid = (lo + hi) >> 1;
554 if (t >= lut[mid])
555 lo = mid;
556 else
557 hi = mid;
558 }
559
560 float y0 = lut[lo];
561 float y1 = lut[hi];
562 float y = fd_min + (float)lo * delta +
563 (y1 > y0 ? (t - y0) * delta / (y1 - y0) : 0.0f);
564
565 *dp++ = y - 0.5f;
566 }
567 }
568 else
569 {
570 for (int i = (int)width; i > 0; --i) {
571 si32 v = *sp++;
572 float t = (float)v * mul; // it is in [0, 1]
573
574 t = ojph_max(t, ft_min);
575 t = ojph_min(t, ft_max);
576 ui32 k = (ui32)floorf((t - ft_min) * inv_delta);
577 k = indices[k];
578
579 ui32 lo = k;
580 ui32 hi = ojph_min(k + rec->precise_max_steps + 1, num_points);
581 while (hi - lo > 1)
582 {
583 ui32 mid = (lo + hi) >> 1;
584 if (t >= lut[mid])
585 lo = mid;
586 else
587 hi = mid;
588 }
589
590 float y0 = lut[lo];
591 float y1 = lut[hi];
592 float y = fd_min + (float)lo * delta +
593 (y1 > y0 ? (t - y0) * delta / (y1 - y0) : 0.0f);
594
595 *dp++ = y - 0.5f;
596 }
597 }
598 }
599
602 ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth,
603 bool is_signed, ui32 width, const nlt_rec* rec)
604 {
605 using nl = nlt_rec::nonlinearity;
606 // if (rec->get_type() == nl::OJPH_NLT_NO_NLT)
607 // local_gen_irv_convert_to_float_nlt0or3<false>(src_line,
608 // src_line_offset, dst_line, bit_depth, is_signed, width);
609 // else
610 if (rec->get_type() == nl::OJPH_NLT_LUT_STYLE_NLT)
611 {
612 if (rec->approx_encoding_nlt)
614 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
615 else if (rec->precise_max_steps == 1)
617 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
618 else
620 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
621 }
622 // else if (rec->get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_NLT)
623 // local_gen_irv_convert_to_float_nlt0or3<true>(src_line,
624 // src_line_offset, dst_line, bit_depth, is_signed, width);
625 else if (rec->get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
626 {
627 if (rec->approx_encoding_nlt)
629 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
630 else if (rec->precise_max_steps == 1)
632 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
633 else
635 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
636 }
637 else
638 assert(0);
639 }
640
642 // The LUT style nonlinearities, types 2 and 4, are implemented for the
643 // irreversible wavelet only. param_nlt::check_validity refuses to write a
644 // codestream that combines them with the reversible wavelet, so this entry
645 // point is unreachable while that check is in place.
648 const line_buf *src_line, const ui32 src_line_offset,
649 line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width,
650 const nlt_rec* rec)
651 {
652 ojph_unused(src_line);
653 ojph_unused(src_line_offset);
654 ojph_unused(dst_line);
655 ojph_unused(bit_depth);
656 ojph_unused(is_signed);
657 ojph_unused(width);
658 ojph_unused(rec);
659 assert(0);
660 }
661
664 const line_buf *src_line, const ui32 src_line_offset,
665 line_buf *dst_line, const ui32 dst_line_offset,
666 ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec* rec)
667 {
668 // A codestream can still carry a LUT style nonlinearity together with the
669 // reversible wavelet, because other encoders may produce one; this
670 // library cannot invert such a nonlinearity, so the samples are passed
671 // through unchanged. The caller was warned about that when the headers
672 // of the codestream were read, which is why this is not a failure here.
673 ojph_unused(src_line);
674 ojph_unused(src_line_offset);
675 ojph_unused(dst_line);
676 ojph_unused(dst_line_offset);
677 ojph_unused(bit_depth);
678 ojph_unused(is_signed);
679 ojph_unused(width);
680 ojph_unused(rec);
681 assert(0);
682 }
683
684#if !defined(OJPH_ENABLE_WASM_SIMD) || !defined(OJPH_EMSCRIPTEN)
685
688 const line_buf *src_line, const ui32 src_line_offset,
689 line_buf *dst_line, const ui32 dst_line_offset,
690 si64 shift, ui32 width)
691 {
692 if (src_line->flags & line_buf::LFT_32BIT)
693 {
694 if (dst_line->flags & line_buf::LFT_32BIT)
695 {
696 const si32 *sp = src_line->i32 + src_line_offset;
697 si32 *dp = dst_line->i32 + dst_line_offset;
698 si32 s = (si32)shift;
699 for (ui32 i = width; i > 0; --i)
700 *dp++ = *sp++ + s;
701 }
702 else
703 {
704 const si32 *sp = src_line->i32 + src_line_offset;
705 si64 *dp = dst_line->i64 + dst_line_offset;
706 for (ui32 i = width; i > 0; --i)
707 *dp++ = *sp++ + shift;
708 }
709 }
710 else
711 {
712 assert(src_line->flags & line_buf::LFT_64BIT);
713 assert(dst_line->flags & line_buf::LFT_32BIT);
714 const si64 *sp = src_line->i64 + src_line_offset;
715 si32 *dp = dst_line->i32 + dst_line_offset;
716 for (ui32 i = width; i > 0; --i)
717 *dp++ = (si32)(*sp++ + shift);
718 }
719 }
720
723 const line_buf *src_line, const ui32 src_line_offset,
724 line_buf *dst_line, const ui32 dst_line_offset,
725 si64 shift, ui32 width)
726 {
727 if (src_line->flags & line_buf::LFT_32BIT)
728 {
729 if (dst_line->flags & line_buf::LFT_32BIT)
730 {
731 const si32 *sp = src_line->i32 + src_line_offset;
732 si32 *dp = dst_line->i32 + dst_line_offset;
733 si32 s = (si32)shift;
734 for (ui32 i = width; i > 0; --i) {
735 const si32 v = *sp++;
736 *dp++ = v >= 0 ? v : (- v - s);
737 }
738 }
739 else
740 {
741 const si32 *sp = src_line->i32 + src_line_offset;
742 si64 *dp = dst_line->i64 + dst_line_offset;
743 for (ui32 i = width; i > 0; --i) {
744 const si64 v = *sp++;
745 *dp++ = v >= 0 ? v : (- v - shift);
746 }
747 }
748 }
749 else
750 {
751 assert(src_line->flags & line_buf::LFT_64BIT);
752 assert(dst_line->flags & line_buf::LFT_32BIT);
753 const si64 *sp = src_line->i64 + src_line_offset;
754 si32 *dp = dst_line->i32 + dst_line_offset;
755 for (ui32 i = width; i > 0; --i) {
756 const si64 v = *sp++;
757 *dp++ = (si32)(v >= 0 ? v : (- v - shift));
758 }
759 }
760 }
761
763 template<bool NLT_TYPE3>
764 static inline
766 line_buf *dst_line, ui32 dst_line_offset,
767 ui32 bit_depth, bool is_signed, ui32 width)
768 {
769 assert((src_line->flags & line_buf::LFT_32BIT) &&
770 (src_line->flags & line_buf::LFT_INTEGER) == 0 &&
771 (dst_line->flags & line_buf::LFT_32BIT) &&
772 (dst_line->flags & line_buf::LFT_INTEGER));
773
774 assert(bit_depth <= 32);
775 const float* sp = src_line->f32;
776 si32* dp = dst_line->i32 + dst_line_offset;
777 // There is the possibility that converting to integer will
778 // exceed the dynamic range of 32bit integer; therefore, care must be
779 // exercised.
780 // We look if the floating point number is outside the half-closed
781 // interval [-0.5f, 0.5f). If so, we limit the resulting integer
782 // to the maximum/minimum that number supports.
783 si32 neg_limit = (si32)INT_MIN >> (32 - bit_depth);
784 float mul = (float)(1ull << bit_depth);
785 float fl_up_lim = -(float)neg_limit; // val < upper
786 float fl_low_lim = (float)neg_limit; // val >= lower
787 si32 s32_up_lim = INT_MAX >> (32 - bit_depth);
788 si32 s32_low_lim = INT_MIN >> (32 - bit_depth);
789
790 if (is_signed)
791 {
792 const ui32 bias = (ui32)(1ULL << (bit_depth - 1)) + 1u;
793 for (int i = (int)width; i > 0; --i) {
794 float t = *sp++ * mul;
795 si32 v = ojph_round(t);
796 v = t >= fl_low_lim ? v : s32_low_lim;
797 v = t < fl_up_lim ? v : s32_up_lim;
798 if (NLT_TYPE3)
799 v = (v >= 0) ? v : (si32)(-(ui32)v - bias);
800 *dp++ = v;
801 }
802 }
803 else
804 {
805 const si32 half = (si32)(1ULL << (bit_depth - 1));
806 for (int i = (int)width; i > 0; --i) {
807 float t = *sp++ * mul;
808 si32 v = ojph_round(t);
809 v = t >= fl_low_lim ? v : s32_low_lim;
810 v = t < fl_up_lim ? v : s32_up_lim;
811 *dp++ = v + half;
812 }
813 }
814 }
815
818 line_buf *dst_line, ui32 dst_line_offset,
819 ui32 bit_depth, bool is_signed, ui32 width)
820 {
822 dst_line_offset, bit_depth, is_signed, width);
823 }
824
827 line_buf *dst_line, ui32 dst_line_offset,
828 ui32 bit_depth, bool is_signed, ui32 width)
829 {
831 dst_line_offset, bit_depth, is_signed, width);
832 }
833
835 template<bool NLT_TYPE3>
836 static inline
838 ui32 src_line_offset, line_buf *dst_line,
839 ui32 bit_depth, bool is_signed, ui32 width)
840 {
841 assert((src_line->flags & line_buf::LFT_32BIT) &&
842 (src_line->flags & line_buf::LFT_INTEGER) &&
843 (dst_line->flags & line_buf::LFT_32BIT) &&
844 (dst_line->flags & line_buf::LFT_INTEGER) == 0);
845
846 assert(bit_depth <= 32);
847 float mul = (float)(1.0 / (double)(1ULL << bit_depth));
848
849 const si32* sp = src_line->i32 + src_line_offset;
850 float* dp = dst_line->f32;
851 if (is_signed)
852 {
853 const ui32 bias = (ui32)(1ULL << (bit_depth - 1)) + 1u;
854 for (int i = (int)width; i > 0; --i) {
855 si32 v = *sp++;
856 if (NLT_TYPE3)
857 v = (v >= 0) ? v : (si32)(-(ui32)v - bias);
858 *dp++ = (float)v * mul;
859 }
860 }
861 else
862 {
863 const si32 half = (si32)(1ULL << (bit_depth - 1));
864 for (int i = (int)width; i > 0; --i) {
865 si32 v = *sp++;
866 v -= half;
867 *dp++ = (float)v * mul;
868 }
869 }
870 }
871
873 void gen_irv_convert_to_float(const line_buf *src_line,
874 ui32 src_line_offset, line_buf *dst_line,
875 ui32 bit_depth, bool is_signed, ui32 width)
876 {
877 local_gen_irv_convert_to_float_nlt0or3<false>(src_line, src_line_offset,
878 dst_line, bit_depth, is_signed, width);
879 }
880
883 ui32 src_line_offset, line_buf *dst_line,
884 ui32 bit_depth, bool is_signed, ui32 width)
885 {
886 local_gen_irv_convert_to_float_nlt0or3<true>(src_line, src_line_offset,
887 dst_line, bit_depth, is_signed, width);
888 }
889
892 const line_buf *r, const line_buf *g, const line_buf *b,
893 line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
894 {
895 assert((y->flags & line_buf::LFT_INTEGER) &&
901
902 if (y->flags & line_buf::LFT_32BIT)
903 {
904 assert((y->flags & line_buf::LFT_32BIT) &&
905 (cb->flags & line_buf::LFT_32BIT) &&
906 (cr->flags & line_buf::LFT_32BIT) &&
907 (r->flags & line_buf::LFT_32BIT) &&
908 (g->flags & line_buf::LFT_32BIT) &&
910 const si32 *rp = r->i32, * gp = g->i32, * bp = b->i32;
911 si32 *yp = y->i32, * cbp = cb->i32, * crp = cr->i32;
912 for (ui32 i = repeat; i > 0; --i)
913 {
914 si32 rr = *rp++, gg = *gp++, bb = *bp++;
915 *yp++ = (rr + 2 * gg + bb) >> 2;
916 *cbp++ = (bb - gg);
917 *crp++ = (rr - gg);
918 }
919 }
920 else
921 {
922 assert((y->flags & line_buf::LFT_64BIT) &&
923 (cb->flags & line_buf::LFT_64BIT) &&
924 (cr->flags & line_buf::LFT_64BIT) &&
925 (r->flags & line_buf::LFT_32BIT) &&
926 (g->flags & line_buf::LFT_32BIT) &&
928 const si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
929 si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
930 for (ui32 i = repeat; i > 0; --i)
931 {
932 si64 rr = *rp++, gg = *gp++, bb = *bp++;
933 *yp++ = (rr + 2 * gg + bb) >> 2;
934 *cbp++ = (bb - gg);
935 *crp++ = (rr - gg);
936 }
937 }
938 }
939
942 const line_buf *y, const line_buf *cb, const line_buf *cr,
943 line_buf *r, line_buf *g, line_buf *b, ui32 repeat)
944 {
945 assert((y->flags & line_buf::LFT_INTEGER) &&
951
952 if (y->flags & line_buf::LFT_32BIT)
953 {
954 assert((y->flags & line_buf::LFT_32BIT) &&
955 (cb->flags & line_buf::LFT_32BIT) &&
956 (cr->flags & line_buf::LFT_32BIT) &&
957 (r->flags & line_buf::LFT_32BIT) &&
958 (g->flags & line_buf::LFT_32BIT) &&
960 const si32 *yp = y->i32, *cbp = cb->i32, *crp = cr->i32;
961 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
962 for (ui32 i = repeat; i > 0; --i)
963 {
964 si32 yy = *yp++, cbb = *cbp++, crr = *crp++;
965 si32 gg = yy - ((cbb + crr) >> 2);
966 *rp++ = crr + gg;
967 *gp++ = gg;
968 *bp++ = cbb + gg;
969 }
970 }
971 else
972 {
973 assert((y->flags & line_buf::LFT_64BIT) &&
974 (cb->flags & line_buf::LFT_64BIT) &&
975 (cr->flags & line_buf::LFT_64BIT) &&
976 (r->flags & line_buf::LFT_32BIT) &&
977 (g->flags & line_buf::LFT_32BIT) &&
979 const si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
980 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
981 for (ui32 i = repeat; i > 0; --i)
982 {
983 si64 yy = *yp++, cbb = *cbp++, crr = *crp++;
984 si64 gg = yy - ((cbb + crr) >> 2);
985 *rp++ = (si32)(crr + gg);
986 *gp++ = (si32)gg;
987 *bp++ = (si32)(cbb + gg);
988 }
989 }
990 }
991
993 void gen_ict_forward(const float *r, const float *g, const float *b,
994 float *y, float *cb, float *cr, ui32 repeat)
995 {
996 for (ui32 i = repeat; i > 0; --i)
997 {
998 *y = CT_CNST::ALPHA_RF * *r
999 + CT_CNST::ALPHA_GF * *g++
1000 + CT_CNST::ALPHA_BF * *b;
1001 *cb++ = CT_CNST::BETA_CbF * (*b++ - *y);
1002 *cr++ = CT_CNST::BETA_CrF * (*r++ - *y++);
1003 }
1004 }
1005
1007 void gen_ict_backward(const float *y, const float *cb, const float *cr,
1008 float *r, float *g, float *b, ui32 repeat)
1009 {
1010 for (ui32 i = repeat; i > 0; --i)
1011 {
1012 *g++ = *y - CT_CNST::GAMMA_CR2G * *cr - CT_CNST::GAMMA_CB2G * *cb;
1013 *r++ = *y + CT_CNST::GAMMA_CR2R * *cr++;
1014 *b++ = *y++ + CT_CNST::GAMMA_CB2B * *cb++;
1015 }
1016 }
1017
1018#endif // !OJPH_ENABLE_WASM_SIMD
1019
1020 }
1021}
void gen_rev_decode_nlt(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void sse2_rct_backward(const line_buf *y, const line_buf *cb, const line_buf *cr, line_buf *r, line_buf *g, line_buf *b, ui32 repeat)
void sse2_irv_convert_to_integer(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void wasm_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void wasm_irv_convert_to_integer(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void avx2_rct_forward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void wasm_rev_convert_nlt_type3(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void vsx_irv_convert_to_float_nlt_type3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void wasm_irv_convert_to_integer_nlt_type3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_irv_convert_to_float_nlt_type3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void(*) ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void sse2_irv_convert_to_integer_nlt_type3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void gen_rct_forward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void(*) rev_decode_nlt(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void avx_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void gen_rct_backward(const line_buf *y, const line_buf *cb, const line_buf *cr, line_buf *r, line_buf *g, line_buf *b, ui32 repeat)
void sse2_rev_convert(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void vsx_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void(*) irv_convert_to_float_nlt_type3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void avx2_rct_backward(const line_buf *y, const line_buf *cb, const line_buf *cr, line_buf *r, line_buf *g, line_buf *b, ui32 repeat)
static void local_gen_irv_convert_to_float_nlt0or3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void gen_irv_convert_to_integer(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void(*) irv_convert_to_integer_nlt_type3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_rev_convert_nlt_type3(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void(*) rev_convert_nlt_type3(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void(*) irv_convert_to_float_nlt(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void wasm_rev_convert(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void gen_irv_convert_to_float(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void vsx_rev_convert_nlt_type3(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void vsx_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void init_colour_transform_functions()
void vsx_rct_backward(const line_buf *y, const line_buf *cb, const line_buf *cr, line_buf *r, line_buf *g, line_buf *b, ui32 repeat)
void gen_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
static void local_gen_irv_convert_to_integer_nlt2or4(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void(*) rct_forward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void(*) irv_convert_to_integer_nlt(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void(*) irv_convert_to_integer(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void vsx_rev_convert(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void gen_rev_convert_nlt_type3(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void wasm_irv_convert_to_float_nlt_type3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void sse_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void avx2_rev_convert(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void avx2_irv_convert_to_float(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void wasm_rct_backward(const line_buf *y, const line_buf *cb, const line_buf *cr, line_buf *r, line_buf *g, line_buf *b, ui32 repeat)
void avx2_irv_convert_to_integer_nlt(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void wasm_rct_forward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void(*) rev_convert(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void gen_irv_convert_to_integer_nlt(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void wasm_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void avx2_rev_convert_nlt_type3(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void gen_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void gen_rev_convert(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void sse2_irv_convert_to_integer_nlt(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void(*) rev_encode_nlt(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
static void local_gen_irv_convert_to_float_nlt2or4_precise_search(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void avx2_irv_convert_to_float_nlt(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void(*) irv_convert_to_float(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void vsx_rct_forward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void avx2_irv_convert_to_integer(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void avx2_irv_convert_to_float_nlt_type3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_rct_forward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void sse2_irv_convert_to_float_nlt(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
static void local_gen_irv_convert_to_float_nlt2or4(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void avx_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void gen_irv_convert_to_float_nlt(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void avx2_irv_convert_to_integer_nlt_type3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void(*) ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void vsx_irv_convert_to_float(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void vsx_irv_convert_to_integer(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void wasm_irv_convert_to_float(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void gen_rev_encode_nlt(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void vsx_irv_convert_to_integer_nlt_type3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void sse_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void(*) rct_backward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void gen_irv_convert_to_integer_nlt_type3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void gen_irv_convert_to_float_nlt_type3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
static void local_gen_irv_convert_to_integer_nlt0or3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
static void local_gen_irv_convert_to_float_nlt2or4_precise_1step(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void sse2_irv_convert_to_float(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
int64_t si64
Definition ojph_defs.h:57
uint16_t ui16
Definition ojph_defs.h:52
@ PPC_CPU_EXT_LEVEL_ARCH_2_07
Definition ojph_arch.h:180
OJPH_EXPORT int get_cpu_ext_level()
int32_t si32
Definition ojph_defs.h:55
uint32_t ui32
Definition ojph_defs.h:54
@ X86_CPU_EXT_LEVEL_AVX2
Definition ojph_arch.h:163
@ X86_CPU_EXT_LEVEL_AVX
Definition ojph_arch.h:162
@ X86_CPU_EXT_LEVEL_SSE2
Definition ojph_arch.h:157
@ X86_CPU_EXT_LEVEL_SSE
Definition ojph_arch.h:156
#define ojph_max(a, b)
Definition ojph_defs.h:73
#define ojph_min(a, b)
Definition ojph_defs.h:76
#define ojph_unused(x)
Definition ojph_defs.h:78
static const float GAMMA_CR2R
static const float BETA_CbF
static const float GAMMA_CB2B
static const float ALPHA_RF
static const float GAMMA_CB2G
static const float GAMMA_CR2G
static const float ALPHA_BF
static const float BETA_CrF
static const float ALPHA_GF
ojph::param_nlt::nonlinearity nonlinearity