1/*
2 * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27/*
28 * FUNCTION
29 * Internal functions for mlib_ImageAffine with bilinear filtering.
30 */
31
32#include "mlib_ImageAffine.h"
33
34/***************************************************************/
35#define DTYPE mlib_s32
36#define FTYPE mlib_d64
37/* handle FTYPE to DTYPE conversion like in mlib_ImageAffine_BC_S32.c */
38#define STORE(res, x) SAT_32(res, x)
39
40#define FUN_NAME(CHAN) mlib_ImageAffine_s32_##CHAN##_bl
41
42/***************************************************************/
43mlib_status FUN_NAME(1ch)(mlib_affine_param *param)
44{
45 DECLAREVAR_BL();
46 DTYPE *dstLineEnd;
47 FTYPE scale = ONE / MLIB_PREC;
48 mlib_s32 srcYStride1;
49
50 srcYStride /= sizeof(DTYPE);
51 srcYStride1 = srcYStride + 1;
52
53 for (j = yStart; j <= yFinish; j++) {
54 FTYPE t, u, k0, k1, k2, k3;
55 FTYPE a00_0, a01_0, a10_0, a11_0;
56 FTYPE pix0;
57
58 CLIP(1);
59 dstLineEnd = (DTYPE *) dstData + xRight;
60
61 t = (X & MLIB_MASK) * scale;
62 u = (Y & MLIB_MASK) * scale;
63 ySrc = MLIB_POINTER_SHIFT(Y);
64 Y += dY;
65 xSrc = X >> MLIB_SHIFT;
66 X += dX;
67 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + xSrc;
68 k3 = t * u;
69 k2 = (ONE - t) * u;
70 k1 = t * (ONE - u);
71 k0 = (ONE - t) * (ONE - u);
72 a00_0 = srcPixelPtr[0];
73 a01_0 = srcPixelPtr[1];
74 a10_0 = srcPixelPtr[srcYStride];
75 a11_0 = srcPixelPtr[srcYStride1];
76
77 for (; dstPixelPtr < dstLineEnd; dstPixelPtr++) {
78 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
79 t = (X & MLIB_MASK) * scale;
80 u = (Y & MLIB_MASK) * scale;
81 ySrc = MLIB_POINTER_SHIFT(Y);
82 Y += dY;
83 xSrc = X >> MLIB_SHIFT;
84 X += dX;
85 srcPixelPtr = *(DTYPE **) ((mlib_u8 *) lineAddr + ySrc) + xSrc;
86 k3 = t * u;
87 k2 = (ONE - t) * u;
88 k1 = t * (ONE - u);
89 k0 = (ONE - t) * (ONE - u);
90 a00_0 = srcPixelPtr[0];
91 a01_0 = srcPixelPtr[1];
92 a10_0 = srcPixelPtr[srcYStride];
93 a11_0 = srcPixelPtr[srcYStride1];
94 STORE(dstPixelPtr[0], pix0);
95 }
96
97 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
98 STORE(dstPixelPtr[0], pix0);
99 }
100
101 return MLIB_SUCCESS;
102}
103
104/***************************************************************/
105mlib_status FUN_NAME(2ch)(mlib_affine_param *param)
106{
107 DECLAREVAR_BL();
108 DTYPE *dstLineEnd;
109 FTYPE scale = ONE / MLIB_PREC;
110
111 for (j = yStart; j <= yFinish; j++) {
112 DTYPE *srcPixelPtr2;
113 FTYPE t, u, k0, k1, k2, k3;
114 FTYPE a00_0, a01_0, a10_0, a11_0;
115 FTYPE a00_1, a01_1, a10_1, a11_1;
116 FTYPE pix0, pix1;
117
118 CLIP(2);
119 dstLineEnd = (DTYPE *) dstData + 2 * xRight;
120
121 t = (X & MLIB_MASK) * scale;
122 u = (Y & MLIB_MASK) * scale;
123 ySrc = MLIB_POINTER_SHIFT(Y);
124 Y += dY;
125 xSrc = X >> MLIB_SHIFT;
126 X += dX;
127 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc;
128 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
129 k3 = t * u;
130 k2 = (ONE - t) * u;
131 k1 = t * (ONE - u);
132 k0 = (ONE - t) * (ONE - u);
133 a00_0 = srcPixelPtr[0];
134 a00_1 = srcPixelPtr[1];
135 a01_0 = srcPixelPtr[2];
136 a01_1 = srcPixelPtr[3];
137 a10_0 = srcPixelPtr2[0];
138 a10_1 = srcPixelPtr2[1];
139 a11_0 = srcPixelPtr2[2];
140 a11_1 = srcPixelPtr2[3];
141
142 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 2) {
143 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
144 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
145 t = (X & MLIB_MASK) * scale;
146 u = (Y & MLIB_MASK) * scale;
147 ySrc = MLIB_POINTER_SHIFT(Y);
148 Y += dY;
149 xSrc = X >> MLIB_SHIFT;
150 X += dX;
151 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc;
152 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
153 k3 = t * u;
154 k2 = (ONE - t) * u;
155 k1 = t * (ONE - u);
156 k0 = (ONE - t) * (ONE - u);
157 a01_0 = srcPixelPtr[2];
158 a01_1 = srcPixelPtr[3];
159 a00_0 = srcPixelPtr[0];
160 a00_1 = srcPixelPtr[1];
161 a10_0 = srcPixelPtr2[0];
162 a10_1 = srcPixelPtr2[1];
163 a11_0 = srcPixelPtr2[2];
164 a11_1 = srcPixelPtr2[3];
165 STORE(dstPixelPtr[0], pix0);
166 STORE(dstPixelPtr[1], pix1);
167 }
168
169 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
170 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
171 STORE(dstPixelPtr[0], pix0);
172 STORE(dstPixelPtr[1], pix1);
173 }
174
175 return MLIB_SUCCESS;
176}
177
178/***************************************************************/
179mlib_status FUN_NAME(3ch)(mlib_affine_param *param)
180{
181 DECLAREVAR_BL();
182 DTYPE *dstLineEnd;
183 FTYPE scale = ONE / MLIB_PREC;
184
185 for (j = yStart; j <= yFinish; j++) {
186 DTYPE *srcPixelPtr2;
187 FTYPE t, u, k0, k1, k2, k3;
188 FTYPE a00_0, a01_0, a10_0, a11_0;
189 FTYPE a00_1, a01_1, a10_1, a11_1;
190 FTYPE a00_2, a01_2, a10_2, a11_2;
191 FTYPE pix0, pix1, pix2;
192
193 CLIP(3);
194 dstLineEnd = (DTYPE *) dstData + 3 * xRight;
195
196 t = (X & MLIB_MASK) * scale;
197 u = (Y & MLIB_MASK) * scale;
198 ySrc = MLIB_POINTER_SHIFT(Y);
199 Y += dY;
200 xSrc = X >> MLIB_SHIFT;
201 X += dX;
202 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc;
203 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
204 k3 = t * u;
205 k2 = (ONE - t) * u;
206 k1 = t * (ONE - u);
207 k0 = (ONE - t) * (ONE - u);
208 a00_0 = srcPixelPtr[0];
209 a00_1 = srcPixelPtr[1];
210 a00_2 = srcPixelPtr[2];
211 a01_0 = srcPixelPtr[3];
212 a01_1 = srcPixelPtr[4];
213 a01_2 = srcPixelPtr[5];
214 a10_0 = srcPixelPtr2[0];
215 a10_1 = srcPixelPtr2[1];
216 a10_2 = srcPixelPtr2[2];
217 a11_0 = srcPixelPtr2[3];
218 a11_1 = srcPixelPtr2[4];
219 a11_2 = srcPixelPtr2[5];
220
221 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 3) {
222 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
223 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
224 pix2 = k0 * a00_2 + k1 * a01_2 + k2 * a10_2 + k3 * a11_2;
225 t = (X & MLIB_MASK) * scale;
226 u = (Y & MLIB_MASK) * scale;
227 ySrc = MLIB_POINTER_SHIFT(Y);
228 Y += dY;
229 xSrc = X >> MLIB_SHIFT;
230 X += dX;
231 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc;
232 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
233 k3 = t * u;
234 k2 = (ONE - t) * u;
235 k1 = t * (ONE - u);
236 k0 = (ONE - t) * (ONE - u);
237 a01_0 = srcPixelPtr[3];
238 a01_1 = srcPixelPtr[4];
239 a01_2 = srcPixelPtr[5];
240 a00_0 = srcPixelPtr[0];
241 a00_1 = srcPixelPtr[1];
242 a00_2 = srcPixelPtr[2];
243 a10_0 = srcPixelPtr2[0];
244 a10_1 = srcPixelPtr2[1];
245 a10_2 = srcPixelPtr2[2];
246 a11_0 = srcPixelPtr2[3];
247 a11_1 = srcPixelPtr2[4];
248 a11_2 = srcPixelPtr2[5];
249 STORE(dstPixelPtr[0], pix0);
250 STORE(dstPixelPtr[1], pix1);
251 STORE(dstPixelPtr[2], pix2);
252 }
253
254 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
255 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
256 pix2 = k0 * a00_2 + k1 * a01_2 + k2 * a10_2 + k3 * a11_2;
257 STORE(dstPixelPtr[0], pix0);
258 STORE(dstPixelPtr[1], pix1);
259 STORE(dstPixelPtr[2], pix2);
260 }
261
262 return MLIB_SUCCESS;
263}
264
265/***************************************************************/
266mlib_status FUN_NAME(4ch)(mlib_affine_param *param)
267{
268 DECLAREVAR_BL();
269 DTYPE *dstLineEnd;
270 FTYPE scale = ONE / MLIB_PREC;
271
272 for (j = yStart; j <= yFinish; j++) {
273 DTYPE *srcPixelPtr2;
274 FTYPE t, u, k0, k1, k2, k3;
275 FTYPE a00_0, a01_0, a10_0, a11_0;
276 FTYPE a00_1, a01_1, a10_1, a11_1;
277 FTYPE a00_2, a01_2, a10_2, a11_2;
278 FTYPE a00_3, a01_3, a10_3, a11_3;
279 FTYPE pix0, pix1, pix2, pix3;
280
281 CLIP(4);
282 dstLineEnd = (DTYPE *) dstData + 4 * xRight;
283
284 t = (X & MLIB_MASK) * scale;
285 u = (Y & MLIB_MASK) * scale;
286 ySrc = MLIB_POINTER_SHIFT(Y);
287 Y += dY;
288 xSrc = X >> MLIB_SHIFT;
289 X += dX;
290 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc;
291 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
292 k3 = t * u;
293 k2 = (ONE - t) * u;
294 k1 = t * (ONE - u);
295 k0 = (ONE - t) * (ONE - u);
296 a00_0 = srcPixelPtr[0];
297 a00_1 = srcPixelPtr[1];
298 a00_2 = srcPixelPtr[2];
299 a00_3 = srcPixelPtr[3];
300 a01_0 = srcPixelPtr[4];
301 a01_1 = srcPixelPtr[5];
302 a01_2 = srcPixelPtr[6];
303 a01_3 = srcPixelPtr[7];
304 a10_0 = srcPixelPtr2[0];
305 a10_1 = srcPixelPtr2[1];
306 a10_2 = srcPixelPtr2[2];
307 a10_3 = srcPixelPtr2[3];
308 a11_0 = srcPixelPtr2[4];
309 a11_1 = srcPixelPtr2[5];
310 a11_2 = srcPixelPtr2[6];
311 a11_3 = srcPixelPtr2[7];
312
313 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 4) {
314 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
315 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
316 pix2 = k0 * a00_2 + k1 * a01_2 + k2 * a10_2 + k3 * a11_2;
317 pix3 = k0 * a00_3 + k1 * a01_3 + k2 * a10_3 + k3 * a11_3;
318 t = (X & MLIB_MASK) * scale;
319 u = (Y & MLIB_MASK) * scale;
320 ySrc = MLIB_POINTER_SHIFT(Y);
321 Y += dY;
322 xSrc = X >> (MLIB_SHIFT - 2);
323 X += dX;
324 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + (xSrc & ~3);
325 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
326 k3 = t * u;
327 k2 = (ONE - t) * u;
328 k1 = t * (ONE - u);
329 k0 = (ONE - t) * (ONE - u);
330 a00_3 = srcPixelPtr[3];
331 a01_3 = srcPixelPtr[7];
332 a10_3 = srcPixelPtr2[3];
333 a11_3 = srcPixelPtr2[7];
334 a00_0 = srcPixelPtr[0];
335 a00_1 = srcPixelPtr[1];
336 a00_2 = srcPixelPtr[2];
337 a01_0 = srcPixelPtr[4];
338 a01_1 = srcPixelPtr[5];
339 a01_2 = srcPixelPtr[6];
340 a10_0 = srcPixelPtr2[0];
341 a10_1 = srcPixelPtr2[1];
342 a10_2 = srcPixelPtr2[2];
343 a11_0 = srcPixelPtr2[4];
344 a11_1 = srcPixelPtr2[5];
345 a11_2 = srcPixelPtr2[6];
346 STORE(dstPixelPtr[0], pix0);
347 STORE(dstPixelPtr[1], pix1);
348 STORE(dstPixelPtr[2], pix2);
349 STORE(dstPixelPtr[3], pix3);
350 }
351
352 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
353 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
354 pix2 = k0 * a00_2 + k1 * a01_2 + k2 * a10_2 + k3 * a11_2;
355 pix3 = k0 * a00_3 + k1 * a01_3 + k2 * a10_3 + k3 * a11_3;
356 STORE(dstPixelPtr[0], pix0);
357 STORE(dstPixelPtr[1], pix1);
358 STORE(dstPixelPtr[2], pix2);
359 STORE(dstPixelPtr[3], pix3);
360 }
361
362 return MLIB_SUCCESS;
363}
364
365/***************************************************************/
366