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_d64
36#define FTYPE DTYPE
37
38#define FUN_NAME(CHAN) mlib_ImageAffine_d64_##CHAN##_bl
39
40/***************************************************************/
41mlib_status FUN_NAME(1ch)(mlib_affine_param *param)
42{
43 DECLAREVAR_BL();
44 DTYPE *dstLineEnd;
45 FTYPE scale = ONE / MLIB_PREC;
46 mlib_s32 srcYStride1;
47
48 srcYStride /= sizeof(DTYPE);
49 srcYStride1 = srcYStride + 1;
50
51 for (j = yStart; j <= yFinish; j++) {
52 FTYPE t, u, k0, k1, k2, k3;
53 FTYPE a00_0, a01_0, a10_0, a11_0;
54 FTYPE pix0;
55
56 CLIP(1);
57 dstLineEnd = (DTYPE *) dstData + xRight;
58
59 t = (X & MLIB_MASK) * scale;
60 u = (Y & MLIB_MASK) * scale;
61 ySrc = MLIB_POINTER_SHIFT(Y);
62 Y += dY;
63 xSrc = X >> MLIB_SHIFT;
64 X += dX;
65 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + xSrc;
66 k3 = t * u;
67 k2 = (ONE - t) * u;
68 k1 = t * (ONE - u);
69 k0 = (ONE - t) * (ONE - u);
70 a00_0 = srcPixelPtr[0];
71 a01_0 = srcPixelPtr[1];
72 a10_0 = srcPixelPtr[srcYStride];
73 a11_0 = srcPixelPtr[srcYStride1];
74
75 for (; dstPixelPtr < dstLineEnd; dstPixelPtr++) {
76 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
77 t = (X & MLIB_MASK) * scale;
78 u = (Y & MLIB_MASK) * scale;
79 ySrc = MLIB_POINTER_SHIFT(Y);
80 Y += dY;
81 xSrc = X >> MLIB_SHIFT;
82 X += dX;
83 srcPixelPtr = *(DTYPE **) ((mlib_u8 *) lineAddr + ySrc) + xSrc;
84 k3 = t * u;
85 k2 = (ONE - t) * u;
86 k1 = t * (ONE - u);
87 k0 = (ONE - t) * (ONE - u);
88 a00_0 = srcPixelPtr[0];
89 a01_0 = srcPixelPtr[1];
90 a10_0 = srcPixelPtr[srcYStride];
91 a11_0 = srcPixelPtr[srcYStride1];
92 dstPixelPtr[0] = pix0;
93 }
94
95 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
96 dstPixelPtr[0] = pix0;
97 }
98
99 return MLIB_SUCCESS;
100}
101
102/***************************************************************/
103mlib_status FUN_NAME(2ch)(mlib_affine_param *param)
104{
105 DECLAREVAR_BL();
106 DTYPE *dstLineEnd;
107 FTYPE scale = ONE / MLIB_PREC;
108
109 for (j = yStart; j <= yFinish; j++) {
110 DTYPE *srcPixelPtr2;
111 FTYPE t, u, k0, k1, k2, k3;
112 FTYPE a00_0, a01_0, a10_0, a11_0;
113 FTYPE a00_1, a01_1, a10_1, a11_1;
114 FTYPE pix0, pix1;
115
116 CLIP(2);
117 dstLineEnd = (DTYPE *) dstData + 2 * xRight;
118
119 t = (X & MLIB_MASK) * scale;
120 u = (Y & MLIB_MASK) * scale;
121 ySrc = MLIB_POINTER_SHIFT(Y);
122 Y += dY;
123 xSrc = X >> MLIB_SHIFT;
124 X += dX;
125 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc;
126 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
127 k3 = t * u;
128 k2 = (ONE - t) * u;
129 k1 = t * (ONE - u);
130 k0 = (ONE - t) * (ONE - u);
131 a00_0 = srcPixelPtr[0];
132 a00_1 = srcPixelPtr[1];
133 a01_0 = srcPixelPtr[2];
134 a01_1 = srcPixelPtr[3];
135 a10_0 = srcPixelPtr2[0];
136 a10_1 = srcPixelPtr2[1];
137 a11_0 = srcPixelPtr2[2];
138 a11_1 = srcPixelPtr2[3];
139
140 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 2) {
141 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
142 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
143 t = (X & MLIB_MASK) * scale;
144 u = (Y & MLIB_MASK) * scale;
145 ySrc = MLIB_POINTER_SHIFT(Y);
146 Y += dY;
147 xSrc = X >> MLIB_SHIFT;
148 X += dX;
149 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc;
150 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
151 k3 = t * u;
152 k2 = (ONE - t) * u;
153 k1 = t * (ONE - u);
154 k0 = (ONE - t) * (ONE - u);
155 a01_0 = srcPixelPtr[2];
156 a01_1 = srcPixelPtr[3];
157 a00_0 = srcPixelPtr[0];
158 a00_1 = srcPixelPtr[1];
159 a10_0 = srcPixelPtr2[0];
160 a10_1 = srcPixelPtr2[1];
161 a11_0 = srcPixelPtr2[2];
162 a11_1 = srcPixelPtr2[3];
163 dstPixelPtr[0] = pix0;
164 dstPixelPtr[1] = pix1;
165 }
166
167 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
168 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
169 dstPixelPtr[0] = pix0;
170 dstPixelPtr[1] = pix1;
171 }
172
173 return MLIB_SUCCESS;
174}
175
176/***************************************************************/
177mlib_status FUN_NAME(3ch)(mlib_affine_param *param)
178{
179 DECLAREVAR_BL();
180 DTYPE *dstLineEnd;
181 FTYPE scale = ONE / MLIB_PREC;
182
183 for (j = yStart; j <= yFinish; j++) {
184 DTYPE *srcPixelPtr2;
185 FTYPE t, u, k0, k1, k2, k3;
186 FTYPE a00_0, a01_0, a10_0, a11_0;
187 FTYPE a00_1, a01_1, a10_1, a11_1;
188 FTYPE a00_2, a01_2, a10_2, a11_2;
189 FTYPE pix0, pix1, pix2;
190
191 CLIP(3);
192 dstLineEnd = (DTYPE *) dstData + 3 * xRight;
193
194 t = (X & MLIB_MASK) * scale;
195 u = (Y & MLIB_MASK) * scale;
196 ySrc = MLIB_POINTER_SHIFT(Y);
197 Y += dY;
198 xSrc = X >> MLIB_SHIFT;
199 X += dX;
200 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc;
201 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
202 k3 = t * u;
203 k2 = (ONE - t) * u;
204 k1 = t * (ONE - u);
205 k0 = (ONE - t) * (ONE - u);
206 a00_0 = srcPixelPtr[0];
207 a00_1 = srcPixelPtr[1];
208 a00_2 = srcPixelPtr[2];
209 a01_0 = srcPixelPtr[3];
210 a01_1 = srcPixelPtr[4];
211 a01_2 = srcPixelPtr[5];
212 a10_0 = srcPixelPtr2[0];
213 a10_1 = srcPixelPtr2[1];
214 a10_2 = srcPixelPtr2[2];
215 a11_0 = srcPixelPtr2[3];
216 a11_1 = srcPixelPtr2[4];
217 a11_2 = srcPixelPtr2[5];
218
219 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 3) {
220 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
221 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
222 pix2 = k0 * a00_2 + k1 * a01_2 + k2 * a10_2 + k3 * a11_2;
223 t = (X & MLIB_MASK) * scale;
224 u = (Y & MLIB_MASK) * scale;
225 ySrc = MLIB_POINTER_SHIFT(Y);
226 Y += dY;
227 xSrc = X >> MLIB_SHIFT;
228 X += dX;
229 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc;
230 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
231 k3 = t * u;
232 k2 = (ONE - t) * u;
233 k1 = t * (ONE - u);
234 k0 = (ONE - t) * (ONE - u);
235 a01_0 = srcPixelPtr[3];
236 a01_1 = srcPixelPtr[4];
237 a01_2 = srcPixelPtr[5];
238 a00_0 = srcPixelPtr[0];
239 a00_1 = srcPixelPtr[1];
240 a00_2 = srcPixelPtr[2];
241 a10_0 = srcPixelPtr2[0];
242 a10_1 = srcPixelPtr2[1];
243 a10_2 = srcPixelPtr2[2];
244 a11_0 = srcPixelPtr2[3];
245 a11_1 = srcPixelPtr2[4];
246 a11_2 = srcPixelPtr2[5];
247 dstPixelPtr[0] = pix0;
248 dstPixelPtr[1] = pix1;
249 dstPixelPtr[2] = pix2;
250 }
251
252 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
253 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
254 pix2 = k0 * a00_2 + k1 * a01_2 + k2 * a10_2 + k3 * a11_2;
255 dstPixelPtr[0] = pix0;
256 dstPixelPtr[1] = pix1;
257 dstPixelPtr[2] = pix2;
258 }
259
260 return MLIB_SUCCESS;
261}
262
263/***************************************************************/
264mlib_status FUN_NAME(4ch)(mlib_affine_param *param)
265{
266 DECLAREVAR_BL();
267 DTYPE *dstLineEnd;
268 FTYPE scale = ONE / MLIB_PREC;
269
270 for (j = yStart; j <= yFinish; j++) {
271 DTYPE *srcPixelPtr2;
272 FTYPE t, u, k0, k1, k2, k3;
273 FTYPE a00_0, a01_0, a10_0, a11_0;
274 FTYPE a00_1, a01_1, a10_1, a11_1;
275 FTYPE a00_2, a01_2, a10_2, a11_2;
276 FTYPE a00_3, a01_3, a10_3, a11_3;
277 FTYPE pix0, pix1, pix2, pix3;
278
279 CLIP(4);
280 dstLineEnd = (DTYPE *) dstData + 4 * xRight;
281
282 t = (X & MLIB_MASK) * scale;
283 u = (Y & MLIB_MASK) * scale;
284 ySrc = MLIB_POINTER_SHIFT(Y);
285 Y += dY;
286 xSrc = X >> MLIB_SHIFT;
287 X += dX;
288 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc;
289 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
290 k3 = t * u;
291 k2 = (ONE - t) * u;
292 k1 = t * (ONE - u);
293 k0 = (ONE - t) * (ONE - u);
294 a00_0 = srcPixelPtr[0];
295 a00_1 = srcPixelPtr[1];
296 a00_2 = srcPixelPtr[2];
297 a00_3 = srcPixelPtr[3];
298 a01_0 = srcPixelPtr[4];
299 a01_1 = srcPixelPtr[5];
300 a01_2 = srcPixelPtr[6];
301 a01_3 = srcPixelPtr[7];
302 a10_0 = srcPixelPtr2[0];
303 a10_1 = srcPixelPtr2[1];
304 a10_2 = srcPixelPtr2[2];
305 a10_3 = srcPixelPtr2[3];
306 a11_0 = srcPixelPtr2[4];
307 a11_1 = srcPixelPtr2[5];
308 a11_2 = srcPixelPtr2[6];
309 a11_3 = srcPixelPtr2[7];
310
311 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 4) {
312 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
313 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
314 pix2 = k0 * a00_2 + k1 * a01_2 + k2 * a10_2 + k3 * a11_2;
315 pix3 = k0 * a00_3 + k1 * a01_3 + k2 * a10_3 + k3 * a11_3;
316 t = (X & MLIB_MASK) * scale;
317 u = (Y & MLIB_MASK) * scale;
318 ySrc = MLIB_POINTER_SHIFT(Y);
319 Y += dY;
320 xSrc = X >> (MLIB_SHIFT - 2);
321 X += dX;
322 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + (xSrc & ~3);
323 srcPixelPtr2 = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
324 k3 = t * u;
325 k2 = (ONE - t) * u;
326 k1 = t * (ONE - u);
327 k0 = (ONE - t) * (ONE - u);
328 a00_3 = srcPixelPtr[3];
329 a01_3 = srcPixelPtr[7];
330 a10_3 = srcPixelPtr2[3];
331 a11_3 = srcPixelPtr2[7];
332 a00_0 = srcPixelPtr[0];
333 a00_1 = srcPixelPtr[1];
334 a00_2 = srcPixelPtr[2];
335 a01_0 = srcPixelPtr[4];
336 a01_1 = srcPixelPtr[5];
337 a01_2 = srcPixelPtr[6];
338 a10_0 = srcPixelPtr2[0];
339 a10_1 = srcPixelPtr2[1];
340 a10_2 = srcPixelPtr2[2];
341 a11_0 = srcPixelPtr2[4];
342 a11_1 = srcPixelPtr2[5];
343 a11_2 = srcPixelPtr2[6];
344 dstPixelPtr[0] = pix0;
345 dstPixelPtr[1] = pix1;
346 dstPixelPtr[2] = pix2;
347 dstPixelPtr[3] = pix3;
348 }
349
350 pix0 = k0 * a00_0 + k1 * a01_0 + k2 * a10_0 + k3 * a11_0;
351 pix1 = k0 * a00_1 + k1 * a01_1 + k2 * a10_1 + k3 * a11_1;
352 pix2 = k0 * a00_2 + k1 * a01_2 + k2 * a10_2 + k3 * a11_2;
353 pix3 = k0 * a00_3 + k1 * a01_3 + k2 * a10_3 + k3 * a11_3;
354 dstPixelPtr[0] = pix0;
355 dstPixelPtr[1] = pix1;
356 dstPixelPtr[2] = pix2;
357 dstPixelPtr[3] = pix3;
358 }
359
360 return MLIB_SUCCESS;
361}
362
363/***************************************************************/
364