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 {
|