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 *      Image affine transformation with Bicubic filtering
30 * SYNOPSIS
31 *      mlib_status mlib_ImageAffine_[s32|f32|d64]_?ch_bc
32 *                                  (mlib_s32 *leftEdges,
33 *                                   mlib_s32 *rightEdges,
34 *                                   mlib_s32 *xStarts,
35 *                                   mlib_s32 *yStarts,
36 *                                   mlib_s32 *sides,
37 *                                   mlib_u8  *dstData,
38 *                                   mlib_u8  **lineAddr,
39 *                                   mlib_s32 dstYStride,
40 *                                   mlib_s32 is_affine,
41 *                                   mlib_s32 srcYStride,
42 *                                   mlib_filter filter)
43 *
44 * ARGUMENTS
45 *      leftEdges  array[dstHeight] of xLeft coordinates
46 *      RightEdges array[dstHeight] of xRight coordinates
47 *      xStarts    array[dstHeight] of xStart * 65536 coordinates
48 *      yStarts    array[dstHeight] of yStart * 65536 coordinates
49 *      sides      output array[4]. sides[0] is yStart, sides[1] is yFinish,
50 *                 sides[2] is dx * 65536, sides[3] is dy * 65536
51 *      dstData    pointer to the first pixel on (yStart - 1) line
52 *      lineAddr   array[srcHeight] of pointers to the first pixel on
53 *                 the corresponding lines
54 *      dstYStride stride of destination image
55 *      is_affine  indicator (Affine - GridWarp)
56 *      srcYStride stride of source image
57 *      filter     type of resampling filter
58 *
59 * DESCRIPTION
60 *      The functions step along the lines from xLeft to xRight and apply
61 *      the Bicubic and Bicubic2 filtering.
62 *
63 */
64
65#include "mlib_ImageAffine.h"
66
67#define IMG_TYPE  4
68
69/***************************************************************/
70#if IMG_TYPE == 3
71
72#define DTYPE  mlib_s32
73#define FTYPE  mlib_d64
74
75#define FUN_NAME(CHAN) mlib_ImageAffine_s32_##CHAN##_bc
76
77#define STORE(res, x) SAT32(res)
78
79#elif IMG_TYPE == 4
80
81#define DTYPE  mlib_f32
82#define FTYPE  DTYPE
83
84#define FUN_NAME(CHAN) mlib_ImageAffine_f32_##CHAN##_bc
85
86#define STORE(res, x) res = (x)
87
88#elif IMG_TYPE == 5
89
90#define DTYPE  mlib_d64
91#define FTYPE  DTYPE
92
93#define FUN_NAME(CHAN) mlib_ImageAffine_d64_##CHAN##_bc
94
95#define STORE(res, x) res = (x)
96
97#endif /* IMG_TYPE == 3 */
98
99/***************************************************************/
100#define CREATE_COEF_BICUBIC( X, Y, OPERATOR )                   \
101  dx = (X & MLIB_MASK) * scale;                                 \
102  dy = (Y & MLIB_MASK) * scale;                                 \
103  dx_2  = ((FTYPE)0.5)  * dx;                                   \
104  dy_2  = ((FTYPE)0.5)  * dy;                                   \
105  dx2   = dx   * dx;    dy2   = dy   * dy;                      \
106  dx3_2 = dx_2 * dx2;   dy3_2 = dy_2 * dy2;                     \
107  dx3_3 = ((FTYPE)3.0)  * dx3_2;                                \
108  dy3_3 = ((FTYPE)3.0)  * dy3_2;                                \
109                                                                \
110  xf0 = dx2 - dx3_2 - dx_2;                                     \
111  xf1 = dx3_3 - ((FTYPE)2.5) * dx2 + ((FTYPE)1.0);              \
112  xf2 = ((FTYPE)2.0) * dx2 - dx3_3 + dx_2;                      \
113  xf3 = dx3_2 - ((FTYPE)0.5) * dx2;                             \
114                                                                \
115  OPERATOR;                                                     \
116                                                                \
117  yf0 = dy2 - dy3_2 - dy_2;                                     \
118  yf1 = dy3_3 - ((FTYPE)2.5) * dy2 + ((FTYPE)1.0);              \
119  yf2 = ((FTYPE)2.0) * dy2 - dy3_3 + dy_2;                      \
120  yf3 = dy3_2 - ((FTYPE)0.5) * dy2
121
122/***************************************************************/
123#define CREATE_COEF_BICUBIC_2( X, Y, OPERATOR )                 \
124  dx = (X & MLIB_MASK) * scale;                                 \
125  dy = (Y & MLIB_MASK) * scale;                                 \
126  dx2   = dx  * dx;    dy2   = dy  * dy;                        \
127  dx3_2 = dx  * dx2;   dy3_2 = dy  * dy2;                       \
128  dx3_3 = ((FTYPE)2.0) * dx2;                                   \
129  dy3_3 = ((FTYPE)2.0) * dy2;                                   \
130                                                                \
131  xf0 = dx3_3 - dx3_2 - dx;                                     \
132  xf1 = dx3_2 - dx3_3 + ((FTYPE)1.0);                           \
133  xf2 = dx2   - dx3_2   + dx;                                   \
134  xf3 = dx3_2 - dx2;                                            \
135                                                                \
136  OPERATOR;                                                     \
137                                                                \
138  yf0 = dy3_3 - dy3_2 - dy;                                     \
139  yf1 = dy3_2 - dy3_3 + ((FTYPE)1.0);                           \
140  yf2 = dy2   - dy3_2   + dy;                                   \
141  yf3 = dy3_2 - dy2
142
143/***************************************************************/
144mlib_status FUN_NAME(1ch)(mlib_affine_param *param)
145{
146  DECLAREVAR_BC();
147  DTYPE *dstLineEnd;
148
149  for (j = yStart; j <= yFinish; j++) {
150    FTYPE xf0, xf1, xf2, xf3;
151    FTYPE yf0, yf1, yf2, yf3;
152    FTYPE dx, dx_2, dx2, dx3_2, dx3_3;
153    FTYPE dy, dy_2, dy2, dy3_2, dy3_3;
154    FTYPE c0, c1, c2, c3, val0;
155    FTYPE scale = 1 / 65536.f;
156    FTYPE s0, s1, s2, s3;
157    FTYPE s4, s5, s6, s7;
158
159    CLIP(1);
160    dstLineEnd = (DTYPE *) dstData + xRight;
161
162    if (filter == MLIB_BICUBIC) {
163      CREATE_COEF_BICUBIC(X, Y,;);
164    }
165    else {
166      CREATE_COEF_BICUBIC_2(X, Y,;);
167    }
168
169    xSrc = (X >> MLIB_SHIFT) - 1;
170    ySrc = (Y >> MLIB_SHIFT) - 1;
171
172    srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + xSrc;
173    s0 = srcPixelPtr[0];
174    s1 = srcPixelPtr[1];
175    s2 = srcPixelPtr[2];
176    s3 = srcPixelPtr[3];
177
178    srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
179    s4 = srcPixelPtr[0];
180    s5 = srcPixelPtr[1];
181    s6 = srcPixelPtr[2];
182    s7 = srcPixelPtr[3];
183
184    if (filter == MLIB_BICUBIC) {
185      for (; dstPixelPtr <= (dstLineEnd - 1); dstPixelPtr++) {
186        X += dX;
187        Y += dY;
188
189        c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
190        c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
191        srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
192        c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 +
193              srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3);
194        srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
195        c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 +
196              srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3);
197
198        CREATE_COEF_BICUBIC(X, Y, val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3));
199
200        STORE(dstPixelPtr[0], val0);
201
202        xSrc = (X >> MLIB_SHIFT) - 1;
203        ySrc = (Y >> MLIB_SHIFT) - 1;
204
205        srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + xSrc;
206        s0 = srcPixelPtr[0];
207        s1 = srcPixelPtr[1];
208        s2 = srcPixelPtr[2];
209        s3 = srcPixelPtr[3];
210
211        srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
212        s4 = srcPixelPtr[0];
213        s5 = srcPixelPtr[1];
214        s6 = srcPixelPtr[2];
215        s7 = srcPixelPtr[3];
216      }
217
218    }
219    else {
220      for (; dstPixelPtr <= (dstLineEnd - 1); dstPixelPtr++) {
221        X += dX;
222        Y += dY;
223
224        c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
225        c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
226        srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
227        c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 +
228              srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3);
229        srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
230        c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 +
231              srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3);
232
233        CREATE_COEF_BICUBIC_2(X, Y, val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3));
234
235        STORE(dstPixelPtr[0], val0);
236
237        xSrc = (X >> MLIB_SHIFT) - 1;
238        ySrc = (Y >> MLIB_SHIFT) - 1;
239
240        srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + xSrc;
241        s0 = srcPixelPtr[0];
242        s1 = srcPixelPtr[1];
243        s2 = srcPixelPtr[2];
244        s3 = srcPixelPtr[3];
245
246        srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
247        s4 = srcPixelPtr[0];
248        s5 = srcPixelPtr[1];
249        s6 = srcPixelPtr[2];
250        s7 = srcPixelPtr[3];
251      }
252    }
253
254    c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
255    c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
256    srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
257    c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 +
258          srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3);
259    srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
260    c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 +
261          srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3);
262
263    val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3);
264    STORE(dstPixelPtr[0], val0);
265  }
266
267  return MLIB_SUCCESS;
268}
269
270/***************************************************************/
271mlib_status FUN_NAME(2ch)(mlib_affine_param *param)
272{
273  DECLAREVAR_BC();
274  DTYPE *dstLineEnd;
275
276  for (j = yStart; j <= yFinish; j++) {
277    FTYPE xf0, xf1, xf2, xf3;
278    FTYPE yf0, yf1, yf2, yf3;
279    FTYPE dx, dx_2, dx2, dx3_2, dx3_3;
280    FTYPE dy, dy_2, dy2, dy3_2, dy3_3;
281    FTYPE c0, c1, c2, c3, val0;
282    FTYPE scale = 1 / 65536.f;
283    FTYPE s0, s1, s2, s3;
284    FTYPE s4, s5, s6, s7;
285    mlib_s32 k;
286
287    CLIP(2);
288    dstLineEnd = (DTYPE *) dstData + 2 * xRight;
289
290    for (k = 0; k < 2; k++) {
291      mlib_s32 X1 = X;
292      mlib_s32 Y1 = Y;
293      DTYPE *dPtr = dstPixelPtr + k;
294
295      if (filter == MLIB_BICUBIC) {
296        CREATE_COEF_BICUBIC(X1, Y1,;);
297      }
298      else {
299        CREATE_COEF_BICUBIC_2(X1, Y1,;);
300      }
301
302      xSrc = (X1 >> MLIB_SHIFT) - 1;
303      ySrc = (Y1 >> MLIB_SHIFT) - 1;
304
305      srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 2 * xSrc + k;
306      s0 = srcPixelPtr[0];
307      s1 = srcPixelPtr[2];
308      s2 = srcPixelPtr[4];
309      s3 = srcPixelPtr[6];
310
311      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
312      s4 = srcPixelPtr[0];
313      s5 = srcPixelPtr[2];
314      s6 = srcPixelPtr[4];
315      s7 = srcPixelPtr[6];
316
317      if (filter == MLIB_BICUBIC) {
318        for (; dPtr <= (dstLineEnd - 1); dPtr += 2) {
319          X1 += dX;
320          Y1 += dY;
321
322          c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
323          c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
324          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
325          c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 +
326                srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3);
327          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
328          c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 +
329                srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3);
330
331          CREATE_COEF_BICUBIC(X1, Y1, val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3));
332
333          STORE(dPtr[0], val0);
334
335          xSrc = (X1 >> MLIB_SHIFT) - 1;
336          ySrc = (Y1 >> MLIB_SHIFT) - 1;
337
338          srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 2 * xSrc + k;
339          s0 = srcPixelPtr[0];
340          s1 = srcPixelPtr[2];
341          s2 = srcPixelPtr[4];
342          s3 = srcPixelPtr[6];
343
344          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
345          s4 = srcPixelPtr[0];
346          s5 = srcPixelPtr[2];
347          s6 = srcPixelPtr[4];
348          s7 = srcPixelPtr[6];
349        }
350
351      }
352      else {
353        for (; dPtr <= (dstLineEnd - 1); dPtr += 2) {
354          X1 += dX;
355          Y1 += dY;
356
357          c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
358          c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
359          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
360          c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 +
361                srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3);
362          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
363          c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 +
364                srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3);
365
366          CREATE_COEF_BICUBIC_2(X1, Y1, val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3));
367
368          STORE(dPtr[0], val0);
369
370          xSrc = (X1 >> MLIB_SHIFT) - 1;
371          ySrc = (Y1 >> MLIB_SHIFT) - 1;
372
373          srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 2 * xSrc + k;
374          s0 = srcPixelPtr[0];
375          s1 = srcPixelPtr[2];
376          s2 = srcPixelPtr[4];
377          s3 = srcPixelPtr[6];
378
379          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
380          s4 = srcPixelPtr[0];
381          s5 = srcPixelPtr[2];
382          s6 = srcPixelPtr[4];
383          s7 = srcPixelPtr[6];
384        }
385      }
386
387      c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
388      c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
389      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
390      c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 +
391            srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3);
392      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
393      c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 +
394            srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3);
395
396      val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3);
397      STORE(dPtr[0], val0);
398    }
399  }
400
401  return MLIB_SUCCESS;
402}
403
404/***************************************************************/
405mlib_status FUN_NAME(3ch)(mlib_affine_param *param)
406{
407  DECLAREVAR_BC();
408  DTYPE *dstLineEnd;
409
410  for (j = yStart; j <= yFinish; j++) {
411    FTYPE xf0, xf1, xf2, xf3;
412    FTYPE yf0, yf1, yf2, yf3;
413    FTYPE dx, dx_2, dx2, dx3_2, dx3_3;
414    FTYPE dy, dy_2, dy2, dy3_2, dy3_3;
415    FTYPE c0, c1, c2, c3, val0;
416    FTYPE scale = 1 / 65536.f;
417    FTYPE s0, s1, s2, s3;
418    FTYPE s4, s5, s6, s7;
419    mlib_s32 k;
420
421    CLIP(3);
422    dstLineEnd = (DTYPE *) dstData + 3 * xRight;
423
424    for (k = 0; k < 3; k++) {
425      mlib_s32 X1 = X;
426      mlib_s32 Y1 = Y;
427      DTYPE *dPtr = dstPixelPtr + k;
428
429      if (filter == MLIB_BICUBIC) {
430        CREATE_COEF_BICUBIC(X1, Y1,;);
431      }
432      else {
433        CREATE_COEF_BICUBIC_2(X1, Y1,;);
434      }
435
436      xSrc = (X1 >> MLIB_SHIFT) - 1;
437      ySrc = (Y1 >> MLIB_SHIFT) - 1;
438
439      srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 3 * xSrc + k;
440      s0 = srcPixelPtr[0];
441      s1 = srcPixelPtr[3];
442      s2 = srcPixelPtr[6];
443      s3 = srcPixelPtr[9];
444
445      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
446      s4 = srcPixelPtr[0];
447      s5 = srcPixelPtr[3];
448      s6 = srcPixelPtr[6];
449      s7 = srcPixelPtr[9];
450
451      if (filter == MLIB_BICUBIC) {
452        for (; dPtr <= (dstLineEnd - 1); dPtr += 3) {
453          X1 += dX;
454          Y1 += dY;
455
456          c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
457          c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
458          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
459          c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 +
460                srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3);
461          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
462          c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 +
463                srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3);
464
465          CREATE_COEF_BICUBIC(X1, Y1, val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3));
466
467          STORE(dPtr[0], val0);
468
469          xSrc = (X1 >> MLIB_SHIFT) - 1;
470          ySrc = (Y1 >> MLIB_SHIFT) - 1;
471
472          srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 3 * xSrc + k;
473          s0 = srcPixelPtr[0];
474          s1 = srcPixelPtr[3];
475          s2 = srcPixelPtr[6];
476          s3 = srcPixelPtr[9];
477
478          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
479          s4 = srcPixelPtr[0];
480          s5 = srcPixelPtr[3];
481          s6 = srcPixelPtr[6];
482          s7 = srcPixelPtr[9];
483        }
484
485      }
486      else {
487        for (; dPtr <= (dstLineEnd - 1); dPtr += 3) {
488          X1 += dX;
489          Y1 += dY;
490
491          c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
492          c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
493          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
494          c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 +
495                srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3);
496          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
497          c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 +
498                srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3);
499
500          CREATE_COEF_BICUBIC_2(X1, Y1, val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3));
501
502          STORE(dPtr[0], val0);
503
504          xSrc = (X1 >> MLIB_SHIFT) - 1;
505          ySrc = (Y1 >> MLIB_SHIFT) - 1;
506
507          srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 3 * xSrc + k;
508          s0 = srcPixelPtr[0];
509          s1 = srcPixelPtr[3];
510          s2 = srcPixelPtr[6];
511          s3 = srcPixelPtr[9];
512
513          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
514          s4 = srcPixelPtr[0];
515          s5 = srcPixelPtr[3];
516          s6 = srcPixelPtr[6];
517          s7 = srcPixelPtr[9];
518        }
519      }
520
521      c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
522      c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
523      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
524      c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 +
525            srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3);
526      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
527      c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 +
528            srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3);
529
530      val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3);
531      STORE(dPtr[0], val0);
532    }
533  }
534
535  return MLIB_SUCCESS;
536}
537
538/***************************************************************/
539mlib_status FUN_NAME(4ch)(mlib_affine_param *param)
540{
541  DECLAREVAR_BC();
542  DTYPE *dstLineEnd;
543
544  for (j = yStart; j <= yFinish; j++) {
545    FTYPE xf0, xf1, xf2, xf3;
546    FTYPE yf0, yf1, yf2, yf3;
547    FTYPE dx, dx_2, dx2, dx3_2, dx3_3;
548    FTYPE dy, dy_2, dy2, dy3_2, dy3_3;
549    FTYPE c0, c1, c2, c3, val0;
550    FTYPE scale = 1 / 65536.f;
551    FTYPE s0, s1, s2, s3;
552    FTYPE s4, s5, s6, s7;
553    mlib_s32 k;
554
555    CLIP(4);
556    dstLineEnd = (DTYPE *) dstData + 4 * xRight;
557
558    for (k = 0; k < 4; k++) {
559      mlib_s32 X1 = X;
560      mlib_s32 Y1 = Y;
561      DTYPE *dPtr = dstPixelPtr + k;
562
563      if (filter == MLIB_BICUBIC) {
564        CREATE_COEF_BICUBIC(X1, Y1,;);
565      }
566      else {
567        CREATE_COEF_BICUBIC_2(X1, Y1,;);
568      }
569
570      xSrc = (X1 >> MLIB_SHIFT) - 1;
571      ySrc = (Y1 >> MLIB_SHIFT) - 1;
572
573      srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 4 * xSrc + k;
574      s0 = srcPixelPtr[0];
575      s1 = srcPixelPtr[4];
576      s2 = srcPixelPtr[8];
577      s3 = srcPixelPtr[12];
578
579      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
580      s4 = srcPixelPtr[0];
581      s5 = srcPixelPtr[4];
582      s6 = srcPixelPtr[8];
583      s7 = srcPixelPtr[12];
584
585      if (filter == MLIB_BICUBIC) {
586        for (; dPtr <= (dstLineEnd - 1); dPtr += 4) {
587
588          X1 += dX;
589          Y1 += dY;
590
591          c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
592          c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
593          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
594          c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 +
595                srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3);
596          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
597          c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 +
598                srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3);
599
600          CREATE_COEF_BICUBIC(X1, Y1, val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3));
601
602          STORE(dPtr[0], val0);
603
604          xSrc = (X1 >> MLIB_SHIFT) - 1;
605          ySrc = (Y1 >> MLIB_SHIFT) - 1;
606
607          srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 4 * xSrc + k;
608          s0 = srcPixelPtr[0];
609          s1 = srcPixelPtr[4];
610          s2 = srcPixelPtr[8];
611          s3 = srcPixelPtr[12];
612
613          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
614          s4 = srcPixelPtr[0];
615          s5 = srcPixelPtr[4];
616          s6 = srcPixelPtr[8];
617          s7 = srcPixelPtr[12];
618        }
619
620      }
621      else {
622        for (; dPtr <= (dstLineEnd - 1); dPtr += 4) {
623
624          X1 += dX;
625          Y1 += dY;
626
627          c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
628          c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
629          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
630          c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 +
631                srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3);
632          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
633          c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 +
634                srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3);
635
636          CREATE_COEF_BICUBIC_2(X1, Y1, val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3));
637
638          STORE(dPtr[0], val0);
639
640          xSrc = (X1 >> MLIB_SHIFT) - 1;
641          ySrc = (Y1 >> MLIB_SHIFT) - 1;
642
643          srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 4 * xSrc + k;
644          s0 = srcPixelPtr[0];
645          s1 = srcPixelPtr[4];
646          s2 = srcPixelPtr[8];
647          s3 = srcPixelPtr[12];
648
649          srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
650          s4 = srcPixelPtr[0];
651          s5 = srcPixelPtr[4];
652          s6 = srcPixelPtr[8];
653          s7 = srcPixelPtr[12];
654        }
655      }
656
657      c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3);
658      c1 = (s4 * xf0 + s5 * xf1 + s6 * xf2 + s7 * xf3);
659      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
660      c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 +
661            srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3);
662      srcPixelPtr = (DTYPE *) ((mlib_u8 *) srcPixelPtr + srcYStride);
663      c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 +
664            srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3);
665
666      val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3);
667      STORE(dPtr[0], val0);
668    }
669  }
670
671  return MLIB_SUCCESS;
672}
673
674/***************************************************************/
675