74 bool is_signed,
ui32 width,
const nlt_rec *rec) = NULL;
85 ui32 bit_depth,
bool is_signed,
ui32 width) = NULL;
100 ui32 bit_depth,
bool is_signed,
ui32 width) = NULL;
105 ui32 bit_depth,
bool is_signed,
ui32 width,
const nlt_rec *rec) = NULL;
124 (
const float *r,
const float *g,
const float *b,
125 float *y,
float *cb,
float *cr,
ui32 repeat) = NULL;
129 (
const float *y,
const float *cb,
const float *cr,
130 float *r,
float *g,
float *b,
ui32 repeat) = NULL;
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)
154 #ifndef OJPH_DISABLE_SIMD
156 #if (defined(OJPH_ARCH_X86_64) || defined(OJPH_ARCH_I386))
158 #ifndef OJPH_DISABLE_SSE
166 #ifndef OJPH_DISABLE_SSE2
184 #ifndef OJPH_DISABLE_AVX
192 #ifndef OJPH_DISABLE_AVX2
210 #elif defined(OJPH_ARCH_ARM)
212 #elif defined(OJPH_ARCH_PPC64LE)
263 float(2.0*
double(ALPHA_BF)*(1.0-
double(ALPHA_BF))/
double(ALPHA_GF));
265 float(2.0*
double(ALPHA_RF)*(1.0-
double(ALPHA_RF))/
double(ALPHA_GF));
272 template<
int NLT_TYPE>
286 const float* sp = src_line->f32;
287 si32* dp = dst_line->i32 + dst_line_offset;
290 float d_min = rec->
fd_min;
291 float d_max = rec->
fd_max;
292 float delta = rec->
delta;
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;
304 ui32 k = (
ui32)floorf((t - d_min) * inv_delta);
305 float d_k = d_min + (float)k * delta;
307 float t_kp1 = lut[k + 1];
308 float z = t_k + (t - d_k) * inv_delta * (t_kp1 - t_k);
310 si32 v = ojph_round(z * mul - half);
312 v = (v >= 0) ? v : (- v - bias);
318 for (
int i = (
int)width; i > 0; --i) {
319 float t = *sp++ + 0.5f;
322 ui32 k = (
ui32)floorf((t - d_min) * inv_delta);
323 float d_k = d_min + (float)k * delta;
325 float t_kp1 = lut[k + 1];
326 float z = t_k + (t - d_k) * inv_delta * (t_kp1 - t_k);
328 si32 v = ojph_round(z * mul);
344 if (rec->
get_type() == nl::OJPH_NLT_LUT_STYLE_NLT)
346 dst_line_offset, bit_depth, is_signed, width, rec);
350 else if (rec->
get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
352 dst_line_offset, bit_depth, is_signed, width, rec);
358 template<
int NLT_TYPE>
370 assert(bit_depth <= 32);
371 float mul = (float)(1.0 / (
double)(1ULL << bit_depth));
372 float d_min = rec->
ft_min;
373 float d_max = rec->
ft_max;
374 float delta = rec->
delta;
378 const si32* sp = src_line->i32 + src_line_offset;
379 float* dp = dst_line->f32;
383 for (
int i = (
int)width; i > 0; --i) {
386 v = (v >= 0) ? v : (- v - bias);
387 float t = (float)v * mul + 0.5f;
390 ui32 k = (
ui32)floorf((t - d_min) * inv_delta);
391 float d_k = d_min + (float)k * delta;
393 float t_kp1 = lut[k + 1];
394 float y = t_k + (t - d_k) * inv_delta * (t_kp1 - t_k);
400 for (
int i = (
int)width; i > 0; --i) {
402 float t = (float)v * mul;
405 ui32 k = (
ui32)floorf((t - d_min) * inv_delta);
406 float d_k = d_min + (float)k * delta;
408 float t_kp1 = lut[k + 1];
409 float y = t_k + (t - d_k) * inv_delta * (t_kp1 - t_k);
425 if (rec->
get_type() == nl::OJPH_NLT_LUT_STYLE_NLT)
427 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
431 else if (rec->
get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
433 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
481#if !defined(OJPH_ENABLE_WASM_SIMD) || !defined(OJPH_EMSCRIPTEN)
493 const si32 *sp = src_line->i32 + src_line_offset;
494 si32 *dp = dst_line->i32 + dst_line_offset;
496 for (
ui32 i = width; i > 0; --i)
501 const si32 *sp = src_line->i32 + src_line_offset;
502 si64 *dp = dst_line->i64 + dst_line_offset;
503 for (
ui32 i = width; i > 0; --i)
504 *dp++ = *sp++ + shift;
511 const si64 *sp = src_line->i64 + src_line_offset;
512 si32 *dp = dst_line->i32 + dst_line_offset;
513 for (
ui32 i = width; i > 0; --i)
514 *dp++ = (
si32)(*sp++ + shift);
528 const si32 *sp = src_line->i32 + src_line_offset;
529 si32 *dp = dst_line->i32 + dst_line_offset;
531 for (
ui32 i = width; i > 0; --i) {
532 const si32 v = *sp++;
533 *dp++ = v >= 0 ? v : (- v - s);
538 const si32 *sp = src_line->i32 + src_line_offset;
539 si64 *dp = dst_line->i64 + dst_line_offset;
540 for (
ui32 i = width; i > 0; --i) {
541 const si64 v = *sp++;
542 *dp++ = v >= 0 ? v : (- v - shift);
550 const si64 *sp = src_line->i64 + src_line_offset;
551 si32 *dp = dst_line->i32 + dst_line_offset;
552 for (
ui32 i = width; i > 0; --i) {
553 const si64 v = *sp++;
554 *dp++ = (
si32)(v >= 0 ? v : (- v - shift));
560 template<
bool NLT_TYPE3>
564 ui32 bit_depth,
bool is_signed,
ui32 width)
571 assert(bit_depth <= 32);
572 const float* sp = src_line->f32;
573 si32* dp = dst_line->i32 + dst_line_offset;
580 si32 neg_limit = (
si32)INT_MIN >> (32 - bit_depth);
581 float mul = (float)(1ull << bit_depth);
582 float fl_up_lim = -(float)neg_limit;
583 float fl_low_lim = (float)neg_limit;
584 si32 s32_up_lim = INT_MAX >> (32 - bit_depth);
585 si32 s32_low_lim = INT_MIN >> (32 - bit_depth);
589 const si32 bias = (
si32)((1ULL << (bit_depth - 1)) + 1);
590 for (
int i = (
int)width; i > 0; --i) {
591 float t = *sp++ * mul;
592 si32 v = ojph_round(t);
593 v = t >= fl_low_lim ? v : s32_low_lim;
594 v = t < fl_up_lim ? v : s32_up_lim;
596 v = (v >= 0) ? v : (- v - bias);
602 const si32 half = (
si32)(1ULL << (bit_depth - 1));
603 for (
int i = (
int)width; i > 0; --i) {
604 float t = *sp++ * mul;
605 si32 v = ojph_round(t);
606 v = t >= fl_low_lim ? v : s32_low_lim;
607 v = t < fl_up_lim ? v : s32_up_lim;
616 ui32 bit_depth,
bool is_signed,
ui32 width)
619 dst_line_offset, bit_depth, is_signed, width);
625 ui32 bit_depth,
bool is_signed,
ui32 width)
628 dst_line_offset, bit_depth, is_signed, width);
632 template<
bool NLT_TYPE3>
636 ui32 bit_depth,
bool is_signed,
ui32 width)
643 assert(bit_depth <= 32);
644 float mul = (float)(1.0 / (
double)(1ULL << bit_depth));
646 const si32* sp = src_line->i32 + src_line_offset;
647 float* dp = dst_line->f32;
650 const si32 bias = (
si32)((1ULL << (bit_depth - 1)) + 1);
651 for (
int i = (
int)width; i > 0; --i) {
654 v = (v >= 0) ? v : (- v - bias);
655 *dp++ = (float)v * mul;
660 const si32 half = (
si32)(1ULL << (bit_depth - 1));
661 for (
int i = (
int)width; i > 0; --i) {
664 *dp++ = (float)v * mul;
672 ui32 bit_depth,
bool is_signed,
ui32 width)
675 dst_line, bit_depth, is_signed, width);
681 ui32 bit_depth,
bool is_signed,
ui32 width)
684 dst_line, bit_depth, is_signed, width);
707 const si32 *rp = r->i32, * gp = g->i32, * bp = b->i32;
708 si32 *yp = y->i32, * cbp = cb->i32, * crp = cr->i32;
709 for (
ui32 i = repeat; i > 0; --i)
711 si32 rr = *rp++, gg = *gp++, bb = *bp++;
712 *yp++ = (rr + (gg << 1) + bb) >> 2;
725 const si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
726 si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
727 for (
ui32 i = repeat; i > 0; --i)
729 si64 rr = *rp++, gg = *gp++, bb = *bp++;
730 *yp++ = (rr + (gg << 1) + bb) >> 2;
757 const si32 *yp = y->i32, *cbp = cb->i32, *crp = cr->i32;
758 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
759 for (
ui32 i = repeat; i > 0; --i)
761 si32 yy = *yp++, cbb = *cbp++, crr = *crp++;
762 si32 gg = yy - ((cbb + crr) >> 2);
776 const si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
777 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
778 for (
ui32 i = repeat; i > 0; --i)
780 si64 yy = *yp++, cbb = *cbp++, crr = *crp++;
781 si64 gg = yy - ((cbb + crr) >> 2);
782 *rp++ = (
si32)(crr + gg);
784 *bp++ = (
si32)(cbb + gg);
791 float *y,
float *cb,
float *cr,
ui32 repeat)
793 for (
ui32 i = repeat; i > 0; --i)
805 float *r,
float *g,
float *b,
ui32 repeat)
807 for (
ui32 i = repeat; i > 0; --i)
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)
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)
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)
@ PPC_CPU_EXT_LEVEL_ARCH_2_07
OJPH_EXPORT int get_cpu_ext_level()
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
ui8 get_bit_depth() const
ojph::param_nlt::nonlinearity nonlinearity