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