Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native_NOTIOS/sun/awt/CImage.m
38829 views
/*1* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24#import "jni_util.h"2526#import <Cocoa/Cocoa.h>27#import <JavaNativeFoundation/JavaNativeFoundation.h>2829#import "GeomUtilities.h"30#import "ThreadUtilities.h"3132#import "sun_lwawt_macosx_CImage.h"333435static void CImage_CopyArrayIntoNSImageRep36(jint *srcPixels, jint *dstPixels, int width, int height)37{38int x, y;39// TODO: test this on big endian systems (not sure if its correct)...40for (y = 0; y < height; y++) {41for (x = 0; x < width; x++) {42jint pix = srcPixels[x];43jint a = (pix >> 24) & 0xff;44jint r = (pix >> 16) & 0xff;45jint g = (pix >> 8) & 0xff;46jint b = (pix ) & 0xff;47dstPixels[x] = (b << 24) | (g << 16) | (r << 8) | a;48}49srcPixels += width; // TODO: use explicit scanStride50dstPixels += width;51}52}5354static void CImage_CopyNSImageIntoArray55(NSImage *srcImage, jint *dstPixels, NSRect fromRect, NSRect toRect)56{57int width = toRect.size.width;58int height = toRect.size.height;59CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();60CGContextRef cgRef = CGBitmapContextCreate(dstPixels, width, height,618, width * 4, colorspace,62kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);63CGColorSpaceRelease(colorspace);64NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:cgRef flipped:NO];65CGContextRelease(cgRef);66NSGraphicsContext *oldContext = [[NSGraphicsContext currentContext] retain];67[NSGraphicsContext setCurrentContext:context];68[srcImage drawInRect:toRect69fromRect:fromRect70operation:NSCompositeSourceOver71fraction:1.0];72[NSGraphicsContext setCurrentContext:oldContext];73[oldContext release];74}7576static NSBitmapImageRep* CImage_CreateImageRep(JNIEnv *env, jintArray buffer, jint width, jint height)77{78NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL79pixelsWide:width80pixelsHigh:height81bitsPerSample:882samplesPerPixel:483hasAlpha:YES84isPlanar:NO85colorSpaceName:NSDeviceRGBColorSpace86bitmapFormat:NSAlphaFirstBitmapFormat87bytesPerRow:width*4 // TODO: use explicit scanStride88bitsPerPixel:32];8990jint *imgData = (jint *)[imageRep bitmapData];91if (imgData == NULL) return 0L;9293jint *src = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL);94if (src == NULL) return 0L;9596CImage_CopyArrayIntoNSImageRep(src, imgData, width, height);9798(*env)->ReleasePrimitiveArrayCritical(env, buffer, src, JNI_ABORT);99100return imageRep;101}102103/*104* Class: sun_lwawt_macosx_CImage105* Method: nativeCreateNSImageFromArray106* Signature: ([III)J107*/108JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArray109(JNIEnv *env, jclass klass, jintArray buffer, jint width, jint height)110{111jlong result = 0L;112113JNF_COCOA_ENTER(env);114115NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, width, height);116if (imageRep) {117NSImage *nsImage = [[[NSImage alloc] initWithSize:NSMakeSize(width, height)] retain];118[nsImage addRepresentation:imageRep];119[imageRep release];120result = ptr_to_jlong(nsImage);121}122123JNF_COCOA_EXIT(env);124125return result;126}127128/*129* Class: sun_lwawt_macosx_CImage130* Method: nativeCreateNSImageFromArrays131* Signature: ([[I[I[I)J132*/133JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArrays134(JNIEnv *env, jclass klass, jobjectArray buffers, jintArray widths, jintArray heights)135{136jlong result = 0L;137138JNF_COCOA_ENTER(env);139140jsize num = (*env)->GetArrayLength(env, buffers);141NSMutableArray * reps = [NSMutableArray arrayWithCapacity: num];142143jint * ws = (*env)->GetIntArrayElements(env, widths, NULL);144if (ws != NULL) {145jint * hs = (*env)->GetIntArrayElements(env, heights, NULL);146if (hs != NULL) {147jsize i;148for (i = 0; i < num; i++) {149jintArray buffer = (*env)->GetObjectArrayElement(env, buffers, i);150151NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, ws[i], hs[i]);152if (imageRep) {153[reps addObject: imageRep];154}155}156157(*env)->ReleaseIntArrayElements(env, heights, hs, JNI_ABORT);158}159(*env)->ReleaseIntArrayElements(env, widths, ws, JNI_ABORT);160}161if ([reps count]) {162NSImage *nsImage = [[[NSImage alloc] initWithSize:NSMakeSize(0, 0)] retain];163[nsImage addRepresentations: reps];164result = ptr_to_jlong(nsImage);165}166167JNF_COCOA_EXIT(env);168169return result;170}171172/*173* Class: sun_lwawt_macosx_CImage174* Method: nativeCreateNSImageFromIconSelector175* Signature: (I)J176*/177JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromIconSelector178(JNIEnv *env, jclass klass, jint selector)179{180NSImage *image = nil;181182JNF_COCOA_ENTER(env);183184IconRef iconRef;185if (noErr == GetIconRef(kOnSystemDisk, kSystemIconsCreator, selector, &iconRef)) {186image = [[[NSImage alloc] initWithIconRef:iconRef] retain];187ReleaseIconRef(iconRef);188}189190JNF_COCOA_EXIT(env);191192return ptr_to_jlong(image);193}194195/*196* Class: sun_lwawt_macosx_CImage197* Method: nativeCreateNSImageFromFileContents198* Signature: (Ljava/lang/String;)J199*/200JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromFileContents201(JNIEnv *env, jclass klass, jstring file)202{203NSImage *image = nil;204205JNF_COCOA_ENTER(env);206207NSString *path = JNFNormalizedNSStringForPath(env, file);208image = [[[NSImage alloc] initByReferencingFile:path] retain];209210JNF_COCOA_EXIT(env);211212return ptr_to_jlong(image);213}214215/*216* Class: sun_lwawt_macosx_CImage217* Method: nativeCreateNSImageOfFileFromLaunchServices218* Signature: (Ljava/lang/String;)J219*/220JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageOfFileFromLaunchServices221(JNIEnv *env, jclass klass, jstring file)222{223__block NSImage *image = nil;224225JNF_COCOA_ENTER(env);226227NSString *path = JNFNormalizedNSStringForPath(env, file);228[ThreadUtilities performOnMainThreadWaiting:YES block:^(){229image = [[[NSWorkspace sharedWorkspace] iconForFile:path] retain];230[image setScalesWhenResized:TRUE];231}];232233JNF_COCOA_EXIT(env);234235return ptr_to_jlong(image);236}237238/*239* Class: sun_lwawt_macosx_CImage240* Method: nativeCreateNSImageFromImageName241* Signature: (Ljava/lang/String;)J242*/243JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromImageName244(JNIEnv *env, jclass klass, jstring name)245{246NSImage *image = nil;247248JNF_COCOA_ENTER(env);249250image = [[NSImage imageNamed:JNFJavaToNSString(env, name)] retain];251252JNF_COCOA_EXIT(env);253254return ptr_to_jlong(image);255}256257/*258* Class: sun_lwawt_macosx_CImage259* Method: nativeCopyNSImageIntoArray260* Signature: (J[IIIII)V261*/262JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeCopyNSImageIntoArray263(JNIEnv *env, jclass klass, jlong nsImgPtr, jintArray buffer, jint sw, jint sh,264jint dw, jint dh)265{266JNF_COCOA_ENTER(env);267268NSImage *img = (NSImage *)jlong_to_ptr(nsImgPtr);269jint *dst = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL);270if (dst) {271NSRect fromRect = NSMakeRect(0, 0, sw, sh);272NSRect toRect = NSMakeRect(0, 0, dw, dh);273CImage_CopyNSImageIntoArray(img, dst, fromRect, toRect);274(*env)->ReleasePrimitiveArrayCritical(env, buffer, dst, JNI_ABORT);275}276277JNF_COCOA_EXIT(env);278}279280/*281* Class: sun_lwawt_macosx_CImage282* Method: nativeGetNSImageSize283* Signature: (J)Ljava/awt/geom/Dimension2D;284*/285JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CImage_nativeGetNSImageSize286(JNIEnv *env, jclass klass, jlong nsImgPtr)287{288jobject size = NULL;289290JNF_COCOA_ENTER(env);291292size = NSToJavaSize(env, [(NSImage *)jlong_to_ptr(nsImgPtr) size]);293294JNF_COCOA_EXIT(env);295296return size;297}298299/*300* Class: sun_lwawt_macosx_CImage301* Method: nativeSetNSImageSize302* Signature: (JDD)V303*/304JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeSetNSImageSize305(JNIEnv *env, jclass clazz, jlong image, jdouble w, jdouble h)306{307if (!image) return;308NSImage *i = (NSImage *)jlong_to_ptr(image);309310JNF_COCOA_ENTER(env);311312[i setScalesWhenResized:TRUE];313[i setSize:NSMakeSize(w, h)];314315JNF_COCOA_EXIT(env);316}317318/*319* Class: sun_lwawt_macosx_CImage320* Method: nativeResizeNSImageRepresentations321* Signature: (JDD)V322*/323JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeResizeNSImageRepresentations324(JNIEnv *env, jclass clazz, jlong image, jdouble w, jdouble h)325{326if (!image) return;327NSImage *i = (NSImage *)jlong_to_ptr(image);328329JNF_COCOA_ENTER(env);330331NSImageRep *imageRep = nil;332NSArray *imageRepresentations = [i representations];333NSEnumerator *imageEnumerator = [imageRepresentations objectEnumerator];334while ((imageRep = [imageEnumerator nextObject]) != nil) {335[imageRep setSize:NSMakeSize(w, h)];336}337338JNF_COCOA_EXIT(env);339}340341NSComparisonResult getOrder(BOOL order){342return (NSComparisonResult) (order ? NSOrderedAscending : NSOrderedDescending);343}344345/*346* Class: sun_lwawt_macosx_CImage347* Method: nativeGetNSImageRepresentationsCount348* Signature: (JDD)[Ljava/awt/geom/Dimension2D;349*/350JNIEXPORT jobjectArray JNICALL351Java_sun_lwawt_macosx_CImage_nativeGetNSImageRepresentationSizes352(JNIEnv *env, jclass clazz, jlong image, jdouble w, jdouble h)353{354if (!image) return NULL;355jobjectArray jreturnArray = NULL;356NSImage *img = (NSImage *)jlong_to_ptr(image);357358JNF_COCOA_ENTER(env);359360NSArray *imageRepresentations = [img representations];361if([imageRepresentations count] == 0){362return NULL;363}364365NSArray *sortedImageRepresentations = [imageRepresentations366sortedArrayUsingComparator: ^(id obj1, id obj2) {367368NSImageRep *imageRep1 = (NSImageRep *) obj1;369NSImageRep *imageRep2 = (NSImageRep *) obj2;370NSSize size1 = [imageRep1 size];371NSSize size2 = [imageRep2 size];372373if (NSEqualSizes(size1, size2)) {374return getOrder([imageRep1 pixelsWide] <= [imageRep2 pixelsWide] &&375[imageRep1 pixelsHigh] <= [imageRep2 pixelsHigh]);376}377378return getOrder(size1.width <= size2.width && size1.height <= size2.height);379}];380381NSMutableArray *sortedPixelSizes = [[[NSMutableArray alloc] init] autorelease];382NSSize lastSize = [[sortedImageRepresentations lastObject] size];383384NSUInteger i = [sortedImageRepresentations indexOfObjectPassingTest:385^BOOL(id obj, NSUInteger idx, BOOL *stop) {386NSSize imageRepSize = [obj size];387return (w <= imageRepSize.width && h <= imageRepSize.height)388|| NSEqualSizes(imageRepSize, lastSize);389}];390391NSUInteger count = [sortedImageRepresentations count];392i = (i == NSNotFound) ? count - 1 : i;393NSSize bestFitSize = [[sortedImageRepresentations objectAtIndex: i] size];394395for(; i < count; i++){396NSImageRep *imageRep = [sortedImageRepresentations objectAtIndex: i];397398if (!NSEqualSizes([imageRep size], bestFitSize)) {399break;400}401402NSSize pixelSize = NSMakeSize(403[imageRep pixelsWide], [imageRep pixelsHigh]);404[sortedPixelSizes addObject: [NSValue valueWithSize: pixelSize]];405}406407count = [sortedPixelSizes count];408static JNF_CLASS_CACHE(jc_Dimension, "java/awt/Dimension");409jreturnArray = JNFNewObjectArray(env, &jc_Dimension, count);410CHECK_NULL_RETURN(jreturnArray, NULL);411412for(i = 0; i < count; i++){413NSSize pixelSize = [[sortedPixelSizes objectAtIndex: i] sizeValue];414415(*env)->SetObjectArrayElement(env, jreturnArray, i,416NSToJavaSize(env, pixelSize));417JNU_CHECK_EXCEPTION_RETURN(env, NULL);418}419420JNF_COCOA_EXIT(env);421422return jreturnArray;423}424425/*426* Class: sun_lwawt_macosx_CImage427* Method: nativeGetPlatformImageBytes428* Signature: ([III)[B429*/430JNIEXPORT jbyteArray JNICALL Java_sun_lwawt_macosx_CImage_nativeGetPlatformImageBytes431(JNIEnv *env, jclass klass, jintArray buffer, jint width, jint height)432{433jbyteArray result = 0L;434435JNF_COCOA_ENTER(env);436437NSBitmapImageRep* imageRep = [CImage_CreateImageRep(env, buffer, width, height) autorelease];438if (imageRep) {439NSData *tiffImage = [imageRep TIFFRepresentation];440jsize tiffSize = (jsize)[tiffImage length];441result = (*env)->NewByteArray(env, tiffSize);442CHECK_NULL_RETURN(result, nil);443jbyte *tiffData = (jbyte *)(*env)->GetPrimitiveArrayCritical(env, result, 0);444CHECK_NULL_RETURN(tiffData, nil);445[tiffImage getBytes:tiffData];446(*env)->ReleasePrimitiveArrayCritical(env, result, tiffData, 0);447}448449JNF_COCOA_EXIT(env);450451return result;452}453454/*455* Class: sun_lwawt_macosx_CImage456* Method: nativeCreateNSImageFromBytes457* Signature: ([B)J458*/459JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromBytes460(JNIEnv *env, jclass klass, jbyteArray sourceData)461{462jlong result = 0L;463CHECK_NULL_RETURN(sourceData, 0L);464465JNF_COCOA_ENTER(env);466467jsize sourceSize = (*env)->GetArrayLength(env, sourceData);468if (sourceSize == 0) return 0L;469470jbyte *sourceBytes = (*env)->GetPrimitiveArrayCritical(env, sourceData, NULL);471CHECK_NULL_RETURN(sourceBytes, 0L);472NSData *rawData = [NSData dataWithBytes:sourceBytes length:sourceSize];473NSImage *newImage = [[NSImage alloc] initWithData:rawData];474475(*env)->ReleasePrimitiveArrayCritical(env, sourceData, sourceBytes, JNI_ABORT);476CHECK_NULL_RETURN(newImage, 0L);477478result = ptr_to_jlong(newImage);479JNF_COCOA_EXIT(env);480481return result;482}483484485486