1 /*
2  * Copyright (c) 2003, 2012, 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  * FUNCTION
28  *      mlib_ImageZoom - image scaling with edge condition
29  *
30  * SYNOPSIS
31  *      mlib_status mlib_ImageZoom(mlib_image       *dst,
32  *                                 const mlib_image *src,
33  *                                 mlib_f32         zoomx,
34  *                                 mlib_f32         zoomy,
35  *                                 mlib_filter      filter,
36  *                                 mlib_edge        edge)
37  *
38  * ARGUMENTS
39  *      dst       Pointer to destination image
40  *      src       Pointer to source image
41  *      zoomx     X zoom factor.
42  *      zoomy     Y zoom factor.
43  *      filter    Type of resampling filter.
44  *      edge      Type of edge condition.
45  *
46  * DESCRIPTION
47  *  The center of the source image is mapped to the center of the
48  *  destination image.
49  *
50  *  The upper-left corner pixel of an image is located at (0.5, 0.5).
51  *
52  *  The resampling filter can be one of the following:
53  *    MLIB_NEAREST
54  *    MLIB_BILINEAR
55  *    MLIB_BICUBIC
56  *    MLIB_BICUBIC2
57  *
58  *  The edge condition can be one of the following:
59  *    MLIB_EDGE_DST_NO_WRITE  (default)
60  *    MLIB_EDGE_DST_FILL_ZERO
61  *    MLIB_EDGE_OP_NEAREST
62  *    MLIB_EDGE_SRC_EXTEND
63  *    MLIB_EDGE_SRC_PADDED
64  */
65 
66 #ifdef MACOSX
67 #include <machine/endian.h>
68 #endif
69 #include <mlib_image.h>
70 #include <mlib_ImageZoom.h>
71 
72 #define MLIB_COPY_FUNC  mlib_ImageCopy_na
73 
74 /***************************************************************/
75 
76 #ifdef i386 /* do not perform the coping by mlib_d64 data type for x86 */
77 
78 typedef struct {
79   mlib_s32 int0, int1;
80 } two_int;
81 
82 #define TYPE_64  two_int
83 
84 #else /* i386 ( do not perform the coping by mlib_d64 data type for x86 ) */
85 
86 #define TYPE_64  mlib_d64
87 
88 #endif /* i386 ( do not perform the coping by mlib_d64 data type for x86 ) */
89 
90 /***************************************************************/
91 
92 typedef union {
93   TYPE_64 d64;
94   struct {
95     mlib_f32 f0, f1;
96   } f32s;
97 } d64_2_f32;
98 
99 /***************************************************************/
100 
101 #define CLAMP_U8(X) ((X >= 256) ? (255) : ((X) &~ ((X) >> 31)))
102 
103 /***************************************************************/
104 
105 #ifdef _LITTLE_ENDIAN
106 
107 static const mlib_u32 mlib_bit_mask4[16] = {
108   0x00000000u, 0xFF000000u, 0x00FF0000u, 0xFFFF0000u,
109   0x0000FF00u, 0xFF00FF00u, 0x00FFFF00u, 0xFFFFFF00u,
110   0x000000FFu, 0xFF0000FFu, 0x00FF00FFu, 0xFFFF00FFu,
111   0x0000FFFFu, 0xFF00FFFFu, 0x00FFFFFFu, 0xFFFFFFFFu
112 };
113 
114 #else /* _LITTLE_ENDIAN */
115 
116 static const mlib_u32 mlib_bit_mask4[16] = {
117   0x00000000u, 0x000000FFu, 0x0000FF00u, 0x0000FFFFu,
118   0x00FF0000u, 0x00FF00FFu, 0x00FFFF00u, 0x00FFFFFFu,
119   0xFF000000u, 0xFF0000FFu, 0xFF00FF00u, 0xFF00FFFFu,
120   0xFFFF0000u, 0xFFFF00FFu, 0xFFFFFF00u, 0xFFFFFFFFu
121 };
122 
123 #endif /* _LITTLE_ENDIAN */
124 
125 /***************************************************************/
126 
127 #define VARIABLE(FORMAT)                                        \
128   mlib_s32 j,                                                   \
129            dx = GetElemStruct(DX),                              \
130            dy = GetElemStruct(DY),                              \
131            x = GetElemSubStruct(current, srcX),                 \
132            y = GetElemSubStruct(current, srcY),                 \
133            src_stride = GetElemStruct(src_stride),              \
134            dst_stride = GetElemStruct(dst_stride),              \
135            width  = GetElemSubStruct(current, width),           \
136            height = GetElemSubStruct(current, height);          \
137   FORMAT *sp = (FORMAT *)GetElemSubStruct(current, sp),         \
138          *dp = (FORMAT *)GetElemSubStruct(current, dp)
139 
140 /***************************************************************/
141 
142 #define BUFF_SIZE     256
143 #define BYTE_POS_MASK ((1 << (MLIB_SHIFT + 3)) - 1)
144 
145 /***************************************************************/
146 
mlib_ImageZoom_BIT_1_Nearest(mlib_work_image * param,mlib_s32 s_bitoff,mlib_s32 d_bitoff)147 mlib_status mlib_ImageZoom_BIT_1_Nearest(mlib_work_image *param,
148                                          mlib_s32        s_bitoff,
149                                          mlib_s32        d_bitoff)
150 {
151   VARIABLE(mlib_u8);
152   mlib_s32 i;
153   mlib_s32 buff_loc[BUFF_SIZE], *buff = buff_loc;
154   mlib_s32 srcX = GetElemSubStruct(current, srcX);
155   mlib_s32 dstX = GetElemSubStruct(current, dstX);
156   mlib_u8 *sl = sp - (srcX >> MLIB_SHIFT), *dl = dp - dstX, *dt;
157   mlib_s32 bit, res, k, y_step = -1;
158   mlib_s32 num0, n_al, mask0, mask1;
159 
160   srcX += (s_bitoff << MLIB_SHIFT);
161   dstX += d_bitoff;
162 
163   num0 = 8 - (dstX & 7);
164 
165   if (num0 > width)
166     num0 = width;
167   num0 &= 7;
168   mask0 = ((0xFF00 >> num0) & 0xFF) >> (dstX & 7);
169   n_al = width - num0;
170   mask1 = ((0xFF00 >> (n_al & 7)) & 0xFF);
171 
172   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
173 
174   if (n_al > BUFF_SIZE) {
175     buff = mlib_malloc(sizeof(mlib_s32) * n_al);
176 
177     if (buff == NULL)
178       return MLIB_FAILURE;
179   }
180 
181 /* save shifts for bit extracting */
182   x = srcX + num0 * dx;
183 #if 0
184 #ifdef __SUNPRO_C
185 #pragma pipeloop(0)
186 #endif /* __SUNPRO_C */
187   for (i = 0; i < (n_al >> 3); i++) {
188     buff[8 * i] = (((x >> MLIB_SHIFT)) & 7) | (x & ~BYTE_POS_MASK);
189     x += dx;
190     buff[8 * i + 1] = (((x >> MLIB_SHIFT) - 1) & 7) | (x & ~BYTE_POS_MASK);
191     x += dx;
192     buff[8 * i + 2] = (((x >> MLIB_SHIFT) - 2) & 7) | (x & ~BYTE_POS_MASK);
193     x += dx;
194     buff[8 * i + 3] = (((x >> MLIB_SHIFT) - 3) & 7) | (x & ~BYTE_POS_MASK);
195     x += dx;
196     buff[8 * i + 4] = (((x >> MLIB_SHIFT) - 4) & 7) | (x & ~BYTE_POS_MASK);
197     x += dx;
198     buff[8 * i + 5] = (((x >> MLIB_SHIFT) - 5) & 7) | (x & ~BYTE_POS_MASK);
199     x += dx;
200     buff[8 * i + 6] = (((x >> MLIB_SHIFT) - 6) & 7) | (x & ~BYTE_POS_MASK);
201     x += dx;
202     buff[8 * i + 7] = (((x >> MLIB_SHIFT) - 7) & 7) | (x & ~BYTE_POS_MASK);
203     x += dx;
204   }
205 
206   x_last = x;
207 #else /* 0 */
208 #ifdef __SUNPRO_C
209 #pragma pipeloop(0)
210 #endif /* __SUNPRO_C */
211   for (i = 0; i < (n_al >> 3); i++) {
212     buff[8 * i] = (((x >> MLIB_SHIFT)) & 7);
213     x += dx;
214     buff[8 * i + 1] = (((x >> MLIB_SHIFT) - 1) & 7);
215     x += dx;
216     buff[8 * i + 2] = (((x >> MLIB_SHIFT) - 2) & 7);
217     x += dx;
218     buff[8 * i + 3] = (((x >> MLIB_SHIFT) - 3) & 7);
219     x += dx;
220     buff[8 * i + 4] = (((x >> MLIB_SHIFT) - 4) & 7);
221     x += dx;
222     buff[8 * i + 5] = (((x >> MLIB_SHIFT) - 5) & 7);
223     x += dx;
224     buff[8 * i + 6] = (((x >> MLIB_SHIFT) - 6) & 7);
225     x += dx;
226     buff[8 * i + 7] = (((x >> MLIB_SHIFT) - 7) & 7);
227     x += dx;
228   }
229 
230 #endif /* 0 */
231 
232   for (j = 0; j < height; j++) {
233 
234     if (!y_step) {
235       dp = dl + (dstX >> 3);
236       dt = dp - dst_stride;
237 
238       if (num0) {
239         dp[0] = (dp[0] & ~mask0) | (*dt++ & mask0);
240         dp++;
241       }
242 
243 #if 0
244       MLIB_COPY_FUNC(dt, dp, n_al >> 3);
245 
246       if (n_al & 7) {
247         dp[n_al >> 3] = (dp[n_al >> 3] & ~mask1) | (dt[n_al >> 3] & mask1);
248       }
249 
250 #else /* 0 */
251 #ifdef __SUNPRO_C
252 #pragma pipeloop(0)
253 #endif /* __SUNPRO_C */
254       for (i = 0; i < (n_al >> 3); i++) {
255         dp[i] = dt[i];
256       }
257 
258       if (n_al & 7) {
259         dp[i] = (dp[i] & ~mask1) | (dt[i] & mask1);
260       }
261 
262 #endif /* 0 */
263     }
264     else {
265 
266       x = srcX;
267       dp = dl + (dstX >> 3);
268 
269       if (num0) {
270         mlib_s32 res = dp[0] & ~mask0;
271 
272         for (k = dstX; k < (dstX + num0); k++) {
273           bit = 7 - (k & 7);
274           res |=
275             (((sl[x >> (MLIB_SHIFT + 3)] >> (7 - (x >> MLIB_SHIFT) & 7)) & 1) << bit);
276           x += dx;
277         }
278 
279         *dp++ = res;
280       }
281 
282 #ifdef __SUNPRO_C
283 #pragma pipeloop(0)
284 #endif /* __SUNPRO_C */
285       for (i = 0; i < (n_al >> 3); i++) {
286 #if 0
287         res = ((sl[buff[8 * i] >> (MLIB_SHIFT + 3)] << buff[8 * i]) & 0x8080);
288         res |= ((sl[buff[8 * i + 1] >> (MLIB_SHIFT + 3)] << buff[8 * i + 1]) & 0x4040);
289         res |= ((sl[buff[8 * i + 2] >> (MLIB_SHIFT + 3)] << buff[8 * i + 2]) & 0x2020);
290         res |= ((sl[buff[8 * i + 3] >> (MLIB_SHIFT + 3)] << buff[8 * i + 3]) & 0x1010);
291         res |= ((sl[buff[8 * i + 4] >> (MLIB_SHIFT + 3)] << buff[8 * i + 4]) & 0x0808);
292         res |= ((sl[buff[8 * i + 5] >> (MLIB_SHIFT + 3)] << buff[8 * i + 5]) & 0x0404);
293         res |= ((sl[buff[8 * i + 6] >> (MLIB_SHIFT + 3)] << buff[8 * i + 6]) & 0x0202);
294         res |= ((sl[buff[8 * i + 7] >> (MLIB_SHIFT + 3)] << buff[8 * i + 7]) & 0x0101);
295 #else /* 0 */
296         res = ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i]) & 0x8080);
297         x += dx;
298         res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 1]) & 0x4040);
299         x += dx;
300         res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 2]) & 0x2020);
301         x += dx;
302         res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 3]) & 0x1010);
303         x += dx;
304         res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 4]) & 0x0808);
305         x += dx;
306         res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 5]) & 0x0404);
307         x += dx;
308         res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 6]) & 0x0202);
309         x += dx;
310         res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 7]) & 0x0101);
311         x += dx;
312 #endif /* 0 */
313         dp[i] = res | (res >> 8);
314       }
315 
316       if (mask1) {
317         mlib_s32 res = dp[i] & ~mask1;
318 
319         for (k = 0; k < (n_al & 7); k++) {
320           bit = 7 - (k & 7);
321           res |=
322             (((sl[x >> (MLIB_SHIFT + 3)] >> (7 - (x >> MLIB_SHIFT) & 7)) & 1) << bit);
323           x += dx;
324         }
325 
326         dp[i] = res;
327       }
328     }
329 
330     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
331     y += dy;
332 
333     dl = (void *)((mlib_u8 *) dl + dst_stride);
334     sl = (void *)((mlib_u8 *) sl + y_step * src_stride);
335   }
336 
337   if (buff != buff_loc)
338     mlib_free(buff);
339   return MLIB_SUCCESS;
340 }
341 
342 /***************************************************************/
343 
344 #ifdef _NO_LONGLONG
345 
346 typedef struct {
347 #ifdef _LITTLE_ENDIAN
348   mlib_u32 uint1, uint0;
349 #else /* _LITTLE_ENDIAN */
350   mlib_u32 uint0, uint1;
351 #endif /* _LITTLE_ENDIAN */
352 } two_uint;
353 
354 /***************************************************************/
355 
356 #define DTYPE two_uint
357 #define MASK(dst) (dst).uint0 = (dst).uint1 = -1
358 
359 /***************************************************************/
360 
361 #define RSHIFT(dst, src, rshift) {                                        \
362   DTYPE tmp = (src);                                                      \
363   if ((rshift) >= 32) {                                                   \
364     tmp.uint1 = tmp.uint0 >> ((rshift) - 32);                             \
365     tmp.uint0 = 0;                                                        \
366   }                                                                       \
367   else {                                                                  \
368     tmp.uint1 = (tmp.uint1 >> (rshift)) | (tmp.uint0 << (32 - (rshift))); \
369     tmp.uint0 = tmp.uint0 >> (rshift);                                    \
370   }                                                                       \
371   (dst) = tmp;                                                            \
372 }
373 
374 /***************************************************************/
375 
376 #define LSHIFT(dst, src, lshift) {                                        \
377   DTYPE tmp = (src);                                                      \
378   if ((lshift) >= 32) {                                                   \
379     tmp.uint0 = tmp.uint1 << ((lshift) - 32);                             \
380     tmp.uint1 = 0;                                                        \
381   }                                                                       \
382   else {                                                                  \
383     tmp.uint0 = (tmp.uint0 << (lshift)) | (tmp.uint1 >> (32 - (lshift))); \
384     tmp.uint1 = tmp.uint1 << (lshift);                                    \
385   }                                                                       \
386   (dst) = tmp;                                                            \
387 }
388 
389 /***************************************************************/
390 
391 #define LOGIC(dst, src1, src2, OPERATION) {                     \
392   DTYPE tmp;                                                    \
393   ((tmp).uint0 = (src1).uint0 OPERATION (src2).uint0);          \
394   ((tmp).uint1 = (src1).uint1 OPERATION (src2).uint1);          \
395   (dst) = tmp;                                                  \
396 }
397 
398 #else /* _NO_LONGLONG */
399 
400 /***************************************************************/
401 
402 #define DTYPE mlib_u64
403 #define MASK(dst) (dst) = ((mlib_u64)((mlib_s64) -1))
404 
405 #define RSHIFT(dst, src, rshift)          (dst) = ((src) >> (rshift))
406 
407 #define LSHIFT(dst, src, lshift)          (dst) = ((src) << (lshift))
408 
409 #define LOGIC(dst, src1, src2, OPERATION) (dst) = ((src1) OPERATION (src2))
410 
411 #endif /* _NO_LONGLONG */
412 
413 /***************************************************************/
414 
mlib_ImageZoom_BitToGray_1_Nearest(mlib_work_image * param,mlib_s32 s_bitoff,const mlib_s32 * ghigh,const mlib_s32 * glow)415 mlib_status mlib_ImageZoom_BitToGray_1_Nearest(mlib_work_image *param,
416                                                mlib_s32        s_bitoff,
417                                                const mlib_s32  *ghigh,
418                                                const mlib_s32  *glow)
419 {
420   VARIABLE(mlib_u8);
421   mlib_s32 i;
422   DTYPE gray_mask[256], dd, dd_old, *da, dtmp, dtmp1;
423   mlib_u32 *pgray = (mlib_u32 *) gray_mask;
424   mlib_u8 buff_loc[2 * BUFF_SIZE], *buff = buff_loc;
425   mlib_u8 *sl, *dl, gray_val[2];
426   mlib_s32 srcX = GetElemSubStruct(current, srcX);
427   mlib_u32 gray_val0, gray_val1;
428   mlib_s32 width8, res, y_step = -1;
429   mlib_s32 k;
430 
431   sl = sp - (srcX >> MLIB_SHIFT);
432   dl = dp;
433   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
434   srcX += (s_bitoff << MLIB_SHIFT);
435 
436   width8 = width / 8;
437 
438   if (width8 > 2 * BUFF_SIZE) {
439     buff = mlib_malloc(width8 * sizeof(mlib_u8));
440 
441     if (buff == NULL)
442       return MLIB_FAILURE;
443   }
444 
445 /* save shifts for bit extracting */
446   x = srcX;
447 #ifdef __SUNPRO_C
448 #pragma pipeloop(0)
449 #endif /* __SUNPRO_C */
450   for (i = 0; i < width8; i++) {
451     buff[8 * i] = (((x >> MLIB_SHIFT)) & 7);
452     x += dx;
453     buff[8 * i + 1] = (((x >> MLIB_SHIFT) - 1) & 7);
454     x += dx;
455     buff[8 * i + 2] = (((x >> MLIB_SHIFT) - 2) & 7);
456     x += dx;
457     buff[8 * i + 3] = (((x >> MLIB_SHIFT) - 3) & 7);
458     x += dx;
459     buff[8 * i + 4] = (((x >> MLIB_SHIFT) - 4) & 7);
460     x += dx;
461     buff[8 * i + 5] = (((x >> MLIB_SHIFT) - 5) & 7);
462     x += dx;
463     buff[8 * i + 6] = (((x >> MLIB_SHIFT) - 6) & 7);
464     x += dx;
465     buff[8 * i + 7] = (((x >> MLIB_SHIFT) - 7) & 7);
466     x += dx;
467   }
468 
469 /* calculate lookup table */
470   gray_val0 = CLAMP_U8(glow[0]);
471   gray_val1 = CLAMP_U8(ghigh[0]);
472   gray_val[0] = gray_val0;
473   gray_val[1] = gray_val1;
474   gray_val0 |= (gray_val0 << 8);
475   gray_val0 |= (gray_val0 << 16);
476   gray_val1 |= (gray_val1 << 8);
477   gray_val1 |= (gray_val1 << 16);
478 
479   for (i = 0; i < 16; i++) {
480     mlib_u32 v, mask = mlib_bit_mask4[i];
481 
482     v = (gray_val0 & ~mask) | (gray_val1 & mask);
483 
484 #ifdef __SUNPRO_C
485 #pragma pipeloop(0)
486 #endif /* __SUNPRO_C */
487     for (j = 0; j < 16; j++) {
488       pgray[2 * (16 * i + j)] = v;
489     }
490 
491 #ifdef __SUNPRO_C
492 #pragma pipeloop(0)
493 #endif /* __SUNPRO_C */
494     for (j = 0; j < 16; j++) {
495       pgray[2 * (i + 16 * j) + 1] = v;
496     }
497   }
498 
499   for (j = 0; j < height; j++) {
500 
501     if (!y_step) {
502       MLIB_COPY_FUNC((mlib_u8 *) dl - dst_stride, dl, width);
503     }
504     else {
505       mlib_s32 off = (mlib_addr) dl & 7;
506 
507       da = (DTYPE *) (dl - off);
508       x = srcX;
509 
510       if (off) {                                           /* not aligned */
511         DTYPE mask;
512         MASK(mask);
513         off *= 8;
514 #ifdef _LITTLE_ENDIAN
515         LSHIFT(dd_old, da[0], 64 - off);
516 #else /* _LITTLE_ENDIAN */
517         RSHIFT(dd_old, da[0], 64 - off);
518 #endif /* _LITTLE_ENDIAN */
519 
520 #ifdef __SUNPRO_C
521 #pragma pipeloop(0)
522 #endif /* __SUNPRO_C */
523         for (i = 0; i < (width / 8); i++) {
524           res = ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i]) & 0x8080);
525           x += dx;
526           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 1]) & 0x4040);
527           x += dx;
528           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 2]) & 0x2020);
529           x += dx;
530           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 3]) & 0x1010);
531           x += dx;
532           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 4]) & 0x0808);
533           x += dx;
534           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 5]) & 0x0404);
535           x += dx;
536           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 6]) & 0x0202);
537           x += dx;
538           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 7]) & 0x0101);
539           x += dx;
540 
541           res = (res & 0xff) | (res >> 8);
542           dd = gray_mask[res];
543 #ifdef _LITTLE_ENDIAN
544 /* *da++ = (dd_old >> (64 - off)) | (dd << off);*/
545           RSHIFT(dd_old, dd_old, 64 - off);
546           LSHIFT(dtmp, dd, off);
547 #else /* _LITTLE_ENDIAN */
548 /* *da++ = (dd_old << (64 - off)) | (dd >> off);*/
549           LSHIFT(dd_old, dd_old, 64 - off);
550           RSHIFT(dtmp, dd, off);
551 #endif /* _LITTLE_ENDIAN */
552           LOGIC(*da++, dd_old, dtmp, |);
553           dd_old = dd;
554         }
555 
556 #ifdef _LITTLE_ENDIAN
557 /* da[0] = (dd_old >> (64 - off)) | (da[0] & ((mlib_u64)((mlib_s64) -1) << off));*/
558         LSHIFT(dtmp, mask, off);
559         LOGIC(dtmp, da[0], dtmp, &);
560         RSHIFT(dtmp1, dd_old, 64 - off);
561 #else /* _LITTLE_ENDIAN */
562 /* da[0] = (dd_old << (64 - off)) | (da[0] & ((mlib_u64)((mlib_s64) -1) >> off));*/
563         RSHIFT(dtmp, mask, off);
564         LOGIC(dtmp, da[0], dtmp, &);
565         LSHIFT(dtmp1, dd_old, 64 - off);
566 #endif /* _LITTLE_ENDIAN */
567         LOGIC(da[0], dtmp, dtmp1, |);
568       }
569       else {                                               /* aligned */
570 
571 #ifdef __SUNPRO_C
572 #pragma pipeloop(0)
573 #endif /* __SUNPRO_C */
574         for (i = 0; i < (width / 8); i++) {
575           res = ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i]) & 0x8080);
576           x += dx;
577           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 1]) & 0x4040);
578           x += dx;
579           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 2]) & 0x2020);
580           x += dx;
581           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 3]) & 0x1010);
582           x += dx;
583           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 4]) & 0x0808);
584           x += dx;
585           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 5]) & 0x0404);
586           x += dx;
587           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 6]) & 0x0202);
588           x += dx;
589           res |= ((sl[x >> (MLIB_SHIFT + 3)] << buff[8 * i + 7]) & 0x0101);
590           x += dx;
591 
592           res = (res & 0xff) | (res >> 8);
593           *da++ = gray_mask[res];
594         }
595       }
596 
597       if (width & 7) {
598         dp = dl + (width & ~7);
599 
600         for (k = 0; k < (width & 7); k++) {
601           dp[k] =
602             gray_val[(sl[x >> (MLIB_SHIFT + 3)] >> (7 - (x >> MLIB_SHIFT) & 7)) & 1];
603           x += dx;
604         }
605       }
606     }
607 
608     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
609     y += dy;
610 
611     dl += dst_stride;
612     sl += y_step * src_stride;
613   }
614 
615   if (buff != buff_loc)
616     mlib_free(buff);
617   return MLIB_SUCCESS;
618 }
619 
620 /***************************************************************/
621 
mlib_ImageZoom_U8_2_Nearest(mlib_work_image * param)622 mlib_status mlib_ImageZoom_U8_2_Nearest(mlib_work_image *param)
623 {
624   VARIABLE(mlib_u8);
625   mlib_s32 i;
626   mlib_u8 *tdp, *tsp, tmp0, tmp1;
627   mlib_s32 cx, y_step = -1;
628 
629   tsp = sp;
630   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
631 
632   for (j = 0; j < height; j++) {
633 
634     if (!y_step) {
635       MLIB_COPY_FUNC((mlib_u8 *) dp - dst_stride, dp, 2 * width);
636     }
637     else {
638       tdp = dp;
639       x = GetElemSubStruct(current, srcX) & MLIB_MASK;
640       cx = (x >> (MLIB_SHIFT - 1)) & ~1;
641       tmp0 = tsp[cx];
642       tmp1 = tsp[cx + 1];
643 
644 #ifdef __SUNPRO_C
645 #pragma pipeloop(0)
646 #endif /* __SUNPRO_C */
647       for (i = 0; i < width - 1; i++, tdp += 2) {
648         tdp[0] = tmp0;
649         tdp[1] = tmp1;
650         x += dx;
651         cx = (x >> (MLIB_SHIFT - 1)) & ~1;
652         tmp0 = tsp[cx];
653         tmp1 = tsp[cx + 1];
654       }
655 
656       tdp[0] = tmp0;
657       tdp[1] = tmp1;
658     }
659 
660     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
661     y += dy;
662 
663     dp = (void *)((mlib_u8 *) dp + dst_stride);
664     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
665   }
666 
667   return MLIB_SUCCESS;
668 }
669 
670 /***************************************************************/
671 
mlib_ImageZoom_U8_4_Nearest(mlib_work_image * param)672 mlib_status mlib_ImageZoom_U8_4_Nearest(mlib_work_image *param)
673 {
674   VARIABLE(mlib_u8);
675   mlib_s32 i;
676   mlib_u8 *tdp, *tsp, tmp0, tmp1, tmp2, tmp3;
677   mlib_u16 utmp0, utmp1;
678   mlib_s32 cx, y_step = -1;
679 
680   tsp = sp;
681   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
682 
683   for (j = 0; j < height; j++) {
684 
685     if (!y_step) {
686       MLIB_COPY_FUNC((mlib_u8 *) dp - dst_stride, dp, 4 * width);
687     }
688     else {
689       tdp = dp;
690       x = GetElemSubStruct(current, srcX) & MLIB_MASK;
691 
692       if (((mlib_addr) tdp | (mlib_addr) tsp) & 1) {       /* sp & dp pointers not aligned */
693 
694         cx = (x >> (MLIB_SHIFT - 2)) & ~3;
695         tmp0 = tsp[cx];
696         tmp1 = tsp[cx + 1];
697         tmp2 = tsp[cx + 2];
698         tmp3 = tsp[cx + 3];
699 
700 #ifdef __SUNPRO_C
701 #pragma pipeloop(0)
702 #endif /* __SUNPRO_C */
703         for (i = 0; i < width - 1; i++) {
704           tdp[0] = tmp0;
705           tdp[1] = tmp1;
706           tdp[2] = tmp2;
707           tdp[3] = tmp3;
708 
709           x += dx;
710           cx = (x >> (MLIB_SHIFT - 2)) & ~3;
711 
712           tmp0 = tsp[cx];
713           tmp1 = tsp[cx + 1];
714           tmp2 = tsp[cx + 2];
715           tmp3 = tsp[cx + 3];
716 
717           tdp += 4;
718         }
719 
720         tdp[0] = tmp0;
721         tdp[1] = tmp1;
722         tdp[2] = tmp2;
723         tdp[3] = tmp3;
724       }
725       else {
726 
727         cx = (x >> (MLIB_SHIFT - 2)) & ~3;
728         utmp0 = *(mlib_u16 *) (tsp + cx);
729         utmp1 = *(mlib_u16 *) (tsp + cx + 2);
730 
731 #ifdef __SUNPRO_C
732 #pragma pipeloop(0)
733 #endif /* __SUNPRO_C */
734         for (i = 0; i < width - 1; i++) {
735           *(mlib_u16 *) tdp = utmp0;
736           *(mlib_u16 *) (tdp + 2) = utmp1;
737 
738           x += dx;
739           cx = (x >> (MLIB_SHIFT - 2)) & ~3;
740 
741           utmp0 = *(mlib_u16 *) (tsp + cx);
742           utmp1 = *(mlib_u16 *) (tsp + cx + 2);
743 
744           tdp += 4;
745         }
746 
747         *(mlib_u16 *) tdp = utmp0;
748         *(mlib_u16 *) (tdp + 2) = utmp1;
749       }
750     }
751 
752     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
753     y += dy;
754 
755     dp = (void *)((mlib_u8 *) dp + dst_stride);
756     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
757   }
758 
759   return MLIB_SUCCESS;
760 }
761 
762 /***************************************************************/
763 
mlib_ImageZoom_S16_2_Nearest(mlib_work_image * param)764 mlib_status mlib_ImageZoom_S16_2_Nearest(mlib_work_image *param)
765 {
766   VARIABLE(mlib_u16);
767   mlib_s32 i;
768   mlib_u8 *tsp, *tdp;
769   mlib_u16 tmp0, tmp1;
770   mlib_s32 cx, y_step = -1;
771   mlib_u32 utmp;
772 
773   tsp = (mlib_u8 *) sp;
774   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
775 
776   for (j = 0; j < height; j++) {
777 
778     if (!y_step) {
779       MLIB_COPY_FUNC((mlib_u8 *) dp - dst_stride, (void *)dp, 4 * width);
780     }
781     else {
782       tdp = (mlib_u8 *) dp;
783       x = GetElemSubStruct(current, srcX) & MLIB_MASK;
784 
785       if (((mlib_addr) tdp | (mlib_addr) tsp) & 3) {       /* sp & dp pointers not aligned */
786 
787         cx = (x >> (MLIB_SHIFT - 2)) & ~3;
788         tmp0 = *(mlib_u16 *) (tsp + cx);
789         tmp1 = *(mlib_u16 *) (tsp + cx + 2);
790 
791 #ifdef __SUNPRO_C
792 #pragma pipeloop(0)
793 #endif /* __SUNPRO_C */
794         for (i = 0; i < width - 1; i++, tdp += 4) {
795 
796           *(mlib_u16 *) tdp = tmp0;
797           *(mlib_u16 *) (tdp + 2) = tmp1;
798 
799           x += dx;
800           cx = (x >> (MLIB_SHIFT - 2)) & ~3;
801 
802           tmp0 = *(mlib_u16 *) (tsp + cx);
803           tmp1 = *(mlib_u16 *) (tsp + cx + 2);
804         }
805 
806         *(mlib_u16 *) tdp = tmp0;
807         *(mlib_u16 *) (tdp + 2) = tmp1;
808       }
809       else {
810 
811         cx = (x >> (MLIB_SHIFT - 2)) & ~3;
812         utmp = *(mlib_u32 *) (tsp + cx);
813 
814 #ifdef __SUNPRO_C
815 #pragma pipeloop(0)
816 #endif /* __SUNPRO_C */
817         for (i = 0; i < width - 1; i++, tdp += 4) {
818 
819           *(mlib_u32 *) tdp = utmp;
820           x += dx;
821           cx = (x >> (MLIB_SHIFT - 2)) & ~3;
822 
823           utmp = *(mlib_u32 *) (tsp + cx);
824         }
825 
826         *(mlib_u32 *) tdp = utmp;
827       }
828     }
829 
830     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
831     y += dy;
832 
833     dp = (void *)((mlib_u8 *) dp + dst_stride);
834     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
835   }
836 
837   return MLIB_SUCCESS;
838 }
839 
840 /***************************************************************/
841 
mlib_ImageZoom_S16_4_Nearest(mlib_work_image * param)842 mlib_status mlib_ImageZoom_S16_4_Nearest(mlib_work_image *param)
843 {
844   VARIABLE(mlib_u16);
845   mlib_s32 i;
846   mlib_u8 *tsp, *tdp;
847   mlib_s32 cx, y_step = -1;
848   mlib_u16 tmp0, tmp1, tmp2, tmp3;
849   TYPE_64 dtmp;
850   mlib_f32 ftmp0, ftmp1;
851 
852   tsp = (mlib_u8 *) sp;
853   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
854 
855   for (j = 0; j < height; j++) {
856 
857     if (!y_step) {
858       MLIB_COPY_FUNC((mlib_u8 *) dp - dst_stride, (void *)dp, 8 * width);
859     }
860     else {
861       tdp = (mlib_u8 *) dp;
862       x = GetElemSubStruct(current, srcX) & MLIB_MASK;
863 
864       if (((mlib_addr) tdp | (mlib_addr) tsp) & 7) {
865         if (((mlib_addr) tdp | (mlib_addr) tsp) & 3) {
866 
867           cx = (x >> (MLIB_SHIFT - 3)) & ~7;
868           tmp0 = *(mlib_u16 *) (tsp + cx);
869           tmp1 = *(mlib_u16 *) (tsp + cx + 2);
870 
871 #ifdef __SUNPRO_C
872 #pragma pipeloop(0)
873 #endif /* __SUNPRO_C */
874           for (i = 0; i < width - 1; i++) {
875 
876             tmp2 = *(mlib_u16 *) (tsp + cx + 4);
877             tmp3 = *(mlib_u16 *) (tsp + cx + 6);
878 
879             *(mlib_u16 *) tdp = tmp0;
880             *(mlib_u16 *) (tdp + 2) = tmp1;
881             *(mlib_u16 *) (tdp + 4) = tmp2;
882             *(mlib_u16 *) (tdp + 6) = tmp3;
883 
884             x += dx;
885             cx = (x >> (MLIB_SHIFT - 3)) & ~7;
886 
887             tmp0 = *(mlib_u16 *) (tsp + cx);
888             tmp1 = *(mlib_u16 *) (tsp + cx + 2);
889 
890             tdp += 8;
891           }
892 
893           tmp2 = *(mlib_u16 *) (tsp + cx + 4);
894           tmp3 = *(mlib_u16 *) (tsp + cx + 6);
895 
896           *(mlib_u16 *) tdp = tmp0;
897           *(mlib_u16 *) (tdp + 2) = tmp1;
898           *(mlib_u16 *) (tdp + 4) = tmp2;
899           *(mlib_u16 *) (tdp + 6) = tmp3;
900         }
901         else {                                             /* align to word */
902 
903           cx = (x >> (MLIB_SHIFT - 3)) & ~7;
904           ftmp0 = *(mlib_f32 *) (tsp + cx);
905           ftmp1 = *(mlib_f32 *) (tsp + cx + 4);
906 
907 #ifdef __SUNPRO_C
908 #pragma pipeloop(0)
909 #endif /* __SUNPRO_C */
910           for (i = 0; i < width - 1; i++) {
911 
912             *(mlib_f32 *) tdp = ftmp0;
913             *(mlib_f32 *) (tdp + 4) = ftmp1;
914 
915             x += dx;
916             cx = (x >> (MLIB_SHIFT - 3)) & ~7;
917 
918             ftmp0 = *(mlib_f32 *) (tsp + cx);
919             ftmp1 = *(mlib_f32 *) (tsp + cx + 4);
920 
921             tdp += 8;
922           }
923 
924           *(mlib_f32 *) tdp = ftmp0;
925           *(mlib_f32 *) (tdp + 4) = ftmp1;
926         }
927       }
928       else {                                               /* align to mlib_d64 word */
929 
930         cx = (x >> (MLIB_SHIFT - 3)) & ~7;
931         dtmp = *(TYPE_64 *) (tsp + cx);
932 
933 #ifdef __SUNPRO_C
934 #pragma pipeloop(0)
935 #endif /* __SUNPRO_C */
936         for (i = 0; i < width - 1; i++) {
937 
938           *(TYPE_64 *) tdp = dtmp;
939 
940           x += dx;
941           cx = (x >> (MLIB_SHIFT - 3)) & ~7;
942 
943           dtmp = *(TYPE_64 *) (tsp + cx);
944 
945           tdp += 8;
946         }
947 
948         *(TYPE_64 *) tdp = dtmp;
949       }
950     }
951 
952     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
953     y += dy;
954 
955     dp = (void *)((mlib_u8 *) dp + dst_stride);
956     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
957   }
958 
959   return MLIB_SUCCESS;
960 }
961 
962 /***************************************************************/
963 
mlib_ImageZoom_S32_1_Nearest(mlib_work_image * param)964 mlib_status mlib_ImageZoom_S32_1_Nearest(mlib_work_image *param)
965 {
966   VARIABLE(mlib_s32);
967   mlib_s32 *dl = dp, *tsp;
968   mlib_s32 y_step = -1;
969 
970   tsp = sp;
971   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
972 
973   for (j = 0; j < height; j++) {
974 
975     if (!y_step) {
976       MLIB_COPY_FUNC((mlib_u8 *) dl - dst_stride, (void *)dl, 4 * width);
977     }
978     else {
979       mlib_s32 *dp = dl, *dend = dl + width;
980 
981       x = GetElemSubStruct(current, srcX) & MLIB_MASK;
982 
983       if ((mlib_addr) dp & 7) {
984         *dp++ = tsp[x >> MLIB_SHIFT];
985         x += dx;
986       }
987 
988 #ifdef __SUNPRO_C
989 #pragma pipeloop(0)
990 #endif /* __SUNPRO_C */
991       for (; dp <= dend - 2; dp += 2) {
992         d64_2_f32 dd;
993         dd.f32s.f0 = *(mlib_f32 *) ((mlib_u8 *) tsp + ((x >> (MLIB_SHIFT - 2)) & ~3));
994         x += dx;
995         dd.f32s.f1 = *(mlib_f32 *) ((mlib_u8 *) tsp + ((x >> (MLIB_SHIFT - 2)) & ~3));
996         x += dx;
997         *(TYPE_64 *) dp = dd.d64;
998       }
999 
1000       if (dp < dend) {
1001         *dp++ = tsp[x >> MLIB_SHIFT];
1002       }
1003     }
1004 
1005     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
1006     y += dy;
1007 
1008     dl = (void *)((mlib_u8 *) dl + dst_stride);
1009     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
1010   }
1011 
1012   return MLIB_SUCCESS;
1013 }
1014 
1015 /***************************************************************/
1016 
mlib_ImageZoom_S32_2_Nearest(mlib_work_image * param)1017 mlib_status mlib_ImageZoom_S32_2_Nearest(mlib_work_image *param)
1018 {
1019   VARIABLE(mlib_s32);
1020   mlib_s32 i;
1021   mlib_u8 *tsp;
1022   mlib_s32 cx, y_step = -1, tmp0, tmp1, tmp2, tmp3, x_max;
1023   TYPE_64 dtmp0;
1024 
1025   tsp = (mlib_u8 *) sp;
1026   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
1027 
1028   x_max = (param->sline_size) << MLIB_SHIFT;
1029 
1030   for (j = 0; j < height; j++) {
1031 
1032     if (!y_step) {
1033       MLIB_COPY_FUNC((mlib_u8 *) dp - dst_stride, (void *)dp, 8 * width);
1034     }
1035     else {
1036       x = GetElemSubStruct(current, srcX) & MLIB_MASK;
1037 
1038       if (!(((mlib_addr) dp | (mlib_addr) tsp) & 7)) {
1039 
1040 #ifdef __SUNPRO_C
1041 #pragma pipeloop(0)
1042 #endif /* __SUNPRO_C */
1043         for (i = 0; i < width; i++) {
1044           cx = (x >> (MLIB_SHIFT - 3)) & ~7;
1045           x += dx;
1046           dtmp0 = *(TYPE_64 *) (tsp + cx);
1047           ((TYPE_64 *) dp)[i] = dtmp0;
1048         }
1049       }
1050       else {
1051 
1052         cx = (x >> (MLIB_SHIFT - 3)) & ~7;
1053         x += dx;
1054         tmp0 = *(mlib_s32 *) (tsp + cx);
1055         tmp1 = *(mlib_s32 *) (tsp + cx + 4);
1056         cx = ((x >> (MLIB_SHIFT - 3)) & ~7) & ((x - x_max) >> 31);
1057         x += dx;
1058         tmp2 = *(mlib_s32 *) (tsp + cx);
1059         tmp3 = *(mlib_s32 *) (tsp + cx + 4);
1060 
1061 #ifdef __SUNPRO_C
1062 #pragma pipeloop(0)
1063 #endif /* __SUNPRO_C */
1064         for (i = 0; i <= width - 2; i += 2) {
1065           dp[2 * i] = tmp0;
1066           dp[2 * i + 1] = tmp1;
1067           dp[2 * i + 2] = tmp2;
1068           dp[2 * i + 3] = tmp3;
1069 
1070           cx = ((x >> (MLIB_SHIFT - 3)) & ~7) & ((x - x_max) >> 31);
1071           x += dx;
1072           tmp0 = *(mlib_s32 *) (tsp + cx);
1073           tmp1 = *(mlib_s32 *) (tsp + cx + 4);
1074           cx = ((x >> (MLIB_SHIFT - 3)) & ~7) & ((x - x_max) >> 31);
1075           x += dx;
1076           tmp2 = *(mlib_s32 *) (tsp + cx);
1077           tmp3 = *(mlib_s32 *) (tsp + cx + 4);
1078         }
1079 
1080         if (width & 1) {
1081           dp[2 * i] = tmp0;
1082           dp[2 * i + 1] = tmp1;
1083         }
1084       }
1085     }
1086 
1087     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
1088     y += dy;
1089 
1090     dp = (void *)((mlib_u8 *) dp + dst_stride);
1091     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
1092   }
1093 
1094   return MLIB_SUCCESS;
1095 }
1096 
1097 /***************************************************************/
1098 
mlib_ImageZoom_S32_3_Nearest(mlib_work_image * param)1099 mlib_status mlib_ImageZoom_S32_3_Nearest(mlib_work_image *param)
1100 {
1101   VARIABLE(mlib_s32);
1102   mlib_s32 i;
1103   mlib_u8 *tsp;
1104   mlib_s32 cx, y_step = -1, tmp0, tmp1, tmp2;
1105 
1106   tsp = (mlib_u8 *) sp;
1107   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
1108 
1109   for (j = 0; j < height; j++) {
1110 
1111     if (!y_step) {
1112       MLIB_COPY_FUNC((mlib_u8 *) dp - dst_stride, (void *)dp, 12 * width);
1113     }
1114     else {
1115       x = GetElemSubStruct(current, srcX) & MLIB_MASK;
1116 
1117       cx = (x >> MLIB_SHIFT) * 12;
1118       x += dx;
1119       tmp0 = *(mlib_s32 *) (tsp + cx);
1120       tmp1 = *(mlib_s32 *) (tsp + cx + 4);
1121       tmp2 = *(mlib_s32 *) (tsp + cx + 8);
1122 
1123       cx = (x >> MLIB_SHIFT) * 12;
1124       x += dx;
1125 
1126 #ifdef __SUNPRO_C
1127 #pragma pipeloop(0)
1128 #endif /* __SUNPRO_C */
1129       for (i = 0; i < width - 1; i++) {
1130         dp[3 * i + 0] = tmp0;
1131         dp[3 * i + 1] = tmp1;
1132         dp[3 * i + 2] = tmp2;
1133 
1134         tmp0 = *(mlib_s32 *) (tsp + cx);
1135         tmp1 = *(mlib_s32 *) (tsp + cx + 4);
1136         tmp2 = *(mlib_s32 *) (tsp + cx + 8);
1137 
1138         cx = (x >> MLIB_SHIFT) * 12;
1139         x += dx;
1140       }
1141 
1142       dp[3 * i + 0] = tmp0;
1143       dp[3 * i + 1] = tmp1;
1144       dp[3 * i + 2] = tmp2;
1145     }
1146 
1147     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
1148     y += dy;
1149 
1150     dp = (void *)((mlib_u8 *) dp + dst_stride);
1151     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
1152   }
1153 
1154   return MLIB_SUCCESS;
1155 }
1156 
1157 /***************************************************************/
1158 
mlib_ImageZoom_S32_4_Nearest(mlib_work_image * param)1159 mlib_status mlib_ImageZoom_S32_4_Nearest(mlib_work_image *param)
1160 {
1161   VARIABLE(mlib_s32);
1162   mlib_s32 i;
1163   mlib_u8 *tsp;
1164   mlib_s32 cx, y_step = -1, tmp0, tmp1, tmp2, tmp3;
1165   TYPE_64 dtmp0, dtmp1;
1166 
1167   tsp = (mlib_u8 *) sp;
1168   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
1169 
1170   for (j = 0; j < height; j++) {
1171 
1172     if (!y_step) {
1173       MLIB_COPY_FUNC((mlib_u8 *) dp - dst_stride, (void *)dp, 16 * width);
1174     }
1175     else {
1176       x = GetElemSubStruct(current, srcX) & MLIB_MASK;
1177 
1178       if (((mlib_addr) dp | (mlib_addr) tsp) & 7) {
1179         cx = (x >> (MLIB_SHIFT - 4)) & ~15;
1180         x += dx;
1181 
1182         tmp0 = *(mlib_s32 *) (tsp + cx);
1183         tmp1 = *(mlib_s32 *) (tsp + cx + 4);
1184         tmp2 = *(mlib_s32 *) (tsp + cx + 8);
1185         tmp3 = *(mlib_s32 *) (tsp + cx + 12);
1186 
1187         cx = (x >> (MLIB_SHIFT - 4)) & ~15;
1188         x += dx;
1189 
1190 #ifdef __SUNPRO_C
1191 #pragma pipeloop(0)
1192 #endif /* __SUNPRO_C */
1193         for (i = 0; i < width - 1; i++) {
1194           dp[4 * i + 0] = tmp0;
1195           dp[4 * i + 1] = tmp1;
1196           dp[4 * i + 2] = tmp2;
1197           dp[4 * i + 3] = tmp3;
1198 
1199           tmp0 = *(mlib_s32 *) (tsp + cx);
1200           tmp1 = *(mlib_s32 *) (tsp + cx + 4);
1201           tmp2 = *(mlib_s32 *) (tsp + cx + 8);
1202           tmp3 = *(mlib_s32 *) (tsp + cx + 12);
1203 
1204           cx = (x >> (MLIB_SHIFT - 4)) & ~15;
1205           x += dx;
1206         }
1207 
1208         dp[4 * i + 0] = tmp0;
1209         dp[4 * i + 1] = tmp1;
1210         dp[4 * i + 2] = tmp2;
1211         dp[4 * i + 3] = tmp3;
1212       }
1213       else {
1214 
1215         cx = (x >> (MLIB_SHIFT - 4)) & ~15;
1216         x += dx;
1217 
1218         dtmp0 = *(TYPE_64 *) (tsp + cx);
1219         dtmp1 = *(TYPE_64 *) (tsp + cx + 8);
1220 
1221         cx = (x >> (MLIB_SHIFT - 4)) & ~15;
1222         x += dx;
1223 
1224 #ifdef __SUNPRO_C
1225 #pragma pipeloop(0)
1226 #endif /* __SUNPRO_C */
1227         for (i = 0; i < width - 1; i++) {
1228           *(TYPE_64 *) (dp + 4 * i) = dtmp0;
1229           *(TYPE_64 *) (dp + 4 * i + 2) = dtmp1;
1230 
1231           dtmp0 = *(TYPE_64 *) (tsp + cx);
1232           dtmp1 = *(TYPE_64 *) (tsp + cx + 8);
1233 
1234           cx = (x >> (MLIB_SHIFT - 4)) & ~15;
1235           x += dx;
1236         }
1237 
1238         *(TYPE_64 *) (dp + 4 * i) = dtmp0;
1239         *(TYPE_64 *) (dp + 4 * i + 2) = dtmp1;
1240       }
1241     }
1242 
1243     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
1244     y += dy;
1245 
1246     dp = (void *)((mlib_u8 *) dp + dst_stride);
1247     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
1248   }
1249 
1250   return MLIB_SUCCESS;
1251 }
1252 
1253 /***************************************************************/
1254 
mlib_ImageZoom_D64_1_Nearest(mlib_work_image * param)1255 mlib_status mlib_ImageZoom_D64_1_Nearest(mlib_work_image *param)
1256 {
1257   VARIABLE(TYPE_64);
1258   mlib_s32 i;
1259   TYPE_64 *tsp, tmp;
1260   mlib_s32 cx, y_step;
1261 
1262   tsp = sp;
1263   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
1264 
1265   for (j = 0; j < height; j++) {
1266     x = GetElemSubStruct(current, srcX) & MLIB_MASK;
1267 
1268 #ifdef __SUNPRO_C
1269 #pragma pipeloop(0)
1270 #endif /* __SUNPRO_C */
1271     for (i = 0; i < width; i++) {
1272       cx = x >> MLIB_SHIFT;
1273       tmp = tsp[cx];
1274       dp[i] = tmp;
1275       x += dx;
1276     }
1277 
1278     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
1279     y += dy;
1280 
1281     dp = (void *)((mlib_u8 *) dp + dst_stride);
1282     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
1283   }
1284 
1285   return MLIB_SUCCESS;
1286 }
1287 
1288 /***************************************************************/
1289 
mlib_ImageZoom_D64_2_Nearest(mlib_work_image * param)1290 mlib_status mlib_ImageZoom_D64_2_Nearest(mlib_work_image *param)
1291 {
1292   VARIABLE(TYPE_64);
1293   mlib_s32 i;
1294   TYPE_64 *tsp, tmp, tmp1;
1295   mlib_s32 cx, y_step;
1296 
1297   tsp = sp;
1298   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
1299 
1300   for (j = 0; j < height; j++) {
1301     x = GetElemSubStruct(current, srcX) & MLIB_MASK;
1302 
1303 #ifdef __SUNPRO_C
1304 #pragma pipeloop(0)
1305 #endif /* __SUNPRO_C */
1306     for (i = 0; i < width; i++) {
1307       cx = (x >> (MLIB_SHIFT - 1)) & ~1;
1308       tmp = tsp[cx];
1309       tmp1 = tsp[cx + 1];
1310       dp[2 * i] = tmp;
1311       dp[2 * i + 1] = tmp1;
1312       x += dx;
1313     }
1314 
1315     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
1316     y += dy;
1317 
1318     dp = (void *)((mlib_u8 *) dp + dst_stride);
1319     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
1320   }
1321 
1322   return MLIB_SUCCESS;
1323 }
1324 
1325 /***************************************************************/
1326 
mlib_ImageZoom_D64_3_Nearest(mlib_work_image * param)1327 mlib_status mlib_ImageZoom_D64_3_Nearest(mlib_work_image *param)
1328 {
1329   VARIABLE(TYPE_64);
1330   mlib_s32 i;
1331   TYPE_64 *tsp, tmp, tmp1, tmp2;
1332   mlib_s32 cx, y_step;
1333 
1334   tsp = sp;
1335   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
1336 
1337   for (j = 0; j < height; j++) {
1338     x = GetElemSubStruct(current, srcX) & MLIB_MASK;
1339 
1340     cx = (x >> MLIB_SHIFT) * 3;
1341     tmp = tsp[cx];
1342     tmp1 = tsp[cx + 1];
1343     tmp2 = tsp[cx + 2];
1344     x += dx;
1345 
1346     cx = (x >> MLIB_SHIFT) * 3;
1347     x += dx;
1348 
1349 #ifdef __SUNPRO_C
1350 #pragma pipeloop(0)
1351 #endif /* __SUNPRO_C */
1352     for (i = 0; i < width - 1; i++) {
1353       dp[3 * i] = tmp;
1354       dp[3 * i + 1] = tmp1;
1355       dp[3 * i + 2] = tmp2;
1356       tmp = tsp[cx];
1357       tmp1 = tsp[cx + 1];
1358       tmp2 = tsp[cx + 2];
1359       cx = (x >> MLIB_SHIFT) * 3;
1360       x += dx;
1361     }
1362 
1363     dp[3 * i] = tmp;
1364     dp[3 * i + 1] = tmp1;
1365     dp[3 * i + 2] = tmp2;
1366 
1367     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
1368     y += dy;
1369 
1370     dp = (void *)((mlib_u8 *) dp + dst_stride);
1371     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
1372   }
1373 
1374   return MLIB_SUCCESS;
1375 }
1376 
1377 /***************************************************************/
1378 
mlib_ImageZoom_D64_4_Nearest(mlib_work_image * param)1379 mlib_status mlib_ImageZoom_D64_4_Nearest(mlib_work_image *param)
1380 {
1381   VARIABLE(TYPE_64);
1382   mlib_s32 i;
1383   TYPE_64 *tsp, tmp, tmp1, tmp2, tmp3;
1384   mlib_s32 cx, y_step;
1385 
1386   tsp = sp;
1387   y = GetElemSubStruct(current, srcY) & MLIB_MASK;
1388 
1389   for (j = 0; j < height; j++) {
1390     x = GetElemSubStruct(current, srcX) & MLIB_MASK;
1391 
1392     cx = (x >> (MLIB_SHIFT - 2)) & ~3;
1393     tmp = tsp[cx];
1394     tmp1 = tsp[cx + 1];
1395     tmp2 = tsp[cx + 2];
1396     tmp3 = tsp[cx + 3];
1397     x += dx;
1398 
1399     cx = (x >> (MLIB_SHIFT - 2)) & ~3;
1400     x += dx;
1401 
1402 #ifdef __SUNPRO_C
1403 #pragma pipeloop(0)
1404 #endif /* __SUNPRO_C */
1405     for (i = 0; i < width - 1; i++) {
1406       dp[4 * i] = tmp;
1407       dp[4 * i + 1] = tmp1;
1408       dp[4 * i + 2] = tmp2;
1409       dp[4 * i + 3] = tmp3;
1410       tmp = tsp[cx];
1411       tmp1 = tsp[cx + 1];
1412       tmp2 = tsp[cx + 2];
1413       tmp3 = tsp[cx + 3];
1414       cx = (x >> (MLIB_SHIFT - 2)) & ~3;
1415       x += dx;
1416     }
1417 
1418     dp[4 * i] = tmp;
1419     dp[4 * i + 1] = tmp1;
1420     dp[4 * i + 2] = tmp2;
1421     dp[4 * i + 3] = tmp3;
1422 
1423     y_step = ((y + dy) - (y & ~MLIB_MASK)) >> MLIB_SHIFT;
1424     y += dy;
1425 
1426     dp = (void *)((mlib_u8 *) dp + dst_stride);
1427     tsp = (void *)((mlib_u8 *) tsp + y_step * src_stride);
1428   }
1429 
1430   return MLIB_SUCCESS;
1431 }
1432 
1433 /***************************************************************/
1434