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