1/*
2 * Copyright (c) 1997, 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 *      mlib_ImageAffine_u8_1ch_nn
30 *      mlib_ImageAffine_u8_2ch_nn
31 *      mlib_ImageAffine_u8_3ch_nn
32 *      mlib_ImageAffine_u8_4ch_nn
33 *      mlib_ImageAffine_s16_1ch_nn
34 *      mlib_ImageAffine_s16_2ch_nn
35 *      mlib_ImageAffine_s16_3ch_nn
36 *      mlib_ImageAffine_s16_4ch_nn
37 *        - image affine transformation with Nearest Neighbor filtering
38 * SYNOPSIS
39 *      mlib_status mlib_ImageAffine_[u8|s16]_?ch_nn(mlib_s32 *leftEdges,
40 *                                                   mlib_s32 *rightEdges,
41 *                                                   mlib_s32 *xStarts,
42 *                                                   mlib_s32 *yStarts,
43 *                                                   mlib_s32 *sides,
44 *                                                   mlib_u8  *dstData,
45 *                                                   mlib_u8  **lineAddr,
46 *                                                   mlib_s32 dstYStride,
47 *                                                   mlib_s32 is_affine)
48 *
49 * ARGUMENTS
50 *      leftEdges  array[dstHeight] of xLeft coordinates
51 *      RightEdges array[dstHeight] of xRight coordinates
52 *      xStarts    array[dstHeight] of xStart * 65536 coordinates
53 *      yStarts    array[dstHeight] of yStart * 65536 coordinates
54 *      sides      output array[4]. sides[0] is yStart, sides[1] is yFinish,
55 *                 sides[2] is dx * 65536, sides[3] is dy * 65536
56 *      dstData    pointer to the first pixel on (yStart - 1) line
57 *      lineAddr   array[srcHeight] of pointers to the first pixel on
58 *                 the corresponding lines
59 *      dstYStride stride of destination image
60 *      is_affine  indicator (Affine - GridWarp)
61 *
62 * DESCRIPTION
63 *      The functions step along the lines from xLeft to xRight and get the
64 *      nearest pixel values as being with the following coordinates
65 *      ((xStart - (i - xLeft) * dx) >> 16, (yStart - (i - xLeft) * dy) >> 16)
66 *
67 */
68
69#include "mlib_ImageAffine.h"
70
71/***************************************************************/
72#undef  DTYPE
73#define DTYPE mlib_u8
74
75mlib_status mlib_ImageAffine_u8_1ch_nn(mlib_affine_param *param)
76{
77  DECLAREVAR_NN();
78  DTYPE *dstLineEnd;
79
80  for (j = yStart; j <= yFinish; j++) {
81    DTYPE pix0;
82
83    CLIP(1);
84    dstLineEnd = (DTYPE *) dstData + xRight;
85
86#ifdef __SUNPRO_C
87#pragma pipeloop(0)
88#endif /* __SUNPRO_C */
89    for (; dstPixelPtr <= dstLineEnd; dstPixelPtr++) {
90      ySrc = MLIB_POINTER_SHIFT(Y);
91      Y += dY;
92      srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc);
93      xSrc = X >> MLIB_SHIFT;
94      X += dX;
95      pix0 = srcPixelPtr[xSrc];
96      dstPixelPtr[0] = pix0;
97    }
98  }
99
100  return MLIB_SUCCESS;
101}
102
103/***************************************************************/
104mlib_status mlib_ImageAffine_u8_2ch_nn(mlib_affine_param *param)
105{
106  DECLAREVAR_NN();
107  DTYPE *dstLineEnd;
108
109  for (j = yStart; j <= yFinish; j++) {
110    DTYPE pix0, pix1;
111
112    CLIP(2);
113    dstLineEnd = (DTYPE *) dstData + 2 * xRight;
114
115    ySrc = MLIB_POINTER_SHIFT(Y);
116    Y += dY;
117    xSrc = X >> MLIB_SHIFT;
118    X += dX;
119    srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc;
120    pix0 = srcPixelPtr[0];
121    pix1 = srcPixelPtr[1];
122    ySrc = MLIB_POINTER_SHIFT(Y);
123    Y += dY;
124    xSrc = X >> MLIB_SHIFT;
125    X += dX;
126#ifdef __SUNPRO_C
127#pragma pipeloop(0)
128#endif /* __SUNPRO_C */
129    for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 2) {
130      srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc;
131      ySrc = MLIB_POINTER_SHIFT(Y);
132      Y += dY;
133      xSrc = X >> MLIB_SHIFT;
134      X += dX;
135      dstPixelPtr[0] = pix0;
136      dstPixelPtr[1] = pix1;
137      pix0 = srcPixelPtr[0];
138      pix1 = srcPixelPtr[1];
139    }
140
141    dstPixelPtr[0] = pix0;
142    dstPixelPtr[1] = pix1;
143  }
144
145  return MLIB_SUCCESS;
146}
147
148/***************************************************************/
149mlib_status mlib_ImageAffine_u8_3ch_nn(mlib_affine_param *param)
150{
151  DECLAREVAR_NN();
152  DTYPE *dstLineEnd;
153
154  for (j = yStart; j <= yFinish; j++) {
155    DTYPE pix0, pix1, pix2;
156
157    CLIP(3);
158    dstLineEnd = (DTYPE *) dstData + 3 * xRight;
159
160    ySrc = MLIB_POINTER_SHIFT(Y);
161    Y += dY;
162    xSrc = X >> MLIB_SHIFT;
163    X += dX;
164    srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc;
165    pix0 = srcPixelPtr[0];
166    pix1 = srcPixelPtr[1];
167    pix2 = srcPixelPtr[2];
168    ySrc = MLIB_POINTER_SHIFT(Y);
169    Y += dY;
170    xSrc = X >> MLIB_SHIFT;
171    X += dX;
172#ifdef __SUNPRO_C
173#pragma pipeloop(0)
174#endif /* __SUNPRO_C */
175    for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 3) {
176      srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc;
177      ySrc = MLIB_POINTER_SHIFT(Y);
178      Y += dY;
179      xSrc = X >> MLIB_SHIFT;
180      X += dX;
181      dstPixelPtr[0] = pix0;
182      dstPixelPtr[1] = pix1;
183      dstPixelPtr[2] = pix2;
184      pix0 = srcPixelPtr[0];
185      pix1 = srcPixelPtr[1];
186      pix2 = srcPixelPtr[2];
187    }
188
189    dstPixelPtr[0] = pix0;
190    dstPixelPtr[1] = pix1;
191    dstPixelPtr[2] = pix2;
192  }
193
194  return MLIB_SUCCESS;
195}
196
197/***************************************************************/
198mlib_status mlib_ImageAffine_u8_4ch_nn(mlib_affine_param *param)
199{
200  DECLAREVAR_NN();
201  DTYPE *dstLineEnd;
202
203  for (j = yStart; j <= yFinish; j++) {
204    DTYPE pix0, pix1, pix2, pix3;
205    CLIP(4);
206    dstLineEnd = (DTYPE *) dstData + 4 * xRight;
207
208    ySrc = MLIB_POINTER_SHIFT(Y);
209    Y += dY;
210    xSrc = X >> MLIB_SHIFT;
211    X += dX;
212    srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc;
213    pix0 = srcPixelPtr[0];
214    pix1 = srcPixelPtr[1];
215    pix2 = srcPixelPtr[2];
216    pix3 = srcPixelPtr[3];
217    ySrc = MLIB_POINTER_SHIFT(Y);
218    Y += dY;
219    xSrc = X >> MLIB_SHIFT;
220    X += dX;
221    for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 4) {
222      srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc;
223      ySrc = MLIB_POINTER_SHIFT(Y);
224      Y += dY;
225      xSrc = X >> MLIB_SHIFT;
226      X += dX;
227      dstPixelPtr[0] = pix0;
228      dstPixelPtr[1] = pix1;
229      dstPixelPtr[2] = pix2;
230      dstPixelPtr[3] = pix3;
231      pix0 = srcPixelPtr[0];
232      pix1 = srcPixelPtr[1];
233      pix2 = srcPixelPtr[2];
234      pix3 = srcPixelPtr[3];
235    }
236
237    dstPixelPtr[0] = pix0;
238    dstPixelPtr[1] = pix1;
239    dstPixelPtr[2] = pix2;
240    dstPixelPtr[3] = pix3;
241  }
242
243  return MLIB_SUCCESS;
244}
245
246/***************************************************************/
247#undef  DTYPE
248#define DTYPE mlib_u16
249
250mlib_status mlib_ImageAffine_s16_1ch_nn(mlib_affine_param *param)
251{
252  DECLAREVAR_NN();
253  DTYPE *dstLineEnd;
254
255  for (j = yStart; j <= yFinish; j++) {
256    mlib_s32 pix0;
257
258    CLIP(1);
259    dstLineEnd = (DTYPE *) dstData + xRight;
260
261    ySrc = MLIB_POINTER_SHIFT(Y);
262    Y += dY;
263    xSrc = X >> MLIB_SHIFT;
264    X += dX;
265    srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc);
266    pix0 = srcPixelPtr[xSrc];
267    ySrc = MLIB_POINTER_SHIFT(Y);
268    Y += dY;
269    for (; dstPixelPtr < dstLineEnd; dstPixelPtr++) {
270      xSrc = X >> MLIB_SHIFT;
271      X += dX;
272      srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc);
273      dstPixelPtr[0] = pix0;
274      ySrc = MLIB_POINTER_SHIFT(Y);
275      Y += dY;
276      pix0 = srcPixelPtr[xSrc];
277    }
278
279    dstPixelPtr[0] = pix0;
280  }
281
282  return MLIB_SUCCESS;
283}
284
285/***************************************************************/
286mlib_status mlib_ImageAffine_s16_2ch_nn(mlib_affine_param *param)
287{
288  DECLAREVAR_NN();
289  DTYPE *dstLineEnd;
290
291  for (j = yStart; j <= yFinish; j++) {
292    mlib_s32 pix0, pix1;
293
294    CLIP(2);
295    dstLineEnd = (DTYPE *) dstData + 2 * xRight;
296
297    ySrc = MLIB_POINTER_SHIFT(Y);
298    Y += dY;
299    xSrc = X >> MLIB_SHIFT;
300    X += dX;
301    srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc;
302    pix0 = srcPixelPtr[0];
303    pix1 = srcPixelPtr[1];
304    ySrc = MLIB_POINTER_SHIFT(Y);
305    Y += dY;
306    xSrc = X >> MLIB_SHIFT;
307    X += dX;
308#ifdef __SUNPRO_C
309#pragma pipeloop(0)
310#endif /* __SUNPRO_C */
311    for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 2) {
312      srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc;
313      ySrc = MLIB_POINTER_SHIFT(Y);
314      Y += dY;
315      xSrc = X >> MLIB_SHIFT;
316      X += dX;
317      dstPixelPtr[0] = pix0;
318      dstPixelPtr[1] = pix1;
319      pix0 = srcPixelPtr[0];
320      pix1 = srcPixelPtr[1];
321    }
322
323    dstPixelPtr[0] = pix0;
324    dstPixelPtr[1] = pix1;
325  }
326
327  return MLIB_SUCCESS;
328}
329
330/***************************************************************/
331mlib_status mlib_ImageAffine_s16_3ch_nn(mlib_affine_param *param)
332{
333  DECLAREVAR_NN();
334  DTYPE *dstLineEnd;
335
336  for (j = yStart; j <= yFinish; j++) {
337    mlib_s32 pix0, pix1, pix2;
338
339    CLIP(3);
340    dstLineEnd = (DTYPE *) dstData + 3 * xRight;
341
342    ySrc = MLIB_POINTER_SHIFT(Y);
343    Y += dY;
344    xSrc = X >> MLIB_SHIFT;
345    X += dX;
346    srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc;
347    pix0 = srcPixelPtr[0];
348    pix1 = srcPixelPtr[1];
349    pix2 = srcPixelPtr[2];
350    ySrc = MLIB_POINTER_SHIFT(Y);
351    Y += dY;
352    xSrc = X >> MLIB_SHIFT;
353    X += dX;
354#ifdef __SUNPRO_C
355#pragma pipeloop(0)
356#endif /* __SUNPRO_C */
357    for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 3) {
358      srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc;
359      ySrc = MLIB_POINTER_SHIFT(Y);
360      Y += dY;
361      xSrc = X >> MLIB_SHIFT;
362      X += dX;
363      dstPixelPtr[0] = pix0;
364      dstPixelPtr[1] = pix1;
365      dstPixelPtr[2] = pix2;
366      pix0 = srcPixelPtr[0];
367      pix1 = srcPixelPtr[1];
368      pix2 = srcPixelPtr[2];
369    }
370
371    dstPixelPtr[0] = pix0;
372    dstPixelPtr[1] = pix1;
373    dstPixelPtr[2] = pix2;
374  }
375
376  return MLIB_SUCCESS;
377}
378
379/***************************************************************/
380mlib_status mlib_ImageAffine_s16_4ch_nn(mlib_affine_param *param)
381{
382  DECLAREVAR_NN();
383  DTYPE *dstLineEnd;
384
385  for (j = yStart; j <= yFinish; j++) {
386    mlib_s32 pix0, pix1, pix2, pix3;
387    CLIP(4);
388    dstLineEnd = (DTYPE *) dstData + 4 * xRight;
389
390    ySrc = MLIB_POINTER_SHIFT(Y);
391    Y += dY;
392    xSrc = X >> MLIB_SHIFT;
393    X += dX;
394    srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc;
395    pix0 = srcPixelPtr[0];
396    pix1 = srcPixelPtr[1];
397    pix2 = srcPixelPtr[2];
398    pix3 = srcPixelPtr[3];
399    ySrc = MLIB_POINTER_SHIFT(Y);
400    Y += dY;
401    xSrc = X >> MLIB_SHIFT;
402    X += dX;
403    for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 4) {
404      srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc;
405      ySrc = MLIB_POINTER_SHIFT(Y);
406      Y += dY;
407      xSrc = X >> MLIB_SHIFT;
408      X += dX;
409      dstPixelPtr[0] = pix0;
410      dstPixelPtr[1] = pix1;
411      dstPixelPtr[2] = pix2;
412      dstPixelPtr[3] = pix3;
413      pix0 = srcPixelPtr[0];
414      pix1 = srcPixelPtr[1];
415      pix2 = srcPixelPtr[2];
416      pix3 = srcPixelPtr[3];
417    }
418
419    dstPixelPtr[0] = pix0;
420    dstPixelPtr[1] = pix1;
421    dstPixelPtr[2] = pix2;
422    dstPixelPtr[3] = pix3;
423  }
424
425  return MLIB_SUCCESS;
426}
427
428/***************************************************************/
429