xref: /aosp_15_r20/external/pdfium/third_party/libopenjpeg/invert.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker /*
2*3ac0a46fSAndroid Build Coastguard Worker  * The copyright in this software is being made available under the 2-clauses
3*3ac0a46fSAndroid Build Coastguard Worker  * BSD License, included below. This software may be subject to other third
4*3ac0a46fSAndroid Build Coastguard Worker  * party and contributor rights, including patent rights, and no such rights
5*3ac0a46fSAndroid Build Coastguard Worker  * are granted under this license.
6*3ac0a46fSAndroid Build Coastguard Worker  *
7*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <[email protected]>
8*3ac0a46fSAndroid Build Coastguard Worker  * All rights reserved.
9*3ac0a46fSAndroid Build Coastguard Worker  *
10*3ac0a46fSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
11*3ac0a46fSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
12*3ac0a46fSAndroid Build Coastguard Worker  * are met:
13*3ac0a46fSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
14*3ac0a46fSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
15*3ac0a46fSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
16*3ac0a46fSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
17*3ac0a46fSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
18*3ac0a46fSAndroid Build Coastguard Worker  *
19*3ac0a46fSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
20*3ac0a46fSAndroid Build Coastguard Worker  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*3ac0a46fSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*3ac0a46fSAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23*3ac0a46fSAndroid Build Coastguard Worker  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*3ac0a46fSAndroid Build Coastguard Worker  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*3ac0a46fSAndroid Build Coastguard Worker  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*3ac0a46fSAndroid Build Coastguard Worker  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*3ac0a46fSAndroid Build Coastguard Worker  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*3ac0a46fSAndroid Build Coastguard Worker  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*3ac0a46fSAndroid Build Coastguard Worker  * POSSIBILITY OF SUCH DAMAGE.
30*3ac0a46fSAndroid Build Coastguard Worker  */
31*3ac0a46fSAndroid Build Coastguard Worker 
32*3ac0a46fSAndroid Build Coastguard Worker #include "opj_includes.h"
33*3ac0a46fSAndroid Build Coastguard Worker 
34*3ac0a46fSAndroid Build Coastguard Worker /**
35*3ac0a46fSAndroid Build Coastguard Worker  * LUP decomposition
36*3ac0a46fSAndroid Build Coastguard Worker  */
37*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,
38*3ac0a46fSAndroid Build Coastguard Worker                                  OPJ_UINT32 * permutations,
39*3ac0a46fSAndroid Build Coastguard Worker                                  OPJ_FLOAT32 * p_swap_area,
40*3ac0a46fSAndroid Build Coastguard Worker                                  OPJ_UINT32 nb_compo);
41*3ac0a46fSAndroid Build Coastguard Worker /**
42*3ac0a46fSAndroid Build Coastguard Worker  * LUP solving
43*3ac0a46fSAndroid Build Coastguard Worker  */
44*3ac0a46fSAndroid Build Coastguard Worker static void opj_lupSolve(OPJ_FLOAT32 * pResult,
45*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_FLOAT32* pMatrix,
46*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_FLOAT32* pVector,
47*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_UINT32* pPermutations,
48*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_UINT32 nb_compo,
49*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_FLOAT32 * p_intermediate_data);
50*3ac0a46fSAndroid Build Coastguard Worker 
51*3ac0a46fSAndroid Build Coastguard Worker /**
52*3ac0a46fSAndroid Build Coastguard Worker  *LUP inversion (call with the result of lupDecompose)
53*3ac0a46fSAndroid Build Coastguard Worker  */
54*3ac0a46fSAndroid Build Coastguard Worker static void opj_lupInvert(OPJ_FLOAT32 * pSrcMatrix,
55*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_FLOAT32 * pDestMatrix,
56*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_UINT32 nb_compo,
57*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_UINT32 * pPermutations,
58*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_FLOAT32 * p_src_temp,
59*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_FLOAT32 * p_dest_temp,
60*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_FLOAT32 * p_swap_area);
61*3ac0a46fSAndroid Build Coastguard Worker 
62*3ac0a46fSAndroid Build Coastguard Worker /*
63*3ac0a46fSAndroid Build Coastguard Worker ==========================================================
64*3ac0a46fSAndroid Build Coastguard Worker    Matric inversion interface
65*3ac0a46fSAndroid Build Coastguard Worker ==========================================================
66*3ac0a46fSAndroid Build Coastguard Worker */
67*3ac0a46fSAndroid Build Coastguard Worker /**
68*3ac0a46fSAndroid Build Coastguard Worker  * Matrix inversion.
69*3ac0a46fSAndroid Build Coastguard Worker  */
opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,OPJ_FLOAT32 * pDestMatrix,OPJ_UINT32 nb_compo)70*3ac0a46fSAndroid Build Coastguard Worker OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,
71*3ac0a46fSAndroid Build Coastguard Worker                                 OPJ_FLOAT32 * pDestMatrix,
72*3ac0a46fSAndroid Build Coastguard Worker                                 OPJ_UINT32 nb_compo)
73*3ac0a46fSAndroid Build Coastguard Worker {
74*3ac0a46fSAndroid Build Coastguard Worker     OPJ_BYTE * l_data = 00;
75*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_permutation_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_UINT32);
76*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_swap_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
77*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 l_total_size = l_permutation_size + 3 * l_swap_size;
78*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 * lPermutations = 00;
79*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * l_double_data = 00;
80*3ac0a46fSAndroid Build Coastguard Worker 
81*3ac0a46fSAndroid Build Coastguard Worker     l_data = (OPJ_BYTE *) opj_malloc(l_total_size);
82*3ac0a46fSAndroid Build Coastguard Worker     if (l_data == 0) {
83*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
84*3ac0a46fSAndroid Build Coastguard Worker     }
85*3ac0a46fSAndroid Build Coastguard Worker     lPermutations = (OPJ_UINT32 *) l_data;
86*3ac0a46fSAndroid Build Coastguard Worker     l_double_data = (OPJ_FLOAT32 *)(l_data + l_permutation_size);
87*3ac0a46fSAndroid Build Coastguard Worker     memset(lPermutations, 0, l_permutation_size);
88*3ac0a46fSAndroid Build Coastguard Worker 
89*3ac0a46fSAndroid Build Coastguard Worker     if (! opj_lupDecompose(pSrcMatrix, lPermutations, l_double_data, nb_compo)) {
90*3ac0a46fSAndroid Build Coastguard Worker         opj_free(l_data);
91*3ac0a46fSAndroid Build Coastguard Worker         return OPJ_FALSE;
92*3ac0a46fSAndroid Build Coastguard Worker     }
93*3ac0a46fSAndroid Build Coastguard Worker 
94*3ac0a46fSAndroid Build Coastguard Worker     opj_lupInvert(pSrcMatrix, pDestMatrix, nb_compo, lPermutations, l_double_data,
95*3ac0a46fSAndroid Build Coastguard Worker                   l_double_data + nb_compo, l_double_data + 2 * nb_compo);
96*3ac0a46fSAndroid Build Coastguard Worker     opj_free(l_data);
97*3ac0a46fSAndroid Build Coastguard Worker 
98*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
99*3ac0a46fSAndroid Build Coastguard Worker }
100*3ac0a46fSAndroid Build Coastguard Worker 
101*3ac0a46fSAndroid Build Coastguard Worker 
102*3ac0a46fSAndroid Build Coastguard Worker /*
103*3ac0a46fSAndroid Build Coastguard Worker ==========================================================
104*3ac0a46fSAndroid Build Coastguard Worker    Local functions
105*3ac0a46fSAndroid Build Coastguard Worker ==========================================================
106*3ac0a46fSAndroid Build Coastguard Worker */
opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations,OPJ_FLOAT32 * p_swap_area,OPJ_UINT32 nb_compo)107*3ac0a46fSAndroid Build Coastguard Worker static OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,
108*3ac0a46fSAndroid Build Coastguard Worker                                  OPJ_UINT32 * permutations,
109*3ac0a46fSAndroid Build Coastguard Worker                                  OPJ_FLOAT32 * p_swap_area,
110*3ac0a46fSAndroid Build Coastguard Worker                                  OPJ_UINT32 nb_compo)
111*3ac0a46fSAndroid Build Coastguard Worker {
112*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 * tmpPermutations = permutations;
113*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 * dstPermutations;
114*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 k2 = 0, t;
115*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 temp;
116*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i, j, k;
117*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 p;
118*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 lLastColum = nb_compo - 1;
119*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
120*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lTmpMatrix = matrix;
121*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lColumnMatrix, * lDestMatrix;
122*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 offset = 1;
123*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 lStride = nb_compo - 1;
124*3ac0a46fSAndroid Build Coastguard Worker 
125*3ac0a46fSAndroid Build Coastguard Worker     /*initialize permutations */
126*3ac0a46fSAndroid Build Coastguard Worker     for (i = 0; i < nb_compo; ++i) {
127*3ac0a46fSAndroid Build Coastguard Worker         *tmpPermutations++ = i;
128*3ac0a46fSAndroid Build Coastguard Worker     }
129*3ac0a46fSAndroid Build Coastguard Worker     /* now make a pivot with column switch */
130*3ac0a46fSAndroid Build Coastguard Worker     tmpPermutations = permutations;
131*3ac0a46fSAndroid Build Coastguard Worker     for (k = 0; k < lLastColum; ++k) {
132*3ac0a46fSAndroid Build Coastguard Worker         p = 0.0;
133*3ac0a46fSAndroid Build Coastguard Worker 
134*3ac0a46fSAndroid Build Coastguard Worker         /* take the middle element */
135*3ac0a46fSAndroid Build Coastguard Worker         lColumnMatrix = lTmpMatrix + k;
136*3ac0a46fSAndroid Build Coastguard Worker 
137*3ac0a46fSAndroid Build Coastguard Worker         /* make permutation with the biggest value in the column */
138*3ac0a46fSAndroid Build Coastguard Worker         for (i = k; i < nb_compo; ++i) {
139*3ac0a46fSAndroid Build Coastguard Worker             temp = ((*lColumnMatrix > 0) ? *lColumnMatrix : -(*lColumnMatrix));
140*3ac0a46fSAndroid Build Coastguard Worker             if (temp > p) {
141*3ac0a46fSAndroid Build Coastguard Worker                 p = temp;
142*3ac0a46fSAndroid Build Coastguard Worker                 k2 = i;
143*3ac0a46fSAndroid Build Coastguard Worker             }
144*3ac0a46fSAndroid Build Coastguard Worker             /* next line */
145*3ac0a46fSAndroid Build Coastguard Worker             lColumnMatrix += nb_compo;
146*3ac0a46fSAndroid Build Coastguard Worker         }
147*3ac0a46fSAndroid Build Coastguard Worker 
148*3ac0a46fSAndroid Build Coastguard Worker         /* a whole rest of 0 -> non singular */
149*3ac0a46fSAndroid Build Coastguard Worker         if (p == 0.0) {
150*3ac0a46fSAndroid Build Coastguard Worker             return OPJ_FALSE;
151*3ac0a46fSAndroid Build Coastguard Worker         }
152*3ac0a46fSAndroid Build Coastguard Worker 
153*3ac0a46fSAndroid Build Coastguard Worker         /* should we permute ? */
154*3ac0a46fSAndroid Build Coastguard Worker         if (k2 != k) {
155*3ac0a46fSAndroid Build Coastguard Worker             /*exchange of line */
156*3ac0a46fSAndroid Build Coastguard Worker             /* k2 > k */
157*3ac0a46fSAndroid Build Coastguard Worker             dstPermutations = tmpPermutations + k2 - k;
158*3ac0a46fSAndroid Build Coastguard Worker             /* swap indices */
159*3ac0a46fSAndroid Build Coastguard Worker             t = *tmpPermutations;
160*3ac0a46fSAndroid Build Coastguard Worker             *tmpPermutations = *dstPermutations;
161*3ac0a46fSAndroid Build Coastguard Worker             *dstPermutations = t;
162*3ac0a46fSAndroid Build Coastguard Worker 
163*3ac0a46fSAndroid Build Coastguard Worker             /* and swap entire line. */
164*3ac0a46fSAndroid Build Coastguard Worker             lColumnMatrix = lTmpMatrix + (k2 - k) * nb_compo;
165*3ac0a46fSAndroid Build Coastguard Worker             memcpy(p_swap_area, lColumnMatrix, lSwapSize);
166*3ac0a46fSAndroid Build Coastguard Worker             memcpy(lColumnMatrix, lTmpMatrix, lSwapSize);
167*3ac0a46fSAndroid Build Coastguard Worker             memcpy(lTmpMatrix, p_swap_area, lSwapSize);
168*3ac0a46fSAndroid Build Coastguard Worker         }
169*3ac0a46fSAndroid Build Coastguard Worker 
170*3ac0a46fSAndroid Build Coastguard Worker         /* now update data in the rest of the line and line after */
171*3ac0a46fSAndroid Build Coastguard Worker         lDestMatrix = lTmpMatrix + k;
172*3ac0a46fSAndroid Build Coastguard Worker         lColumnMatrix = lDestMatrix + nb_compo;
173*3ac0a46fSAndroid Build Coastguard Worker         /* take the middle element */
174*3ac0a46fSAndroid Build Coastguard Worker         temp = *(lDestMatrix++);
175*3ac0a46fSAndroid Build Coastguard Worker 
176*3ac0a46fSAndroid Build Coastguard Worker         /* now compute up data (i.e. coeff up of the diagonal). */
177*3ac0a46fSAndroid Build Coastguard Worker         for (i = offset; i < nb_compo; ++i)  {
178*3ac0a46fSAndroid Build Coastguard Worker             /*lColumnMatrix; */
179*3ac0a46fSAndroid Build Coastguard Worker             /* divide the lower column elements by the diagonal value */
180*3ac0a46fSAndroid Build Coastguard Worker 
181*3ac0a46fSAndroid Build Coastguard Worker             /* matrix[i][k] /= matrix[k][k]; */
182*3ac0a46fSAndroid Build Coastguard Worker             /* p = matrix[i][k] */
183*3ac0a46fSAndroid Build Coastguard Worker             p = *lColumnMatrix / temp;
184*3ac0a46fSAndroid Build Coastguard Worker             *(lColumnMatrix++) = p;
185*3ac0a46fSAndroid Build Coastguard Worker 
186*3ac0a46fSAndroid Build Coastguard Worker             for (j = /* k + 1 */ offset; j < nb_compo; ++j) {
187*3ac0a46fSAndroid Build Coastguard Worker                 /* matrix[i][j] -= matrix[i][k] * matrix[k][j]; */
188*3ac0a46fSAndroid Build Coastguard Worker                 *(lColumnMatrix++) -= p * (*(lDestMatrix++));
189*3ac0a46fSAndroid Build Coastguard Worker             }
190*3ac0a46fSAndroid Build Coastguard Worker             /* come back to the k+1th element */
191*3ac0a46fSAndroid Build Coastguard Worker             lDestMatrix -= lStride;
192*3ac0a46fSAndroid Build Coastguard Worker             /* go to kth element of the next line */
193*3ac0a46fSAndroid Build Coastguard Worker             lColumnMatrix += k;
194*3ac0a46fSAndroid Build Coastguard Worker         }
195*3ac0a46fSAndroid Build Coastguard Worker 
196*3ac0a46fSAndroid Build Coastguard Worker         /* offset is now k+2 */
197*3ac0a46fSAndroid Build Coastguard Worker         ++offset;
198*3ac0a46fSAndroid Build Coastguard Worker         /* 1 element less for stride */
199*3ac0a46fSAndroid Build Coastguard Worker         --lStride;
200*3ac0a46fSAndroid Build Coastguard Worker         /* next line */
201*3ac0a46fSAndroid Build Coastguard Worker         lTmpMatrix += nb_compo;
202*3ac0a46fSAndroid Build Coastguard Worker         /* next permutation element */
203*3ac0a46fSAndroid Build Coastguard Worker         ++tmpPermutations;
204*3ac0a46fSAndroid Build Coastguard Worker     }
205*3ac0a46fSAndroid Build Coastguard Worker     return OPJ_TRUE;
206*3ac0a46fSAndroid Build Coastguard Worker }
207*3ac0a46fSAndroid Build Coastguard Worker 
opj_lupSolve(OPJ_FLOAT32 * pResult,OPJ_FLOAT32 * pMatrix,OPJ_FLOAT32 * pVector,OPJ_UINT32 * pPermutations,OPJ_UINT32 nb_compo,OPJ_FLOAT32 * p_intermediate_data)208*3ac0a46fSAndroid Build Coastguard Worker static void opj_lupSolve(OPJ_FLOAT32 * pResult,
209*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_FLOAT32 * pMatrix,
210*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_FLOAT32 * pVector,
211*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_UINT32* pPermutations,
212*3ac0a46fSAndroid Build Coastguard Worker                          OPJ_UINT32 nb_compo, OPJ_FLOAT32 * p_intermediate_data)
213*3ac0a46fSAndroid Build Coastguard Worker {
214*3ac0a46fSAndroid Build Coastguard Worker     OPJ_INT32 k;
215*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 i, j;
216*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 sum;
217*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 u;
218*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 lStride = nb_compo + 1;
219*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lCurrentPtr;
220*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lIntermediatePtr;
221*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lDestPtr;
222*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lTmpMatrix;
223*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lLineMatrix = pMatrix;
224*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lBeginPtr = pResult + nb_compo - 1;
225*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lGeneratedData;
226*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 * lCurrentPermutationPtr = pPermutations;
227*3ac0a46fSAndroid Build Coastguard Worker 
228*3ac0a46fSAndroid Build Coastguard Worker 
229*3ac0a46fSAndroid Build Coastguard Worker     lIntermediatePtr = p_intermediate_data;
230*3ac0a46fSAndroid Build Coastguard Worker     lGeneratedData = p_intermediate_data + nb_compo - 1;
231*3ac0a46fSAndroid Build Coastguard Worker 
232*3ac0a46fSAndroid Build Coastguard Worker     for (i = 0; i < nb_compo; ++i) {
233*3ac0a46fSAndroid Build Coastguard Worker         sum = 0.0;
234*3ac0a46fSAndroid Build Coastguard Worker         lCurrentPtr = p_intermediate_data;
235*3ac0a46fSAndroid Build Coastguard Worker         lTmpMatrix = lLineMatrix;
236*3ac0a46fSAndroid Build Coastguard Worker         for (j = 1; j <= i; ++j) {
237*3ac0a46fSAndroid Build Coastguard Worker             /* sum += matrix[i][j-1] * y[j-1]; */
238*3ac0a46fSAndroid Build Coastguard Worker             sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++));
239*3ac0a46fSAndroid Build Coastguard Worker         }
240*3ac0a46fSAndroid Build Coastguard Worker         /*y[i] = pVector[pPermutations[i]] - sum; */
241*3ac0a46fSAndroid Build Coastguard Worker         *(lIntermediatePtr++) = pVector[*(lCurrentPermutationPtr++)] - sum;
242*3ac0a46fSAndroid Build Coastguard Worker         lLineMatrix += nb_compo;
243*3ac0a46fSAndroid Build Coastguard Worker     }
244*3ac0a46fSAndroid Build Coastguard Worker 
245*3ac0a46fSAndroid Build Coastguard Worker     /* we take the last point of the matrix */
246*3ac0a46fSAndroid Build Coastguard Worker     lLineMatrix = pMatrix + nb_compo * nb_compo - 1;
247*3ac0a46fSAndroid Build Coastguard Worker 
248*3ac0a46fSAndroid Build Coastguard Worker     /* and we take after the last point of the destination vector */
249*3ac0a46fSAndroid Build Coastguard Worker     lDestPtr = pResult + nb_compo;
250*3ac0a46fSAndroid Build Coastguard Worker 
251*3ac0a46fSAndroid Build Coastguard Worker 
252*3ac0a46fSAndroid Build Coastguard Worker     assert(nb_compo != 0);
253*3ac0a46fSAndroid Build Coastguard Worker     for (k = (OPJ_INT32)nb_compo - 1; k != -1 ; --k) {
254*3ac0a46fSAndroid Build Coastguard Worker         sum = 0.0;
255*3ac0a46fSAndroid Build Coastguard Worker         lTmpMatrix = lLineMatrix;
256*3ac0a46fSAndroid Build Coastguard Worker         u = *(lTmpMatrix++);
257*3ac0a46fSAndroid Build Coastguard Worker         lCurrentPtr = lDestPtr--;
258*3ac0a46fSAndroid Build Coastguard Worker         for (j = (OPJ_UINT32)(k + 1); j < nb_compo; ++j) {
259*3ac0a46fSAndroid Build Coastguard Worker             /* sum += matrix[k][j] * x[j] */
260*3ac0a46fSAndroid Build Coastguard Worker             sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++));
261*3ac0a46fSAndroid Build Coastguard Worker         }
262*3ac0a46fSAndroid Build Coastguard Worker         /*x[k] = (y[k] - sum) / u; */
263*3ac0a46fSAndroid Build Coastguard Worker         *(lBeginPtr--) = (*(lGeneratedData--) - sum) / u;
264*3ac0a46fSAndroid Build Coastguard Worker         lLineMatrix -= lStride;
265*3ac0a46fSAndroid Build Coastguard Worker     }
266*3ac0a46fSAndroid Build Coastguard Worker }
267*3ac0a46fSAndroid Build Coastguard Worker 
268*3ac0a46fSAndroid Build Coastguard Worker 
opj_lupInvert(OPJ_FLOAT32 * pSrcMatrix,OPJ_FLOAT32 * pDestMatrix,OPJ_UINT32 nb_compo,OPJ_UINT32 * pPermutations,OPJ_FLOAT32 * p_src_temp,OPJ_FLOAT32 * p_dest_temp,OPJ_FLOAT32 * p_swap_area)269*3ac0a46fSAndroid Build Coastguard Worker static void opj_lupInvert(OPJ_FLOAT32 * pSrcMatrix,
270*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_FLOAT32 * pDestMatrix,
271*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_UINT32 nb_compo,
272*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_UINT32 * pPermutations,
273*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_FLOAT32 * p_src_temp,
274*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_FLOAT32 * p_dest_temp,
275*3ac0a46fSAndroid Build Coastguard Worker                           OPJ_FLOAT32 * p_swap_area)
276*3ac0a46fSAndroid Build Coastguard Worker {
277*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 j, i;
278*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lCurrentPtr;
279*3ac0a46fSAndroid Build Coastguard Worker     OPJ_FLOAT32 * lLineMatrix = pDestMatrix;
280*3ac0a46fSAndroid Build Coastguard Worker     OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
281*3ac0a46fSAndroid Build Coastguard Worker 
282*3ac0a46fSAndroid Build Coastguard Worker     for (j = 0; j < nb_compo; ++j) {
283*3ac0a46fSAndroid Build Coastguard Worker         lCurrentPtr = lLineMatrix++;
284*3ac0a46fSAndroid Build Coastguard Worker         memset(p_src_temp, 0, lSwapSize);
285*3ac0a46fSAndroid Build Coastguard Worker         p_src_temp[j] = 1.0;
286*3ac0a46fSAndroid Build Coastguard Worker         opj_lupSolve(p_dest_temp, pSrcMatrix, p_src_temp, pPermutations, nb_compo,
287*3ac0a46fSAndroid Build Coastguard Worker                      p_swap_area);
288*3ac0a46fSAndroid Build Coastguard Worker 
289*3ac0a46fSAndroid Build Coastguard Worker         for (i = 0; i < nb_compo; ++i) {
290*3ac0a46fSAndroid Build Coastguard Worker             *(lCurrentPtr) = p_dest_temp[i];
291*3ac0a46fSAndroid Build Coastguard Worker             lCurrentPtr += nb_compo;
292*3ac0a46fSAndroid Build Coastguard Worker         }
293*3ac0a46fSAndroid Build Coastguard Worker     }
294*3ac0a46fSAndroid Build Coastguard Worker }
295*3ac0a46fSAndroid Build Coastguard Worker 
296