1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The copyright in this software is being made available under the 2-clauses
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * BSD License, included below. This software may be subject to other third
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * party and contributor rights, including patent rights, and no such rights
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * are granted under this license.
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2002-2014, Professor Benoit Macq
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2001-2003, David Janssens
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2002-2003, Yannick Verschueren
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2003-2007, Francois-Olivier Devaux
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2003-2014, Antonin Descampe
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2005, Herve Drolon, FreeImage Team
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (c) 2012, CS Systemes d'Information, France
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * All rights reserved.
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Redistribution and use in source and binary forms, with or without
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * modification, are permitted provided that the following conditions
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * are met:
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1. Redistributions of source code must retain the above copyright
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *    notice, this list of conditions and the following disclaimer.
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 2. Redistributions in binary form must reproduce the above copyright
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *    notice, this list of conditions and the following disclaimer in the
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *    documentation and/or other materials provided with the distribution.
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * POSSIBILITY OF SUCH DAMAGE.
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef __SSE__
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <xmmintrin.h>
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "opj_includes.h"
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* <summary> */
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This table contains the norms of the basis function of the reversible MCT. */
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* </summary> */
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const OPJ_FLOAT64 opj_mct_norms[3] = { 1.732, .8292, .8292 };
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* <summary> */
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This table contains the norms of the basis function of the irreversible MCT. */
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* </summary> */
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const OPJ_FLOAT64 opj_mct_norms_real[3] = { 1.732, 1.805, 1.573 };
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst OPJ_FLOAT64 * opj_mct_get_mct_norms ()
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return opj_mct_norms;
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst OPJ_FLOAT64 * opj_mct_get_mct_norms_real ()
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return opj_mct_norms_real;
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* <summary> */
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Foward reversible MCT. */
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* </summary> */
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid opj_mct_encode(
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c0,
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c1,
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c2,
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_UINT32 n)
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 i;
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for(i = 0; i < n; ++i) {
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 r = c0[i];
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 g = c1[i];
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 b = c2[i];
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 y = (r + (g * 2) + b) >> 2;
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 u = b - g;
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 v = r - g;
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c0[i] = y;
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c1[i] = u;
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c2[i] = v;
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* <summary> */
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Inverse reversible MCT. */
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* </summary> */
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid opj_mct_decode(
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c0,
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c1,
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c2,
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_UINT32 n)
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 i;
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for (i = 0; i < n; ++i) {
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 y = c0[i];
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 u = c1[i];
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 v = c2[i];
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 g = y - ((u + v) >> 2);
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 r = v + g;
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 b = u + g;
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c0[i] = r;
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c1[i] = g;
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c2[i] = b;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* <summary> */
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Get norm of basis function of reversible MCT. */
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* </summary> */
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovOPJ_FLOAT64 opj_mct_getnorm(OPJ_UINT32 compno) {
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return opj_mct_norms[compno];
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* <summary> */
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Foward irreversible MCT. */
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* </summary> */
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid opj_mct_encode_real(
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c0,
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c1,
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32* restrict c2,
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_UINT32 n)
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 i;
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for(i = 0; i < n; ++i) {
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 r = c0[i];
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 g = c1[i];
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 b = c2[i];
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 y =  opj_int_fix_mul(r, 2449) + opj_int_fix_mul(g, 4809) + opj_int_fix_mul(b, 934);
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 u = -opj_int_fix_mul(r, 1382) - opj_int_fix_mul(g, 2714) + opj_int_fix_mul(b, 4096);
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_INT32 v =  opj_int_fix_mul(r, 4096) - opj_int_fix_mul(g, 3430) - opj_int_fix_mul(b, 666);
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c0[i] = y;
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c1[i] = u;
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c2[i] = v;
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* <summary> */
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Inverse irreversible MCT. */
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* </summary> */
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid opj_mct_decode_real(
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32* restrict c0,
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32* restrict c1,
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32* restrict c2,
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_UINT32 n)
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 i;
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef __SSE__
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	// Mantis BUGID: 0056291. The address must be 16-byte aligned.
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	// TestFile: fuzz-signal_sigsegv_6e9e7f_5076_5265.pdf
1552b892c2e57cabed4bf84661770eba7d70e80088eGreg Hackmann	if ((uintptr_t)c0 % 16 == 0 && (uintptr_t)c1 % 16 == 0 && (uintptr_t)c2 % 16 == 0){
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		__m128 vrv, vgu, vgv, vbu;
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		vrv = _mm_set1_ps(1.402f);
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		vgu = _mm_set1_ps(0.34413f);
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		vgv = _mm_set1_ps(0.71414f);
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		vbu = _mm_set1_ps(1.772f);
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		for (i = 0; i < (n >> 3); ++i) {
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			__m128 vy, vu, vv;
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			__m128 vr, vg, vb;
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vy = _mm_load_ps(c0);
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vu = _mm_load_ps(c1);
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vv = _mm_load_ps(c2);
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vr = _mm_add_ps(vy, _mm_mul_ps(vv, vrv));
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vg = _mm_sub_ps(_mm_sub_ps(vy, _mm_mul_ps(vu, vgu)), _mm_mul_ps(vv, vgv));
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vb = _mm_add_ps(vy, _mm_mul_ps(vu, vbu));
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			_mm_store_ps(c0, vr);
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			_mm_store_ps(c1, vg);
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			_mm_store_ps(c2, vb);
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c0 += 4;
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c1 += 4;
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c2 += 4;
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vy = _mm_load_ps(c0);
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vu = _mm_load_ps(c1);
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vv = _mm_load_ps(c2);
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vr = _mm_add_ps(vy, _mm_mul_ps(vv, vrv));
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vg = _mm_sub_ps(_mm_sub_ps(vy, _mm_mul_ps(vu, vgu)), _mm_mul_ps(vv, vgv));
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			vb = _mm_add_ps(vy, _mm_mul_ps(vu, vbu));
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			_mm_store_ps(c0, vr);
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			_mm_store_ps(c1, vg);
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			_mm_store_ps(c2, vb);
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c0 += 4;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c1 += 4;
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c2 += 4;
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		n &= 7;
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	} else {
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		for(i = 0; i < n; ++i) {
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			OPJ_FLOAT32 y = c0[i];
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			OPJ_FLOAT32 u = c1[i];
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			OPJ_FLOAT32 v = c2[i];
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			OPJ_FLOAT32 r = y + (v * 1.402f);
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			OPJ_FLOAT32 g = y - (u * 0.34413f) - (v * (0.71414f));
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			OPJ_FLOAT32 b = y + (u * 1.772f);
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c0[i] = r;
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c1[i] = g;
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			c2[i] = b;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for(i = 0; i < n; ++i) {
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32 y = c0[i];
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32 u = c1[i];
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32 v = c2[i];
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32 r = y + (v * 1.402f);
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32 g = y - (u * 0.34413f) - (v * (0.71414f));
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		OPJ_FLOAT32 b = y + (u * 1.772f);
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c0[i] = r;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c1[i] = g;
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		c2[i] = b;
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* <summary> */
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Get norm of basis function of irreversible MCT. */
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* </summary> */
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovOPJ_FLOAT64 opj_mct_getnorm_real(OPJ_UINT32 compno) {
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return opj_mct_norms_real[compno];
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovOPJ_BOOL opj_mct_encode_custom(
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_BYTE * pCodingdata,
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_UINT32 n,
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_BYTE ** pData,
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_UINT32 pNbComp,
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_UINT32 isSigned)
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_FLOAT32 * lMct = (OPJ_FLOAT32 *) pCodingdata;
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 i;
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 j;
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 k;
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 lNbMatCoeff = pNbComp * pNbComp;
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_INT32 * lCurrentData = 00;
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_INT32 * lCurrentMatrix = 00;
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_INT32 ** lData = (OPJ_INT32 **) pData;
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 lMultiplicator = 1 << 13;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_INT32 * lMctPtr;
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    OPJ_ARG_NOT_USED(isSigned);
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	lCurrentData = (OPJ_INT32 *) opj_malloc((pNbComp + lNbMatCoeff) * sizeof(OPJ_INT32));
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if (! lCurrentData) {
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return OPJ_FALSE;
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	lCurrentMatrix = lCurrentData + pNbComp;
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for (i =0;i<lNbMatCoeff;++i) {
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		lCurrentMatrix[i] = (OPJ_INT32) (*(lMct++) * (OPJ_FLOAT32)lMultiplicator);
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for (i = 0; i < n; ++i)  {
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		lMctPtr = lCurrentMatrix;
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		for (j=0;j<pNbComp;++j) {
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			lCurrentData[j] = (*(lData[j]));
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		for (j=0;j<pNbComp;++j) {
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			*(lData[j]) = 0;
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			for (k=0;k<pNbComp;++k) {
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				*(lData[j]) += opj_int_fix_mul(*lMctPtr, lCurrentData[k]);
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				++lMctPtr;
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			}
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			++lData[j];
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	opj_free(lCurrentData);
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return OPJ_TRUE;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovOPJ_BOOL opj_mct_decode_custom(
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_BYTE * pDecodingData,
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_UINT32 n,
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_BYTE ** pData,
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_UINT32 pNbComp,
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov					   OPJ_UINT32 isSigned)
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_FLOAT32 * lMct;
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 i;
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 j;
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 k;
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_FLOAT32 * lCurrentData = 00;
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_FLOAT32 * lCurrentResult = 00;
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_FLOAT32 ** lData = (OPJ_FLOAT32 **) pData;
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    OPJ_ARG_NOT_USED(isSigned);
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	lCurrentData = (OPJ_FLOAT32 *) opj_malloc (2 * pNbComp * sizeof(OPJ_FLOAT32));
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	if (! lCurrentData) {
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		return OPJ_FALSE;
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	lCurrentResult = lCurrentData + pNbComp;
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for (i = 0; i < n; ++i) {
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		lMct = (OPJ_FLOAT32 *) pDecodingData;
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		for (j=0;j<pNbComp;++j) {
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			lCurrentData[j] = (OPJ_FLOAT32) (*(lData[j]));
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		for (j=0;j<pNbComp;++j) {
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			lCurrentResult[j] = 0;
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			for	(k=0;k<pNbComp;++k)	{
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov				lCurrentResult[j] += *(lMct++) * lCurrentData[k];
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			}
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			*(lData[j]++) = (OPJ_FLOAT32) (lCurrentResult[j]);
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	opj_free(lCurrentData);
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	return OPJ_TRUE;
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid opj_calculate_norms(	OPJ_FLOAT64 * pNorms,
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov							OPJ_UINT32 pNbComps,
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov							OPJ_FLOAT32 * pMatrix)
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_UINT32 i,j,lIndex;
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_FLOAT32 lCurrentValue;
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_FLOAT64 * lNorms = (OPJ_FLOAT64 *) pNorms;
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	OPJ_FLOAT32 * lMatrix = (OPJ_FLOAT32 *) pMatrix;
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	for	(i=0;i<pNbComps;++i) {
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		lNorms[i] = 0;
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		lIndex = i;
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		for	(j=0;j<pNbComps;++j) {
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			lCurrentValue = lMatrix[lIndex];
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			lIndex += pNbComps;
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov			lNorms[i] += lCurrentValue * lCurrentValue;
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		}
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov		lNorms[i] = sqrt(lNorms[i]);
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov	}
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
343