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(mlib_s32 *leftEdges,
32 * mlib_s32 *rightEdges,
33 * mlib_s32 *xStarts,
34 * mlib_s32 *yStarts,
35 * mlib_s32 *sides,
36 * mlib_u8 *dstData,
37 * mlib_u8 **lineAddr,
38 * mlib_s32 dstYStride,
39 * mlib_s32 is_affine,
40 * mlib_s32 srcYStride,
41 * mlib_filter filter)
42 *
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 5
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