1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #import "common.h"
  27 #import "com_sun_glass_ui_Pixels_Format.h"
  28 #import "com_sun_glass_ui_mac_MacPixels.h"
  29 
  30 #import "GlassMacros.h"
  31 
  32 //#define VERBOSE
  33 #ifndef VERBOSE
  34     #define LOG(MSG, ...)
  35 #else
  36     #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__);
  37 #endif
  38 
  39 /*
  40  * Class:     com_sun_glass_ui_mac_MacPixels
  41  * Method:    _initIDs
  42  * Signature: ()I
  43  */
  44 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacPixels__1initIDs
  45 (JNIEnv *env, jclass jClass)
  46 {
  47     LOG("Java_com_sun_glass_ui_mac_MacPixels__1initIDs");
  48 
  49     if (jPixelsAttachData == NULL)
  50     {
  51         jPixelsAttachData =  (*env)->GetMethodID(env, jClass, "attachData", "(J)V");
  52     }
  53 
  54     // http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_designstrategies/opengl_designstrategies.html%23//apple_ref/doc/uid/TP40001987-CH2-SW17
  55     // GL_BGRA + GL_UNSIGNED_INT_8_8_8_8_REV == ARGB (big) == BGRA (little)
  56     return com_sun_glass_ui_Pixels_Format_BYTE_BGRA_PRE;
  57 }
  58 
  59 /*
  60  * Class:     com_sun_glass_ui_mac_MacPixels
  61  * Method:    _copyPixels
  62  * Signature: (Ljava/nio/Buffer;Ljava/nio/Buffer;I)V
  63  */
  64 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacPixels__1copyPixels
  65 (JNIEnv *env, jobject jPixels, jobject jSrc, jobject jDst, jint jSize)
  66 {
  67     LOG("Java_com_sun_glass_ui_mac_MacPixels__1copyPixels");
  68 
  69     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
  70 
  71     void *src = (*env)->GetDirectBufferAddress(env, jSrc);
  72     void *dst = (*env)->GetDirectBufferAddress(env, jDst);
  73     if ((src != NULL) && (src != NULL) && (jSize > 0))
  74     {
  75         memcpy(src, dst, jSize);
  76     }
  77     GLASS_CHECK_EXCEPTION(env);
  78 }
  79 
  80 /*
  81  * Class:     com_sun_glass_ui_mac_MacPixels
  82  * Method:    _attachInt
  83  * Signature: (JIILjava/nio/IntBuffer;[II)V
  84  */
  85 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacPixels__1attachInt
  86 (JNIEnv *env, jobject jPixels, jlong jPtr, jint jWidth, jint jHeight, jobject jBuffer, jintArray jArray, jint jOffset)
  87 {
  88     LOG("Java_com_sun_glass_ui_mac_MacPixels__1attachInt");
  89 
  90     Java_com_sun_glass_ui_mac_MacPixels__1attachByte(env, jPixels, jPtr, jWidth, jHeight, jBuffer, jArray, 4*jOffset);
  91 }
  92 
  93 /*
  94  * Class:     com_sun_glass_ui_mac_MacPixels
  95  * Method:    _attachByte
  96  * Signature: (JIILjava/nio/ByteBuffer;[BI)V
  97  */
  98 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacPixels__1attachByte
  99 (JNIEnv *env, jobject jPixels, jlong jPtr, jint jWidth, jint jHeight, jobject jBuffer, jbyteArray jArray, jint jOffset)
 100 {
 101     LOG("Java_com_sun_glass_ui_mac_MacPixels__1attachByte");
 102 
 103     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 104     {
 105         u_int8_t *data = NULL;
 106         if (jArray != NULL)
 107         {
 108             jboolean isCopy = JNI_FALSE;
 109             data = (*env)->GetPrimitiveArrayCritical(env, jArray, &isCopy);
 110         }
 111         else
 112         {
 113             data = (*env)->GetDirectBufferAddress(env, jBuffer);
 114         }
 115 
 116         CGImageRef cgImage = NULL;
 117         if ((data != NULL) && (jWidth > 0) && (jHeight > 0))
 118         {
 119             CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
 120             {
 121                 size_t width = (size_t)jWidth;
 122                 size_t height = (size_t)jHeight;
 123                 CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data+jOffset, width*height*4, NULL);
 124                 if (provider != NULL)
 125                 {
 126                     cgImage = CGImageCreate(width, height, 8, 32, 4*width, colorSpace, kCGImageAlphaPremultipliedFirst|kCGBitmapByteOrder32Little, provider, NULL, 1, kCGRenderingIntentDefault);
 127                     CGDataProviderRelease(provider);
 128                 }
 129             }
 130             CGColorSpaceRelease(colorSpace);
 131         }
 132 
 133         if (jArray != NULL)
 134         {
 135             (*env)->ReleasePrimitiveArrayCritical(env, jArray, data, JNI_ABORT);
 136         }
 137 
 138         NSImage **nsImage = (NSImage**)jlong_to_ptr(jPtr);
 139         if (cgImage != NULL)
 140         {
 141             *nsImage = [[NSImage alloc] initWithCGImage:cgImage size:NSMakeSize(jWidth, jHeight)];
 142 
 143             CGImageRelease(cgImage);
 144         }
 145         else
 146         {
 147             *nsImage = nil;
 148         }
 149     }
 150     GLASS_CHECK_EXCEPTION(env);
 151 }