< prev index next >

src/java.desktop/macosx/native/libawt_lwawt/awt/ImageSurfaceData.m

Print this page
rev 54094 : 8257853: Remove dependencies on JNF's JNI utility functions in AWT and 2D code
rev 54096 : 8259651: [macOS] Replace JNF_COCOA_ENTER/EXIT macros
rev 54097 : 8259869: [macOS] Remove desktop module dependencies on JNF Reference APIs
rev 54098 : 8260616: Removing remaining JNF dependencies in the java.desktop module
8259729: Missed JNFInstanceOf -> IsInstanceOf conversion


  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 #import "ImageSurfaceData.h"
  27 
  28 #import "java_awt_Transparency.h"
  29 #import "java_awt_image_BufferedImage.h"
  30 #import "sun_awt_image_BufImgSurfaceData.h"
  31 #import "sun_java2d_OSXOffScreenSurfaceData.h"
  32 
  33 #import "jni_util.h"
  34 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  35 
  36 #import "BufImgSurfaceData.h"
  37 
  38 //#define DEBUG 1
  39 #if defined DEBUG
  40     #define IMAGE_SURFACE_INLINE
  41     #define PRINT(msg) {fprintf(stderr, "%s\n", msg);fflush(stderr);}
  42 #else
  43     #define IMAGE_SURFACE_INLINE static inline
  44     #define PRINT(msg) {}
  45 #endif
  46 
  47 // same value as defined in Sun's own code
  48 #define XOR_ALPHA_CUTOFF 128
  49 
  50 // for vImage framework headers
  51 #include <Accelerate/Accelerate.h>
  52 
  53 static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] =
  54 {


  86     {8,        32,        4,        0,        kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,    NULL},    // TYPE_4BYTE_ABGR_PRE
  87 #ifdef __LITTLE_ENDIAN__
  88     {5,        16,        2,        0,        kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Host,        NULL},    // TYPE_USHORT_565_RGB
  89     {5,        16,        2,        0,        kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Host,        NULL},    // TYPE_USHORT_555_RGB
  90 #else
  91     {5,        16,        2,        0,        kCGImageAlphaNoneSkipFirst,                                    NULL},    // TYPE_USHORT_565_RGB
  92     {5,        16,        2,        0,        kCGImageAlphaNoneSkipFirst,                                    NULL},    // TYPE_USHORT_555_RGB
  93 #endif
  94     {8,        8,        1,        0,        kCGImageAlphaNone,                                            NULL},    // TYPE_BYTE_GRAY
  95     {16,    16,        2,        0,        kCGImageAlphaNone | kCGBitmapByteOrder16Host,                NULL},    // TYPE_USHORT_GRAY
  96     {0,        0,        0,        0,        -1,                                                            NULL},    // TYPE_BYTE_BINARY        mapped to TYPE_CUSTOM
  97     {8,        32,        4,        0,        kCGImageAlphaFirst | kCGBitmapByteOrder32Host,                NULL},    // TYPE_BYTE_INDEXED  // Fully OPAQUE INDEXED images will use kCGImageAlphaNoneSkipFirst for performance reasosn. see <rdar://4224874>
  98     {8,        32,        4,        0,        kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host,        NULL},    // TYPE_3BYTE_RGB
  99 };
 100 
 101 static jfieldID        rgbID;
 102 static jfieldID        mapSizeID;
 103 static jfieldID        CMpDataID;
 104 static jfieldID        allGrayID;
 105 
 106 
 107 static JNF_CLASS_CACHE(jc_OSXOffScreenSurfaceData, "sun/java2d/OSXOffScreenSurfaceData");
 108 static JNF_MEMBER_CACHE(jm_syncFromCustom, jc_OSXOffScreenSurfaceData, "syncFromCustom", "()V");
 109 static JNF_MEMBER_CACHE(jm_syncToCustom, jc_OSXOffScreenSurfaceData, "syncToCustom", "()V");
 110 static JNF_CLASS_CACHE(jc_BufferedImage, "java/awt/image/BufferedImage");
 111 static JNF_MEMBER_CACHE(jm_SurfaceData, jc_BufferedImage, "sData", "Lsun/java2d/SurfaceData;");
 112 static JNF_CLASS_CACHE(jc_IndexColorModel, "java/awt/image/IndexColorModel");
 113 static JNF_MEMBER_CACHE(jm_rgb, jc_IndexColorModel, "rgb", "[I");
 114 static JNF_MEMBER_CACHE(jm_transparency, jc_IndexColorModel, "transparency", "I");
 115 static JNF_MEMBER_CACHE(jm_transparent_index, jc_IndexColorModel, "transparent_index", "I");
 116 
 117 CGColorSpaceRef gColorspaceRGB = NULL;
 118 CGColorSpaceRef gColorspaceGray = NULL;
 119 
 120 IMAGE_SURFACE_INLINE void PrintImageInfo(ImageSDOps* isdo)
 121 {
 122     fprintf(stderr, "\n");
 123     fprintf(stderr, "PrintImageInfo:\n");
 124     fprintf(stderr, "\t \n");
 125     //fprintf(stderr, "\t magicID=%d\n", (jint)isdo->magicID);
 126     //fprintf(stderr, "\n");
 127     fprintf(stderr, "\t isdo=%p\n", isdo);
 128     fprintf(stderr, "\t \n");
 129     fprintf(stderr, "\t contextInfo:\n");
 130     fprintf(stderr, "\t        useWindowContextReference=%d\n", isdo->contextInfo.useWindowContextReference);
 131     fprintf(stderr, "\t        canUseJavaPixelsAsContext=%d\n", isdo->contextInfo.canUseJavaPixelsAsContext);
 132     fprintf(stderr, "\t        bitsPerComponent=%ld\n", (long)isdo->contextInfo.bitsPerComponent);
 133     fprintf(stderr, "\t        bytesPerPixel=%ld\n", (long)isdo->contextInfo.bytesPerPixel);
 134     fprintf(stderr, "\t        bytesPerRow=%ld\n", (long)isdo->contextInfo.bytesPerRow);
 135     fprintf(stderr, "\t        alphaInfo=%ld\n", (long)isdo->contextInfo.alphaInfo);


 175     {
 176         isdo->imgRef = CGImageCreate(isdo->width,
 177                                       isdo->height,
 178                                       isdo->contextInfo.bitsPerComponent,
 179                                       isdo->contextInfo.bytesPerPixel * 8,
 180                                       isdo->contextInfo.bytesPerRow,
 181                                       isdo->contextInfo.colorSpace,
 182                                       isdo->contextInfo.alphaInfo,
 183                                       isdo->dataProvider,
 184                                       NULL,
 185                                       NO,
 186                                       kCGRenderingIntentDefault);
 187     }
 188 }
 189 
 190 IMAGE_SURFACE_INLINE void customPixelsFromJava(JNIEnv *env, ImageSDOps *isdo)
 191 {
 192 PRINT("    customPixelsFromJava")
 193 
 194     SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
 195     JNFCallVoidMethod(env, sdo->sdObject, jm_syncFromCustom); // AWT_THREADING Safe (known object)




 196 }
 197 
 198 IMAGE_SURFACE_INLINE void copyBits(jint w, jint h, jint javaPixelsBytesPerRow, Pixel8bit *pixelsSrc, jint dstPixelsBytesPerRow, Pixel8bit *pixelsDst)
 199 {
 200 PRINT("    copyBits")
 201 
 202     if (javaPixelsBytesPerRow == dstPixelsBytesPerRow)
 203     {
 204         memcpy(pixelsDst, pixelsSrc, h*javaPixelsBytesPerRow);
 205     }
 206     else
 207     {
 208         register jint y;
 209         for (y=0; y<h; y++)
 210         {
 211             memcpy(pixelsDst, pixelsSrc, dstPixelsBytesPerRow);
 212 
 213             pixelsSrc += javaPixelsBytesPerRow;
 214             pixelsDst += dstPixelsBytesPerRow;
 215         }


 406 
 407             green = ((pixel >> 5) & 63);  // rrrrrggggggbbbbb => shift 5 right = 00000rrrrrgggggg => and 63 = 0000000000gggggg
 408             green = ((jint) (((CGFloat) green / 63.0f) * 31.0f)) & 31; // first normalize to value between 0 and 1 and then un-normalize to 5 bit (31 = 0000000000011111)
 409 
 410             *pixelsDst++ = ((pixel&0xf800)>>1) | (green << 5) | (pixel&0x01f);
 411         }
 412         pixelsSrc += skip;
 413 
 414         p8Bit = (Pixel8bit *) pixelsDst;
 415         p8Bit += extraBytesPerRow;
 416         pixelsDst = (Pixel16bit *) p8Bit;
 417     }
 418 }
 419 
 420 
 421 IMAGE_SURFACE_INLINE void customPixelsToJava(JNIEnv *env, ImageSDOps *isdo)
 422 {
 423 PRINT("    customPixelsToJava")
 424 
 425     SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
 426     JNFCallVoidMethod(env, sdo->sdObject, jm_syncToCustom); // AWT_THREADING Safe (known object)



 427 }
 428 
 429 IMAGE_SURFACE_INLINE void removeAlphaPre_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
 430 {
 431 PRINT("    removeAlphaPre_32bit")
 432 
 433     register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
 434     register Pixel32bit pixel, alpha, red, green, blue;
 435     register jint x, y;
 436 
 437     for (y=0; y<h; y++)
 438     {
 439         for (x=0; x<w; x++)
 440         {
 441             pixel = *pixelsSrc;
 442 
 443             alpha        = (pixel >> 24) & 0xff;
 444 
 445             if (alpha != 0)
 446             {


1223                 break;
1224             default:
1225                 break;
1226         }
1227     }
1228     else
1229     {
1230         processPixels(isdo, 0, 0, isdo->width, isdo->height, &syncToJavaPixels_processPixelsCallback);
1231     }
1232 
1233     unholdJavaPixels(env, isdo);
1234 }
1235 
1236 
1237 IMAGE_SURFACE_INLINE jboolean xorSurfacePixels(JNIEnv *env, jobject dstIsd, jobject srcIsd, jint colorXOR, jint x, jint y, jint w, jint h)
1238 {
1239 PRINT("xorSurfacePixels")
1240 
1241     jboolean handled = JNI_FALSE;
1242 
1243 JNF_COCOA_ENTER(env);
1244     ImageSDOps* srcIsdo = LockImagePixels(env, srcIsd);
1245     ImageSDOps* dstIsdo = LockImagePixels(env, dstIsd);
1246 
1247     if ((x < 0) || (y < 0) || (x+w > dstIsdo->width) || (y+h > dstIsdo->height) || (w > srcIsdo->width) || (h > srcIsdo->height))
1248     {
1249 #ifdef PRINT_WARNINGS
1250 fprintf(stderr, "xorSurfacePixels INVALID parameters: x=%d, y=%d, w=%d, h=%d\n", x, y, w, h);
1251 fprintf(stderr, "   dstIsdo->width=%d, dstIsdo->height=%d, biqsdoPixels->width=%d, biqsdoPixels->height=%d\n",
1252                         dstIsdo->width, dstIsdo->height, srcIsdo->width, srcIsdo->height);
1253 #endif
1254         UnlockImagePixels(env, srcIsdo);
1255         UnlockImagePixels(env, dstIsdo);
1256 
1257         return JNI_FALSE;
1258     }
1259 
1260     jint offset = (dstIsdo->width*y)+x;
1261     register Pixel32bit* dstPixels = (Pixel32bit*)dstIsdo->pixels;
1262     register jint skip = dstIsdo->width - w;
1263     register Pixel32bit* srcPixels = (Pixel32bit*)srcIsdo->pixels;


1302                 dstPixels += skip;
1303                 srcPixels += skipPixels;
1304             }
1305 
1306             handled = JNI_TRUE;
1307             break;
1308         }
1309         default:
1310         {
1311             handled = JNI_FALSE;
1312 #if defined(PRINT_WARNINGS)
1313             fprintf(stderr, "WARNING: unknown type (%d) in compositeXOR\n", dstIsdo->type);
1314             PrintImageInfo(dstIsdo);
1315 #endif
1316         }
1317     }
1318 
1319     UnlockImagePixels(env, srcIsdo);
1320     UnlockImagePixels(env, dstIsdo);
1321 
1322 JNF_COCOA_EXIT(env);
1323     return handled;
1324 }
1325 
1326 IMAGE_SURFACE_INLINE jboolean clearSurfacePixels(JNIEnv *env, jobject bisd, jint w, jint h)
1327 {
1328 PRINT("clearSurfacePixels")
1329     jboolean handled = JNI_FALSE;
1330 
1331 JNF_COCOA_ENTER(env);
1332 
1333     ImageSDOps *isdo = LockImagePixels(env, bisd);
1334 
1335     if (isdo->type == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)
1336     {
1337         isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
1338 
1339         w = (w < isdo->width) ? w : isdo->width;
1340         h = (h < isdo->height) ? h : isdo->height;
1341 
1342         register Pixel32bit* data = (Pixel32bit*)isdo->pixels;
1343         register jint i;
1344         if ((w < isdo->width) || (h < isdo->height)) //cmcnote: necessary to special-case for small height? wouldn't 4*w*h do it?
1345         {
1346             register jint skip = isdo->width;
1347             register jint row = 4*w;
1348             for (i=0; i<h; i++)
1349             {
1350                 bzero(data, row);
1351                 data += skip;
1352             }
1353         }
1354         else
1355         {
1356             bzero(data, 4*w*h);
1357         }
1358 
1359         handled = JNI_TRUE;
1360     }
1361     UnlockImagePixels(env, isdo);
1362 
1363 JNF_COCOA_EXIT(env);
1364 
1365     return handled;
1366 }
1367 
1368 static void ImageSD_startCGContext(JNIEnv *env, QuartzSDOps *qsdo, SDRenderType renderType)
1369 {
1370 PRINT("ImageSD_startCGContext")
1371 
1372     ImageSDOps *isdo = (ImageSDOps*)qsdo;
1373 
1374     pthread_mutex_lock(&isdo->lock);
1375 
1376     if (isdo->imgRef != NULL)
1377     {
1378         CGImageRelease(isdo->imgRef);
1379         isdo->imgRef = NULL;
1380     }
1381 
1382     if (qsdo->cgRef == NULL)
1383     {


1434     {
1435         /* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */
1436         BufImgSDOps *bisdo = (BufImgSDOps *)ops;
1437         (*env)->DeleteWeakGlobalRef(env, bisdo->array);
1438         if (bisdo->lutarray != NULL) {
1439         (*env)->DeleteWeakGlobalRef(env, bisdo->lutarray);
1440         }
1441         if (bisdo->icm != NULL) {
1442         (*env)->DeleteWeakGlobalRef(env, bisdo->icm);
1443         }
1444     }
1445 
1446     QuartzSDOps *qsdo = (QuartzSDOps *)ops;
1447 
1448     if (qsdo->graphicsStateInfo.batchedLines != NULL)
1449     {
1450         free(qsdo->graphicsStateInfo.batchedLines);
1451         qsdo->graphicsStateInfo.batchedLines = NULL;
1452     }
1453 
1454     JNFDeleteGlobalRef(env, qsdo->javaGraphicsStatesObjects);
1455 
1456     if (qsdo->cgRef != NULL)
1457     {
1458         CGContextRelease(qsdo->cgRef);
1459         qsdo->cgRef = NULL;
1460     }
1461 
1462     ImageSDOps *isdo = (ImageSDOps *)ops;
1463 
1464     if (isdo->dataProvider != NULL)
1465     {
1466         CGDataProviderRelease(isdo->dataProvider);
1467         isdo->dataProvider = NULL;
1468     }
1469     if (isdo->imgRef != NULL)
1470     {
1471         CGImageRelease(isdo->imgRef);
1472         isdo->imgRef = NULL;
1473     }
1474     if (isdo->indexedColorTable != NULL)
1475     {
1476         free(isdo->indexedColorTable);
1477         isdo->indexedColorTable = NULL;
1478     }
1479     if (isdo->lutData != NULL)
1480     {
1481         free(isdo->lutData);
1482         isdo->indexedColorTable = NULL;
1483     }
1484     if (isdo->array != NULL)
1485     {
1486         JNFDeleteGlobalRef(env, isdo->array);
1487         isdo->array = NULL;
1488     }
1489     if (isdo->icm != NULL)
1490     {
1491         JNFDeleteGlobalRef(env, isdo->icm);
1492         isdo->icm = NULL;
1493     }
1494 
1495     if (isdo->nsRef) {
1496         [isdo->nsRef release];
1497         isdo->nsRef = nil;
1498     }
1499 
1500     pthread_mutex_destroy(&isdo->lock);
1501 }
1502 
1503 // used by XOR (Java pixels must be up to date)
1504 ImageSDOps* LockImagePixels(JNIEnv* env, jobject imageSurfaceData)
1505 {
1506 PRINT("LockImagePixels")
1507 
1508     ImageSDOps* isdo = (ImageSDOps*)SurfaceData_GetOps(env, imageSurfaceData);
1509 
1510     pthread_mutex_lock(&isdo->lock);
1511 


1605         static char *icmName = "java/awt/image/IndexColorModel";
1606         jclass icm;
1607 
1608         if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
1609         JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
1610         return;
1611         }
1612 
1613         CHECK_NULL(icm = (*env)->FindClass(env, icmName));
1614         CHECK_NULL(rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I"));
1615         CHECK_NULL(allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z"));
1616         CHECK_NULL(mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I"));
1617         CHECK_NULL(CMpDataID = (*env)->GetFieldID(env, icm, "pData", "J"));
1618     }
1619 
1620     gColorspaceRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
1621     gColorspaceGray = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
1622 //fprintf(stderr, "gColorspaceRGB=%p, gColorspaceGray=%p\n", gColorspaceRGB, gColorspaceGray);
1623 }
1624 



1625 JNIEXPORT jobject JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_getSurfaceData
1626     (JNIEnv *env, jclass bisd, jobject bufImg)
1627 {
1628 PRINT("getSurfaceData")
1629 
1630     return JNFGetObjectField(env, bufImg, jm_SurfaceData);

1631 }
1632 
1633 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_setSurfaceData
1634     (JNIEnv *env, jclass bisd, jobject bufImg, jobject sData)
1635 {
1636 PRINT("setSurfaceData")
1637 
1638     JNFSetObjectField(env, bufImg, jm_SurfaceData, sData);


1639 }
1640 
1641 static jint ImageSD_Lock(JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo, jint lockflags)
1642 {
1643     ImageSDOps *isdo = (ImageSDOps*)ops;
1644     pthread_mutex_lock(&isdo->lock);
1645 
1646     // copied from BufImg_Lock in BufImgSurfaceData.c
1647     {
1648         BufImgSDOps *bisdo = (BufImgSDOps *)ops;
1649         BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
1650 
1651         if ((lockflags & (SD_LOCK_LUT)) != 0 && !bisdo->lutarray) {
1652             /* REMIND: Should this be an InvalidPipe exception? */
1653             JNU_ThrowNullPointerException(env, "Attempt to lock missing colormap");
1654             return SD_FAILURE;
1655         }
1656 // TODO:BG
1657         /*
1658         if ((lockflags & SD_LOCK_INVCOLOR) != 0 ||


1824     isdo->contextInfo.bytesPerRow        = width*isdo->contextInfo.bytesPerPixel;
1825     isdo->imageInfo.bytesPerRow            = width*isdo->imageInfo.bytesPerPixel;
1826 
1827     switch (type)
1828     {
1829         case java_awt_image_BufferedImage_TYPE_BYTE_GRAY:
1830             isdo->contextInfo.colorSpace = isdo->imageInfo.colorSpace = gColorspaceGray;
1831             break;
1832         case java_awt_image_BufferedImage_TYPE_USHORT_GRAY:
1833             isdo->contextInfo.colorSpace = gColorspaceRGB;
1834             isdo->imageInfo.colorSpace = gColorspaceGray;
1835             break;
1836         default:
1837             isdo->contextInfo.colorSpace = isdo->imageInfo.colorSpace = gColorspaceRGB;
1838             break;
1839     }
1840     isdo->isSubImage                    = (offset%scanStride != 0) || (scanStride != (pixelStride*width));
1841 
1842     // parameters specifying this image given to us from Java
1843     isdo->javaImageInfo                    = (jint*)((*env)->GetDirectBufferAddress(env, jImageInfo));
1844     isdo->array                            = (array != NULL) ? JNFNewGlobalRef(env, array) : NULL;
1845     isdo->offset                        = offset;
1846     isdo->width                            = width;
1847     isdo->height                        = height;
1848     isdo->javaPixelBytes                = pixelStride;
1849     isdo->javaPixelsBytesPerRow            = scanStride;
1850     isdo->icm                            = (icm != NULL) ? JNFNewGlobalRef(env, icm) : NULL;
1851     isdo->type                            = type;
1852 
1853     if ((isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kImageStolenIndex] == 1) ||
1854         (isdo->type == java_awt_image_BufferedImage_TYPE_CUSTOM))
1855     {
1856         // don't waste (precious, precious) VRAM on stolen or custom images that will be slow no matter what
1857         isdo->contextInfo.useWindowContextReference = NO;
1858     }
1859 
1860     // needed by TYPE_BYTE_INDEXED
1861     isdo->indexedColorTable                = NULL;
1862     isdo->lutData                        = NULL;
1863     isdo->lutDataSize                    = 0;
1864     if ((type == java_awt_image_BufferedImage_TYPE_BYTE_INDEXED) && ((*env)->IsSameObject(env, icm, NULL) == NO))
1865     {
1866         jarray lutarray = JNFGetObjectField(env, icm, jm_rgb);









1867         isdo->lutDataSize = (*env)->GetArrayLength(env, lutarray);
1868         if (isdo->lutDataSize > 0)
1869         {
1870             jint transparency = JNFGetIntField(env, icm, jm_transparency);
1871             jint transparent_index = -1;
1872             if (transparency == java_awt_Transparency_BITMASK)
1873             {
1874                 transparent_index = JNFGetIntField(env, icm, jm_transparent_index);
1875             }
1876 
1877             Pixel32bit* lutdata = (Pixel32bit*)((*env)->GetPrimitiveArrayCritical(env, lutarray, NULL));
1878             if (lutdata != NULL)
1879             {
1880                 isdo->lutData = NULL;
1881 
1882                 isdo->lutData = malloc(isdo->lutDataSize * sizeof(Pixel32bit));
1883                 if (isdo->lutData != NULL)
1884                 {
1885                     if (transparency == java_awt_Transparency_BITMASK)
1886                     {
1887                         Pixel32bit* src = lutdata;
1888                         Pixel32bit* dst = isdo->lutData;
1889                         jint i;
1890                         for (i=0; (unsigned)i<isdo->lutDataSize; i++)
1891                         {
1892                             if (i != transparent_index)
1893                             {
1894                                 *dst = *src;


1929                     (*env)->ReleasePrimitiveArrayCritical(env, lutarray, lutdata, 0);
1930                 }
1931                 else
1932                 {
1933                     fprintf(stderr, "ERROR: malloc returns NULL for isdo->lutData in initRaster!\n");
1934                 }
1935             }
1936             else
1937             {
1938                 fprintf(stderr, "ERROR: GetPrimitiveArrayCritical returns NULL for lutdata in initRaster!\n");
1939             }
1940         }
1941         (*env)->DeleteLocalRef(env, lutarray);
1942     }
1943 
1944     QuartzSDOps *qsdo = (QuartzSDOps*)isdo;
1945     qsdo->BeginSurface                    = ImageSD_startCGContext;
1946     qsdo->FinishSurface                    = ImageSD_finishCGContext;
1947 
1948     qsdo->javaGraphicsStates            = (jint*)((*env)->GetDirectBufferAddress(env, jGraphicsState));
1949     qsdo->javaGraphicsStatesObjects        = JNFNewGlobalRef(env, jGraphicsStateObject);
1950 
1951     qsdo->graphicsStateInfo.batchedLines = NULL;
1952     qsdo->graphicsStateInfo.batchedLinesCount = 0;
1953 
1954     SurfaceDataOps *sdo = (SurfaceDataOps*)qsdo;
1955     sdo->Lock        = ImageSD_Lock;
1956     sdo->Unlock        = ImageSD_Unlock;
1957     sdo->GetRasInfo    = ImageSD_GetRasInfo;
1958     sdo->Release    = ImageSD_Release;
1959     sdo->Setup        = NULL;
1960     sdo->Dispose    = ImageSD_dispose;
1961 
1962     pthread_mutex_unlock(&isdo->lock);
1963 
1964 //PrintImageInfo(isdo);
1965 }
1966 
1967 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_initCustomRaster(JNIEnv* env, jobject bisd, jobject array, jint width, jint height,
1968                                                                                     jobject jGraphicsState, jobject jGraphicsStateObject, jobject jImageInfo)
1969 {




  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 #import "ImageSurfaceData.h"
  27 
  28 #import "java_awt_Transparency.h"
  29 #import "java_awt_image_BufferedImage.h"
  30 #import "sun_awt_image_BufImgSurfaceData.h"
  31 #import "sun_java2d_OSXOffScreenSurfaceData.h"
  32 
  33 #import "ThreadUtilities.h"
  34 #import "JNIUtilities.h"
  35 
  36 #import "BufImgSurfaceData.h"
  37 
  38 //#define DEBUG 1
  39 #if defined DEBUG
  40     #define IMAGE_SURFACE_INLINE
  41     #define PRINT(msg) {fprintf(stderr, "%s\n", msg);fflush(stderr);}
  42 #else
  43     #define IMAGE_SURFACE_INLINE static inline
  44     #define PRINT(msg) {}
  45 #endif
  46 
  47 // same value as defined in Sun's own code
  48 #define XOR_ALPHA_CUTOFF 128
  49 
  50 // for vImage framework headers
  51 #include <Accelerate/Accelerate.h>
  52 
  53 static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] =
  54 {


  86     {8,        32,        4,        0,        kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,    NULL},    // TYPE_4BYTE_ABGR_PRE
  87 #ifdef __LITTLE_ENDIAN__
  88     {5,        16,        2,        0,        kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Host,        NULL},    // TYPE_USHORT_565_RGB
  89     {5,        16,        2,        0,        kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Host,        NULL},    // TYPE_USHORT_555_RGB
  90 #else
  91     {5,        16,        2,        0,        kCGImageAlphaNoneSkipFirst,                                    NULL},    // TYPE_USHORT_565_RGB
  92     {5,        16,        2,        0,        kCGImageAlphaNoneSkipFirst,                                    NULL},    // TYPE_USHORT_555_RGB
  93 #endif
  94     {8,        8,        1,        0,        kCGImageAlphaNone,                                            NULL},    // TYPE_BYTE_GRAY
  95     {16,    16,        2,        0,        kCGImageAlphaNone | kCGBitmapByteOrder16Host,                NULL},    // TYPE_USHORT_GRAY
  96     {0,        0,        0,        0,        -1,                                                            NULL},    // TYPE_BYTE_BINARY        mapped to TYPE_CUSTOM
  97     {8,        32,        4,        0,        kCGImageAlphaFirst | kCGBitmapByteOrder32Host,                NULL},    // TYPE_BYTE_INDEXED  // Fully OPAQUE INDEXED images will use kCGImageAlphaNoneSkipFirst for performance reasosn. see <rdar://4224874>
  98     {8,        32,        4,        0,        kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host,        NULL},    // TYPE_3BYTE_RGB
  99 };
 100 
 101 static jfieldID        rgbID;
 102 static jfieldID        mapSizeID;
 103 static jfieldID        CMpDataID;
 104 static jfieldID        allGrayID;
 105 
 106 static jclass jc_OSXOffScreenSurfaceData = NULL;
 107 #define GET_OSXOSD_CLASS() \
 108     GET_CLASS(jc_OSXOffScreenSurfaceData, "sun/java2d/OSXOffScreenSurfaceData");







 109 
 110 CGColorSpaceRef gColorspaceRGB = NULL;
 111 CGColorSpaceRef gColorspaceGray = NULL;
 112 
 113 IMAGE_SURFACE_INLINE void PrintImageInfo(ImageSDOps* isdo)
 114 {
 115     fprintf(stderr, "\n");
 116     fprintf(stderr, "PrintImageInfo:\n");
 117     fprintf(stderr, "\t \n");
 118     //fprintf(stderr, "\t magicID=%d\n", (jint)isdo->magicID);
 119     //fprintf(stderr, "\n");
 120     fprintf(stderr, "\t isdo=%p\n", isdo);
 121     fprintf(stderr, "\t \n");
 122     fprintf(stderr, "\t contextInfo:\n");
 123     fprintf(stderr, "\t        useWindowContextReference=%d\n", isdo->contextInfo.useWindowContextReference);
 124     fprintf(stderr, "\t        canUseJavaPixelsAsContext=%d\n", isdo->contextInfo.canUseJavaPixelsAsContext);
 125     fprintf(stderr, "\t        bitsPerComponent=%ld\n", (long)isdo->contextInfo.bitsPerComponent);
 126     fprintf(stderr, "\t        bytesPerPixel=%ld\n", (long)isdo->contextInfo.bytesPerPixel);
 127     fprintf(stderr, "\t        bytesPerRow=%ld\n", (long)isdo->contextInfo.bytesPerRow);
 128     fprintf(stderr, "\t        alphaInfo=%ld\n", (long)isdo->contextInfo.alphaInfo);


 168     {
 169         isdo->imgRef = CGImageCreate(isdo->width,
 170                                       isdo->height,
 171                                       isdo->contextInfo.bitsPerComponent,
 172                                       isdo->contextInfo.bytesPerPixel * 8,
 173                                       isdo->contextInfo.bytesPerRow,
 174                                       isdo->contextInfo.colorSpace,
 175                                       isdo->contextInfo.alphaInfo,
 176                                       isdo->dataProvider,
 177                                       NULL,
 178                                       NO,
 179                                       kCGRenderingIntentDefault);
 180     }
 181 }
 182 
 183 IMAGE_SURFACE_INLINE void customPixelsFromJava(JNIEnv *env, ImageSDOps *isdo)
 184 {
 185 PRINT("    customPixelsFromJava")
 186 
 187     SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
 188     GET_OSXOSD_CLASS();
 189     DECLARE_METHOD(jm_syncFromCustom, jc_OSXOffScreenSurfaceData, "syncFromCustom", "()V");
 190 
 191     (*env)->CallVoidMethod(env, sdo->sdObject, jm_syncFromCustom); // AWT_THREADING Safe (known object)
 192     CHECK_EXCEPTION();
 193 }
 194 
 195 IMAGE_SURFACE_INLINE void copyBits(jint w, jint h, jint javaPixelsBytesPerRow, Pixel8bit *pixelsSrc, jint dstPixelsBytesPerRow, Pixel8bit *pixelsDst)
 196 {
 197 PRINT("    copyBits")
 198 
 199     if (javaPixelsBytesPerRow == dstPixelsBytesPerRow)
 200     {
 201         memcpy(pixelsDst, pixelsSrc, h*javaPixelsBytesPerRow);
 202     }
 203     else
 204     {
 205         register jint y;
 206         for (y=0; y<h; y++)
 207         {
 208             memcpy(pixelsDst, pixelsSrc, dstPixelsBytesPerRow);
 209 
 210             pixelsSrc += javaPixelsBytesPerRow;
 211             pixelsDst += dstPixelsBytesPerRow;
 212         }


 403 
 404             green = ((pixel >> 5) & 63);  // rrrrrggggggbbbbb => shift 5 right = 00000rrrrrgggggg => and 63 = 0000000000gggggg
 405             green = ((jint) (((CGFloat) green / 63.0f) * 31.0f)) & 31; // first normalize to value between 0 and 1 and then un-normalize to 5 bit (31 = 0000000000011111)
 406 
 407             *pixelsDst++ = ((pixel&0xf800)>>1) | (green << 5) | (pixel&0x01f);
 408         }
 409         pixelsSrc += skip;
 410 
 411         p8Bit = (Pixel8bit *) pixelsDst;
 412         p8Bit += extraBytesPerRow;
 413         pixelsDst = (Pixel16bit *) p8Bit;
 414     }
 415 }
 416 
 417 
 418 IMAGE_SURFACE_INLINE void customPixelsToJava(JNIEnv *env, ImageSDOps *isdo)
 419 {
 420 PRINT("    customPixelsToJava")
 421 
 422     SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
 423     GET_OSXOSD_CLASS();
 424     DECLARE_METHOD(jm_syncToCustom, jc_OSXOffScreenSurfaceData, "syncToCustom", "()V");
 425     (*env)->CallVoidMethod(env, sdo->sdObject, jm_syncToCustom); // AWT_THREADING Safe (known object)
 426     CHECK_EXCEPTION();
 427 }
 428 
 429 IMAGE_SURFACE_INLINE void removeAlphaPre_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
 430 {
 431 PRINT("    removeAlphaPre_32bit")
 432 
 433     register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
 434     register Pixel32bit pixel, alpha, red, green, blue;
 435     register jint x, y;
 436 
 437     for (y=0; y<h; y++)
 438     {
 439         for (x=0; x<w; x++)
 440         {
 441             pixel = *pixelsSrc;
 442 
 443             alpha        = (pixel >> 24) & 0xff;
 444 
 445             if (alpha != 0)
 446             {


1223                 break;
1224             default:
1225                 break;
1226         }
1227     }
1228     else
1229     {
1230         processPixels(isdo, 0, 0, isdo->width, isdo->height, &syncToJavaPixels_processPixelsCallback);
1231     }
1232 
1233     unholdJavaPixels(env, isdo);
1234 }
1235 
1236 
1237 IMAGE_SURFACE_INLINE jboolean xorSurfacePixels(JNIEnv *env, jobject dstIsd, jobject srcIsd, jint colorXOR, jint x, jint y, jint w, jint h)
1238 {
1239 PRINT("xorSurfacePixels")
1240 
1241     jboolean handled = JNI_FALSE;
1242 
1243 JNI_COCOA_ENTER(env);
1244     ImageSDOps* srcIsdo = LockImagePixels(env, srcIsd);
1245     ImageSDOps* dstIsdo = LockImagePixels(env, dstIsd);
1246 
1247     if ((x < 0) || (y < 0) || (x+w > dstIsdo->width) || (y+h > dstIsdo->height) || (w > srcIsdo->width) || (h > srcIsdo->height))
1248     {
1249 #ifdef PRINT_WARNINGS
1250 fprintf(stderr, "xorSurfacePixels INVALID parameters: x=%d, y=%d, w=%d, h=%d\n", x, y, w, h);
1251 fprintf(stderr, "   dstIsdo->width=%d, dstIsdo->height=%d, biqsdoPixels->width=%d, biqsdoPixels->height=%d\n",
1252                         dstIsdo->width, dstIsdo->height, srcIsdo->width, srcIsdo->height);
1253 #endif
1254         UnlockImagePixels(env, srcIsdo);
1255         UnlockImagePixels(env, dstIsdo);
1256 
1257         return JNI_FALSE;
1258     }
1259 
1260     jint offset = (dstIsdo->width*y)+x;
1261     register Pixel32bit* dstPixels = (Pixel32bit*)dstIsdo->pixels;
1262     register jint skip = dstIsdo->width - w;
1263     register Pixel32bit* srcPixels = (Pixel32bit*)srcIsdo->pixels;


1302                 dstPixels += skip;
1303                 srcPixels += skipPixels;
1304             }
1305 
1306             handled = JNI_TRUE;
1307             break;
1308         }
1309         default:
1310         {
1311             handled = JNI_FALSE;
1312 #if defined(PRINT_WARNINGS)
1313             fprintf(stderr, "WARNING: unknown type (%d) in compositeXOR\n", dstIsdo->type);
1314             PrintImageInfo(dstIsdo);
1315 #endif
1316         }
1317     }
1318 
1319     UnlockImagePixels(env, srcIsdo);
1320     UnlockImagePixels(env, dstIsdo);
1321 
1322 JNI_COCOA_EXIT(env);
1323     return handled;
1324 }
1325 
1326 IMAGE_SURFACE_INLINE jboolean clearSurfacePixels(JNIEnv *env, jobject bisd, jint w, jint h)
1327 {
1328 PRINT("clearSurfacePixels")
1329     jboolean handled = JNI_FALSE;
1330 
1331 JNI_COCOA_ENTER(env);
1332 
1333     ImageSDOps *isdo = LockImagePixels(env, bisd);
1334 
1335     if (isdo->type == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)
1336     {
1337         isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
1338 
1339         w = (w < isdo->width) ? w : isdo->width;
1340         h = (h < isdo->height) ? h : isdo->height;
1341 
1342         register Pixel32bit* data = (Pixel32bit*)isdo->pixels;
1343         register jint i;
1344         if ((w < isdo->width) || (h < isdo->height)) //cmcnote: necessary to special-case for small height? wouldn't 4*w*h do it?
1345         {
1346             register jint skip = isdo->width;
1347             register jint row = 4*w;
1348             for (i=0; i<h; i++)
1349             {
1350                 bzero(data, row);
1351                 data += skip;
1352             }
1353         }
1354         else
1355         {
1356             bzero(data, 4*w*h);
1357         }
1358 
1359         handled = JNI_TRUE;
1360     }
1361     UnlockImagePixels(env, isdo);
1362 
1363 JNI_COCOA_EXIT(env);
1364 
1365     return handled;
1366 }
1367 
1368 static void ImageSD_startCGContext(JNIEnv *env, QuartzSDOps *qsdo, SDRenderType renderType)
1369 {
1370 PRINT("ImageSD_startCGContext")
1371 
1372     ImageSDOps *isdo = (ImageSDOps*)qsdo;
1373 
1374     pthread_mutex_lock(&isdo->lock);
1375 
1376     if (isdo->imgRef != NULL)
1377     {
1378         CGImageRelease(isdo->imgRef);
1379         isdo->imgRef = NULL;
1380     }
1381 
1382     if (qsdo->cgRef == NULL)
1383     {


1434     {
1435         /* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */
1436         BufImgSDOps *bisdo = (BufImgSDOps *)ops;
1437         (*env)->DeleteWeakGlobalRef(env, bisdo->array);
1438         if (bisdo->lutarray != NULL) {
1439         (*env)->DeleteWeakGlobalRef(env, bisdo->lutarray);
1440         }
1441         if (bisdo->icm != NULL) {
1442         (*env)->DeleteWeakGlobalRef(env, bisdo->icm);
1443         }
1444     }
1445 
1446     QuartzSDOps *qsdo = (QuartzSDOps *)ops;
1447 
1448     if (qsdo->graphicsStateInfo.batchedLines != NULL)
1449     {
1450         free(qsdo->graphicsStateInfo.batchedLines);
1451         qsdo->graphicsStateInfo.batchedLines = NULL;
1452     }
1453 
1454     (*env)->DeleteGlobalRef(env, qsdo->javaGraphicsStatesObjects);
1455 
1456     if (qsdo->cgRef != NULL)
1457     {
1458         CGContextRelease(qsdo->cgRef);
1459         qsdo->cgRef = NULL;
1460     }
1461 
1462     ImageSDOps *isdo = (ImageSDOps *)ops;
1463 
1464     if (isdo->dataProvider != NULL)
1465     {
1466         CGDataProviderRelease(isdo->dataProvider);
1467         isdo->dataProvider = NULL;
1468     }
1469     if (isdo->imgRef != NULL)
1470     {
1471         CGImageRelease(isdo->imgRef);
1472         isdo->imgRef = NULL;
1473     }
1474     if (isdo->indexedColorTable != NULL)
1475     {
1476         free(isdo->indexedColorTable);
1477         isdo->indexedColorTable = NULL;
1478     }
1479     if (isdo->lutData != NULL)
1480     {
1481         free(isdo->lutData);
1482         isdo->indexedColorTable = NULL;
1483     }
1484     if (isdo->array != NULL)
1485     {
1486         (*env)->DeleteGlobalRef(env, isdo->array);
1487         isdo->array = NULL;
1488     }
1489     if (isdo->icm != NULL)
1490     {
1491         (*env)->DeleteGlobalRef(env, isdo->icm);
1492         isdo->icm = NULL;
1493     }
1494 
1495     if (isdo->nsRef) {
1496         [isdo->nsRef release];
1497         isdo->nsRef = nil;
1498     }
1499 
1500     pthread_mutex_destroy(&isdo->lock);
1501 }
1502 
1503 // used by XOR (Java pixels must be up to date)
1504 ImageSDOps* LockImagePixels(JNIEnv* env, jobject imageSurfaceData)
1505 {
1506 PRINT("LockImagePixels")
1507 
1508     ImageSDOps* isdo = (ImageSDOps*)SurfaceData_GetOps(env, imageSurfaceData);
1509 
1510     pthread_mutex_lock(&isdo->lock);
1511 


1605         static char *icmName = "java/awt/image/IndexColorModel";
1606         jclass icm;
1607 
1608         if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
1609         JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
1610         return;
1611         }
1612 
1613         CHECK_NULL(icm = (*env)->FindClass(env, icmName));
1614         CHECK_NULL(rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I"));
1615         CHECK_NULL(allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z"));
1616         CHECK_NULL(mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I"));
1617         CHECK_NULL(CMpDataID = (*env)->GetFieldID(env, icm, "pData", "J"));
1618     }
1619 
1620     gColorspaceRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
1621     gColorspaceGray = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
1622 //fprintf(stderr, "gColorspaceRGB=%p, gColorspaceGray=%p\n", gColorspaceRGB, gColorspaceGray);
1623 }
1624 
1625 static jclass jc_BufferedImage = NULL;
1626 static jfieldID jm_SurfaceData = NULL;
1627 
1628 JNIEXPORT jobject JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_getSurfaceData
1629     (JNIEnv *env, jclass bisd, jobject bufImg)
1630 {
1631 PRINT("getSurfaceData")
1632     GET_CLASS_RETURN(jc_BufferedImage, "java/awt/image/BufferedImage", NULL);
1633     GET_FIELD_RETURN(jm_SurfaceData, jc_BufferedImage, "sData", "Lsun/java2d/SurfaceData;", NULL);
1634     return (*env)->GetObjectField(env, bufImg, jm_SurfaceData);
1635 }
1636 
1637 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_setSurfaceData
1638     (JNIEnv *env, jclass bisd, jobject bufImg, jobject sData)
1639 {
1640 PRINT("setSurfaceData")
1641 
1642     GET_CLASS(jc_BufferedImage, "java/awt/image/BufferedImage");
1643     GET_FIELD(jm_SurfaceData, jc_BufferedImage, "sData", "Lsun/java2d/SurfaceData;");
1644     (*env)->SetObjectField(env, bufImg, jm_SurfaceData, sData);
1645 }
1646 
1647 static jint ImageSD_Lock(JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo, jint lockflags)
1648 {
1649     ImageSDOps *isdo = (ImageSDOps*)ops;
1650     pthread_mutex_lock(&isdo->lock);
1651 
1652     // copied from BufImg_Lock in BufImgSurfaceData.c
1653     {
1654         BufImgSDOps *bisdo = (BufImgSDOps *)ops;
1655         BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
1656 
1657         if ((lockflags & (SD_LOCK_LUT)) != 0 && !bisdo->lutarray) {
1658             /* REMIND: Should this be an InvalidPipe exception? */
1659             JNU_ThrowNullPointerException(env, "Attempt to lock missing colormap");
1660             return SD_FAILURE;
1661         }
1662 // TODO:BG
1663         /*
1664         if ((lockflags & SD_LOCK_INVCOLOR) != 0 ||


1830     isdo->contextInfo.bytesPerRow        = width*isdo->contextInfo.bytesPerPixel;
1831     isdo->imageInfo.bytesPerRow            = width*isdo->imageInfo.bytesPerPixel;
1832 
1833     switch (type)
1834     {
1835         case java_awt_image_BufferedImage_TYPE_BYTE_GRAY:
1836             isdo->contextInfo.colorSpace = isdo->imageInfo.colorSpace = gColorspaceGray;
1837             break;
1838         case java_awt_image_BufferedImage_TYPE_USHORT_GRAY:
1839             isdo->contextInfo.colorSpace = gColorspaceRGB;
1840             isdo->imageInfo.colorSpace = gColorspaceGray;
1841             break;
1842         default:
1843             isdo->contextInfo.colorSpace = isdo->imageInfo.colorSpace = gColorspaceRGB;
1844             break;
1845     }
1846     isdo->isSubImage                    = (offset%scanStride != 0) || (scanStride != (pixelStride*width));
1847 
1848     // parameters specifying this image given to us from Java
1849     isdo->javaImageInfo                    = (jint*)((*env)->GetDirectBufferAddress(env, jImageInfo));
1850     isdo->array                            = (array != NULL) ? (*env)->NewGlobalRef(env, array) : NULL;
1851     isdo->offset                        = offset;
1852     isdo->width                            = width;
1853     isdo->height                        = height;
1854     isdo->javaPixelBytes                = pixelStride;
1855     isdo->javaPixelsBytesPerRow            = scanStride;
1856     isdo->icm                            = (icm != NULL) ? (*env)->NewGlobalRef(env, icm) : NULL;
1857     isdo->type                            = type;
1858 
1859     if ((isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kImageStolenIndex] == 1) ||
1860         (isdo->type == java_awt_image_BufferedImage_TYPE_CUSTOM))
1861     {
1862         // don't waste (precious, precious) VRAM on stolen or custom images that will be slow no matter what
1863         isdo->contextInfo.useWindowContextReference = NO;
1864     }
1865 
1866     // needed by TYPE_BYTE_INDEXED
1867     isdo->indexedColorTable                = NULL;
1868     isdo->lutData                        = NULL;
1869     isdo->lutDataSize                    = 0;
1870     if ((type == java_awt_image_BufferedImage_TYPE_BYTE_INDEXED) && ((*env)->IsSameObject(env, icm, NULL) == NO))
1871     {
1872         static jclass jc_IndexColorModel = NULL;
1873         if (jc_IndexColorModel == NULL) {
1874             jc_IndexColorModel = (*env)->FindClass(env, "java/awt/image/IndexColorModel");
1875         }
1876         CHECK_NULL(jc_IndexColorModel);
1877         DECLARE_FIELD(jm_rgb, jc_IndexColorModel, "rgb", "[I");
1878         DECLARE_FIELD(jm_transparency, jc_IndexColorModel, "transparency", "I");
1879         DECLARE_FIELD(jm_transparent_index, jc_IndexColorModel, "transparent_index", "I");
1880 
1881         jarray lutarray = (*env)->GetObjectField(env, icm, jm_rgb);
1882         isdo->lutDataSize = (*env)->GetArrayLength(env, lutarray);
1883         if (isdo->lutDataSize > 0)
1884         {
1885             jint transparency = (*env)->GetIntField(env, icm, jm_transparency);
1886             jint transparent_index = -1;
1887             if (transparency == java_awt_Transparency_BITMASK)
1888             {
1889                 transparent_index = (*env)->GetIntField(env, icm, jm_transparent_index);
1890             }
1891 
1892             Pixel32bit* lutdata = (Pixel32bit*)((*env)->GetPrimitiveArrayCritical(env, lutarray, NULL));
1893             if (lutdata != NULL)
1894             {
1895                 isdo->lutData = NULL;
1896 
1897                 isdo->lutData = malloc(isdo->lutDataSize * sizeof(Pixel32bit));
1898                 if (isdo->lutData != NULL)
1899                 {
1900                     if (transparency == java_awt_Transparency_BITMASK)
1901                     {
1902                         Pixel32bit* src = lutdata;
1903                         Pixel32bit* dst = isdo->lutData;
1904                         jint i;
1905                         for (i=0; (unsigned)i<isdo->lutDataSize; i++)
1906                         {
1907                             if (i != transparent_index)
1908                             {
1909                                 *dst = *src;


1944                     (*env)->ReleasePrimitiveArrayCritical(env, lutarray, lutdata, 0);
1945                 }
1946                 else
1947                 {
1948                     fprintf(stderr, "ERROR: malloc returns NULL for isdo->lutData in initRaster!\n");
1949                 }
1950             }
1951             else
1952             {
1953                 fprintf(stderr, "ERROR: GetPrimitiveArrayCritical returns NULL for lutdata in initRaster!\n");
1954             }
1955         }
1956         (*env)->DeleteLocalRef(env, lutarray);
1957     }
1958 
1959     QuartzSDOps *qsdo = (QuartzSDOps*)isdo;
1960     qsdo->BeginSurface                    = ImageSD_startCGContext;
1961     qsdo->FinishSurface                    = ImageSD_finishCGContext;
1962 
1963     qsdo->javaGraphicsStates            = (jint*)((*env)->GetDirectBufferAddress(env, jGraphicsState));
1964     qsdo->javaGraphicsStatesObjects        = (*env)->NewGlobalRef(env, jGraphicsStateObject);
1965 
1966     qsdo->graphicsStateInfo.batchedLines = NULL;
1967     qsdo->graphicsStateInfo.batchedLinesCount = 0;
1968 
1969     SurfaceDataOps *sdo = (SurfaceDataOps*)qsdo;
1970     sdo->Lock        = ImageSD_Lock;
1971     sdo->Unlock        = ImageSD_Unlock;
1972     sdo->GetRasInfo    = ImageSD_GetRasInfo;
1973     sdo->Release    = ImageSD_Release;
1974     sdo->Setup        = NULL;
1975     sdo->Dispose    = ImageSD_dispose;
1976 
1977     pthread_mutex_unlock(&isdo->lock);
1978 
1979 //PrintImageInfo(isdo);
1980 }
1981 
1982 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_initCustomRaster(JNIEnv* env, jobject bisd, jobject array, jint width, jint height,
1983                                                                                     jobject jGraphicsState, jobject jGraphicsStateObject, jobject jImageInfo)
1984 {


< prev index next >