OpenJPH
Open-source implementation of JPEG2000 Part-15
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
40#include "ojph_defs.h"
41#include "ojph_arch.h"
42#include "ojph_colour.h"
43#include "ojph_colour_local.h"
44
45namespace ojph {
46 namespace local {
47
50 (const si32 *sp, si32 *dp, int shift, ui32 width) = NULL;
51
54 (const si32 *sp, float *dp, float mul, ui32 width) = NULL;
55
58 (const si32 *sp, float *dp, float mul, ui32 width) = NULL;
59
62 (const float *sp, si32 *dp, float mul, ui32 width) = NULL;
63
66 (const float *sp, si32 *dp, float mul, ui32 width) = NULL;
67
70 (const si32 *r, const si32 *g, const si32 *b,
71 si32 *y, si32 *cb, si32 *cr, ui32 repeat) = NULL;
72
75 (const si32 *y, const si32 *cb, const si32 *cr,
76 si32 *r, si32 *g, si32 *b, ui32 repeat) = NULL;
77
80 (const float *r, const float *g, const float *b,
81 float *y, float *cb, float *cr, ui32 repeat) = NULL;
82
85 (const float *y, const float *cb, const float *cr,
86 float *r, float *g, float *b, ui32 repeat) = NULL;
87
90
93 {
95 return;
96
97#if !defined(OJPH_ENABLE_WASM_SIMD) || !defined(OJPH_EMSCRIPTEN)
98
108
109#ifndef OJPH_DISABLE_INTEL_SIMD
110 int level = get_cpu_ext_level();
111
112 if (level >= X86_CPU_EXT_LEVEL_SSE)
113 {
120 }
121
122 if (level >= X86_CPU_EXT_LEVEL_SSE2)
123 {
129 }
130
131 if (level >= X86_CPU_EXT_LEVEL_AVX)
132 {
139 }
140
141 if (level >= X86_CPU_EXT_LEVEL_AVX2)
142 {
146 }
147#endif // !OJPH_DISABLE_INTEL_SIMD
148
149#else // OJPH_ENABLE_WASM_SIMD
159#endif // !OJPH_ENABLE_WASM_SIMD
160
162 }
163
165 const float CT_CNST::ALPHA_RF = 0.299f;
166 const float CT_CNST::ALPHA_GF = 0.587f;
167 const float CT_CNST::ALPHA_BF = 0.114f;
168 const float CT_CNST::BETA_CbF = float(0.5/(1-double(CT_CNST::ALPHA_BF)));
169 const float CT_CNST::BETA_CrF = float(0.5/(1-double(CT_CNST::ALPHA_RF)));
170 const float CT_CNST::GAMMA_CB2G =
171 float(2.0*double(ALPHA_BF)*(1.0-double(ALPHA_BF))/double(ALPHA_GF));
172 const float CT_CNST::GAMMA_CR2G =
173 float(2.0*double(ALPHA_RF)*(1.0-double(ALPHA_RF))/double(ALPHA_GF));
174 const float CT_CNST::GAMMA_CB2B = float(2.0 * (1.0 - double(ALPHA_BF)));
175 const float CT_CNST::GAMMA_CR2R = float(2.0 * (1.0 - double(ALPHA_RF)));
176
178
179#if !defined(OJPH_ENABLE_WASM_SIMD) || !defined(OJPH_EMSCRIPTEN)
180
182 void gen_cnvrt_si32_to_si32_shftd(const si32 *sp, si32 *dp, int shift,
183 ui32 width)
184 {
185 for (ui32 i = width; i > 0; --i)
186 *dp++ = *sp++ + shift;
187 }
188
190 void gen_cnvrt_si32_to_float_shftd(const si32 *sp, float *dp, float mul,
191 ui32 width)
192 {
193 for (ui32 i = width; i > 0; --i)
194 *dp++ = (float)*sp++ * mul - 0.5f;
195 }
196
198 void gen_cnvrt_si32_to_float(const si32 *sp, float *dp, float mul,
199 ui32 width)
200 {
201 for (ui32 i = width; i > 0; --i)
202 *dp++ = (float)*sp++ * mul;
203 }
204
206 void gen_cnvrt_float_to_si32_shftd(const float *sp, si32 *dp, float mul,
207 ui32 width)
208 {
209 for (ui32 i = width; i > 0; --i)
210 *dp++ = ojph_round((*sp++ + 0.5f) * mul);
211 }
212
214 void gen_cnvrt_float_to_si32(const float *sp, si32 *dp, float mul,
215 ui32 width)
216 {
217 for (ui32 i = width; i > 0; --i)
218 *dp++ = ojph_round(*sp++ * mul);
219 }
220
222 void gen_rct_forward(const si32 *r, const si32 *g, const si32 *b,
223 si32 *y, si32 *cb, si32 *cr, ui32 repeat)
224 {
225 for (ui32 i = repeat; i > 0; --i)
226 {
227 *y++ = (*r + (*g << 1) + *b) >> 2;
228 *cb++ = (*b++ - *g);
229 *cr++ = (*r++ - *g++);
230 }
231 }
232
234 void gen_rct_backward(const si32 *y, const si32 *cb, const si32 *cr,
235 si32 *r, si32 *g, si32 *b, ui32 repeat)
236 {
237 for (ui32 i = repeat; i > 0; --i)
238 {
239 *g = *y++ - ((*cb + *cr)>>2);
240 *b++ = *cb++ + *g;
241 *r++ = *cr++ + *g++;
242 }
243 }
244
246 void gen_ict_forward(const float *r, const float *g, const float *b,
247 float *y, float *cb, float *cr, ui32 repeat)
248 {
249 for (ui32 i = repeat; i > 0; --i)
250 {
251 *y = CT_CNST::ALPHA_RF * *r
252 + CT_CNST::ALPHA_GF * *g++
253 + CT_CNST::ALPHA_BF * *b;
254 *cb++ = CT_CNST::BETA_CbF * (*b++ - *y);
255 *cr++ = CT_CNST::BETA_CrF * (*r++ - *y++);
256 }
257 }
258
260 void gen_ict_backward(const float *y, const float *cb, const float *cr,
261 float *r, float *g, float *b, ui32 repeat)
262 {
263 for (ui32 i = repeat; i > 0; --i)
264 {
265 *g++ = *y - CT_CNST::GAMMA_CR2G * *cr - CT_CNST::GAMMA_CB2G * *cb;
266 *r++ = *y + CT_CNST::GAMMA_CR2R * *cr++;
267 *b++ = *y++ + CT_CNST::GAMMA_CB2B * *cb++;
268 }
269 }
270
271#endif // !OJPH_ENABLE_WASM_SIMD
272
273 }
274}
void wasm_cnvrt_float_to_si32_shftd(const float *sp, si32 *dp, float mul, ui32 width)
void(* cnvrt_float_to_si32)(const float *sp, si32 *dp, float mul, ui32 width)
Definition: ojph_colour.cpp:66
void wasm_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void avx2_rct_forward(const si32 *r, const si32 *g, const si32 *b, si32 *y, si32 *cb, si32 *cr, ui32 repeat)
void wasm_cnvrt_si32_to_float_shftd(const si32 *sp, float *dp, float mul, ui32 width)
void avx_cnvrt_float_to_si32(const float *sp, si32 *dp, float mul, ui32 width)
void(* cnvrt_si32_to_float_shftd)(const si32 *sp, float *dp, float mul, ui32 width)
Definition: ojph_colour.cpp:54
void(* ict_forward)(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
Definition: ojph_colour.cpp:80
void avx_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void(* cnvrt_si32_to_si32_shftd)(const si32 *sp, si32 *dp, int shift, ui32 width)
Definition: ojph_colour.cpp:50
void avx_cnvrt_si32_to_float_shftd(const si32 *sp, float *dp, float mul, ui32 width)
void(* ict_backward)(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
Definition: ojph_colour.cpp:85
void gen_rct_backward(const si32 *y, const si32 *cb, const si32 *cr, si32 *r, si32 *g, si32 *b, ui32 repeat)
void(* rct_backward)(const si32 *y, const si32 *cb, const si32 *cr, si32 *r, si32 *g, si32 *b, ui32 repeat)
Definition: ojph_colour.cpp:75
void gen_cnvrt_si32_to_float(const si32 *sp, float *dp, float mul, ui32 width)
void avx2_rct_backward(const si32 *y, const si32 *cb, const si32 *cr, si32 *r, si32 *g, si32 *b, ui32 repeat)
void init_colour_transform_functions()
Definition: ojph_colour.cpp:92
void gen_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void sse2_rct_forward(const si32 *r, const si32 *g, const si32 *b, si32 *y, si32 *cb, si32 *cr, ui32 repeat)
void sse_cnvrt_float_to_si32_shftd(const float *sp, si32 *dp, float mul, ui32 width)
void wasm_cnvrt_float_to_si32(const float *sp, si32 *dp, float mul, ui32 width)
void sse2_cnvrt_float_to_si32_shftd(const float *sp, si32 *dp, float mul, ui32 width)
void(* cnvrt_float_to_si32_shftd)(const float *sp, si32 *dp, float mul, ui32 width)
Definition: ojph_colour.cpp:62
void sse2_cnvrt_si32_to_si32_shftd(const si32 *sp, si32 *dp, int shift, ui32 width)
void gen_cnvrt_si32_to_si32_shftd(const si32 *sp, si32 *dp, int shift, ui32 width)
void sse_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void avx_cnvrt_si32_to_float(const si32 *sp, float *dp, float mul, ui32 width)
static bool colour_transform_functions_initialized
Definition: ojph_colour.cpp:89
void sse_cnvrt_si32_to_float_shftd(const si32 *sp, float *dp, float mul, ui32 width)
void wasm_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void(* cnvrt_si32_to_float)(const si32 *sp, float *dp, float mul, ui32 width)
Definition: ojph_colour.cpp:58
void wasm_rct_forward(const si32 *r, const si32 *g, const si32 *b, si32 *y, si32 *cb, si32 *cr, ui32 repeat)
void gen_cnvrt_float_to_si32(const float *sp, si32 *dp, float mul, ui32 width)
void gen_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void wasm_cnvrt_si32_to_si32_shftd(const si32 *sp, si32 *dp, int shift, ui32 width)
void sse2_rct_backward(const si32 *y, const si32 *cb, const si32 *cr, si32 *r, si32 *g, si32 *b, ui32 repeat)
void(* rct_forward)(const si32 *r, const si32 *g, const si32 *b, si32 *y, si32 *cb, si32 *cr, ui32 repeat)
Definition: ojph_colour.cpp:70
void wasm_cnvrt_si32_to_float(const si32 *sp, float *dp, float mul, ui32 width)
void gen_cnvrt_float_to_si32_shftd(const float *sp, si32 *dp, float mul, ui32 width)
void wasm_rct_backward(const si32 *y, const si32 *cb, const si32 *cr, si32 *r, si32 *g, si32 *b, ui32 repeat)
void gen_rct_forward(const si32 *r, const si32 *g, const si32 *b, si32 *y, si32 *cb, si32 *cr, ui32 repeat)
void avx_cnvrt_float_to_si32_shftd(const float *sp, si32 *dp, float mul, ui32 width)
void avx_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void sse2_cnvrt_float_to_si32(const float *sp, si32 *dp, float mul, ui32 width)
void sse_cnvrt_si32_to_float(const si32 *sp, float *dp, float mul, ui32 width)
void gen_cnvrt_si32_to_float_shftd(const si32 *sp, float *dp, float mul, ui32 width)
void avx2_cnvrt_si32_to_si32_shftd(const si32 *sp, si32 *dp, int shift, ui32 width)
void sse_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void sse_cnvrt_float_to_si32(const float *sp, si32 *dp, float mul, ui32 width)
static si32 ojph_round(float val)
Definition: ojph_arch.h:171
@ X86_CPU_EXT_LEVEL_AVX2
Definition: ojph_arch.h:104
@ X86_CPU_EXT_LEVEL_AVX
Definition: ojph_arch.h:103
@ X86_CPU_EXT_LEVEL_SSE2
Definition: ojph_arch.h:98
@ X86_CPU_EXT_LEVEL_SSE
Definition: ojph_arch.h:97
OJPH_EXPORT int get_cpu_ext_level()
Definition: ojph_arch.cpp:184
int32_t si32
Definition: ojph_defs.h:55
uint32_t ui32
Definition: ojph_defs.h:54
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