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 
mlib_ImageAffine_u8_1ch_nn(mlib_affine_param * param)75 mlib_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 /***************************************************************/
mlib_ImageAffine_u8_2ch_nn(mlib_affine_param * param)104 mlib_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 /***************************************************************/
mlib_ImageAffine_u8_3ch_nn(mlib_affine_param * param)149 mlib_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 /***************************************************************/
mlib_ImageAffine_u8_4ch_nn(mlib_affine_param * param)198 mlib_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 
mlib_ImageAffine_s16_1ch_nn(mlib_affine_param * param)250 mlib_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 /***************************************************************/
mlib_ImageAffine_s16_2ch_nn(mlib_affine_param * param)286 mlib_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 /***************************************************************/
mlib_ImageAffine_s16_3ch_nn(mlib_affine_param * param)331 mlib_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 /***************************************************************/
mlib_ImageAffine_s16_4ch_nn(mlib_affine_param * param)380 mlib_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