1 /*
2  * Copyright (c) 2003, 2010, 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 #if !defined(JAVA2D_NO_MLIB) || defined(MLIB_ADD_SUFF)
27 
28 #include "java2d_Mlib.h"
29 #include "SurfaceData.h"
30 
31 #include "mlib_ImageZoom.h"
32 
33 /***************************************************************/
34 
35 #define DEFINE_ISO_COPY(FUNC, ANYTYPE)               \
36 void ADD_SUFF(ANYTYPE##FUNC)(BLIT_PARAMS)            \
37 {                                                    \
38     mlib_s32 srcScan = pSrcInfo->scanStride;         \
39     mlib_s32 dstScan = pDstInfo->scanStride;         \
40     mlib_s32 xsize = width*ANYTYPE##PixelStride;     \
41     mlib_s32 i;                                      \
42                                                      \
43     if (srcScan == xsize && dstScan == xsize) {      \
44         xsize *= height;                             \
45         height = 1;                                  \
46     }                                                \
47                                                      \
48     for (i = 0; i < height; i++) {                   \
49         mlib_ImageCopy_na(srcBase, dstBase, xsize);  \
50         srcBase = (mlib_u8*)srcBase + srcScan;       \
51         dstBase = (mlib_u8*)dstBase + dstScan;       \
52     }                                                \
53 }
54 
55 DEFINE_ISO_COPY(IsomorphicCopy, Any3Byte)
56 DEFINE_ISO_COPY(IsomorphicCopy, Any4Byte)
57 DEFINE_ISO_COPY(IsomorphicCopy, AnyByte)
58 DEFINE_ISO_COPY(IsomorphicCopy, AnyInt)
59 DEFINE_ISO_COPY(IsomorphicCopy, AnyShort)
60 
61 /***************************************************************/
62 
63 #define SET_PIX(index, chan)         \
64     dst_ptr[index] = pixel##chan
65 
66 #define W_LEVEL_1   8
67 #define W_LEVEL_3  16
68 #define W_LEVEL_4   8
69 
70 #define DEFINE_SET_RECT(FUNC, ANYTYPE, NCHAN)                       \
71 void ADD_SUFF(ANYTYPE##FUNC)(SurfaceDataRasInfo * pRasInfo,         \
72                              jint lox, jint loy, jint hix,          \
73                              jint hiy, jint pixel,                  \
74                              NativePrimitive * pPrim,               \
75                              CompositeInfo * pCompInfo)             \
76 {                                                                   \
77     mlib_image dst[1];                                              \
78     mlib_s32 dstScan = pRasInfo->scanStride;                        \
79     mlib_s32 height = hiy - loy;                                    \
80     mlib_s32 width  = hix - lox;                                    \
81     mlib_u8  *dstBase = (mlib_u8*)(pRasInfo->rasBase);              \
82     mlib_s32 c_arr[4];                                              \
83                                                                     \
84     dstBase += loy*dstScan + lox*ANYTYPE##PixelStride;              \
85                                                                     \
86     if (width <= W_LEVEL_##NCHAN) {                                 \
87         EXTRACT_CONST_##NCHAN(pixel);                               \
88                                                                     \
89         LOOP_DST(ANYTYPE, NCHAN, dstBase, dstScan, SET_PIX);        \
90         return;                                                     \
91     }                                                               \
92                                                                     \
93     STORE_CONST_##NCHAN(c_arr, pixel);                              \
94                                                                     \
95     MLIB_IMAGE_SET(dst, MLIB_##ANYTYPE, NCHAN,                      \
96                    width, height, dstScan, dstBase);                \
97                                                                     \
98     mlib_ImageClear(dst, c_arr);                                    \
99 }
100 
101 DEFINE_SET_RECT(SetRect, Any3Byte, 3)
102 DEFINE_SET_RECT(SetRect, Any4Byte, 4)
103 DEFINE_SET_RECT(SetRect, AnyByte,  1)
104 DEFINE_SET_RECT(SetRect, AnyInt,   1)
105 DEFINE_SET_RECT(SetRect, AnyShort, 1)
106 
107 /***************************************************************/
108 
109 #define XOR_PIX(index, chan)         \
110     dst_ptr[index] ^= pixel##chan
111 
112 #define DEFINE_XOR_RECT(FUNC, ANYTYPE, NCHAN)                       \
113 void ADD_SUFF(ANYTYPE##FUNC)(SurfaceDataRasInfo * pRasInfo,         \
114                              jint lox, jint loy, jint hix,          \
115                              jint hiy, jint pixel,                  \
116                              NativePrimitive * pPrim,               \
117                              CompositeInfo * pCompInfo)             \
118 {                                                                   \
119     mlib_image dst[1];                                              \
120     mlib_s32 dstScan = pRasInfo->scanStride;                        \
121     mlib_s32 height = hiy - loy;                                    \
122     mlib_s32 width  = hix - lox;                                    \
123     mlib_u8  *dstBase = (mlib_u8*)(pRasInfo->rasBase);              \
124     mlib_s32 c_arr[4];                                              \
125     mlib_s32 xorpixel = pCompInfo->details.xorPixel;                \
126     mlib_s32 alphamask = pCompInfo->alphaMask;                      \
127                                                                     \
128     pixel = (pixel ^ xorpixel) &~ alphamask;                        \
129                                                                     \
130     dstBase += loy*dstScan + lox*ANYTYPE##PixelStride;              \
131                                                                     \
132     if (width < 8) {                                                \
133         EXTRACT_CONST_##NCHAN(pixel);                               \
134                                                                     \
135         LOOP_DST(ANYTYPE, NCHAN, dstBase, dstScan, XOR_PIX);        \
136         return;                                                     \
137     }                                                               \
138                                                                     \
139     STORE_CONST_##NCHAN(c_arr, pixel);                              \
140                                                                     \
141     MLIB_IMAGE_SET(dst, MLIB_##ANYTYPE, NCHAN,                      \
142                    width, height, dstScan, dstBase);                \
143                                                                     \
144     mlib_ImageConstXor(dst, dst, c_arr);                            \
145 }
146 
147 DEFINE_XOR_RECT(XorRect, Any3Byte, 3)
148 DEFINE_XOR_RECT(XorRect, Any4Byte, 4)
149 DEFINE_XOR_RECT(XorRect, AnyByte,  1)
150 DEFINE_XOR_RECT(XorRect, AnyInt,   1)
151 DEFINE_XOR_RECT(XorRect, AnyShort, 1)
152 
153 /***************************************************************/
154 
155 #define XOR_COPY(index, chan)         \
156     dst_ptr[index] = dst_ptr[index] ^ src_ptr[index] ^ pixel##chan
157 
158 #define DEFINE_XOR_COPY(FUNC, ANYTYPE, NCHAN)                  \
159 void ADD_SUFF(ANYTYPE##FUNC)(void *srcBase,                    \
160                              void *dstBase,                    \
161                              juint width,                      \
162                              juint height,                     \
163                              SurfaceDataRasInfo *pSrcInfo,     \
164                              SurfaceDataRasInfo *pDstInfo,     \
165                              NativePrimitive *pPrim,           \
166                              CompositeInfo *pCompInfo)         \
167 {                                                              \
168     mlib_image src[1], dst[1];                                 \
169     mlib_s32 srcScan = pSrcInfo->scanStride;                   \
170     mlib_s32 dstScan = pDstInfo->scanStride;                   \
171     mlib_s32 c_arr[4];                                         \
172     mlib_s32 pixel  = pCompInfo->details.xorPixel;             \
173                                                                \
174     if (width < 8*sizeof(ANYTYPE##DataType)) {                 \
175         EXTRACT_CONST_##NCHAN(pixel);                          \
176                                                                \
177         LOOP_DST_SRC(ANYTYPE, NCHAN, dstBase, dstScan,         \
178                      srcBase, srcScan, XOR_COPY);              \
179         return;                                                \
180     }                                                          \
181                                                                \
182     STORE_CONST_##NCHAN(c_arr, pixel);                         \
183                                                                \
184     MLIB_IMAGE_SET(src, MLIB_##ANYTYPE, NCHAN,                 \
185                    width, height, srcScan, srcBase);           \
186     MLIB_IMAGE_SET(dst, MLIB_##ANYTYPE, NCHAN,                 \
187                    width, height, dstScan, dstBase);           \
188                                                                \
189     mlib_ImageXor(dst, dst, src);                              \
190     mlib_ImageConstXor(dst, dst, c_arr);                       \
191 }
192 
193 DEFINE_XOR_COPY(IsomorphicXorCopy, Any3Byte, 3)
194 DEFINE_XOR_COPY(IsomorphicXorCopy, Any4Byte, 4)
195 DEFINE_XOR_COPY(IsomorphicXorCopy, AnyByte,  1)
196 DEFINE_XOR_COPY(IsomorphicXorCopy, AnyInt,   1)
197 DEFINE_XOR_COPY(IsomorphicXorCopy, AnyShort, 1)
198 
199 /***************************************************************/
200 
201 #define DEFINE_SET_SPANS(FUNC, ANYTYPE, NCHAN)                      \
202 void ADD_SUFF(ANYTYPE##FUNC)(SurfaceDataRasInfo * pRasInfo,         \
203                              SpanIteratorFuncs * pSpanFuncs,        \
204                              void *siData, jint pixel,              \
205                              NativePrimitive * pPrim,               \
206                              CompositeInfo * pCompInfo)             \
207 {                                                                   \
208     mlib_image dst[1];                                              \
209     mlib_s32 dstScan = pRasInfo->scanStride;                        \
210     mlib_s32 height;                                                \
211     mlib_s32 width;                                                 \
212     mlib_u8  *dstBase = (mlib_u8*)(pRasInfo->rasBase), *pdst;       \
213     mlib_s32 c_arr[4];                                              \
214     jint     bbox[4];                                               \
215                                                                     \
216     STORE_CONST_##NCHAN(c_arr, pixel);                              \
217                                                                     \
218     while ((*pSpanFuncs->nextSpan)(siData, bbox)) {                 \
219         mlib_s32 lox = bbox[0];                                     \
220         mlib_s32 loy = bbox[1];                                     \
221         mlib_s32 width  = bbox[2] - lox;                            \
222         mlib_s32 height = bbox[3] - loy;                            \
223                                                                     \
224         pdst = dstBase + loy*dstScan + lox*ANYTYPE##PixelStride;    \
225                                                                     \
226         MLIB_IMAGE_SET(dst, MLIB_##ANYTYPE, NCHAN_##ANYTYPE,        \
227                        width, height, dstScan, pdst);               \
228                                                                     \
229         mlib_ImageClear(dst, c_arr);                                \
230     }                                                               \
231 }
232 
233 DEFINE_SET_SPANS(SetSpans, Any3Byte, 3)
234 DEFINE_SET_SPANS(SetSpans, Any4Byte, 4)
235 DEFINE_SET_SPANS(SetSpans, AnyByte,  1)
236 DEFINE_SET_SPANS(SetSpans, AnyInt,   1)
237 DEFINE_SET_SPANS(SetSpans, AnyShort, 1)
238 
239 /***************************************************************/
240 
241 #define DEFINE_XOR_SPANS(FUNC, ANYTYPE, NCHAN)                      \
242 void ADD_SUFF(ANYTYPE##FUNC)(SurfaceDataRasInfo * pRasInfo,         \
243                              SpanIteratorFuncs * pSpanFuncs,        \
244                              void *siData, jint pixel,              \
245                              NativePrimitive * pPrim,               \
246                              CompositeInfo * pCompInfo)             \
247 {                                                                   \
248     mlib_image dst[1];                                              \
249     mlib_s32 dstScan = pRasInfo->scanStride;                        \
250     mlib_s32 height;                                                \
251     mlib_s32 width;                                                 \
252     mlib_u8  *dstBase = (mlib_u8*)(pRasInfo->rasBase), *pdst;       \
253     mlib_s32 c_arr[4];                                              \
254     mlib_s32 xorpixel = pCompInfo->details.xorPixel;                \
255     mlib_s32 alphamask = pCompInfo->alphaMask;                      \
256     jint     bbox[4];                                               \
257                                                                     \
258     pixel = (pixel ^ xorpixel) &~ alphamask;                        \
259                                                                     \
260     STORE_CONST_##NCHAN(c_arr, pixel);                              \
261                                                                     \
262     while ((*pSpanFuncs->nextSpan)(siData, bbox)) {                 \
263         mlib_s32 lox = bbox[0];                                     \
264         mlib_s32 loy = bbox[1];                                     \
265         mlib_s32 width  = bbox[2] - lox;                            \
266         mlib_s32 height = bbox[3] - loy;                            \
267                                                                     \
268         pdst = dstBase + loy*dstScan + lox*ANYTYPE##PixelStride;    \
269                                                                     \
270         MLIB_IMAGE_SET(dst, MLIB_##ANYTYPE, NCHAN_##ANYTYPE,        \
271                        width, height, dstScan, pdst);               \
272                                                                     \
273         mlib_ImageConstXor(dst, dst, c_arr);                        \
274     }                                                               \
275 }
276 
277 DEFINE_XOR_SPANS(XorSpans, Any3Byte, 3)
278 DEFINE_XOR_SPANS(XorSpans, Any4Byte, 4)
279 DEFINE_XOR_SPANS(XorSpans, AnyByte,  1)
280 DEFINE_XOR_SPANS(XorSpans, AnyInt,   1)
281 DEFINE_XOR_SPANS(XorSpans, AnyShort, 1)
282 
283 /***************************************************************/
284 
285 #define DEFINE_SET_PGRAM(FUNC, ANYTYPE, NCHAN)                      \
286 void ADD_SUFF(ANYTYPE##FUNC)(SurfaceDataRasInfo *pRasInfo,          \
287                              jint lox, jint loy,                    \
288                              jint hix, jint hiy,                    \
289                              jlong leftx, jlong dleftx,             \
290                              jlong rightx, jlong drightx,           \
291                              jint pixel, NativePrimitive * pPrim,   \
292                              CompositeInfo * pCompInfo)             \
293 {                                                                   \
294     mlib_image dst[1];                                              \
295     mlib_s32 dstScan = pRasInfo->scanStride;                        \
296     mlib_u8  *dstBase = (mlib_u8*)(pRasInfo->rasBase), *pdst;       \
297     mlib_s32 c_arr[4];                                              \
298                                                                     \
299     STORE_CONST_##NCHAN(c_arr, pixel);                              \
300     pdst = dstBase + loy*dstScan;                                   \
301                                                                     \
302     while (loy < hiy) {                                             \
303         jint lx = WholeOfLong(leftx);                               \
304         jint rx = WholeOfLong(rightx);                              \
305         if (lx < lox) lx = lox;                                     \
306         if (rx > hix) rx = hix;                                     \
307                                                                     \
308         MLIB_IMAGE_SET(dst, MLIB_##ANYTYPE, NCHAN_##ANYTYPE,        \
309                        rx-lx, 1, dstScan,                           \
310                        pdst + lx*ANYTYPE##PixelStride);             \
311                                                                     \
312         mlib_ImageClear(dst, c_arr);                                \
313                                                                     \
314         pdst = PtrAddBytes(pdst, dstScan);                          \
315         leftx += dleftx;                                            \
316         rightx += drightx;                                          \
317         loy++;                                                      \
318     }                                                               \
319 }
320 
321 DEFINE_SET_PGRAM(SetParallelogram, Any3Byte, 3)
322 DEFINE_SET_PGRAM(SetParallelogram, Any4Byte, 4)
323 DEFINE_SET_PGRAM(SetParallelogram, AnyByte,  1)
324 DEFINE_SET_PGRAM(SetParallelogram, AnyInt,   1)
325 DEFINE_SET_PGRAM(SetParallelogram, AnyShort, 1)
326 
327 /***************************************************************/
328 
329 #define SCALE_COPY(index, chan)         \
330     pDst[chan] = pSrc[index]
331 
332 #define MLIB_ZOOM_NN_AnyByte  mlib_ImageZoom_U8_1_Nearest(param);
333 #define MLIB_ZOOM_NN_Any3Byte mlib_ImageZoom_U8_3_Nearest(param);
334 #define MLIB_ZOOM_NN_AnyShort mlib_ImageZoom_S16_1_Nearest(param);
335 #define MLIB_ZOOM_NN_AnyInt   mlib_ImageZoom_S32_1_Nearest(param);
336 
337 #define MLIB_ZOOM_NN_Any4Byte                                      \
338 {                                                                  \
339     mlib_s32 b_align = (mlib_s32)srcBase | (mlib_s32)dstBase |     \
340                        srcScan | dstScan;                          \
341                                                                    \
342     if (!(b_align & 3)) {                                          \
343         mlib_ImageZoom_S32_1_Nearest(param);                       \
344     } else if (!(b_align & 1)) {                                   \
345         mlib_ImageZoom_S16_2_Nearest(param);                       \
346     } else {                                                       \
347         mlib_ImageZoom_U8_4_Nearest(param);                        \
348     }                                                              \
349 }
350 
351 #define DEFINE_ISO_SCALE(FUNC, ANYTYPE, NCHAN)                     \
352 void ADD_SUFF(ANYTYPE##FUNC)(void *srcBase, void *dstBase,         \
353                              juint width, juint height,            \
354                              jint sxloc, jint syloc,               \
355                              jint sxinc, jint syinc,               \
356                              jint shift,                           \
357                              SurfaceDataRasInfo *pSrcInfo,         \
358                              SurfaceDataRasInfo *pDstInfo,         \
359                              NativePrimitive *pPrim,               \
360                              CompositeInfo *pCompInfo)             \
361 {                                                                  \
362     mlib_work_image param[1];                                      \
363     mlib_clipping current[1];                                      \
364     mlib_s32 srcScan = pSrcInfo->scanStride;                       \
365     mlib_s32 dstScan = pDstInfo->scanStride;                       \
366                                                                    \
367     if (width <= 32) {                                             \
368         ANYTYPE##DataType *pSrc;                                   \
369         ANYTYPE##DataType *pDst = dstBase;                         \
370         dstScan -= (width) * ANYTYPE##PixelStride;                 \
371                                                                    \
372         do {                                                       \
373             juint w = width;                                       \
374             jint  tmpsxloc = sxloc;                                \
375             pSrc = srcBase;                                        \
376             PTR_ADD(pSrc, (syloc >> shift) * srcScan);             \
377             do {                                                   \
378                 jint i = (tmpsxloc >> shift);                      \
379                 PROCESS_PIX_##NCHAN(SCALE_COPY);                   \
380                 pDst += NCHAN;                                     \
381                 tmpsxloc += sxinc;                                 \
382             }                                                      \
383             while (--w > 0);                                       \
384             PTR_ADD(pDst, dstScan);                                \
385             syloc += syinc;                                        \
386         }                                                          \
387         while (--height > 0);                                      \
388         return;                                                    \
389     }                                                              \
390                                                                    \
391     param->current = current;                                      \
392                                                                    \
393     if (shift <= MLIB_SHIFT /* 16 */) {                            \
394         jint dshift = MLIB_SHIFT - shift;                          \
395         sxloc <<= dshift;                                          \
396         syloc <<= dshift;                                          \
397         sxinc <<= dshift;                                          \
398         syinc <<= dshift;                                          \
399     } else {                                                       \
400         jint dshift = shift - MLIB_SHIFT;                          \
401         sxloc >>= dshift;                                          \
402         syloc >>= dshift;                                          \
403         sxinc >>= dshift;                                          \
404         syinc >>= dshift;                                          \
405     }                                                              \
406                                                                    \
407     current->width  = width;                                       \
408     current->height = height;                                      \
409     param->DX = sxinc;                                             \
410     param->DY = syinc;                                             \
411     param->src_stride = srcScan;                                   \
412     param->dst_stride = dstScan;                                   \
413     current->srcX = sxloc;                                         \
414     current->srcY = syloc;                                         \
415     current->sp = (mlib_u8*)srcBase                                \
416           + (sxloc >> MLIB_SHIFT)*ANYTYPE##PixelStride             \
417           + (syloc >> MLIB_SHIFT)*srcScan;                         \
418     current->dp = dstBase;                                         \
419                                                                    \
420     MLIB_ZOOM_NN_##ANYTYPE                                         \
421 }
422 
423 DEFINE_ISO_SCALE(IsomorphicScaleCopy, Any3Byte, 3)
424 DEFINE_ISO_SCALE(IsomorphicScaleCopy, Any4Byte, 4)
425 DEFINE_ISO_SCALE(IsomorphicScaleCopy, AnyByte,  1)
426 DEFINE_ISO_SCALE(IsomorphicScaleCopy, AnyInt,   1)
427 DEFINE_ISO_SCALE(IsomorphicScaleCopy, AnyShort, 1)
428 
429 /***************************************************************/
430 
431 #endif /* JAVA2D_NO_MLIB */
432