annotate src/macosx/native/sun/awt/ImageSurfaceData.m @ 5304:0fa8d5080fd8

7187834: [macosx] Usage of private API in macosx 2d implementation causes Apple Store rejection Reviewed-by: prr, igor, swingler
author skovatch
date Fri, 07 Sep 2012 08:22:15 -0700
parents 5cca2f1a37da
children
rev   line source
michaelm@4628 1 /*
michaelm@4628 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
michaelm@4628 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
michaelm@4628 4 *
michaelm@4628 5 * This code is free software; you can redistribute it and/or modify it
michaelm@4628 6 * under the terms of the GNU General Public License version 2 only, as
michaelm@4628 7 * published by the Free Software Foundation. Oracle designates this
michaelm@4628 8 * particular file as subject to the "Classpath" exception as provided
michaelm@4628 9 * by Oracle in the LICENSE file that accompanied this code.
michaelm@4628 10 *
michaelm@4628 11 * This code is distributed in the hope that it will be useful, but WITHOUT
michaelm@4628 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
michaelm@4628 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
michaelm@4628 14 * version 2 for more details (a copy is included in the LICENSE file that
michaelm@4628 15 * accompanied this code).
michaelm@4628 16 *
michaelm@4628 17 * You should have received a copy of the GNU General Public License version
michaelm@4628 18 * 2 along with this work; if not, write to the Free Software Foundation,
michaelm@4628 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
michaelm@4628 20 *
michaelm@4628 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
michaelm@4628 22 * or visit www.oracle.com if you need additional information or have any
michaelm@4628 23 * questions.
michaelm@4628 24 */
michaelm@4628 25
michaelm@4628 26 #import "ImageSurfaceData.h"
michaelm@4628 27
michaelm@4628 28 #import "java_awt_Transparency.h"
michaelm@4628 29 #import "java_awt_image_BufferedImage.h"
michaelm@4628 30 #import "sun_awt_image_BufImgSurfaceData.h"
michaelm@4628 31 #import "sun_java2d_OSXOffScreenSurfaceData.h"
michaelm@4628 32
michaelm@4628 33 #import "jni_util.h"
michaelm@4628 34 #import <JavaNativeFoundation/JavaNativeFoundation.h>
michaelm@4628 35
michaelm@4628 36 #import "BufImgSurfaceData.h"
michaelm@4628 37 #import "ThreadUtilities.h"
michaelm@4628 38
michaelm@4628 39
michaelm@4628 40
michaelm@4628 41 //#define DEBUG 1
michaelm@4628 42 #if defined DEBUG
michaelm@4628 43 #define IMAGE_SURFACE_INLINE
michaelm@4628 44 #define PRINT(msg) {fprintf(stderr, "%s\n", msg);fflush(stderr);}
michaelm@4628 45 #else
michaelm@4628 46 #define IMAGE_SURFACE_INLINE static inline
michaelm@4628 47 #define PRINT(msg) {}
michaelm@4628 48 #endif
michaelm@4628 49
michaelm@4628 50 // same value as defined in Sun's own code
michaelm@4628 51 #define XOR_ALPHA_CUTOFF 128
michaelm@4628 52
michaelm@4628 53 // for vImage framework headers
michaelm@4628 54 #include <Accelerate/Accelerate.h>
michaelm@4628 55
michaelm@4628 56 static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] =
michaelm@4628 57 {
michaelm@4628 58 {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM // special case
michaelm@4628 59 {YES, YES, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_RGB
michaelm@4628 60 {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_ARGB
michaelm@4628 61 {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_ARGB_PRE
michaelm@4628 62 {YES, YES, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_BGR
michaelm@4628 63 {YES, NO, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_3BYTE_BGR // use the default ARGB_PRE context synce we have to sync by hand anyway
michaelm@4628 64 {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_4BYTE_ABGR
michaelm@4628 65 {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_4BYTE_ABGR_PRE
michaelm@4628 66 #ifdef __LITTLE_ENDIAN__
michaelm@4628 67 {YES, YES, 5, 2, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Host, NULL}, // TYPE_USHORT_565_RGB
michaelm@4628 68 {YES, YES, 5, 2, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Host, NULL}, // TYPE_USHORT_555_RGB
michaelm@4628 69 #else
michaelm@4628 70 {YES, YES, 5, 2, 0, kCGImageAlphaNoneSkipFirst, NULL}, // TYPE_USHORT_565_RGB
michaelm@4628 71 {YES, YES, 5, 2, 0, kCGImageAlphaNoneSkipFirst, NULL}, // TYPE_USHORT_555_RGB
michaelm@4628 72 #endif
michaelm@4628 73 {YES, YES, 8, 1, 0, kCGImageAlphaNone, NULL}, // TYPE_BYTE_GRAY
michaelm@4628 74 {YES, NO, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_USHORT_GRAY // use the default ARGB_PRE context synce we have to sync by hand anyway
michaelm@4628 75 {NO, NO, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_BYTE_BINARY mapped to TYPE_CUSTOM
michaelm@4628 76 {YES, NO, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_BYTE_INDEXED // use the default ARGB_PRE context synce we have to sync by hand anyway
michaelm@4628 77 {YES, NO, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_3BYTE_RGB
michaelm@4628 78 };
michaelm@4628 79
michaelm@4628 80 static ImageInfo sDefaultImageInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] =
michaelm@4628 81 {
michaelm@4628 82 {8, 32, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM
michaelm@4628 83 {8, 32, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_RGB
michaelm@4628 84 {8, 32, 4, 0, kCGImageAlphaFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_ARGB
michaelm@4628 85 {8, 32, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_ARGB_PRE
michaelm@4628 86 {8, 32, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_BGR
michaelm@4628 87 {8, 32, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_3BYTE_BGR
michaelm@4628 88 {8, 32, 4, 0, kCGImageAlphaFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_4BYTE_ABGR
michaelm@4628 89 {8, 32, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_4BYTE_ABGR_PRE
michaelm@4628 90 #ifdef __LITTLE_ENDIAN__
michaelm@4628 91 {5, 16, 2, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Host, NULL}, // TYPE_USHORT_565_RGB
michaelm@4628 92 {5, 16, 2, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Host, NULL}, // TYPE_USHORT_555_RGB
michaelm@4628 93 #else
michaelm@4628 94 {5, 16, 2, 0, kCGImageAlphaNoneSkipFirst, NULL}, // TYPE_USHORT_565_RGB
michaelm@4628 95 {5, 16, 2, 0, kCGImageAlphaNoneSkipFirst, NULL}, // TYPE_USHORT_555_RGB
michaelm@4628 96 #endif
michaelm@4628 97 {8, 8, 1, 0, kCGImageAlphaNone, NULL}, // TYPE_BYTE_GRAY
michaelm@4628 98 {16, 16, 2, 0, kCGImageAlphaNone | kCGBitmapByteOrder16Host, NULL}, // TYPE_USHORT_GRAY
michaelm@4628 99 {0, 0, 0, 0, -1, NULL}, // TYPE_BYTE_BINARY mapped to TYPE_CUSTOM
michaelm@4628 100 {8, 32, 4, 0, kCGImageAlphaFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_BYTE_INDEXED // Fully OPAQUE INDEXED images will use kCGImageAlphaNoneSkipFirst for performance reasosn. see <rdar://4224874>
michaelm@4628 101 {8, 32, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_3BYTE_RGB
michaelm@4628 102 };
michaelm@4628 103
michaelm@4628 104 static jfieldID rgbID;
michaelm@4628 105 static jfieldID mapSizeID;
michaelm@4628 106 static jfieldID CMpDataID;
michaelm@4628 107 static jfieldID allGrayID;
michaelm@4628 108
michaelm@4628 109
michaelm@4628 110 static JNF_CLASS_CACHE(jc_OSXOffScreenSurfaceData, "sun/java2d/OSXOffScreenSurfaceData");
michaelm@4628 111 static JNF_MEMBER_CACHE(jm_syncFromCustom, jc_OSXOffScreenSurfaceData, "syncFromCustom", "()V");
michaelm@4628 112 static JNF_MEMBER_CACHE(jm_syncToCustom, jc_OSXOffScreenSurfaceData, "syncToCustom", "()V");
michaelm@4628 113 static JNF_CLASS_CACHE(jc_BufferedImage, "java/awt/image/BufferedImage");
michaelm@4628 114 static JNF_MEMBER_CACHE(jm_SurfaceData, jc_BufferedImage, "sData", "Lsun/java2d/SurfaceData;");
michaelm@4628 115 static JNF_CLASS_CACHE(jc_IndexColorModel, "java/awt/image/IndexColorModel");
michaelm@4628 116 static JNF_MEMBER_CACHE(jm_rgb, jc_IndexColorModel, "rgb", "[I");
michaelm@4628 117 static JNF_MEMBER_CACHE(jm_transparency, jc_IndexColorModel, "transparency", "I");
michaelm@4628 118 static JNF_MEMBER_CACHE(jm_transparent_index, jc_IndexColorModel, "transparent_index", "I");
michaelm@4628 119
michaelm@4628 120 CGColorSpaceRef gColorspaceRGB = NULL;
michaelm@4628 121 CGColorSpaceRef gColorspaceGray = NULL;
michaelm@4628 122
michaelm@4628 123 IMAGE_SURFACE_INLINE void PrintImageInfo(ImageSDOps* isdo)
michaelm@4628 124 {
michaelm@4628 125 fprintf(stderr, "\n");
michaelm@4628 126 fprintf(stderr, "PrintImageInfo:\n");
michaelm@4628 127 fprintf(stderr, "\t \n");
michaelm@4628 128 //fprintf(stderr, "\t magicID=%d\n", (jint)isdo->magicID);
michaelm@4628 129 //fprintf(stderr, "\n");
michaelm@4628 130 fprintf(stderr, "\t isdo=%p\n", isdo);
michaelm@4628 131 fprintf(stderr, "\t \n");
michaelm@4628 132 fprintf(stderr, "\t contextInfo:\n");
michaelm@4628 133 fprintf(stderr, "\t useWindowContextReference=%d\n", isdo->contextInfo.useWindowContextReference);
michaelm@4628 134 fprintf(stderr, "\t canUseJavaPixelsAsContext=%d\n", isdo->contextInfo.canUseJavaPixelsAsContext);
michaelm@4628 135 fprintf(stderr, "\t bitsPerComponent=%ld\n", (long)isdo->contextInfo.bitsPerComponent);
michaelm@4628 136 fprintf(stderr, "\t bytesPerPixel=%ld\n", (long)isdo->contextInfo.bytesPerPixel);
michaelm@4628 137 fprintf(stderr, "\t bytesPerRow=%ld\n", (long)isdo->contextInfo.bytesPerRow);
michaelm@4628 138 fprintf(stderr, "\t alphaInfo=%ld\n", (long)isdo->contextInfo.alphaInfo);
michaelm@4628 139 fprintf(stderr, "\t \n");
michaelm@4628 140 fprintf(stderr, "\t imageInfo:\n");
michaelm@4628 141 fprintf(stderr, "\t bitsPerComponent=%ld\n", (long)isdo->imageInfo.bitsPerComponent);
michaelm@4628 142 fprintf(stderr, "\t bitsPerPixel=%ld\n", (long)isdo->imageInfo.bitsPerPixel);
michaelm@4628 143 fprintf(stderr, "\t bytesPerPixel=%ld\n", (long)isdo->imageInfo.bytesPerPixel);
michaelm@4628 144 fprintf(stderr, "\t bytesPerRow=%ld\n", (long)isdo->imageInfo.bytesPerRow);
michaelm@4628 145 fprintf(stderr, "\t alphaInfo=%ld\n", (long)isdo->imageInfo.alphaInfo);
michaelm@4628 146 fprintf(stderr, "\t \n");
michaelm@4628 147 fprintf(stderr, "\t isSubImage=%d\n", isdo->isSubImage);
michaelm@4628 148 fprintf(stderr, "\t \n");
michaelm@4628 149 fprintf(stderr, "\t java info:\n");
michaelm@4628 150 fprintf(stderr, "\t array=%p\n", isdo->array);
michaelm@4628 151 fprintf(stderr, "\t offset=%d\n", (int)isdo->offset);
michaelm@4628 152 fprintf(stderr, "\t width=%d\n", (int)isdo->width);
michaelm@4628 153 fprintf(stderr, "\t height=%d\n", (int)isdo->height);
michaelm@4628 154 fprintf(stderr, "\t javaPixelBytes=%d\n", (int)isdo->javaPixelBytes);
michaelm@4628 155 fprintf(stderr, "\t javaPixelsBytesPerRow=%d\n", (int)isdo->javaPixelsBytesPerRow);
michaelm@4628 156 fprintf(stderr, "\t icm=%p\n", isdo->icm);
michaelm@4628 157 fprintf(stderr, "\t type=%d\n", (int)isdo->type);
michaelm@4628 158 fprintf(stderr, "\n");
michaelm@4628 159 fprintf(stderr, "\t cgRef=%p\n", isdo->qsdo.cgRef);
michaelm@4628 160 fprintf(stderr, "\t nsRef=%p\n", isdo->nsRef);
michaelm@4628 161 fprintf(stderr, "\n");
michaelm@4628 162 fprintf(stderr, "\t pixelsLocked=%p\n", isdo->pixelsLocked);
michaelm@4628 163 fprintf(stderr, "\t pixels=%p\n", isdo->pixels);
michaelm@4628 164 fprintf(stderr, "\n");
michaelm@4628 165 fprintf(stderr, "\t indexedColorTable=%p\n", isdo->indexedColorTable);
michaelm@4628 166 fprintf(stderr, "\t lutData=%p\n", isdo->lutData);
michaelm@4628 167 fprintf(stderr, "\t lutDataSize=%u\n", (unsigned)isdo->lutDataSize);
michaelm@4628 168 fprintf(stderr, "\n");
michaelm@4628 169 fprintf(stderr, "\t nrOfPixelsOwners=%u\n", (unsigned)isdo->nrOfPixelsOwners);
michaelm@4628 170 fprintf(stderr, "\n");
michaelm@4628 171 }
michaelm@4628 172
michaelm@4628 173 // if there is no image created for isdo.imgRef, it creates and image using the isdo.dataProvider
michaelm@4628 174 // If there is an image present, this is a no-op
michaelm@4628 175 void makeSureImageIsCreated(ImageSDOps* isdo)
michaelm@4628 176 {
michaelm@4628 177 if (isdo->imgRef == NULL) // create the image
michaelm@4628 178 {
michaelm@4628 179 isdo->imgRef = CGImageCreate(isdo->width,
michaelm@4628 180 isdo->height,
michaelm@4628 181 isdo->contextInfo.bitsPerComponent,
michaelm@4628 182 isdo->contextInfo.bytesPerPixel * 8,
michaelm@4628 183 isdo->contextInfo.bytesPerRow,
michaelm@4628 184 isdo->contextInfo.colorSpace,
michaelm@4628 185 isdo->contextInfo.alphaInfo,
michaelm@4628 186 isdo->dataProvider,
michaelm@4628 187 NULL,
michaelm@4628 188 NO,
michaelm@4628 189 kCGRenderingIntentDefault);
michaelm@4628 190 }
michaelm@4628 191 }
michaelm@4628 192
michaelm@4628 193 IMAGE_SURFACE_INLINE void customPixelsFromJava(JNIEnv *env, ImageSDOps *isdo)
michaelm@4628 194 {
michaelm@4628 195 PRINT(" customPixelsFromJava")
michaelm@4628 196
michaelm@4628 197 SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
michaelm@4628 198 JNFCallVoidMethod([ThreadUtilities getJNIEnv], sdo->sdObject, jm_syncFromCustom); // AWT_THREADING Safe (known object)
michaelm@4628 199 }
michaelm@4628 200
michaelm@4628 201
michaelm@4628 202 IMAGE_SURFACE_INLINE void copyBits(jint w, jint h, jint javaPixelsBytesPerRow, Pixel8bit *pixelsSrc, jint dstPixelsBytesPerRow, Pixel8bit *pixelsDst)
michaelm@4628 203 {
michaelm@4628 204 PRINT(" copyBits")
michaelm@4628 205
michaelm@4628 206 if (javaPixelsBytesPerRow == dstPixelsBytesPerRow)
michaelm@4628 207 {
michaelm@4628 208 memcpy(pixelsDst, pixelsSrc, h*javaPixelsBytesPerRow);
michaelm@4628 209 }
michaelm@4628 210 else
michaelm@4628 211 {
michaelm@4628 212 register jint y;
michaelm@4628 213 for (y=0; y<h; y++)
michaelm@4628 214 {
michaelm@4628 215 memcpy(pixelsDst, pixelsSrc, dstPixelsBytesPerRow);
michaelm@4628 216
michaelm@4628 217 pixelsSrc += javaPixelsBytesPerRow;
michaelm@4628 218 pixelsDst += dstPixelsBytesPerRow;
michaelm@4628 219 }
michaelm@4628 220 }
michaelm@4628 221 }
michaelm@4628 222
michaelm@4628 223 IMAGE_SURFACE_INLINE void copySwapRandB_32bit_TYPE_4BYTE(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc, Pixel32bit *pixelsDst, size_t extraBytesPerRow)
michaelm@4628 224 {
michaelm@4628 225 PRINT(" copySwapRandB_32bit_TYPE_4BYTE")
michaelm@4628 226
michaelm@4628 227 register Pixel8bit *p8Bit = NULL;
michaelm@4628 228 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 229 register Pixel32bit pixel, red, blue;
michaelm@4628 230 register jint x, y;
michaelm@4628 231
michaelm@4628 232 for (y=0; y<h; y++)
michaelm@4628 233 {
michaelm@4628 234 for (x=0; x<w; x++)
michaelm@4628 235 {
michaelm@4628 236 pixel = *pixelsSrc++;
michaelm@4628 237
michaelm@4628 238 #ifdef __LITTLE_ENDIAN__
michaelm@4628 239 pixel = CFSwapInt32BigToHost(pixel); // the jint is in big endian format, we need to swap the bits
michaelm@4628 240 #endif
michaelm@4628 241
michaelm@4628 242 red = (pixel & 0x00ff0000) >> 16; // get original red and shift to new position
michaelm@4628 243 blue = (pixel & 0x000000ff) << 16; // get original blue and shift to new position
michaelm@4628 244
michaelm@4628 245 pixel = (pixel & 0xff00ff00); // erase original red&blue
michaelm@4628 246
michaelm@4628 247 pixel = pixel | red | blue; // construct new pixel
michaelm@4628 248
michaelm@4628 249 *pixelsDst++ = pixel;
michaelm@4628 250 }
michaelm@4628 251 pixelsSrc += skip;
michaelm@4628 252
michaelm@4628 253 p8Bit = (Pixel8bit *) pixelsDst;
michaelm@4628 254 p8Bit += extraBytesPerRow;
michaelm@4628 255 pixelsDst = (Pixel32bit *) p8Bit;
michaelm@4628 256 }
michaelm@4628 257 }
michaelm@4628 258
michaelm@4628 259
michaelm@4628 260 IMAGE_SURFACE_INLINE void copySwapRandB_32bit_TYPE_INT(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc, Pixel32bit *pixelsDst, size_t extraBytesPerRow)
michaelm@4628 261 {
michaelm@4628 262 PRINT(" copySwapRandB_32bit_TYPE_INT")
michaelm@4628 263
michaelm@4628 264 register Pixel8bit *p8Bit = NULL;
michaelm@4628 265 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 266 register Pixel32bit pixel, red, blue;
michaelm@4628 267 register jint x, y;
michaelm@4628 268
michaelm@4628 269 for (y=0; y<h; y++)
michaelm@4628 270 {
michaelm@4628 271 for (x=0; x<w; x++)
michaelm@4628 272 {
michaelm@4628 273 pixel = *pixelsSrc++;
michaelm@4628 274
michaelm@4628 275 red = (pixel & 0x00ff0000) >> 16; // get original red and shift to new position
michaelm@4628 276 blue = (pixel & 0x000000ff) << 16; // get original blue and shift to new position
michaelm@4628 277
michaelm@4628 278 pixel = (pixel & 0xff00ff00); // erase original red&blue
michaelm@4628 279
michaelm@4628 280 pixel = pixel | red | blue; // construct new pixel
michaelm@4628 281
michaelm@4628 282 *pixelsDst++ = pixel;
michaelm@4628 283 }
michaelm@4628 284 pixelsSrc += skip;
michaelm@4628 285
michaelm@4628 286 p8Bit = (Pixel8bit *) pixelsDst;
michaelm@4628 287 p8Bit += extraBytesPerRow;
michaelm@4628 288 pixelsDst = (Pixel32bit *) p8Bit;
michaelm@4628 289 }
michaelm@4628 290 }
michaelm@4628 291
michaelm@4628 292
michaelm@4628 293 IMAGE_SURFACE_INLINE void copyBGR_24bitToXRGB_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel8bit *pixelsSrc, Pixel32bit *pixelsDst, size_t extraBytesPerRow)
michaelm@4628 294 {
michaelm@4628 295 PRINT(" copyBGR_24bitToXRGB_32bit")
michaelm@4628 296
michaelm@4628 297 register Pixel8bit *p8Bit = NULL;
michaelm@4628 298 register jint skip = ((javaPixelsBytesPerRow/javaPixelBytes)-w)*javaPixelBytes; // in pixelsSrc units
michaelm@4628 299 register Pixel32bit red, green, blue, pixel;
michaelm@4628 300 register jint x, y;
michaelm@4628 301
michaelm@4628 302 for (y=0; y<h; y++)
michaelm@4628 303 {
michaelm@4628 304 for (x=0; x<w; x++)
michaelm@4628 305 {
michaelm@4628 306 pixel = *pixelsSrc++;
michaelm@4628 307 blue = pixel << 0;
michaelm@4628 308
michaelm@4628 309 pixel = *pixelsSrc++;
michaelm@4628 310 green = pixel << 8;
michaelm@4628 311
michaelm@4628 312 pixel = *pixelsSrc++;
michaelm@4628 313 red = pixel << 16;
michaelm@4628 314
michaelm@4628 315 *pixelsDst = red | green | blue;
michaelm@4628 316
michaelm@4628 317 *pixelsDst = 0xff000000 | *pixelsDst;
michaelm@4628 318
michaelm@4628 319 pixelsDst++;
michaelm@4628 320 }
michaelm@4628 321 pixelsSrc += skip;
michaelm@4628 322
michaelm@4628 323 p8Bit = (Pixel8bit *) pixelsDst;
michaelm@4628 324 p8Bit += extraBytesPerRow;
michaelm@4628 325 pixelsDst = (Pixel32bit *) p8Bit;
michaelm@4628 326 }
michaelm@4628 327 }
michaelm@4628 328
michaelm@4628 329 IMAGE_SURFACE_INLINE void copyRGB_24bitToXRGB_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel8bit *pixelsSrc, Pixel32bit *pixelsDst, size_t extraBytesPerRow)
michaelm@4628 330 {
michaelm@4628 331 PRINT(" copyRGB_24bitToXRGB_32bit")
michaelm@4628 332
michaelm@4628 333 register Pixel8bit *p8Bit = NULL;
michaelm@4628 334 register jint skip = ((javaPixelsBytesPerRow/javaPixelBytes)-w)*javaPixelBytes; // in pixelsSrc units
michaelm@4628 335 register Pixel32bit red, green, blue, pixel;
michaelm@4628 336 register jint x, y;
michaelm@4628 337
michaelm@4628 338 for (y=0; y<h; y++)
michaelm@4628 339 {
michaelm@4628 340 for (x=0; x<w; x++)
michaelm@4628 341 {
michaelm@4628 342 pixel = *pixelsSrc++;
michaelm@4628 343 red = pixel << 16;
michaelm@4628 344
michaelm@4628 345 pixel = *pixelsSrc++;
michaelm@4628 346 green = pixel << 8;
michaelm@4628 347
michaelm@4628 348 pixel = *pixelsSrc++;
michaelm@4628 349 blue = pixel << 0;
michaelm@4628 350
michaelm@4628 351 *pixelsDst = red | green | blue;
michaelm@4628 352
michaelm@4628 353 *pixelsDst = 0xff000000 | *pixelsDst;
michaelm@4628 354
michaelm@4628 355 pixelsDst++;
michaelm@4628 356 }
michaelm@4628 357 pixelsSrc += skip;
michaelm@4628 358
michaelm@4628 359 p8Bit = (Pixel8bit *) pixelsDst;
michaelm@4628 360 p8Bit += extraBytesPerRow;
michaelm@4628 361 pixelsDst = (Pixel32bit *) p8Bit;
michaelm@4628 362 }
michaelm@4628 363 }
michaelm@4628 364
michaelm@4628 365 IMAGE_SURFACE_INLINE void copyIndexed_8bitToARGB_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel8bit *pixelsSrc,
michaelm@4628 366 Pixel32bit* lutdata, Pixel32bit *pixelsDst, size_t extraBytesPerRow)
michaelm@4628 367 {
michaelm@4628 368 PRINT(" copyIndexed_8bitToARGB_32bit")
michaelm@4628 369
michaelm@4628 370 //gznote: how is the performance if the extraBytesPerRow != 0 ?
michaelm@4628 371 const vImage_Buffer src = {pixelsSrc, h, w, javaPixelsBytesPerRow};
michaelm@4628 372 const vImage_Buffer dest = {pixelsDst, h, w, w*sizeof(Pixel32bit)+extraBytesPerRow};
michaelm@4628 373 vImage_Error err = vImageLookupTable_Planar8toPlanarF(&src, &dest, (Pixel_F*)lutdata, kvImageDoNotTile);
michaelm@4628 374 if (err != kvImageNoError)
michaelm@4628 375 {
michaelm@4628 376 fprintf(stderr, "Error in copyIndexed_8bitToARGB_32bit: vImageLookupTable_Planar8toPlanarF returns %ld\n", (long)err);
michaelm@4628 377 register Pixel8bit *p8Bit = NULL;
michaelm@4628 378 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 379 register jint x, y;
michaelm@4628 380 for (y=0; y<h; y++)
michaelm@4628 381 {
michaelm@4628 382 for (x=0; x<w; x++)
michaelm@4628 383 {
michaelm@4628 384 *pixelsDst++ = lutdata[*pixelsSrc++]; // case 1
michaelm@4628 385 //*pixelsDst++ = *(lutdata + *pixelsSrc++); // case 2: at best ~1% better than case 1
michaelm@4628 386 }
michaelm@4628 387 pixelsSrc += skip;
michaelm@4628 388
michaelm@4628 389 p8Bit = (Pixel8bit *) pixelsDst;
michaelm@4628 390 p8Bit += extraBytesPerRow;
michaelm@4628 391 pixelsDst = (Pixel32bit *) p8Bit;
michaelm@4628 392 }
michaelm@4628 393 }
michaelm@4628 394 }
michaelm@4628 395
michaelm@4628 396 IMAGE_SURFACE_INLINE void copy565_16bitTo555_16bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel16bit *pixelsSrc, Pixel16bit *pixelsDst, size_t extraBytesPerRow)
michaelm@4628 397 {
michaelm@4628 398 PRINT(" copy565_16bitTo555_16bit")
michaelm@4628 399
michaelm@4628 400 register Pixel8bit *p8Bit = NULL;
michaelm@4628 401 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 402 register jint green;
michaelm@4628 403 register Pixel16bit pixel;
michaelm@4628 404 register jint x, y;
michaelm@4628 405 for (y=0; y<h; y++)
michaelm@4628 406 {
michaelm@4628 407 for (x=0; x<w; x++)
michaelm@4628 408 {
michaelm@4628 409 pixel = *pixelsSrc++;
michaelm@4628 410
michaelm@4628 411 green = ((pixel >> 5) & 63); // rrrrrggggggbbbbb => shift 5 right = 00000rrrrrgggggg => and 63 = 0000000000gggggg
michaelm@4628 412 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)
michaelm@4628 413
michaelm@4628 414 *pixelsDst++ = ((pixel&0xf800)>>1) | (green << 5) | (pixel&0x01f);
michaelm@4628 415 }
michaelm@4628 416 pixelsSrc += skip;
michaelm@4628 417
michaelm@4628 418 p8Bit = (Pixel8bit *) pixelsDst;
michaelm@4628 419 p8Bit += extraBytesPerRow;
michaelm@4628 420 pixelsDst = (Pixel16bit *) p8Bit;
michaelm@4628 421 }
michaelm@4628 422 }
michaelm@4628 423
michaelm@4628 424
michaelm@4628 425 IMAGE_SURFACE_INLINE void customPixelsToJava(JNIEnv *env, ImageSDOps *isdo)
michaelm@4628 426 {
michaelm@4628 427 PRINT(" customPixelsToJava")
michaelm@4628 428
michaelm@4628 429 SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
michaelm@4628 430 JNFCallVoidMethod([ThreadUtilities getJNIEnv], sdo->sdObject, jm_syncToCustom); // AWT_THREADING Safe (known object)
michaelm@4628 431 }
michaelm@4628 432
michaelm@4628 433 IMAGE_SURFACE_INLINE void removeAlphaPre_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
michaelm@4628 434 {
michaelm@4628 435 PRINT(" removeAlphaPre_32bit")
michaelm@4628 436
michaelm@4628 437 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 438 register Pixel32bit pixel, alpha, red, green, blue;
michaelm@4628 439 register jint x, y;
michaelm@4628 440
michaelm@4628 441 for (y=0; y<h; y++)
michaelm@4628 442 {
michaelm@4628 443 for (x=0; x<w; x++)
michaelm@4628 444 {
michaelm@4628 445 pixel = *pixelsSrc;
michaelm@4628 446
michaelm@4628 447 alpha = (pixel >> 24) & 0xff;
michaelm@4628 448
michaelm@4628 449 if (alpha != 0)
michaelm@4628 450 {
michaelm@4628 451 // get color components
michaelm@4628 452 red = (pixel >> 16) & 0xff;
michaelm@4628 453 green = (pixel >> 8) & 0xff;
michaelm@4628 454 blue = (pixel >> 0) & 0xff;
michaelm@4628 455
michaelm@4628 456 // remove alpha pre
michaelm@4628 457 red = ((red * 0xff) + 0x7f) / alpha;
michaelm@4628 458 green = ((green * 0xff) + 0x7f) / alpha;
michaelm@4628 459 blue = ((blue * 0xff) + 0x7f) / alpha;
michaelm@4628 460
michaelm@4628 461 // clamp
michaelm@4628 462 red = (red <= 0xff) ? red : 0xff;
michaelm@4628 463 green = (green <= 0xff) ? green : 0xff;
michaelm@4628 464 blue = (blue <= 0xff) ? blue : 0xff;
michaelm@4628 465
michaelm@4628 466 *pixelsSrc++ = (alpha<<24) | (red<<16) | (green<<8) | blue; // construct new pixel
michaelm@4628 467 }
michaelm@4628 468 else
michaelm@4628 469 {
michaelm@4628 470 *pixelsSrc++ = 0;
michaelm@4628 471 }
michaelm@4628 472 }
michaelm@4628 473
michaelm@4628 474 pixelsSrc += skip;
michaelm@4628 475 }
michaelm@4628 476 }
michaelm@4628 477
michaelm@4628 478 IMAGE_SURFACE_INLINE void swapRandBAndRemoveAlphaPre_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
michaelm@4628 479 {
michaelm@4628 480 PRINT(" swapRandBAndRemoveAlphaPre_32bit")
michaelm@4628 481
michaelm@4628 482 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 483 register Pixel32bit pixel, alpha, red, green, blue;
michaelm@4628 484 register jint x, y;
michaelm@4628 485
michaelm@4628 486 for (y=0; y<h; y++)
michaelm@4628 487 {
michaelm@4628 488 for (x=0; x<w; x++)
michaelm@4628 489 {
michaelm@4628 490 pixel = *pixelsSrc;
michaelm@4628 491
michaelm@4628 492 alpha = (pixel & 0xff000000) >> 24;
michaelm@4628 493
michaelm@4628 494 if (alpha != 0)
michaelm@4628 495 {
michaelm@4628 496 // get color components
michaelm@4628 497 red = (pixel & 0x00ff0000) >> 16;
michaelm@4628 498 green = (pixel & 0x0000ff00) >> 8;
michaelm@4628 499 blue = (pixel & 0x000000ff) >> 0;
michaelm@4628 500
michaelm@4628 501 // remove alpha pre
michaelm@4628 502 red = ((red * 0xff) + 0x7f) / alpha;
michaelm@4628 503 green = ((green * 0xff) + 0x7f) / alpha;
michaelm@4628 504 blue = ((blue * 0xff) + 0x7f) / alpha;
michaelm@4628 505
michaelm@4628 506 // clamp
michaelm@4628 507 red = (red <= 0xff) ? red : 0xff;
michaelm@4628 508 green = (green <= 0xff) ? green : 0xff;
michaelm@4628 509 blue = (blue <= 0xff) ? blue : 0xff;
michaelm@4628 510
michaelm@4628 511 pixel = (alpha<<24) | (blue<<16) | (green<<8) | red; // construct new pixel
michaelm@4628 512
michaelm@4628 513 #ifdef __LITTLE_ENDIAN__
michaelm@4628 514 pixel = CFSwapInt32HostToBig(pixel); // the jint is little endian, we need to swap the bits before we send it back to Java
michaelm@4628 515 #endif
michaelm@4628 516
michaelm@4628 517 *pixelsSrc++ = pixel;
michaelm@4628 518 }
michaelm@4628 519 else
michaelm@4628 520 {
michaelm@4628 521 *pixelsSrc++ = 0;
michaelm@4628 522 }
michaelm@4628 523 }
michaelm@4628 524
michaelm@4628 525 pixelsSrc += skip;
michaelm@4628 526 }
michaelm@4628 527 }
michaelm@4628 528
michaelm@4628 529 IMAGE_SURFACE_INLINE void swapRandB_32bit_TYPE_INT(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
michaelm@4628 530 {
michaelm@4628 531 PRINT(" swapRandB_32bit_TYPE_INT")
michaelm@4628 532
michaelm@4628 533 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 534 register Pixel32bit pixel, red, blue;
michaelm@4628 535 register jint x, y;
michaelm@4628 536
michaelm@4628 537 for (y=0; y<h; y++)
michaelm@4628 538 {
michaelm@4628 539 for (x=0; x<w; x++)
michaelm@4628 540 {
michaelm@4628 541 pixel = *pixelsSrc;
michaelm@4628 542
michaelm@4628 543 red = (pixel & 0x00ff0000) >> 16; // get original red and shift to new position
michaelm@4628 544 blue = (pixel & 0x000000ff) << 16; // get original blue and shift to new position
michaelm@4628 545
michaelm@4628 546 pixel = (pixel & 0xff00ff00); // erase original red&blue
michaelm@4628 547
michaelm@4628 548 pixel = pixel | red | blue; // construct new pixel
michaelm@4628 549
michaelm@4628 550 *pixelsSrc++ = pixel;
michaelm@4628 551 }
michaelm@4628 552
michaelm@4628 553 pixelsSrc += skip;
michaelm@4628 554 }
michaelm@4628 555 }
michaelm@4628 556
michaelm@4628 557 IMAGE_SURFACE_INLINE void swapRandB_32bit_TYPE_4BYTE(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
michaelm@4628 558 {
michaelm@4628 559 PRINT(" swapRandB_32bit_TYPE_4BYTE")
michaelm@4628 560
michaelm@4628 561 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 562 register Pixel32bit pixel, red, blue;
michaelm@4628 563 register jint x, y;
michaelm@4628 564
michaelm@4628 565 for (y=0; y<h; y++)
michaelm@4628 566 {
michaelm@4628 567 for (x=0; x<w; x++)
michaelm@4628 568 {
michaelm@4628 569 pixel = *pixelsSrc;
michaelm@4628 570
michaelm@4628 571 red = (pixel & 0x00ff0000) >> 16; // get original red and shift to new position
michaelm@4628 572 blue = (pixel & 0x000000ff) << 16; // get original blue and shift to new position
michaelm@4628 573
michaelm@4628 574 pixel = (pixel & 0xff00ff00); // erase original red&blue
michaelm@4628 575
michaelm@4628 576 pixel = pixel | red | blue; // construct new pixel
michaelm@4628 577
michaelm@4628 578 #ifdef __LITTLE_ENDIAN__
michaelm@4628 579 pixel = CFSwapInt32HostToBig(pixel); // the jint is little endian, we need to swap the bits before we send it back to Java
michaelm@4628 580 #endif
michaelm@4628 581
michaelm@4628 582 *pixelsSrc++ = pixel;
michaelm@4628 583 }
michaelm@4628 584
michaelm@4628 585 pixelsSrc += skip;
michaelm@4628 586 }
michaelm@4628 587 }
michaelm@4628 588
michaelm@4628 589 IMAGE_SURFACE_INLINE void map555_16bitTo565_16bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel16bit *pixelsSrc)
michaelm@4628 590 {
michaelm@4628 591 PRINT(" map555_16bitTo565_16bit")
michaelm@4628 592 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 593 register jint green;
michaelm@4628 594 register Pixel16bit pixel;
michaelm@4628 595 register jint x, y;
michaelm@4628 596 for (y=0; y<h; y++)
michaelm@4628 597 {
michaelm@4628 598 for (x=0; x<w; x++)
michaelm@4628 599 {
michaelm@4628 600 pixel = *pixelsSrc;
michaelm@4628 601
michaelm@4628 602 green = ((pixel >> 5) & 31); // rrrrrgggggbbbbb => shift 5 right = 000000rrrrrggggg => and 31 = 00000000000ggggg
michaelm@4628 603 green = ((jint) (((CGFloat) green / 31.0f) * 63.0f)) & 63; // first normalize between 0 and 1 and then un-normalize to 6 bit (63 = 0000000000111111)
michaelm@4628 604
michaelm@4628 605 *pixelsSrc++ = ((pixel&0x7c00)<<1) | (green << 5) | (pixel&0x01f);
michaelm@4628 606 }
michaelm@4628 607
michaelm@4628 608 pixelsSrc += skip;
michaelm@4628 609 }
michaelm@4628 610 }
michaelm@4628 611
michaelm@4628 612 IMAGE_SURFACE_INLINE void copyARGB_PRE_32bitToBGR_24bit(jint w, jint h, jint nativePixelsBytesPerRow, Pixel32bit *pixelsSrc, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel8bit *pixelsDst)
michaelm@4628 613 {
michaelm@4628 614 PRINT(" copyARGB_PRE_32bitToBGR_24bit")
michaelm@4628 615
michaelm@4628 616 static const jint mask = 0x000000ff;
michaelm@4628 617 register jint skipSrc = (nativePixelsBytesPerRow/sizeof(Pixel32bit))-w; // in pixelsSrc units
michaelm@4628 618 register jint skipDst = ((javaPixelsBytesPerRow/javaPixelBytes)-w)*javaPixelBytes; // in pixelsDst units
michaelm@4628 619 register Pixel32bit pixel, alpha, red, green, blue;
michaelm@4628 620 register jint x, y;
michaelm@4628 621
michaelm@4628 622 for (y=0; y<h; y++)
michaelm@4628 623 {
michaelm@4628 624 for (x=0; x<w; x++)
michaelm@4628 625 {
michaelm@4628 626 pixel = *pixelsSrc;
michaelm@4628 627
michaelm@4628 628 alpha = (pixel >> 24) & mask;
michaelm@4628 629
michaelm@4628 630 if (alpha != 0)
michaelm@4628 631 {
michaelm@4628 632 // extract color components
michaelm@4628 633 red = (pixel >> 16) & mask;
michaelm@4628 634 green = (pixel >> 8) & mask;
michaelm@4628 635 blue = (pixel >> 0) & mask;
michaelm@4628 636
michaelm@4628 637 // remove alpha pre
michaelm@4628 638 red = ((red * 0xff) + 0x7f) / alpha;
michaelm@4628 639 green = ((green * 0xff) + 0x7f) / alpha;
michaelm@4628 640 blue = ((blue * 0xff) + 0x7f) / alpha;
michaelm@4628 641
michaelm@4628 642 // clamp
michaelm@4628 643 *pixelsDst++ = (blue <= 0xff) ? blue : 0xff;
michaelm@4628 644 *pixelsDst++ = (green <= 0xff) ? green : 0xff;
michaelm@4628 645 *pixelsDst++ = (red <= 0xff) ? red : 0xff;
michaelm@4628 646 }
michaelm@4628 647 else
michaelm@4628 648 {
michaelm@4628 649 *pixelsDst++ = 0; // blue
michaelm@4628 650 *pixelsDst++ = 0; // green
michaelm@4628 651 *pixelsDst++ = 0; // red
michaelm@4628 652 }
michaelm@4628 653
michaelm@4628 654 pixelsSrc++;
michaelm@4628 655 }
michaelm@4628 656
michaelm@4628 657 pixelsSrc += skipSrc;
michaelm@4628 658 pixelsDst += skipDst;
michaelm@4628 659 }
michaelm@4628 660 }
michaelm@4628 661
michaelm@4628 662
michaelm@4628 663 IMAGE_SURFACE_INLINE void copyARGB_PRE_32bitToRGB_24bit(jint w, jint h, jint nativePixelsBytesPerRow, Pixel32bit *pixelsSrc, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel8bit *pixelsDst)
michaelm@4628 664 {
michaelm@4628 665 PRINT(" copyARGB_PRE_32bitToRGB_24bit")
michaelm@4628 666
michaelm@4628 667 static const jint mask = 0x000000ff;
michaelm@4628 668 register jint skipSrc = (nativePixelsBytesPerRow/sizeof(Pixel32bit))-w; // in pixelsSrc units
michaelm@4628 669 register jint skipDst = ((javaPixelsBytesPerRow/javaPixelBytes)-w)*javaPixelBytes; // in pixelsDst units
michaelm@4628 670 register Pixel32bit pixel, alpha, red, green, blue;
michaelm@4628 671 register jint x, y;
michaelm@4628 672
michaelm@4628 673 for (y=0; y<h; y++)
michaelm@4628 674 {
michaelm@4628 675 for (x=0; x<w; x++)
michaelm@4628 676 {
michaelm@4628 677 pixel = *pixelsSrc;
michaelm@4628 678
michaelm@4628 679 alpha = (pixel >> 24) & mask;
michaelm@4628 680
michaelm@4628 681 if (alpha != 0)
michaelm@4628 682 {
michaelm@4628 683 // extract color components
michaelm@4628 684 red = (pixel >> 16) & mask;
michaelm@4628 685 green = (pixel >> 8) & mask;
michaelm@4628 686 blue = (pixel >> 0) & mask;
michaelm@4628 687
michaelm@4628 688 // remove alpha pre
michaelm@4628 689 red = ((red * 0xff) + 0x7f) / alpha;
michaelm@4628 690 green = ((green * 0xff) + 0x7f) / alpha;
michaelm@4628 691 blue = ((blue * 0xff) + 0x7f) / alpha;
michaelm@4628 692
michaelm@4628 693 // clamp
michaelm@4628 694 *pixelsDst++ = (red <= 0xff) ? red : 0xff;
michaelm@4628 695 *pixelsDst++ = (green <= 0xff) ? green : 0xff;
michaelm@4628 696 *pixelsDst++ = (blue <= 0xff) ? blue : 0xff;
michaelm@4628 697 }
michaelm@4628 698 else
michaelm@4628 699 {
michaelm@4628 700 *pixelsDst++ = 0; // blue
michaelm@4628 701 *pixelsDst++ = 0; // green
michaelm@4628 702 *pixelsDst++ = 0; // red
michaelm@4628 703 }
michaelm@4628 704
michaelm@4628 705 pixelsSrc++;
michaelm@4628 706 }
michaelm@4628 707
michaelm@4628 708 pixelsSrc += skipSrc;
michaelm@4628 709 pixelsDst += skipDst;
michaelm@4628 710 }
michaelm@4628 711 }
michaelm@4628 712
michaelm@4628 713
michaelm@4628 714 // gray = 0.3red + 0.59green + 0.11blue - NTSC standard (according to Luke Wallis)
michaelm@4628 715 IMAGE_SURFACE_INLINE void copyARGB_PRE_32bitToGray_16bit(jint w, jint h, jint nativePixelsBytesPerRow, Pixel32bit *pixelsSrc, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel16bit *pixelsDst)
michaelm@4628 716 {
michaelm@4628 717 PRINT(" copyARGB_PRE_32bitToGray_16bit")
michaelm@4628 718
michaelm@4628 719 static const jint mask = 0x000000ff;
michaelm@4628 720 register jint skipSrc = (nativePixelsBytesPerRow/sizeof(Pixel32bit))-w; // in pixelsSrc units
michaelm@4628 721 register jint skipDst = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsDst units
michaelm@4628 722 register Pixel32bit alpha;
michaelm@4628 723 register Pixel32bit pixel, red, green, blue;
michaelm@4628 724 register CGFloat pixelFloat;
michaelm@4628 725 register jint x, y;
michaelm@4628 726
michaelm@4628 727 for (y=0; y<h; y++)
michaelm@4628 728 {
michaelm@4628 729 for (x=0; x<w; x++)
michaelm@4628 730 {
michaelm@4628 731 pixel = *pixelsSrc;
michaelm@4628 732
michaelm@4628 733 // gznote: do we remove alpha pre here?
michaelm@4628 734 alpha = ((pixel >> 24) & mask); //extract
michaelm@4628 735
michaelm@4628 736 if (alpha != 0)
michaelm@4628 737 {
michaelm@4628 738 red = ((pixel >> 16) & mask); // extract
michaelm@4628 739 green = ((pixel >> 8) & mask); // extract
michaelm@4628 740 blue = ((pixel >> 0) & mask); // extract
michaelm@4628 741
michaelm@4628 742 alpha *= 0xff; // upsample to 16bit
michaelm@4628 743 red *= 0xff; // upsample to 16bit
michaelm@4628 744 green *= 0xff; // upsample to 16bit
michaelm@4628 745 blue *= 0xff; // upsample to 16bit
michaelm@4628 746
michaelm@4628 747 red = ((red * 0xffff) + 0x7fff) / alpha; // remove alpha pre
michaelm@4628 748 red = (red <= 0xffff) ? red : 0xffff;
michaelm@4628 749 green = ((green * 0xffff) + 0x7fff) / alpha; // remove alpha pre
michaelm@4628 750 green = (green <= 0xffff) ? green : 0xffff;
michaelm@4628 751 blue = ((blue * 0xffff) + 0x7fff) / alpha; // remove alpha pre
michaelm@4628 752 blue = (blue <= 0xffff) ? blue : 0xffff;
michaelm@4628 753
michaelm@4628 754 pixelFloat = red*0.3f + green*0.59f + blue*0.11f; // rgb->gray NTSC conversion
michaelm@4628 755 }
michaelm@4628 756 else
michaelm@4628 757 {
michaelm@4628 758 pixelFloat = 0;
michaelm@4628 759 }
michaelm@4628 760
michaelm@4628 761 *pixelsDst = (jint)pixelFloat;
michaelm@4628 762 pixelsDst++;
michaelm@4628 763
michaelm@4628 764 pixelsSrc++;
michaelm@4628 765 }
michaelm@4628 766
michaelm@4628 767 pixelsSrc += skipSrc;
michaelm@4628 768 pixelsDst += skipDst;
michaelm@4628 769 }
michaelm@4628 770 }
michaelm@4628 771
michaelm@4628 772 // 1. first "dither" the true color down by creating a 16 bit value of the real color that will serve as an index into the cache of indexes
michaelm@4628 773 // 2. if the cache has a valid entry use it otherwise go through 3 and 4
michaelm@4628 774 // 3. go through the color table and calculate Euclidian distance between the true color and the indexed colors
michaelm@4628 775 // 4. map the shortest distance into the one and true index color and stick it into the dst (and cache)
michaelm@4628 776 IMAGE_SURFACE_INLINE UInt16* copyARGB_PRE_bitToIndexed_8bit(jint w, jint h, jint nativePixelsBytesPerRow, Pixel32bit *pixelsSrc, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel8bit *pixelsDst, Pixel32bit* lutdata, UInt32 lutDataSize, UInt16 *indexedColorTable)
michaelm@4628 777 {
michaelm@4628 778 PRINT(" copyARGB_PRE_bitToIndexed_8bit")
michaelm@4628 779 static const UInt32 mask = 0x000000ff;
michaelm@4628 780
michaelm@4628 781 static const UInt32 indexSize = 65536; // 2^16 - 16 bits of precision
michaelm@4628 782 static const UInt32 indexMask = 0x000000f0; // 00000000000000000000000011110000
michaelm@4628 783 static const UInt16 invalidIndex = 0xffff; // 1111111111111111
michaelm@4628 784
michaelm@4628 785 register jint skipSrc = (nativePixelsBytesPerRow/sizeof(Pixel32bit))-w; // in pixelsSrc units
michaelm@4628 786 register jint skipDst = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
michaelm@4628 787 register jint indexOfBest, indexOfBestCached = -1;
michaelm@4628 788 register CGFloat distanceOfBest, distance;
michaelm@4628 789 register UInt32 p1, p1Cached = 0, p1a, p1r, p1g, p1b, p2;
michaelm@4628 790 register SInt32 da, dr, dg, db;
michaelm@4628 791 register jint x, y, i;
michaelm@4628 792 BOOL cachedValueReady = NO;
michaelm@4628 793
michaelm@4628 794 if (indexedColorTable == NULL)
michaelm@4628 795 {
michaelm@4628 796 indexedColorTable = (UInt16*)malloc(indexSize*sizeof(UInt16)); // 15 bit precision, each entry capable of holding a 2 byte value
michaelm@4628 797 // (lower byte for the actual index, higher byte to mark it valid/invalid)
michaelm@4628 798
michaelm@4628 799 if (indexedColorTable != NULL)
michaelm@4628 800 {
michaelm@4628 801 memset((void*)indexedColorTable, invalidIndex, indexSize*sizeof(UInt16));
michaelm@4628 802 }
michaelm@4628 803 else
michaelm@4628 804 {
michaelm@4628 805 fprintf(stderr, "ERROR: malloc returns NULL for isdo->indexedColorTable in copyARGB_PRE_bitToIndexed_8bit");
michaelm@4628 806 return NULL;
michaelm@4628 807 }
michaelm@4628 808 }
michaelm@4628 809
michaelm@4628 810 register UInt16 cacheIndex;
michaelm@4628 811
michaelm@4628 812 for (y=0; y<h; y++)
michaelm@4628 813 {
michaelm@4628 814 for (x=0; x<w; x++)
michaelm@4628 815 {
michaelm@4628 816 p1 = *pixelsSrc;
michaelm@4628 817
michaelm@4628 818 if ((p1Cached != p1) || (cachedValueReady == NO))
michaelm@4628 819 {
michaelm@4628 820 p1a = ((p1 >> 24) & mask);
michaelm@4628 821
michaelm@4628 822 if (p1a != 0)
michaelm@4628 823 {
michaelm@4628 824 // extract color components
michaelm@4628 825 p1r = ((p1 >> 16) & mask);
michaelm@4628 826 p1g = ((p1 >> 8) & mask);
michaelm@4628 827 p1b = ((p1 >> 0) & mask);
michaelm@4628 828
michaelm@4628 829 // remove alpha pre
michaelm@4628 830 p1r = ((p1r * 0xff) + 0x7f) / p1a;
michaelm@4628 831 p1g = ((p1g * 0xff) + 0x7f) / p1a;
michaelm@4628 832 p1b = ((p1b * 0xff) + 0x7f) / p1a;
michaelm@4628 833
michaelm@4628 834 // clamp
michaelm@4628 835 p1r = (p1r <= 0xff) ? p1r : 0xff;
michaelm@4628 836 p1g = (p1g <= 0xff) ? p1g : 0xff;
michaelm@4628 837 p1b = (p1b <= 0xff) ? p1b : 0xff;
michaelm@4628 838 }
michaelm@4628 839 else
michaelm@4628 840 {
michaelm@4628 841 p1r = 0;
michaelm@4628 842 p1g = 0;
michaelm@4628 843 p1b = 0;
michaelm@4628 844 }
michaelm@4628 845
michaelm@4628 846 cacheIndex = (UInt16)(((p1a & indexMask) << 8) | ((p1r & indexMask) << 4) | ((p1g & indexMask) << 0) | ((p1b & indexMask) >> 4));
michaelm@4628 847 if (indexedColorTable[cacheIndex] == invalidIndex)
michaelm@4628 848 {
michaelm@4628 849 indexOfBest = 0;
michaelm@4628 850 distanceOfBest = DBL_MAX;
michaelm@4628 851
michaelm@4628 852 for (i=0; i<lutDataSize; i++)
michaelm@4628 853 {
michaelm@4628 854 p2 = lutdata[i];
michaelm@4628 855
michaelm@4628 856 da = p1a - ((p2 >> 24) & mask);
michaelm@4628 857 dr = p1r - ((p2 >> 16) & mask);
michaelm@4628 858 dg = p1g - ((p2 >> 8) & mask);
michaelm@4628 859 db = p1b - ((p2 >> 0) & mask);
michaelm@4628 860
michaelm@4628 861 distance = sqrt((da*da)+(dr*dr)+(dg*dg)+(db*db));
michaelm@4628 862 if (distance < distanceOfBest)
michaelm@4628 863 {
michaelm@4628 864 distanceOfBest = distance;
michaelm@4628 865 indexOfBest = i;
michaelm@4628 866 }
michaelm@4628 867 }
michaelm@4628 868
michaelm@4628 869 indexedColorTable[cacheIndex] = indexOfBest;
michaelm@4628 870 }
michaelm@4628 871 else
michaelm@4628 872 {
michaelm@4628 873 indexOfBest = indexedColorTable[cacheIndex];
michaelm@4628 874 }
michaelm@4628 875
michaelm@4628 876 cachedValueReady = YES;
michaelm@4628 877 p1Cached = p1;
michaelm@4628 878 indexOfBestCached = indexOfBest;
michaelm@4628 879 }
michaelm@4628 880 else
michaelm@4628 881 {
michaelm@4628 882 indexOfBest = indexOfBestCached;
michaelm@4628 883 }
michaelm@4628 884
michaelm@4628 885 *pixelsDst = indexOfBest;
michaelm@4628 886
michaelm@4628 887 pixelsDst++;
michaelm@4628 888 pixelsSrc++;
michaelm@4628 889 }
michaelm@4628 890 pixelsSrc += skipSrc;
michaelm@4628 891 pixelsDst += skipDst;
michaelm@4628 892 }
michaelm@4628 893
michaelm@4628 894 return indexedColorTable;
michaelm@4628 895 }
michaelm@4628 896
michaelm@4628 897 // callback from CG telling us it's done with the data. <rdar://problem/4762033>
michaelm@4628 898 static void releaseDataFromProvider(void *info, const void *data, size_t size)
michaelm@4628 899 {
michaelm@4628 900 if (data != NULL)
michaelm@4628 901 {
michaelm@4628 902 free(data);
michaelm@4628 903 }
michaelm@4628 904 }
michaelm@4628 905
michaelm@4628 906 IMAGE_SURFACE_INLINE void createContext(JNIEnv *env, ImageSDOps *isdo)
michaelm@4628 907 {
michaelm@4628 908 PRINT("createContext")
michaelm@4628 909
michaelm@4628 910 QuartzSDOps *qsdo = (QuartzSDOps*)isdo;
michaelm@4628 911 if (qsdo->cgRef == NULL) // lazy creation
michaelm@4628 912 {
michaelm@4628 913 size_t bitsPerComponent = isdo->contextInfo.bitsPerComponent;
michaelm@4628 914 CGColorSpaceRef colorSpace = isdo->contextInfo.colorSpace;
michaelm@4628 915 CGImageAlphaInfo alphaInfo = isdo->contextInfo.alphaInfo;
michaelm@4628 916
michaelm@4628 917 size_t bytesPerRow = isdo->contextInfo.bytesPerRow;
michaelm@4628 918 size_t size = bytesPerRow * isdo->height;
michaelm@4628 919 isdo->nativePixels = malloc(size);
michaelm@4628 920
michaelm@4628 921 if (isdo->nativePixels == NULL)
michaelm@4628 922 {
michaelm@4628 923 fprintf(stderr, "malloc failed for size %d bytes in ImageSurfaceData.createContext()\n", (int) size);
michaelm@4628 924 }
michaelm@4628 925
michaelm@4628 926 //fprintf(stderr, "isdo=%p isdo->type=%d, bitsPerComponent=%d, bytesPerRow=%d, colorSpace=%p, alphaInfo=%d, width=%d, height=%d, size=%d\n", isdo, type, (jint)bitsPerComponent, (jint)bytesPerRow, colorSpace, (jint)alphaInfo, (jint) isdo->width, (jint) isdo->height, (jint) size);
michaelm@4628 927
michaelm@4628 928 qsdo->cgRef = CGBitmapContextCreate(isdo->nativePixels, isdo->width, isdo->height, bitsPerComponent, bytesPerRow, colorSpace, alphaInfo);
michaelm@4628 929 isdo->dataProvider = CGDataProviderCreateWithData(NULL, isdo->nativePixels, size, releaseDataFromProvider);
michaelm@4628 930 }
michaelm@4628 931
michaelm@4628 932 //fprintf(stderr, "cgRef=%p\n", qsdo->cgRef);
michaelm@4628 933 if (qsdo->cgRef == NULL)
michaelm@4628 934 {
michaelm@4628 935 fprintf(stderr, "ERROR: (qsdo->cgRef == NULL) in createContext!\n");
michaelm@4628 936 }
michaelm@4628 937
michaelm@4628 938 // intitalize the context to match the Java coordinate system
michaelm@4628 939
michaelm@4628 940 // BG, since the context is created above, we can just concat
michaelm@4628 941 CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height));
michaelm@4628 942
michaelm@4628 943 CGContextSaveGState(qsdo->cgRef); // this will make sure we don't go pass device context settings
michaelm@4628 944 CGContextSaveGState(qsdo->cgRef); // this will put user settings on top, used by LazyStateManagement code
michaelm@4628 945 qsdo->newContext = YES;
michaelm@4628 946 }
michaelm@4628 947
michaelm@4628 948 IMAGE_SURFACE_INLINE void holdJavaPixels(JNIEnv* env, ImageSDOps* isdo)
michaelm@4628 949 {
michaelm@4628 950 PRINT("holdJavaPixels")
michaelm@4628 951
michaelm@4628 952 if (isdo->type != java_awt_image_BufferedImage_TYPE_CUSTOM)
michaelm@4628 953 {
michaelm@4628 954 Pixel8bit* pixels = NULL;
michaelm@4628 955 if (isdo->nrOfPixelsOwners == 0)
michaelm@4628 956 {
michaelm@4628 957 pixels = (Pixel8bit*)((*env)->GetPrimitiveArrayCritical(env, isdo->array, NULL));
michaelm@4628 958 if (pixels != NULL)
michaelm@4628 959 {
michaelm@4628 960 isdo->pixelsLocked = pixels;
michaelm@4628 961
michaelm@4628 962 isdo->pixels = isdo->pixelsLocked + isdo->offset;
michaelm@4628 963 }
michaelm@4628 964 else
michaelm@4628 965 {
michaelm@4628 966 fprintf(stderr, "ERROR: GetPrimitiveArrayCritical returns NULL for pixels in holdJavaPixels!\n");
michaelm@4628 967 }
michaelm@4628 968 }
michaelm@4628 969 isdo->nrOfPixelsOwners++;
michaelm@4628 970 }
michaelm@4628 971 else if (isdo->pixels == NULL)
michaelm@4628 972 {
michaelm@4628 973 isdo->pixels = (Pixel8bit*)((*env)->GetDirectBufferAddress(env, isdo->array));
michaelm@4628 974 }
michaelm@4628 975 }
michaelm@4628 976
michaelm@4628 977 IMAGE_SURFACE_INLINE void unholdJavaPixels(JNIEnv* env, ImageSDOps* isdo)
michaelm@4628 978 {
michaelm@4628 979 PRINT("unholdJavaPixels")
michaelm@4628 980
michaelm@4628 981 if (isdo->type != java_awt_image_BufferedImage_TYPE_CUSTOM)
michaelm@4628 982 {
michaelm@4628 983 isdo->nrOfPixelsOwners--;
michaelm@4628 984 if (isdo->nrOfPixelsOwners == 0)
michaelm@4628 985 {
michaelm@4628 986 isdo->pixels = NULL;
michaelm@4628 987
michaelm@4628 988 (*env)->ReleasePrimitiveArrayCritical(env, isdo->array, isdo->pixelsLocked, 0); // Do not use JNI_COMMIT, as that will not free the buffer copy when +ProtectJavaHeap is on.
michaelm@4628 989 isdo->pixelsLocked = NULL;
michaelm@4628 990 }
michaelm@4628 991 }
michaelm@4628 992 }
michaelm@4628 993
michaelm@4628 994 static void imageDataProvider_UnholdJavaPixels(void *info, const void *data, size_t size)
michaelm@4628 995 {
michaelm@4628 996 PRINT("imageDataProvider_UnholdJavaPixels")
michaelm@4628 997
michaelm@4628 998 ImageSDOps* isdo = (ImageSDOps*)info;
michaelm@4628 999 unholdJavaPixels([ThreadUtilities getJNIEnv], isdo);
michaelm@4628 1000 }
michaelm@4628 1001 static void imageDataProvider_FreeTempPixels(void *info, const void *data, size_t size)
michaelm@4628 1002 {
michaelm@4628 1003 PRINT("imageDataProvider_FreeTempPixels")
michaelm@4628 1004
michaelm@4628 1005 free((void *)data);
michaelm@4628 1006 }
michaelm@4628 1007 IMAGE_SURFACE_INLINE void syncFromJavaPixels(JNIEnv* env, ImageSDOps* isdo)
michaelm@4628 1008 {
michaelm@4628 1009 PRINT("syncFromJavaPixels")
michaelm@4628 1010
michaelm@4628 1011 // check to see if we have any work to do
michaelm@4628 1012 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] == 1)
michaelm@4628 1013 {
michaelm@4628 1014 // if we do, lock down Java pixels, this halts GarbageCollector!
michaelm@4628 1015 holdJavaPixels(env, isdo);
michaelm@4628 1016 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] == 1)
michaelm@4628 1017 {
michaelm@4628 1018 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 0;
michaelm@4628 1019
michaelm@4628 1020 void *dataProviderData = NULL;
michaelm@4628 1021 void *dataProviderInfo = NULL;
michaelm@4628 1022 void *dataProviderCallback = NULL;
michaelm@4628 1023 size_t dataProviderDataSize = 0;
michaelm@4628 1024 size_t width = isdo->width;
michaelm@4628 1025 size_t height = isdo->height;
michaelm@4628 1026 size_t bitsPerComponent = isdo->imageInfo.bitsPerComponent;
michaelm@4628 1027 size_t bitsPerPixel = isdo->imageInfo.bitsPerPixel;
michaelm@4628 1028 size_t bytesPerRow = 0;
michaelm@4628 1029 size_t extraBytesPerRow = 0; // these are the extra bytesPerRow used for alignement
michaelm@4628 1030
michaelm@4628 1031 switch (isdo->type)
michaelm@4628 1032 {
michaelm@4628 1033 //case java_awt_image_BufferedImage_TYPE_BYTE_BINARY: // mapped to TYPE_CUSTOM
michaelm@4628 1034 case java_awt_image_BufferedImage_TYPE_CUSTOM:
michaelm@4628 1035 holdJavaPixels(env, isdo); // we lock again since we are reusing pixels, but we must ensure CGImageRef immutability
michaelm@4628 1036 // we can lock these pixels down because they are nio based, so we don't halt the GarbageCollector
michaelm@4628 1037 bytesPerRow = isdo->javaPixelsBytesPerRow;
michaelm@4628 1038 dataProviderDataSize = bytesPerRow*isdo->height;
michaelm@4628 1039 dataProviderData = isdo->pixels;
michaelm@4628 1040 dataProviderInfo = isdo;
michaelm@4628 1041 dataProviderCallback = imageDataProvider_UnholdJavaPixels;
michaelm@4628 1042 break;
michaelm@4628 1043 default:
michaelm@4628 1044 bytesPerRow = isdo->imageInfo.bytesPerRow;
michaelm@4628 1045 dataProviderDataSize = bytesPerRow*height;
michaelm@4628 1046 dataProviderData = malloc(dataProviderDataSize);
michaelm@4628 1047 dataProviderInfo = isdo;
michaelm@4628 1048 dataProviderCallback = imageDataProvider_FreeTempPixels;
michaelm@4628 1049 }
michaelm@4628 1050
michaelm@4628 1051 switch (isdo->type)
michaelm@4628 1052 {
michaelm@4628 1053 //case java_awt_image_BufferedImage_TYPE_BYTE_BINARY: // mapped to TYPE_CUSTOM
michaelm@4628 1054 case java_awt_image_BufferedImage_TYPE_CUSTOM:
michaelm@4628 1055 customPixelsFromJava(env, isdo);
michaelm@4628 1056 break;
michaelm@4628 1057 case java_awt_image_BufferedImage_TYPE_INT_RGB:
michaelm@4628 1058 case java_awt_image_BufferedImage_TYPE_INT_ARGB:
michaelm@4628 1059 case java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE:
michaelm@4628 1060 case java_awt_image_BufferedImage_TYPE_USHORT_555_RGB:
michaelm@4628 1061 case java_awt_image_BufferedImage_TYPE_USHORT_GRAY:
michaelm@4628 1062 case java_awt_image_BufferedImage_TYPE_BYTE_GRAY:
michaelm@4628 1063 copyBits(width, height, isdo->javaPixelsBytesPerRow, (Pixel8bit*)isdo->pixels, bytesPerRow, dataProviderData);
michaelm@4628 1064 break;
michaelm@4628 1065 case java_awt_image_BufferedImage_TYPE_INT_BGR:
michaelm@4628 1066 copySwapRandB_32bit_TYPE_INT(width, height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel32bit*)isdo->pixels, dataProviderData, extraBytesPerRow);
michaelm@4628 1067 break;
michaelm@4628 1068 case java_awt_image_BufferedImage_TYPE_4BYTE_ABGR:
michaelm@4628 1069 case java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE:
michaelm@4628 1070 copySwapRandB_32bit_TYPE_4BYTE(width, height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel32bit*)isdo->pixels, dataProviderData, extraBytesPerRow);
michaelm@4628 1071 break;
michaelm@4628 1072 case java_awt_image_BufferedImage_TYPE_3BYTE_BGR:
michaelm@4628 1073 copyBGR_24bitToXRGB_32bit(width, height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, isdo->pixels, dataProviderData, extraBytesPerRow);
michaelm@4628 1074 break;
michaelm@4628 1075 case sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB:
michaelm@4628 1076 copyRGB_24bitToXRGB_32bit(width, height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, isdo->pixels, dataProviderData, extraBytesPerRow);
michaelm@4628 1077 break;
michaelm@4628 1078 case java_awt_image_BufferedImage_TYPE_USHORT_565_RGB:
michaelm@4628 1079 copy565_16bitTo555_16bit(width, height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel16bit*)isdo->pixels, dataProviderData, extraBytesPerRow);
michaelm@4628 1080 break;
michaelm@4628 1081 case java_awt_image_BufferedImage_TYPE_BYTE_INDEXED:
michaelm@4628 1082 copyIndexed_8bitToARGB_32bit(width, height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, isdo->pixels, isdo->lutData, dataProviderData, extraBytesPerRow);
michaelm@4628 1083 break;
michaelm@4628 1084 default:
michaelm@4628 1085 break;
michaelm@4628 1086 }
michaelm@4628 1087
michaelm@4628 1088 CGDataProviderRef provider = CGDataProviderCreateWithData(dataProviderInfo, dataProviderData, dataProviderDataSize, dataProviderCallback);
michaelm@4628 1089 CGImageRef javaImg = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow,
michaelm@4628 1090 isdo->imageInfo.colorSpace, isdo->imageInfo.alphaInfo, provider, NULL, NO, kCGRenderingIntentDefault);
michaelm@4628 1091 //fprintf(stderr, "javaImg=%p\n", javaImg);
michaelm@4628 1092 CGDataProviderRelease(provider);
michaelm@4628 1093
michaelm@4628 1094 if (javaImg != NULL)
michaelm@4628 1095 {
michaelm@4628 1096 QuartzSDOps *qsdo = (QuartzSDOps*)isdo;
michaelm@4628 1097
michaelm@4628 1098 if (isdo->imgRef != NULL)
michaelm@4628 1099 {
michaelm@4628 1100 CGImageRelease(isdo->imgRef);
michaelm@4628 1101 isdo->imgRef = NULL;
michaelm@4628 1102 }
michaelm@4628 1103
michaelm@4628 1104 if (qsdo->cgRef == NULL)
michaelm@4628 1105 {
michaelm@4628 1106 createContext(env, isdo);
michaelm@4628 1107 }
michaelm@4628 1108
michaelm@4628 1109 if (qsdo->cgRef != NULL)
michaelm@4628 1110 {
michaelm@4628 1111 CGContextSaveGState(qsdo->cgRef);
skovatch@5304 1112 CGAffineTransform currCTM = CGContextGetCTM(qsdo->cgRef);
skovatch@5304 1113 CGAffineTransform inverse = CGAffineTransformInvert(currCTM);
skovatch@5304 1114 CGContextConcatCTM(qsdo->cgRef, inverse);
michaelm@4628 1115 CGContextSetBlendMode(qsdo->cgRef, kCGBlendModeCopy);
michaelm@4628 1116 CGContextSetAlpha(qsdo->cgRef, 1.0f);
michaelm@4628 1117 CGContextDrawImage(qsdo->cgRef, CGRectMake(0, 0, width, height), javaImg);
michaelm@4628 1118 CGContextFlush(qsdo->cgRef);
michaelm@4628 1119 CGContextRestoreGState(qsdo->cgRef);
michaelm@4628 1120 CGImageRelease(javaImg);
michaelm@4628 1121 }
michaelm@4628 1122 else
michaelm@4628 1123 {
michaelm@4628 1124 fprintf(stderr, "ERROR: (cgRef == NULL) in syncFromJavaPixels!\n");
michaelm@4628 1125 }
michaelm@4628 1126 }
michaelm@4628 1127 else
michaelm@4628 1128 {
michaelm@4628 1129 //fprintf(stderr, "isdo->type=%d, isdo->width=%d, isdo->height=%d, isdo->imageInfo.bitsPerComponent=%d, isdo->imageInfo.bytesPerPixel=%d, isdo->imageInfo.bitsPerPixel=%d, isdo->imageInfo.bytesPerRow=%d, isdo->imageInfo.colorSpace=%p, isdo->imageInfo.alphaInfo=%d\n",
michaelm@4628 1130 //(jint)isdo->type, (jint)isdo->width, (jint)isdo->height, (jint)isdo->imageInfo.bitsPerComponent, (jint)isdo->imageInfo.bytesPerPixel, (jint)isdo->imageInfo.bitsPerPixel, (jint)isdo->imageInfo.bytesPerRow, isdo->imageInfo.colorSpace, (jint)isdo->imageInfo.alphaInfo);
michaelm@4628 1131 fprintf(stderr, "ERROR: (javaImg == NULL) in syncFromJavaPixels!\n");
michaelm@4628 1132 }
michaelm@4628 1133 }
michaelm@4628 1134
michaelm@4628 1135 unholdJavaPixels(env, isdo);
michaelm@4628 1136 }
michaelm@4628 1137 }
michaelm@4628 1138
michaelm@4628 1139 IMAGE_SURFACE_INLINE void processPixels(ImageSDOps* isdo, jint x, jint y, jint width, jint height, void (*processPixelsCallback) (ImageSDOps *, jint, Pixel32bit *, jint, jint, jint, jint))
michaelm@4628 1140 {
michaelm@4628 1141 processPixelsCallback(isdo, (jint) isdo->contextInfo.bytesPerRow, (Pixel32bit *) isdo->nativePixels, x, y, width, height);
michaelm@4628 1142 }
michaelm@4628 1143
michaelm@4628 1144 IMAGE_SURFACE_INLINE void syncToJavaPixels_processPixelsCallback(ImageSDOps* isdo, jint nativePixelsBytesPerRow, Pixel32bit *dataSrc, jint x, jint y, jint width, jint height)
michaelm@4628 1145 {
michaelm@4628 1146 switch (isdo->type)
michaelm@4628 1147 {
michaelm@4628 1148 case java_awt_image_BufferedImage_TYPE_3BYTE_BGR:
michaelm@4628 1149 copyARGB_PRE_32bitToBGR_24bit(isdo->width, isdo->height, nativePixelsBytesPerRow, dataSrc, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, isdo->pixels);
michaelm@4628 1150 break;
michaelm@4628 1151 case sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB:
michaelm@4628 1152 copyARGB_PRE_32bitToRGB_24bit(isdo->width, isdo->height, nativePixelsBytesPerRow, dataSrc, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, isdo->pixels);
michaelm@4628 1153 break;
michaelm@4628 1154 case java_awt_image_BufferedImage_TYPE_USHORT_GRAY:
michaelm@4628 1155 copyARGB_PRE_32bitToGray_16bit(isdo->width, isdo->height, nativePixelsBytesPerRow, dataSrc, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel16bit*)isdo->pixels);
michaelm@4628 1156 break;
michaelm@4628 1157 case java_awt_image_BufferedImage_TYPE_BYTE_INDEXED:
michaelm@4628 1158 isdo->indexedColorTable = copyARGB_PRE_bitToIndexed_8bit(isdo->width, isdo->height, nativePixelsBytesPerRow, dataSrc, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, isdo->pixels, isdo->lutData, isdo->lutDataSize, isdo->indexedColorTable);
michaelm@4628 1159 break;
michaelm@4628 1160 default:
michaelm@4628 1161 break;
michaelm@4628 1162 }
michaelm@4628 1163 }
michaelm@4628 1164
michaelm@4628 1165
michaelm@4628 1166 IMAGE_SURFACE_INLINE void syncToJavaPixels(JNIEnv* env, ImageSDOps* isdo)
michaelm@4628 1167 {
michaelm@4628 1168 PRINT("syncToJavaPixels")
michaelm@4628 1169
michaelm@4628 1170 holdJavaPixels(env, isdo);
michaelm@4628 1171
michaelm@4628 1172 QuartzSDOps *qsdo = (QuartzSDOps*)isdo;
michaelm@4628 1173 if (qsdo->cgRef == NULL)
michaelm@4628 1174 {
michaelm@4628 1175 createContext(env, isdo);
michaelm@4628 1176 }
michaelm@4628 1177
michaelm@4628 1178 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNativePixelsChangedIndex] = 0;
michaelm@4628 1179
michaelm@4628 1180 if (isdo->contextInfo.canUseJavaPixelsAsContext == YES)
michaelm@4628 1181 {
michaelm@4628 1182
michaelm@4628 1183 jint srcBytesPerRow = isdo->contextInfo.bytesPerRow;
michaelm@4628 1184 jint dstBytesPerRow = isdo->javaPixelsBytesPerRow;
michaelm@4628 1185 jint h = isdo->height;
michaelm@4628 1186 Pixel8bit *pixelsSrc = isdo->nativePixels;
michaelm@4628 1187 Pixel8bit *pixelsDst = isdo->pixels;
michaelm@4628 1188
michaelm@4628 1189 if (srcBytesPerRow == dstBytesPerRow)
michaelm@4628 1190 {
michaelm@4628 1191 memcpy(pixelsDst, pixelsSrc, h * dstBytesPerRow);
michaelm@4628 1192 }
michaelm@4628 1193 else
michaelm@4628 1194 {
michaelm@4628 1195 jint widthInBytes = isdo->width * isdo->contextInfo.bytesPerPixel;
michaelm@4628 1196 jint y;
michaelm@4628 1197 for (y=0; y < h; y++)
michaelm@4628 1198 {
michaelm@4628 1199 memcpy(pixelsDst, pixelsSrc, widthInBytes);
michaelm@4628 1200
michaelm@4628 1201 pixelsSrc += srcBytesPerRow;
michaelm@4628 1202 pixelsDst += dstBytesPerRow;
michaelm@4628 1203 }
michaelm@4628 1204 }
michaelm@4628 1205
michaelm@4628 1206 switch (isdo->type)
michaelm@4628 1207 {
michaelm@4628 1208 //case java_awt_image_BufferedImage_TYPE_BYTE_BINARY: // mapped to TYPE_CUSTOM
michaelm@4628 1209 case java_awt_image_BufferedImage_TYPE_CUSTOM:
michaelm@4628 1210 customPixelsToJava(env, isdo);
michaelm@4628 1211 break;
michaelm@4628 1212 case java_awt_image_BufferedImage_TYPE_INT_ARGB:
michaelm@4628 1213 removeAlphaPre_32bit(isdo->width, isdo->height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel32bit*)isdo->pixels);
michaelm@4628 1214 break;
michaelm@4628 1215 case java_awt_image_BufferedImage_TYPE_4BYTE_ABGR:
michaelm@4628 1216 swapRandBAndRemoveAlphaPre_32bit(isdo->width, isdo->height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel32bit*)isdo->pixels);
michaelm@4628 1217 break;
michaelm@4628 1218 case java_awt_image_BufferedImage_TYPE_INT_BGR:
michaelm@4628 1219 swapRandB_32bit_TYPE_INT(isdo->width, isdo->height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel32bit*)isdo->pixels);
michaelm@4628 1220 break;
michaelm@4628 1221 case java_awt_image_BufferedImage_TYPE_4BYTE_ABGR_PRE:
michaelm@4628 1222 swapRandB_32bit_TYPE_4BYTE(isdo->width, isdo->height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel32bit*)isdo->pixels);
michaelm@4628 1223 break;
michaelm@4628 1224 case java_awt_image_BufferedImage_TYPE_USHORT_565_RGB:
michaelm@4628 1225 map555_16bitTo565_16bit(isdo->width, isdo->height, isdo->javaPixelsBytesPerRow, isdo->javaPixelBytes, (Pixel16bit*)isdo->pixels);
michaelm@4628 1226 break;
michaelm@4628 1227 default:
michaelm@4628 1228 break;
michaelm@4628 1229 }
michaelm@4628 1230 }
michaelm@4628 1231 else
michaelm@4628 1232 {
michaelm@4628 1233 processPixels(isdo, 0, 0, isdo->width, isdo->height, &syncToJavaPixels_processPixelsCallback);
michaelm@4628 1234 }
michaelm@4628 1235
michaelm@4628 1236 unholdJavaPixels(env, isdo);
michaelm@4628 1237 }
michaelm@4628 1238
michaelm@4628 1239
michaelm@4628 1240 IMAGE_SURFACE_INLINE jboolean xorSurfacePixels(JNIEnv *env, jobject dstIsd, jobject srcIsd, jint colorXOR, jint x, jint y, jint w, jint h)
michaelm@4628 1241 {
michaelm@4628 1242 PRINT("xorSurfacePixels")
michaelm@4628 1243
michaelm@4628 1244 jboolean handled = JNI_FALSE;
michaelm@4628 1245
michaelm@4628 1246 JNF_COCOA_ENTER(env);
michaelm@4628 1247 ImageSDOps* srcIsdo = LockImagePixels(env, srcIsd);
michaelm@4628 1248 ImageSDOps* dstIsdo = LockImagePixels(env, dstIsd);
michaelm@4628 1249
michaelm@4628 1250 if ((x < 0) || (y < 0) || (x+w > dstIsdo->width) || (y+h > dstIsdo->height) || (w > srcIsdo->width) || (h > srcIsdo->height))
michaelm@4628 1251 {
michaelm@4628 1252 #ifdef PRINT_WARNINGS
michaelm@4628 1253 fprintf(stderr, "xorSurfacePixels INVALID parameters: x=%d, y=%d, w=%d, h=%d\n", x, y, w, h);
michaelm@4628 1254 fprintf(stderr, " dstIsdo->width=%d, dstIsdo->height=%d, biqsdoPixels->width=%d, biqsdoPixels->height=%d\n",
michaelm@4628 1255 dstIsdo->width, dstIsdo->height, srcIsdo->width, srcIsdo->height);
michaelm@4628 1256 #endif
michaelm@4628 1257 UnlockImagePixels(env, srcIsdo);
michaelm@4628 1258 UnlockImagePixels(env, dstIsdo);
michaelm@4628 1259
michaelm@4628 1260 return JNI_FALSE;
michaelm@4628 1261 }
michaelm@4628 1262
michaelm@4628 1263 jint offset = (dstIsdo->width*y)+x;
michaelm@4628 1264 register Pixel32bit* dstPixels = (Pixel32bit*)dstIsdo->pixels;
michaelm@4628 1265 register jint skip = dstIsdo->width - w;
michaelm@4628 1266 register Pixel32bit* srcPixels = (Pixel32bit*)srcIsdo->pixels;
michaelm@4628 1267 register jint skipPixels = srcIsdo->width - w;
michaelm@4628 1268 register jint i, j;
michaelm@4628 1269
michaelm@4628 1270 dstPixels += offset;
michaelm@4628 1271
michaelm@4628 1272 switch (dstIsdo->type)
michaelm@4628 1273 {
michaelm@4628 1274 case java_awt_image_BufferedImage_TYPE_INT_RGB:
michaelm@4628 1275 case java_awt_image_BufferedImage_TYPE_INT_ARGB:
michaelm@4628 1276 case java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE:
michaelm@4628 1277 {
michaelm@4628 1278 dstIsdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
michaelm@4628 1279
michaelm@4628 1280 if (dstIsdo->type == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)
michaelm@4628 1281 {
michaelm@4628 1282 Pixel8bit alpha = (colorXOR>>24)&0xff;
michaelm@4628 1283 Pixel8bit red = (colorXOR>>16)&0xff;
michaelm@4628 1284 red = (jint)(((CGFloat)red/255.0f * (CGFloat)alpha/255.0f)*255.0f);
michaelm@4628 1285 Pixel8bit green = (colorXOR>>8)&0xff;
michaelm@4628 1286 green = (jint)(((CGFloat)green/255.0f * (CGFloat)alpha/255.0f)*255.0f);
michaelm@4628 1287 Pixel8bit blue = (colorXOR>>0)&0xff;
michaelm@4628 1288 blue = (jint)(((CGFloat)blue/255.0f * (CGFloat)alpha/255.0f)*255.0f);
michaelm@4628 1289 colorXOR = (alpha<<24) | (red<<16) | (green<<8) | blue; // the color is now alpha premultiplied
michaelm@4628 1290 }
michaelm@4628 1291
michaelm@4628 1292 for (i=0; i<h; i++)
michaelm@4628 1293 {
michaelm@4628 1294 for (j=0; j<w; j++)
michaelm@4628 1295 {
michaelm@4628 1296 Pixel32bit srcPixel = *srcPixels;
michaelm@4628 1297 Pixel8bit pixelAlpha = (srcPixel>>24);
michaelm@4628 1298 if (pixelAlpha > XOR_ALPHA_CUTOFF)
michaelm@4628 1299 {
michaelm@4628 1300 *dstPixels = (*dstPixels ^ (srcPixel ^ colorXOR));
michaelm@4628 1301 }
michaelm@4628 1302 dstPixels++; srcPixels++;
michaelm@4628 1303 }
michaelm@4628 1304
michaelm@4628 1305 dstPixels += skip;
michaelm@4628 1306 srcPixels += skipPixels;
michaelm@4628 1307 }
michaelm@4628 1308
michaelm@4628 1309 handled = JNI_TRUE;
michaelm@4628 1310 break;
michaelm@4628 1311 }
michaelm@4628 1312 default:
michaelm@4628 1313 {
michaelm@4628 1314 handled = JNI_FALSE;
michaelm@4628 1315 #if defined(PRINT_WARNINGS)
michaelm@4628 1316 fprintf(stderr, "WARNING: unknown type (%d) in compositeXOR\n", dstIsdo->type);
michaelm@4628 1317 PrintImageInfo(dstIsdo);
michaelm@4628 1318 #endif
michaelm@4628 1319 }
michaelm@4628 1320 }
michaelm@4628 1321
michaelm@4628 1322 UnlockImagePixels(env, srcIsdo);
michaelm@4628 1323 UnlockImagePixels(env, dstIsdo);
michaelm@4628 1324
michaelm@4628 1325 JNF_COCOA_EXIT(env);
michaelm@4628 1326 return handled;
michaelm@4628 1327 }
michaelm@4628 1328
michaelm@4628 1329 IMAGE_SURFACE_INLINE jboolean clearSurfacePixels(JNIEnv *env, jobject bisd, jint w, jint h)
michaelm@4628 1330 {
michaelm@4628 1331 PRINT("clearSurfacePixels")
michaelm@4628 1332 jboolean handled = JNI_FALSE;
michaelm@4628 1333
michaelm@4628 1334 JNF_COCOA_ENTER(env);
michaelm@4628 1335
michaelm@4628 1336 ImageSDOps *isdo = LockImagePixels(env, bisd);
michaelm@4628 1337
michaelm@4628 1338 if (isdo->type == java_awt_image_BufferedImage_TYPE_INT_ARGB_PRE)
michaelm@4628 1339 {
michaelm@4628 1340 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
michaelm@4628 1341
michaelm@4628 1342 w = (w < isdo->width) ? w : isdo->width;
michaelm@4628 1343 h = (h < isdo->height) ? h : isdo->height;
michaelm@4628 1344
michaelm@4628 1345 register Pixel32bit* data = (Pixel32bit*)isdo->pixels;
michaelm@4628 1346 register jint i;
michaelm@4628 1347 if ((w < isdo->width) || (h < isdo->height)) //cmcnote: necessary to special-case for small height? wouldn't 4*w*h do it?
michaelm@4628 1348 {
michaelm@4628 1349 register jint skip = isdo->width;
michaelm@4628 1350 register jint row = 4*w;
michaelm@4628 1351 for (i=0; i<h; i++)
michaelm@4628 1352 {
michaelm@4628 1353 bzero(data, row);
michaelm@4628 1354 data += skip;
michaelm@4628 1355 }
michaelm@4628 1356 }
michaelm@4628 1357 else
michaelm@4628 1358 {
michaelm@4628 1359 bzero(data, 4*w*h);
michaelm@4628 1360 }
michaelm@4628 1361
michaelm@4628 1362 handled = JNI_TRUE;
michaelm@4628 1363 }
michaelm@4628 1364 UnlockImagePixels(env, isdo);
michaelm@4628 1365
michaelm@4628 1366 JNF_COCOA_EXIT(env);
michaelm@4628 1367
michaelm@4628 1368 return handled;
michaelm@4628 1369 }
michaelm@4628 1370
michaelm@4628 1371 static void ImageSD_startCGContext(JNIEnv *env, QuartzSDOps *qsdo, SDRenderType renderType)
michaelm@4628 1372 {
michaelm@4628 1373 PRINT("ImageSD_startCGContext")
michaelm@4628 1374
michaelm@4628 1375 ImageSDOps *isdo = (ImageSDOps*)qsdo;
michaelm@4628 1376
michaelm@4628 1377 pthread_mutex_lock(&isdo->lock);
michaelm@4628 1378
michaelm@4628 1379 if (isdo->imgRef != NULL)
michaelm@4628 1380 {
michaelm@4628 1381 CGImageRelease(isdo->imgRef);
michaelm@4628 1382 isdo->imgRef = NULL;
michaelm@4628 1383 }
michaelm@4628 1384
michaelm@4628 1385 if (qsdo->cgRef == NULL)
michaelm@4628 1386 {
michaelm@4628 1387 createContext(env, isdo);
michaelm@4628 1388 }
michaelm@4628 1389 else
michaelm@4628 1390 {
michaelm@4628 1391 qsdo->newContext = NO;
michaelm@4628 1392 }
michaelm@4628 1393
michaelm@4628 1394 if (qsdo->cgRef != NULL)
michaelm@4628 1395 {
michaelm@4628 1396 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kImageStolenIndex] == 1)
michaelm@4628 1397 {
michaelm@4628 1398 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
michaelm@4628 1399 }
michaelm@4628 1400
michaelm@4628 1401 // sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex can be set right above or somewhere else
michaelm@4628 1402 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] == 1)
michaelm@4628 1403 {
michaelm@4628 1404 syncFromJavaPixels(env, isdo);
michaelm@4628 1405 }
michaelm@4628 1406
michaelm@4628 1407 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNativePixelsChangedIndex] = 1;
michaelm@4628 1408
michaelm@4628 1409 SetUpCGContext(env, qsdo, renderType);
michaelm@4628 1410 }
michaelm@4628 1411 }
michaelm@4628 1412 static void ImageSD_finishCGContext(JNIEnv *env, QuartzSDOps *qsdo)
michaelm@4628 1413 {
michaelm@4628 1414 PRINT("ImageSD_finishCGContext")
michaelm@4628 1415
michaelm@4628 1416 ImageSDOps *isdo = (ImageSDOps*)qsdo;
michaelm@4628 1417
michaelm@4628 1418 if (qsdo->cgRef != NULL)
michaelm@4628 1419 {
michaelm@4628 1420 CompleteCGContext(env, qsdo);
michaelm@4628 1421
michaelm@4628 1422 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kImageStolenIndex] == 1)
michaelm@4628 1423 {
michaelm@4628 1424 syncToJavaPixels(env, isdo);
michaelm@4628 1425 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
michaelm@4628 1426 }
michaelm@4628 1427 }
michaelm@4628 1428
michaelm@4628 1429 pthread_mutex_unlock(&isdo->lock);
michaelm@4628 1430 }
michaelm@4628 1431
michaelm@4628 1432 static void ImageSD_dispose(JNIEnv *env, SurfaceDataOps *ops)
michaelm@4628 1433 {
michaelm@4628 1434 PRINT("ImageSD_dispose")
michaelm@4628 1435
michaelm@4628 1436 // copied from BufImg_Dispose in BufImgSurfaceData.c
michaelm@4628 1437 {
michaelm@4628 1438 /* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */
michaelm@4628 1439 BufImgSDOps *bisdo = (BufImgSDOps *)ops;
michaelm@4628 1440 (*env)->DeleteWeakGlobalRef(env, bisdo->array);
michaelm@4628 1441 if (bisdo->lutarray != NULL) {
michaelm@4628 1442 (*env)->DeleteWeakGlobalRef(env, bisdo->lutarray);
michaelm@4628 1443 }
michaelm@4628 1444 if (bisdo->icm != NULL) {
michaelm@4628 1445 (*env)->DeleteWeakGlobalRef(env, bisdo->icm);
michaelm@4628 1446 }
michaelm@4628 1447 }
michaelm@4628 1448
michaelm@4628 1449 QuartzSDOps *qsdo = (QuartzSDOps *)ops;
michaelm@4628 1450
michaelm@4628 1451 if (qsdo->graphicsStateInfo.batchedLines != NULL)
michaelm@4628 1452 {
michaelm@4628 1453 free(qsdo->graphicsStateInfo.batchedLines);
michaelm@4628 1454 qsdo->graphicsStateInfo.batchedLines = NULL;
michaelm@4628 1455 }
michaelm@4628 1456
michaelm@4628 1457 JNFDeleteGlobalRef(env, qsdo->javaGraphicsStatesObjects);
michaelm@4628 1458
michaelm@4628 1459 if (qsdo->cgRef != NULL)
michaelm@4628 1460 {
michaelm@4628 1461 CGContextRelease(qsdo->cgRef);
michaelm@4628 1462 qsdo->cgRef = NULL;
michaelm@4628 1463 }
michaelm@4628 1464
michaelm@4628 1465 ImageSDOps *isdo = (ImageSDOps *)ops;
michaelm@4628 1466
michaelm@4628 1467 if (isdo->dataProvider != NULL)
michaelm@4628 1468 {
michaelm@4628 1469 CGDataProviderRelease(isdo->dataProvider);
michaelm@4628 1470 isdo->dataProvider = NULL;
michaelm@4628 1471 }
michaelm@4628 1472 if (isdo->imgRef != NULL)
michaelm@4628 1473 {
michaelm@4628 1474 CGImageRelease(isdo->imgRef);
michaelm@4628 1475 isdo->imgRef = NULL;
michaelm@4628 1476 }
michaelm@4628 1477 if (isdo->indexedColorTable != NULL)
michaelm@4628 1478 {
michaelm@4628 1479 free(isdo->indexedColorTable);
michaelm@4628 1480 isdo->indexedColorTable = NULL;
michaelm@4628 1481 }
michaelm@4628 1482 if (isdo->lutData != NULL)
michaelm@4628 1483 {
michaelm@4628 1484 free(isdo->lutData);
michaelm@4628 1485 isdo->indexedColorTable = NULL;
michaelm@4628 1486 }
michaelm@4628 1487 if (isdo->array != NULL)
michaelm@4628 1488 {
michaelm@4628 1489 JNFDeleteGlobalRef(env, isdo->array);
michaelm@4628 1490 isdo->array = NULL;
michaelm@4628 1491 }
michaelm@4628 1492 if (isdo->icm != NULL)
michaelm@4628 1493 {
michaelm@4628 1494 JNFDeleteGlobalRef(env, isdo->icm);
michaelm@4628 1495 isdo->icm = NULL;
michaelm@4628 1496 }
michaelm@4628 1497
michaelm@4628 1498 if (isdo->nsRef) {
michaelm@4628 1499 CFRelease(isdo->nsRef); // GC
michaelm@4628 1500 isdo->nsRef = nil;
michaelm@4628 1501 }
michaelm@4628 1502
michaelm@4628 1503 pthread_mutex_destroy(&isdo->lock);
michaelm@4628 1504 }
michaelm@4628 1505
michaelm@4628 1506 // used by XOR (Java pixels must be up to date)
michaelm@4628 1507 ImageSDOps* LockImagePixels(JNIEnv* env, jobject imageSurfaceData)
michaelm@4628 1508 {
michaelm@4628 1509 PRINT("LockImagePixels")
michaelm@4628 1510
michaelm@4628 1511 ImageSDOps* isdo = (ImageSDOps*)SurfaceData_GetOps(env, imageSurfaceData);
michaelm@4628 1512
michaelm@4628 1513 pthread_mutex_lock(&isdo->lock);
michaelm@4628 1514
michaelm@4628 1515 holdJavaPixels(env, isdo);
michaelm@4628 1516
michaelm@4628 1517 // if we need to access this image's pixels we need to convert native pixels (if any) back to Java
michaelm@4628 1518 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNativePixelsChangedIndex] == 1)
michaelm@4628 1519 {
michaelm@4628 1520 syncToJavaPixels(env, isdo);
michaelm@4628 1521 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
michaelm@4628 1522 }
michaelm@4628 1523
michaelm@4628 1524 return isdo;
michaelm@4628 1525 }
michaelm@4628 1526 void UnlockImagePixels(JNIEnv* env, ImageSDOps* isdo)
michaelm@4628 1527 {
michaelm@4628 1528 PRINT("UnlockImagePixels")
michaelm@4628 1529 // don't do that since the native pixels haven't changed (Java pixels == native pixels)
michaelm@4628 1530 //syncToJavaPixels(env, isdo);
michaelm@4628 1531
michaelm@4628 1532 unholdJavaPixels(env, isdo);
michaelm@4628 1533
michaelm@4628 1534 pthread_mutex_unlock(&isdo->lock);
michaelm@4628 1535 }
michaelm@4628 1536
michaelm@4628 1537 // used by drawImage (native pixels must be up to date)
michaelm@4628 1538 ImageSDOps* LockImage(JNIEnv* env, jobject imageSurfaceData)
michaelm@4628 1539 {
michaelm@4628 1540 PRINT("LockImage")
michaelm@4628 1541
michaelm@4628 1542 ImageSDOps* isdo = (ImageSDOps*)SurfaceData_GetOps(env, imageSurfaceData);
michaelm@4628 1543
michaelm@4628 1544 pthread_mutex_lock(&isdo->lock);
michaelm@4628 1545
michaelm@4628 1546 // if we need to access this image's pixels we need to convert native pixels (if any) back to Java
michaelm@4628 1547 // for those images whose context type doesn't match layer type or is a custom image
michaelm@4628 1548 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kImageStolenIndex] == 1)
michaelm@4628 1549 {
michaelm@4628 1550 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
michaelm@4628 1551 }
michaelm@4628 1552
michaelm@4628 1553 // sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex can be set right above or somewhere else
michaelm@4628 1554 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] == 1)
michaelm@4628 1555 {
michaelm@4628 1556 syncFromJavaPixels(env, isdo);
michaelm@4628 1557 }
michaelm@4628 1558
michaelm@4628 1559 return isdo;
michaelm@4628 1560 }
michaelm@4628 1561 void UnlockImage(JNIEnv* env, ImageSDOps* isdo)
michaelm@4628 1562 {
michaelm@4628 1563 PRINT("UnlockImage")
michaelm@4628 1564
michaelm@4628 1565 // don't do that since the native pixels haven't changed (Java pixels == native pixels)
michaelm@4628 1566 //syncToJavaPixels(env, isdo);
michaelm@4628 1567
michaelm@4628 1568 pthread_mutex_unlock(&isdo->lock);
michaelm@4628 1569 }
michaelm@4628 1570
michaelm@4628 1571 JNIEXPORT jobject JNICALL Java_sun_awt_image_BufImgSurfaceData_getSurfaceData
michaelm@4628 1572 (JNIEnv *env, jclass bisd, jobject bufImg)
michaelm@4628 1573 {
michaelm@4628 1574 static jfieldID sDataID = 0;
michaelm@4628 1575 if (sDataID == 0)
michaelm@4628 1576 {
michaelm@4628 1577 static char *bimgName = "java/awt/image/BufferedImage";
michaelm@4628 1578 jclass bimg = (*env)->FindClass(env, bimgName);
michaelm@4628 1579 sDataID = (*env)->GetFieldID(env, bimg, "sData", "Lsun/java2d/SurfaceData;");
michaelm@4628 1580 }
michaelm@4628 1581
michaelm@4628 1582 return (*env)->GetObjectField(env, bufImg, sDataID);
michaelm@4628 1583 }
michaelm@4628 1584
michaelm@4628 1585 JNIEXPORT void JNICALL Java_sun_awt_image_BufImgSurfaceData_setSurfaceData
michaelm@4628 1586 (JNIEnv *env, jclass bisd, jobject bufImg, jobject sData)
michaelm@4628 1587 {
michaelm@4628 1588 static jfieldID sDataID = 0;
michaelm@4628 1589 if (sDataID == 0)
michaelm@4628 1590 {
michaelm@4628 1591 static char *bimgName = "java/awt/image/BufferedImage";
michaelm@4628 1592 jclass bimg = (*env)->FindClass(env, bimgName);
michaelm@4628 1593 sDataID = (*env)->GetFieldID(env, bimg, "sData", "Lsun/java2d/SurfaceData;");
michaelm@4628 1594 }
michaelm@4628 1595
michaelm@4628 1596 (*env)->SetObjectField(env, bufImg, sDataID, sData);
michaelm@4628 1597 }
michaelm@4628 1598
michaelm@4628 1599 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_initIDs(JNIEnv *env, jclass bisd)
michaelm@4628 1600 {
michaelm@4628 1601 //PRINT("initIDs")
michaelm@4628 1602 // copied from Java_sun_awt_image_BufImgSurfaceData_initIDs in BufImgSurfaceData.c
michaelm@4628 1603 {
michaelm@4628 1604 static char *icmName = "java/awt/image/IndexColorModel";
michaelm@4628 1605 jclass icm;
michaelm@4628 1606
michaelm@4628 1607 if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
michaelm@4628 1608 JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
michaelm@4628 1609 return;
michaelm@4628 1610 }
michaelm@4628 1611
michaelm@4628 1612 icm = (*env)->FindClass(env, icmName);
michaelm@4628 1613 if (icm == NULL) {
michaelm@4628 1614 return;
michaelm@4628 1615 }
michaelm@4628 1616
michaelm@4628 1617 rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I");
michaelm@4628 1618 allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z");
michaelm@4628 1619 mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I");
michaelm@4628 1620 CMpDataID = (*env)->GetFieldID(env, icm, "pData", "J");
michaelm@4628 1621 if (allGrayID == 0 || rgbID == 0 || mapSizeID == 0 || CMpDataID == 0) {
michaelm@4628 1622 JNU_ThrowInternalError(env, "Could not get field IDs");
michaelm@4628 1623 }
michaelm@4628 1624 }
michaelm@4628 1625
michaelm@4628 1626 gColorspaceRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
michaelm@4628 1627 gColorspaceGray = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
michaelm@4628 1628 //fprintf(stderr, "gColorspaceRGB=%p, gColorspaceGray=%p\n", gColorspaceRGB, gColorspaceGray);
michaelm@4628 1629 }
michaelm@4628 1630
michaelm@4628 1631 JNIEXPORT jobject JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_getSurfaceData
michaelm@4628 1632 (JNIEnv *env, jclass bisd, jobject bufImg)
michaelm@4628 1633 {
michaelm@4628 1634 PRINT("getSurfaceData")
michaelm@4628 1635
michaelm@4628 1636 return JNFGetObjectField(env, bufImg, jm_SurfaceData);
michaelm@4628 1637 }
michaelm@4628 1638
michaelm@4628 1639 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_setSurfaceData
michaelm@4628 1640 (JNIEnv *env, jclass bisd, jobject bufImg, jobject sData)
michaelm@4628 1641 {
michaelm@4628 1642 PRINT("setSurfaceData")
michaelm@4628 1643
michaelm@4628 1644 JNFSetObjectField(env, bufImg, jm_SurfaceData, sData);
michaelm@4628 1645 }
michaelm@4628 1646
michaelm@4628 1647 static jint ImageSD_Lock(JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo, jint lockflags)
michaelm@4628 1648 {
michaelm@4628 1649 ImageSDOps *isdo = (ImageSDOps*)ops;
michaelm@4628 1650 pthread_mutex_lock(&isdo->lock);
michaelm@4628 1651
michaelm@4628 1652 // copied from BufImg_Lock in BufImgSurfaceData.c
michaelm@4628 1653 {
michaelm@4628 1654 BufImgSDOps *bisdo = (BufImgSDOps *)ops;
michaelm@4628 1655 BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
michaelm@4628 1656
michaelm@4628 1657 if ((lockflags & (SD_LOCK_LUT)) != 0 && !bisdo->lutarray) {
michaelm@4628 1658 /* REMIND: Should this be an InvalidPipe exception? */
michaelm@4628 1659 JNU_ThrowNullPointerException(env, "Attempt to lock missing colormap");
michaelm@4628 1660 return SD_FAILURE;
michaelm@4628 1661 }
michaelm@4628 1662 // TODO:BG
michaelm@4628 1663 /*
michaelm@4628 1664 if ((lockflags & SD_LOCK_INVCOLOR) != 0 ||
michaelm@4628 1665 (lockflags & SD_LOCK_INVGRAY) != 0)
michaelm@4628 1666 {
michaelm@4628 1667 bipriv->cData = BufImg_SetupICM(env, bisdo);
michaelm@4628 1668 if (bipriv->cData == NULL) {
michaelm@4628 1669 JNU_ThrowNullPointerException(env, "Could not initialize "
michaelm@4628 1670 "inverse tables");
michaelm@4628 1671 return SD_FAILURE;
michaelm@4628 1672 }
michaelm@4628 1673 } else {
michaelm@4628 1674 bipriv->cData = NULL;
michaelm@4628 1675 }
michaelm@4628 1676 */
michaelm@4628 1677 bipriv->cData = NULL;
michaelm@4628 1678
michaelm@4628 1679 bipriv->lockFlags = lockflags;
michaelm@4628 1680 bipriv->base = NULL;
michaelm@4628 1681 bipriv->lutbase = NULL;
michaelm@4628 1682
michaelm@4628 1683 SurfaceData_IntersectBounds(&pRasInfo->bounds, &bisdo->rasbounds);
michaelm@4628 1684
michaelm@4628 1685 /* TODO:BG
michaelm@4628 1686 if ((bipriv->lockFlags & SD_LOCK_WRITE) &&
michaelm@4628 1687 bisdo->sdOps.dirty != TRUE) {
michaelm@4628 1688 SurfaceData_MarkDirty(env, &bisdo->sdOps);
michaelm@4628 1689 } */
michaelm@4628 1690 return SD_SUCCESS;
michaelm@4628 1691 }
michaelm@4628 1692 }
michaelm@4628 1693 static void ImageSD_Unlock(JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo)
michaelm@4628 1694 {
michaelm@4628 1695 ImageSDOps *isdo = (ImageSDOps*)ops;
michaelm@4628 1696
michaelm@4628 1697 // For every ImageSD_Unlock, we need to be be conservative and mark the pixels
michaelm@4628 1698 // as modified by the Sun2D renderer.
michaelm@4628 1699 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 1;
michaelm@4628 1700
michaelm@4628 1701 pthread_mutex_unlock(&isdo->lock);
michaelm@4628 1702 }
michaelm@4628 1703 static void ImageSD_GetRasInfo(JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo)
michaelm@4628 1704 {
michaelm@4628 1705 // copied from BufImg_GetRasInfo in BufImgSurfaceData.c
michaelm@4628 1706 {
michaelm@4628 1707 BufImgSDOps *bisdo = (BufImgSDOps *)ops;
michaelm@4628 1708 BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
michaelm@4628 1709
michaelm@4628 1710 if ((bipriv->lockFlags & (SD_LOCK_RD_WR)) != 0) {
michaelm@4628 1711 bipriv->base =
michaelm@4628 1712 (*env)->GetPrimitiveArrayCritical(env, bisdo->array, NULL);
michaelm@4628 1713 }
michaelm@4628 1714 if ((bipriv->lockFlags & (SD_LOCK_LUT)) != 0) {
michaelm@4628 1715 bipriv->lutbase =
michaelm@4628 1716 (*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL);
michaelm@4628 1717 }
michaelm@4628 1718
michaelm@4628 1719 if (bipriv->base == NULL) {
michaelm@4628 1720 pRasInfo->rasBase = NULL;
michaelm@4628 1721 pRasInfo->pixelStride = 0;
michaelm@4628 1722 pRasInfo->scanStride = 0;
michaelm@4628 1723 } else {
michaelm@4628 1724 pRasInfo->rasBase = (void *)
michaelm@4628 1725 (((uintptr_t) bipriv->base) + bisdo->offset);
michaelm@4628 1726 pRasInfo->pixelStride = bisdo->pixStr;
michaelm@4628 1727 pRasInfo->scanStride = bisdo->scanStr;
michaelm@4628 1728 }
michaelm@4628 1729 if (bipriv->lutbase == NULL) {
michaelm@4628 1730 pRasInfo->lutBase = NULL;
michaelm@4628 1731 pRasInfo->lutSize = 0;
michaelm@4628 1732 } else {
michaelm@4628 1733 pRasInfo->lutBase = bipriv->lutbase;
michaelm@4628 1734 pRasInfo->lutSize = bisdo->lutsize;
michaelm@4628 1735 }
michaelm@4628 1736 if (bipriv->cData == NULL) {
michaelm@4628 1737 pRasInfo->invColorTable = NULL;
michaelm@4628 1738 pRasInfo->redErrTable = NULL;
michaelm@4628 1739 pRasInfo->grnErrTable = NULL;
michaelm@4628 1740 pRasInfo->bluErrTable = NULL;
michaelm@4628 1741 } else {
michaelm@4628 1742 pRasInfo->invColorTable = bipriv->cData->img_clr_tbl;
michaelm@4628 1743 pRasInfo->redErrTable = bipriv->cData->img_oda_red;
michaelm@4628 1744 pRasInfo->grnErrTable = bipriv->cData->img_oda_green;
michaelm@4628 1745 pRasInfo->bluErrTable = bipriv->cData->img_oda_blue;
michaelm@4628 1746 pRasInfo->invGrayTable = bipriv->cData->pGrayInverseLutData;
michaelm@4628 1747 }
michaelm@4628 1748 }
michaelm@4628 1749 }
michaelm@4628 1750 static void ImageSD_Release(JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo)
michaelm@4628 1751 {
michaelm@4628 1752 // copied from BufImg_Release in BufImgSurfaceData.c
michaelm@4628 1753 {
michaelm@4628 1754 BufImgSDOps *bisdo = (BufImgSDOps *)ops;
michaelm@4628 1755 BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
michaelm@4628 1756
michaelm@4628 1757 if (bipriv->base != NULL) {
michaelm@4628 1758 jint mode = (((bipriv->lockFlags & (SD_LOCK_WRITE)) != 0)
michaelm@4628 1759 ? 0 : JNI_ABORT);
michaelm@4628 1760 (*env)->ReleasePrimitiveArrayCritical(env, bisdo->array,
michaelm@4628 1761 bipriv->base, mode);
michaelm@4628 1762 }
michaelm@4628 1763 if (bipriv->lutbase != NULL) {
michaelm@4628 1764 (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray,
michaelm@4628 1765 bipriv->lutbase, JNI_ABORT);
michaelm@4628 1766 }
michaelm@4628 1767 }
michaelm@4628 1768 }
michaelm@4628 1769
michaelm@4628 1770 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_initRaster(JNIEnv *env, jobject bisd, jobject array, jint offset, jint width, jint height,
michaelm@4628 1771 jint pixelStride, jint scanStride, jobject icm, jint type,
michaelm@4628 1772 jobject jGraphicsState, jobjectArray jGraphicsStateObject, jobject jImageInfo)
michaelm@4628 1773 {
michaelm@4628 1774 PRINT("Java_sun_java2d_OSXOffScreenSurfaceData_initRaster")
michaelm@4628 1775
michaelm@4628 1776 ImageSDOps* isdo = (ImageSDOps*)SurfaceData_InitOps(env, bisd, sizeof(ImageSDOps));
michaelm@4628 1777
michaelm@4628 1778 pthread_mutexattr_t attr;
michaelm@4628 1779 pthread_mutexattr_init(&attr);
michaelm@4628 1780 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
michaelm@4628 1781 pthread_mutex_init(&isdo->lock, &attr);
michaelm@4628 1782 pthread_mutex_lock(&isdo->lock);
michaelm@4628 1783 pthread_mutexattr_destroy(&attr);
michaelm@4628 1784
michaelm@4628 1785 // copied (and modified) from Java_sun_awt_image_BufImgSurfaceData_initRaster in BufImgSurfaceData.c
michaelm@4628 1786 {
michaelm@4628 1787 BufImgSDOps *bisdo =
michaelm@4628 1788 //(BufImgSDOps*)SurfaceData_InitOps(env, bisd, sizeof(BufImgSDOps));
michaelm@4628 1789 (BufImgSDOps*)isdo;
michaelm@4628 1790 //bisdo->sdOps.Lock = BufImg_Lock;
michaelm@4628 1791 //bisdo->sdOps.GetRasInfo = BufImg_GetRasInfo;
michaelm@4628 1792 //bisdo->sdOps.Release = BufImg_Release;
michaelm@4628 1793 //bisdo->sdOps.Unlock = NULL;
michaelm@4628 1794 //bisdo->sdOps.Dispose = BufImg_Dispose;
michaelm@4628 1795
michaelm@4628 1796 bisdo->array = (*env)->NewWeakGlobalRef(env, array);
michaelm@4628 1797 bisdo->offset = offset;
michaelm@4628 1798 //bisdo->scanStr = scanStr;
michaelm@4628 1799 bisdo->scanStr = scanStride;
michaelm@4628 1800 //bisdo->pixStr = pixStr;
michaelm@4628 1801 bisdo->pixStr = pixelStride;
michaelm@4628 1802 if (!icm) {
michaelm@4628 1803 bisdo->lutarray = NULL;
michaelm@4628 1804 bisdo->lutsize = 0;
michaelm@4628 1805 bisdo->icm = NULL;
michaelm@4628 1806 } else {
michaelm@4628 1807 jobject lutarray = (*env)->GetObjectField(env, icm, rgbID);
michaelm@4628 1808 bisdo->lutarray = (*env)->NewWeakGlobalRef(env, lutarray);
michaelm@4628 1809 bisdo->lutsize = (*env)->GetIntField(env, icm, mapSizeID);
michaelm@4628 1810 bisdo->icm = (*env)->NewWeakGlobalRef(env, icm);
michaelm@4628 1811 }
michaelm@4628 1812 bisdo->rasbounds.x1 = 0;
michaelm@4628 1813 bisdo->rasbounds.y1 = 0;
michaelm@4628 1814 bisdo->rasbounds.x2 = width;
michaelm@4628 1815 bisdo->rasbounds.y2 = height;
michaelm@4628 1816 }
michaelm@4628 1817
michaelm@4628 1818 isdo->nrOfPixelsOwners = 0;
michaelm@4628 1819
michaelm@4628 1820 isdo->contextInfo = sDefaultContextInfo[type];
michaelm@4628 1821 isdo->imageInfo = sDefaultImageInfo[type];
michaelm@4628 1822
michaelm@4628 1823 isdo->contextInfo.bytesPerRow = width*isdo->contextInfo.bytesPerPixel;
michaelm@4628 1824 isdo->imageInfo.bytesPerRow = width*isdo->imageInfo.bytesPerPixel;
michaelm@4628 1825
michaelm@4628 1826 switch (type)
michaelm@4628 1827 {
michaelm@4628 1828 case java_awt_image_BufferedImage_TYPE_BYTE_GRAY:
michaelm@4628 1829 isdo->contextInfo.colorSpace = isdo->imageInfo.colorSpace = gColorspaceGray;
michaelm@4628 1830 break;
michaelm@4628 1831 case java_awt_image_BufferedImage_TYPE_USHORT_GRAY:
michaelm@4628 1832 isdo->contextInfo.colorSpace = gColorspaceRGB;
michaelm@4628 1833 isdo->imageInfo.colorSpace = gColorspaceGray;
michaelm@4628 1834 break;
michaelm@4628 1835 default:
michaelm@4628 1836 isdo->contextInfo.colorSpace = isdo->imageInfo.colorSpace = gColorspaceRGB;
michaelm@4628 1837 break;
michaelm@4628 1838 }
michaelm@4628 1839 isdo->isSubImage = (offset%scanStride != 0) || (scanStride != (pixelStride*width));
michaelm@4628 1840
michaelm@4628 1841 // parameters specifying this image given to us from Java
michaelm@4628 1842 isdo->javaImageInfo = (jint*)((*env)->GetDirectBufferAddress(env, jImageInfo));
michaelm@4628 1843 isdo->array = (array != NULL) ? JNFNewGlobalRef(env, array) : NULL;
michaelm@4628 1844 isdo->offset = offset;
michaelm@4628 1845 isdo->width = width;
michaelm@4628 1846 isdo->height = height;
michaelm@4628 1847 isdo->javaPixelBytes = pixelStride;
michaelm@4628 1848 isdo->javaPixelsBytesPerRow = scanStride;
michaelm@4628 1849 isdo->icm = (icm != NULL) ? JNFNewGlobalRef(env, icm) : NULL;
michaelm@4628 1850 isdo->type = type;
michaelm@4628 1851
michaelm@4628 1852 if ((isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kImageStolenIndex] == 1) ||
michaelm@4628 1853 (isdo->type == java_awt_image_BufferedImage_TYPE_CUSTOM))
michaelm@4628 1854 {
michaelm@4628 1855 // don't waste (precious, precious) VRAM on stolen or custom images that will be slow no matter what
michaelm@4628 1856 isdo->contextInfo.useWindowContextReference = NO;
michaelm@4628 1857 }
michaelm@4628 1858
michaelm@4628 1859 // needed by TYPE_BYTE_INDEXED
michaelm@4628 1860 isdo->indexedColorTable = NULL;
michaelm@4628 1861 isdo->lutData = NULL;
michaelm@4628 1862 isdo->lutDataSize = 0;
michaelm@4628 1863 if ((type == java_awt_image_BufferedImage_TYPE_BYTE_INDEXED) && ((*env)->IsSameObject(env, icm, NULL) == NO))
michaelm@4628 1864 {
michaelm@4628 1865 jarray lutarray = JNFGetObjectField(env, icm, jm_rgb);
michaelm@4628 1866 isdo->lutDataSize = (*env)->GetArrayLength(env, lutarray);
michaelm@4628 1867 if (isdo->lutDataSize > 0)
michaelm@4628 1868 {
michaelm@4628 1869 jint transparency = JNFGetIntField(env, icm, jm_transparency);
michaelm@4628 1870 jint transparent_index = -1;
michaelm@4628 1871 if (transparency == java_awt_Transparency_BITMASK)
michaelm@4628 1872 {
michaelm@4628 1873 transparent_index = JNFGetIntField(env, icm, jm_transparent_index);
michaelm@4628 1874 }
michaelm@4628 1875
michaelm@4628 1876 Pixel32bit* lutdata = (Pixel32bit*)((*env)->GetPrimitiveArrayCritical(env, lutarray, NULL));
michaelm@4628 1877 if (lutdata != NULL)
michaelm@4628 1878 {
michaelm@4628 1879 isdo->lutData = NULL;
michaelm@4628 1880
michaelm@4628 1881 isdo->lutData = malloc(isdo->lutDataSize * sizeof(Pixel32bit));
michaelm@4628 1882 if (isdo->lutData != NULL)
michaelm@4628 1883 {
michaelm@4628 1884 if (transparency == java_awt_Transparency_BITMASK)
michaelm@4628 1885 {
michaelm@4628 1886 Pixel32bit* src = lutdata;
michaelm@4628 1887 Pixel32bit* dst = isdo->lutData;
michaelm@4628 1888 jint i;
michaelm@4628 1889 for (i=0; i<isdo->lutDataSize; i++)
michaelm@4628 1890 {
michaelm@4628 1891 if (i != transparent_index)
michaelm@4628 1892 {
michaelm@4628 1893 *dst = *src;
michaelm@4628 1894 // rdar://problem/3390518 - don't force all indexed colors
michaelm@4628 1895 // to be fully opaque. They could be set up for us.
michaelm@4628 1896 // we used to call: *dst = 0xff000000 | *src;
michaelm@4628 1897 // but that was forcing colors to be opaque when developers
michaelm@4628 1898 // could have set the alpha.
michaelm@4628 1899 }
michaelm@4628 1900 else
michaelm@4628 1901 {
michaelm@4628 1902 *dst = 0x00000000; // mark as translucent color
michaelm@4628 1903 }
michaelm@4628 1904 dst++; src++;
michaelm@4628 1905 }
michaelm@4628 1906 }
michaelm@4628 1907 else //if ((transparency == java_awt_Transparency_OPAQUE) || (transparency == java_awt_Transparency_TRANSLUCENT))
michaelm@4628 1908 {
michaelm@4628 1909 jint mask = 0x00000000;
michaelm@4628 1910 // <rdar://4224874> If the color model is OPAQUE than we need to create an opaque image for performance purposes.
michaelm@4628 1911 // the default alphaInfo for INDEXED images is kCGImageAlphaFirst. Therefore we need to special case this.
michaelm@4628 1912 if ((transparency == java_awt_Transparency_OPAQUE))
michaelm@4628 1913 {
michaelm@4628 1914 isdo->imageInfo.alphaInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
michaelm@4628 1915 mask = 0xff000000; // this is just a safeguard to make sure we fill the alpha
michaelm@4628 1916 }
michaelm@4628 1917
michaelm@4628 1918 Pixel32bit* src = lutdata;
michaelm@4628 1919 Pixel32bit* dst = isdo->lutData;
michaelm@4628 1920 jint i;
michaelm@4628 1921 for (i=0; i<isdo->lutDataSize; i++)
michaelm@4628 1922 {
michaelm@4628 1923 *dst = *src | mask;
michaelm@4628 1924 dst++; src++;
michaelm@4628 1925 }
michaelm@4628 1926 }
michaelm@4628 1927
michaelm@4628 1928 (*env)->ReleasePrimitiveArrayCritical(env, lutarray, lutdata, 0);
michaelm@4628 1929 }
michaelm@4628 1930 else
michaelm@4628 1931 {
michaelm@4628 1932 fprintf(stderr, "ERROR: malloc returns NULL for isdo->lutData in initRaster!\n");
michaelm@4628 1933 }
michaelm@4628 1934 }
michaelm@4628 1935 else
michaelm@4628 1936 {
michaelm@4628 1937 fprintf(stderr, "ERROR: GetPrimitiveArrayCritical returns NULL for lutdata in initRaster!\n");
michaelm@4628 1938 }
michaelm@4628 1939 }
michaelm@4628 1940 (*env)->DeleteLocalRef(env, lutarray);
michaelm@4628 1941 }
michaelm@4628 1942
michaelm@4628 1943 QuartzSDOps *qsdo = (QuartzSDOps*)isdo;
michaelm@4628 1944 qsdo->BeginSurface = ImageSD_startCGContext;
michaelm@4628 1945 qsdo->FinishSurface = ImageSD_finishCGContext;
michaelm@4628 1946
michaelm@4628 1947 qsdo->javaGraphicsStates = (jint*)((*env)->GetDirectBufferAddress(env, jGraphicsState));
michaelm@4628 1948 qsdo->javaGraphicsStatesObjects = JNFNewGlobalRef(env, jGraphicsStateObject);
michaelm@4628 1949
michaelm@4628 1950 qsdo->graphicsStateInfo.batchedLines = NULL;
michaelm@4628 1951 qsdo->graphicsStateInfo.batchedLinesCount = 0;
michaelm@4628 1952
michaelm@4628 1953 SurfaceDataOps *sdo = (SurfaceDataOps*)qsdo;
michaelm@4628 1954 sdo->Lock = ImageSD_Lock;
michaelm@4628 1955 sdo->Unlock = ImageSD_Unlock;
michaelm@4628 1956 sdo->GetRasInfo = ImageSD_GetRasInfo;
michaelm@4628 1957 sdo->Release = ImageSD_Release;
michaelm@4628 1958 sdo->Setup = NULL;
michaelm@4628 1959 sdo->Dispose = ImageSD_dispose;
michaelm@4628 1960
michaelm@4628 1961 pthread_mutex_unlock(&isdo->lock);
michaelm@4628 1962
michaelm@4628 1963 //PrintImageInfo(isdo);
michaelm@4628 1964 }
michaelm@4628 1965
michaelm@4628 1966 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_initCustomRaster(JNIEnv* env, jobject bisd, jobject array, jint width, jint height,
michaelm@4628 1967 jobject jGraphicsState, jobject jGraphicsStateObject, jobject jImageInfo)
michaelm@4628 1968 {
michaelm@4628 1969 PRINT("Java_sun_java2d_OSXOffScreenSurfaceData_initCustomRaster")
michaelm@4628 1970 jint offset = 0;
michaelm@4628 1971 jint pixelStride = 4;
michaelm@4628 1972 jint scanStride = pixelStride*width;
michaelm@4628 1973 jobject icm = NULL;
michaelm@4628 1974 jint type = java_awt_image_BufferedImage_TYPE_CUSTOM;
michaelm@4628 1975
michaelm@4628 1976 Java_sun_java2d_OSXOffScreenSurfaceData_initRaster(env, bisd, array, offset, width, height, pixelStride, scanStride, icm, type, jGraphicsState, jGraphicsStateObject, jImageInfo);
michaelm@4628 1977 }
michaelm@4628 1978
michaelm@4628 1979 JNIEXPORT void JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_syncToJavaPixels(JNIEnv *env, jobject bisd)
michaelm@4628 1980 {
michaelm@4628 1981 PRINT("Java_sun_java2d_OSXOffScreenSurfaceData_syncToJavaPixels")
michaelm@4628 1982
michaelm@4628 1983 syncToJavaPixels(env, (ImageSDOps*)SurfaceData_GetOps(env, bisd));
michaelm@4628 1984 }
michaelm@4628 1985
michaelm@4628 1986 JNIEXPORT jboolean JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_xorSurfacePixels
michaelm@4628 1987 (JNIEnv *env, jobject dstIsd, jobject srcIsd, jint colorXOR, jint x, jint y, jint w, jint h)
michaelm@4628 1988 {
michaelm@4628 1989 PRINT("Java_sun_java2d_OSXOffScreenSurfaceData_xorSurfacePixels")
michaelm@4628 1990 return xorSurfacePixels(env, dstIsd, srcIsd, colorXOR, x, y, w, h);
michaelm@4628 1991 }
michaelm@4628 1992
michaelm@4628 1993 JNIEXPORT jboolean JNICALL Java_sun_java2d_OSXOffScreenSurfaceData_clearSurfacePixels
michaelm@4628 1994 (JNIEnv *env, jobject bisd, jint w, jint h)
michaelm@4628 1995 {
michaelm@4628 1996 PRINT("Java_sun_java2d_OSXOffScreenSurfaceData_clearSurfacePixels")
michaelm@4628 1997 return clearSurfacePixels(env, bisd, w, h);
michaelm@4628 1998
michaelm@4628 1999 }