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 */