Bitmap.cpp revision b933055cf3f7f8ea89bfd3bc9c37a3891ff7310a
132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkBitmap.h" 232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkPixelRef.h" 332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkImageEncoder.h" 432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkColorPriv.h" 532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "GraphicsJNI.h" 632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkDither.h" 732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkUnPreMultiply.h" 832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "SkStream.h" 932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <binder/Parcel.h> 1132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_os_Parcel.h" 1232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_util_Binder.h" 1332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "android_nio_utils.h" 1432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include "CreateJavaOutputStreamAdaptor.h" 1532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <jni.h> 1732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 1832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <Caches.h> 1932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 2032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#if 0 2132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik #define TRACE_BITMAP(code) code 2232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#else 2332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik #define TRACE_BITMAP(code) 2432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#endif 2532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 2632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 2732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// Conversions to/from SkColor, for get/setPixels, and the create method, which 2832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// is basically like setPixels 2932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 3032054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*FromColorProc)(void* dst, const SkColor src[], int width, 3132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y); 3232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 3332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32(void* dst, const SkColor src[], int width, 3432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int, int) { 3532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor* d = (SkPMColor*)dst; 3632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 3732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int i = 0; i < width; i++) { 3832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkPreMultiplyColor(*src++); 3932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 4032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 4132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 4232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D32_Raw(void* dst, const SkColor src[], int width, 4332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int, int) { 4432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // SkColor's ordering may be different from SkPMColor 4532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER) { 4632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(dst, src, width * sizeof(SkColor)); 4732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 4832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 4932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 5032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // order isn't same, repack each pixel manually 5132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor* d = (SkPMColor*)dst; 5232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int i = 0; i < width; i++) { 5332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 5432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 5532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorGetG(c), SkColorGetB(c)); 5632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 5732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 5832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 5932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D565(void* dst, const SkColor src[], int width, 6032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 6132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t* d = (uint16_t*)dst; 6232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 6332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_565_SCAN(y); 6432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 6532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 6632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), 6732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_VALUE(x)); 6832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 6932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 7032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 7132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444(void* dst, const SkColor src[], int width, 7232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 7332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor16* d = (SkPMColor16*)dst; 7432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 7532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_4444_SCAN(y); 7632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 7732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor pmc = SkPreMultiplyColor(*src++); 7832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 7932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// *d++ = SkPixel32ToPixel4444(pmc); 8032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 8132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 8232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 8332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void FromColor_D4444_Raw(void* dst, const SkColor src[], int width, 8432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y) { 8532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor16* d = (SkPMColor16*)dst; 8632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 8732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik DITHER_4444_SCAN(y); 8832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int stop = x + width; x < stop; x++) { 8932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor c = *src++; 9032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 9132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied 9232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c), 9332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorGetG(c), SkColorGetB(c)); 9432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x)); 9532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// *d++ = SkPixel32ToPixel4444(pmc); 9632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 9732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 9832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 9932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 10032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic FromColorProc ChooseFromColorProc(SkBitmap::Config config, bool isPremultiplied) { 10132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik switch (config) { 10232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case SkBitmap::kARGB_8888_Config: 10332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return isPremultiplied ? FromColor_D32 : FromColor_D32_Raw; 10432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case SkBitmap::kARGB_4444_Config: 10532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return isPremultiplied ? FromColor_D4444 : FromColor_D4444_Raw; 10632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case SkBitmap::kRGB_565_Config: 10732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return FromColor_D565; 10832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 10932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 11032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 11132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 11232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 11332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 11432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikbool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride, 11532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int x, int y, int width, int height, 11632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap& dstBitmap, bool isPremultiplied) { 11732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(dstBitmap); 11832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik void* dst = dstBitmap.getPixels(); 11932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik FromColorProc proc = ChooseFromColorProc(dstBitmap.config(), isPremultiplied); 12032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 12132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == dst || NULL == proc) { 12232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return false; 12332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 12432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 12532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const jint* array = env->GetIntArrayElements(srcColors, NULL); 12632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkColor* src = (const SkColor*)array + srcOffset; 12732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 12832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // reset to to actual choice from caller 12932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dst = dstBitmap.getAddr(x, y); 13032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // now copy/convert each scanline 13132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int y = 0; y < height; y++) { 13232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik proc(dst, src, width, x, y); 13332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik src += srcStride; 13432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dst = (char*)dst + dstBitmap.rowBytes(); 13532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 13632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 13732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik dstBitmap.notifyPixelsChanged(); 13832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 13932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), 14032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik JNI_ABORT); 14132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return true; 14232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 14332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 14432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik//////////////////// ToColor procs 14532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 14632054b0b3edb350a5444c47753b2982312dd7ffdChris Craiktypedef void (*ToColorProc)(SkColor dst[], const void* src, int width, 14732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*); 14832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 14932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Alpha(SkColor dst[], const void* src, int width, 15032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 15132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 15232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 15332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 15432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(*s++); 15532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 15632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 15732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 15832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Raw(SkColor dst[], const void* src, int width, 15932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 16032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 16132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 16232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 16332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 16432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 16532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 16632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 16732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 16832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 16932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S32_Opaque(SkColor dst[], const void* src, int width, 17032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 17132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 17232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* s = (const SkPMColor*)src; 17332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 17432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = *s++; 17532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 17632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 17732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 17832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 17932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 18032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width, 18132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 18232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 18332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 18432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 18532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++)); 18632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 18732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 18832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 18932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Raw(SkColor dst[], const void* src, int width, 19032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 19132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 19232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 19332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 19432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 19532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 19632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 19732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 19832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 19932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 20032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width, 20132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 20232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 20332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor16* s = (const SkPMColor16*)src; 20432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 20532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = SkPixel4444ToPixel32(*s++); 20632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 20732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 20832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 20932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 21032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 21132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_S565(SkColor dst[], const void* src, int width, 21232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable*) { 21332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 21432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint16_t* s = (const uint16_t*)src; 21532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 21632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik uint16_t c = *s++; 21732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c), 21832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPacked16ToB32(c)); 21932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 22032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 22132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 22232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, 22332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 22432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 22532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 22632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* colors = ctable->lockColors(); 22732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 22832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]); 22932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 23032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable->unlockColors(); 23132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 23232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 23332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, 23432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 23532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 23632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 23732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* colors = ctable->lockColors(); 23832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 23932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 24032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c), 24132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedG32(c), SkGetPackedB32(c)); 24232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 24332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable->unlockColors(); 24432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 24532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 24632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, 24732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable) { 24832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkASSERT(width > 0); 24932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const uint8_t* s = (const uint8_t*)src; 25032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* colors = ctable->lockColors(); 25132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik do { 25232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPMColor c = colors[*s++]; 25332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c), 25432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkGetPackedB32(c)); 25532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } while (--width != 0); 25632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable->unlockColors(); 25732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 25832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 25932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// can return NULL 26032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic ToColorProc ChooseToColorProc(const SkBitmap& src, bool isPremultiplied) { 261b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed switch (src.colorType()) { 262b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kN32_SkColorType: 26332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (src.isOpaque()) return ToColor_S32_Opaque; 26432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return isPremultiplied ? ToColor_S32_Alpha : ToColor_S32_Raw; 265b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kARGB_4444_SkColorType: 26632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (src.isOpaque()) return ToColor_S4444_Opaque; 26732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return isPremultiplied ? ToColor_S4444_Alpha : ToColor_S4444_Raw; 268b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kRGB_565_SkColorType: 26932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return ToColor_S565; 270b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed case kIndex_8_SkColorType: 27132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (src.getColorTable() == NULL) { 27232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 27332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 27432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (src.isOpaque()) return ToColor_SI8_Opaque; 27532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return isPremultiplied ? ToColor_SI8_Raw : ToColor_SI8_Alpha; 27632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 27732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 27832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 27932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 28032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 28132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 28232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 28332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 28432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 28532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic int getPremulBitmapCreateFlags(bool isMutable) { 28632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int flags = GraphicsJNI::kBitmapCreateFlag_Premultiplied; 28732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (isMutable) flags |= GraphicsJNI::kBitmapCreateFlag_Mutable; 28832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return flags; 28932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 29032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 29132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, 29232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint offset, jint stride, jint width, jint height, 29332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint configHandle, jboolean isMutable) { 294b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed SkColorType colorType = SkBitmapConfigToColorType(static_cast<SkBitmap::Config>(configHandle)); 29532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != jColors) { 29632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t n = env->GetArrayLength(jColors); 29732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (n < SkAbs32(stride) * (size_t)height) { 29832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowAIOOBE(env); 29932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 30032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 30132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 30232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 30332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // ARGB_4444 is a deprecated format, convert automatically to 8888 304b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kARGB_4444_SkColorType) { 305b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed colorType = kN32_SkColorType; 30632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 30732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 30832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap bitmap; 309b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType)); 31032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 31132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jbyteArray buff = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL); 31232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == buff) { 31332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 31432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 31532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 31632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (jColors != NULL) { 31732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik GraphicsJNI::SetPixels(env, jColors, offset, stride, 31832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 0, 0, width, height, bitmap, true); 31932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 32032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 32132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff, 32232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik getPremulBitmapCreateFlags(isMutable), NULL, NULL); 32332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 32432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 32532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle, 32632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint dstConfigHandle, jboolean isMutable) { 32732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* src = reinterpret_cast<SkBitmap*>(srcHandle); 32832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap::Config dstConfig = static_cast<SkBitmap::Config>(dstConfigHandle); 32932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap result; 33032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik JavaPixelAllocator allocator(env); 33132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 332cc11f15f76a62ded3e403cb2bc818c6aa5bf261cLeon Scroggins if (!src->copyTo(&result, SkBitmapConfigToColorType(dstConfig), &allocator)) { 33332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 33432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 33532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return GraphicsJNI::createBitmap(env, new SkBitmap(result), allocator.getStorageObj(), 33632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik getPremulBitmapCreateFlags(isMutable), NULL, NULL); 33732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 33832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 33932054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) { 34032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 34132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#ifdef USE_OPENGL_RENDERER 34232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (android::uirenderer::Caches::hasInstance()) { 34332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::uirenderer::Caches::getInstance().resourceCache.destructor(bitmap); 34432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 34532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 34632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#endif // USE_OPENGL_RENDERER 34732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik delete bitmap; 34832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 34932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 35032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) { 35132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 35232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#ifdef USE_OPENGL_RENDERER 35332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (android::uirenderer::Caches::hasInstance()) { 35432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bool result; 35532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik result = android::uirenderer::Caches::getInstance().resourceCache.recycle(bitmap); 35632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return result ? JNI_TRUE : JNI_FALSE; 35732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 35832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#endif // USE_OPENGL_RENDERER 35932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setPixels(NULL, NULL); 36032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 36132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 36232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 36332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle, 36417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III jint width, jint height, jint configHandle, jint allocSize, 36517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III jboolean requestPremul) { 36632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 36732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap::Config config = static_cast<SkBitmap::Config>(configHandle); 36817a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III SkColorType colorType = SkBitmapConfigToColorType(config); 36917a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III 37017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // ARGB_4444 is a deprecated format, convert automatically to 8888 37117a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III if (colorType == kARGB_4444_SkColorType) { 37217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III colorType = kN32_SkColorType; 37317a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 37417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III 37517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III if (width * height * SkColorTypeBytesPerPixel(colorType) > allocSize) { 37632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // done in native as there's no way to get BytesPerPixel in Java 37732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowIAE(env, "Bitmap not large enough to support new configuration"); 37832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 37932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 38032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkPixelRef* ref = bitmap->pixelRef(); 38117a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III ref->ref(); 38217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III SkAlphaType alphaType; 38317a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III if (bitmap->colorType() != kRGB_565_SkColorType 38417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III && bitmap->alphaType() == kOpaque_SkAlphaType) { 38517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // If the original bitmap was set to opaque, keep that setting, unless it 38617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // was 565, which is required to be opaque. 38717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = kOpaque_SkAlphaType; 38817a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } else { 38917a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // Otherwise respect the premultiplied request. 39017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType; 39117a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III } 39217a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType)); 39317a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // FIXME: Skia thinks of an SkPixelRef as having a constant SkImageInfo (except for 39417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // its alphatype), so it would make more sense from Skia's perspective to create a 39517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // new SkPixelRef. That said, libhwui uses the pointer to the SkPixelRef as a key 39617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // for its cache, so it won't realize this is the same Java Bitmap. 39717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III SkImageInfo& info = const_cast<SkImageInfo&>(ref->info()); 39817a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // Use the updated from the SkBitmap, which may have corrected an invalid alphatype. 39917a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // (e.g. 565 non-opaque) 40017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III info = bitmap->info(); 40132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setPixelRef(ref); 40232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 40332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // notifyPixelsChanged will increment the generation ID even though the actual pixel data 40432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // hasn't been touched. This signals the renderer that the bitmap (including width, height, 40517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III // colortype and alphatype) has changed. 40632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ref->notifyPixelsChanged(); 40717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III ref->unref(); 40832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 40932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 41032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik// These must match the int values in Bitmap.java 41132054b0b3edb350a5444c47753b2982312dd7ffdChris Craikenum JavaEncodeFormat { 41232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kJPEG_JavaEncodeFormat = 0, 41332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kPNG_JavaEncodeFormat = 1, 41432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik kWEBP_JavaEncodeFormat = 2 41532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 41632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 41732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle, 41832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint format, jint quality, 41932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject jstream, jbyteArray jstorage) { 42032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 42132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkImageEncoder::Type fm; 42232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 42332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik switch (format) { 42432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kJPEG_JavaEncodeFormat: 42532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kJPEG_Type; 42632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 42732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kPNG_JavaEncodeFormat: 42832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kPNG_Type; 42932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 43032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik case kWEBP_JavaEncodeFormat: 43132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik fm = SkImageEncoder::kWEBP_Type; 43232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik break; 43332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik default: 43432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 43532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 43632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 43732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bool success = false; 43832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != bitmap) { 43932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(*bitmap); 44032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 44132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == bitmap->getPixels()) { 44232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 44332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 44432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 44532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage); 44632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == strm) { 44732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 44832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 44932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 45032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkImageEncoder* encoder = SkImageEncoder::Create(fm); 45132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != encoder) { 45232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik success = encoder->encodeStream(strm, *bitmap, quality); 45332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik delete encoder; 45432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 45532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik delete strm; 45632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 45732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return success ? JNI_TRUE : JNI_FALSE; 45832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 45932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 46032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) { 46132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 46232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->eraseColor(color); 46332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 46432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 46532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) { 46632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 46732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(bitmap->rowBytes()); 46832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 46932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 47032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_config(JNIEnv* env, jobject, jlong bitmapHandle) { 47132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 47232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(bitmap->config()); 47332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 47432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 47532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) { 47632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 47732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(bitmap->getGenerationID()); 47832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 47932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 48032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) { 48132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 48232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return !bitmap->isOpaque() ? JNI_TRUE : JNI_FALSE; 48332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 48432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 48532054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setAlphaAndPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle, 48632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean hasAlpha, jboolean isPremul) { 48732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 48832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (!hasAlpha) { 48932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setAlphaType(kOpaque_SkAlphaType); 49032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else if (isPremul) { 49132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setAlphaType(kPremul_SkAlphaType); 49232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 49332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setAlphaType(kUnpremul_SkAlphaType); 49432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 49532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 49632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 49732054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) { 49832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 49932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return bitmap->hasHardwareMipMap() ? JNI_TRUE : JNI_FALSE; 50032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 50132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 50232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle, 50332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean hasMipMap) { 50432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 50532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->setHasHardwareMipMap(hasMipMap); 50632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 50732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 50832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 50932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 51032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { 51132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 51232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("-------- unparcel parcel is NULL\n"); 51332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 51432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 51532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 51632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 51732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 518b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const bool isMutable = p->readInt32() != 0; 519b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkColorType colorType = (SkColorType)p->readInt32(); 520b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const SkAlphaType alphaType = (SkAlphaType)p->readInt32(); 521b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int width = p->readInt32(); 522b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int height = p->readInt32(); 523b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int rowBytes = p->readInt32(); 524b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed const int density = p->readInt32(); 525b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed 526b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (kN32_SkColorType != colorType && 527b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kRGB_565_SkColorType != colorType && 528b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kARGB_4444_SkColorType != colorType && 529b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kIndex_8_SkColorType != colorType && 530b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed kAlpha_8_SkColorType != colorType) { 531b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed SkDebugf("Bitmap_createFromParcel unknown colortype: %d\n", colorType); 53232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 53332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 53432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 53532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = new SkBitmap; 53632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 537b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType), rowBytes); 53832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 53932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable = NULL; 540b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (colorType == kIndex_8_SkColorType) { 54132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = p->readInt32(); 54232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (count > 0) { 54332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t size = count * sizeof(SkPMColor); 54432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPMColor* src = (const SkPMColor*)p->readInplace(size); 54532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable = new SkColorTable(src, count); 54632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 54732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 54832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 54932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable); 55032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == buffer) { 55132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkSafeUnref(ctable); 55232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik delete bitmap; 55332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 55432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 55532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 55632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkSafeUnref(ctable); 55732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 55832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t size = bitmap->getSize(); 55932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 56032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel::ReadableBlob blob; 56132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::status_t status = p->readBlob(size, &blob); 56232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (status) { 56332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowRE(env, "Could not read bitmap from parcel blob."); 56432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik delete bitmap; 56532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 56632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 56732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 56832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->lockPixels(); 56932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(bitmap->getPixels(), blob.data(), size); 57032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->unlockPixels(); 57132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 57232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik blob.release(); 57332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 57432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return GraphicsJNI::createBitmap(env, bitmap, buffer, getPremulBitmapCreateFlags(isMutable), 57532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik NULL, NULL, density); 57632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 57732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 57832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, 57932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, 58032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jboolean isMutable, jint density, 58132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jobject parcel) { 58232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 58332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (parcel == NULL) { 58432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkDebugf("------- writeToParcel null parcel\n"); 58532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 58632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 58732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 58832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel* p = android::parcelForJavaObject(env, parcel); 58932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 59032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(isMutable); 591b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed p->writeInt32(bitmap->colorType()); 592b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed p->writeInt32(bitmap->alphaType()); 59332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(bitmap->width()); 59432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(bitmap->height()); 59532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(bitmap->rowBytes()); 59632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(density); 59732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 598b933055cf3f7f8ea89bfd3bc9c37a3891ff7310aMike Reed if (bitmap->colorType() == kIndex_8_SkColorType) { 59932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable = bitmap->getColorTable(); 60032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ctable != NULL) { 60132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int count = ctable->count(); 60232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(count); 60332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(p->writeInplace(count * sizeof(SkPMColor)), 60432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable->lockColors(), count * sizeof(SkPMColor)); 60532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ctable->unlockColors(); 60632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 60732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik p->writeInt32(0); // indicate no ctable 60832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 60932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 61032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 61132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik size_t size = bitmap->getSize(); 61232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 61332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::Parcel::WritableBlob blob; 61432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::status_t status = p->writeBlob(size, &blob); 61532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (status) { 61632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowRE(env, "Could not write bitmap to parcel blob."); 61732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 61832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 61932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 62032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->lockPixels(); 62132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const void* pSrc = bitmap->getPixels(); 62232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (pSrc == NULL) { 62332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memset(blob.data(), 0, size); 62432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } else { 62532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(blob.data(), pSrc, size); 62632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 62732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->unlockPixels(); 62832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 62932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik blob.release(); 63032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 63132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 63232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 63332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz, 63432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong srcHandle, jlong paintHandle, 63532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray offsetXY) { 63632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* src = reinterpret_cast<SkBitmap*>(srcHandle); 63732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle); 63832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkIPoint offset; 63932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* dst = new SkBitmap; 64032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik JavaPixelAllocator allocator(env); 64132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 64232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik src->extractAlpha(dst, paint, &allocator, &offset); 64332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // If Skia can't allocate pixels for destination bitmap, it resets 64432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // it, that is set its pixels buffer to NULL, and zero width and height. 64532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (dst->getPixels() == NULL && src->getPixels() != NULL) { 64632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik delete dst; 64732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik doThrowOOME(env, "failed to allocate pixels for alpha"); 64832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return NULL; 64932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 65032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) { 65132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik int* array = env->GetIntArrayElements(offsetXY, NULL); 65232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[0] = offset.fX; 65332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik array[1] = offset.fY; 65432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(offsetXY, array, 0); 65532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 65632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 65732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return GraphicsJNI::createBitmap(env, dst, allocator.getStorageObj(), 65832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik getPremulBitmapCreateFlags(true), NULL, NULL); 65932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 66032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 66132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 66232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 66332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle, 66432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint x, jint y, jboolean isPremultiplied) { 66532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 66632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(*bitmap); 66732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 66832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ToColorProc proc = ChooseToColorProc(*bitmap, isPremultiplied); 66932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 67032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 67132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 67232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const void* src = bitmap->getAddr(x, y); 67332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 67432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return 0; 67532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 67632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 67732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor dst[1]; 67832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik proc(dst, src, 1, bitmap->getColorTable()); 67932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return static_cast<jint>(dst[0]); 68032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 68132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 68232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle, 68332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 68432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint x, jint y, jint width, jint height, jboolean isPremultiplied) { 68532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 68632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(*bitmap); 68732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 68832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik ToColorProc proc = ChooseToColorProc(*bitmap, isPremultiplied); 68932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 69032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 69132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 69232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const void* src = bitmap->getAddr(x, y); 69332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == src) { 69432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 69532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 69632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 69732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ctable = bitmap->getColorTable(); 69832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint* dst = env->GetIntArrayElements(pixelArray, NULL); 69932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor* d = (SkColor*)dst + offset; 70032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik while (--height >= 0) { 70132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik proc(d, src, width, ctable); 70232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik d += stride; 70332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik src = (void*)((const char*)src + bitmap->rowBytes()); 70432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 70532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik env->ReleaseIntArrayElements(pixelArray, dst, 0); 70632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 70732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 70832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 70932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 71032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle, 71132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint x, jint y, jint colorHandle, jboolean isPremultiplied) { 71232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 71332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColor color = static_cast<SkColor>(colorHandle); 71432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(*bitmap); 71532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == bitmap->getPixels()) { 71632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 71732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 71832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 71932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik FromColorProc proc = ChooseFromColorProc(bitmap->config(), isPremultiplied); 72032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == proc) { 72132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return; 72232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 72332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 72432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik proc(bitmap->getAddr(x, y), &color, 1, x, y); 72532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->notifyPixelsChanged(); 72632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 72732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 72832054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_setPixels(JNIEnv* env, jobject, jlong bitmapHandle, 72932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jintArray pixelArray, jint offset, jint stride, 73032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jint x, jint y, jint width, jint height, jboolean isPremultiplied) { 73132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 73232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik GraphicsJNI::SetPixels(env, pixelArray, offset, stride, 73332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik x, y, width, height, *bitmap, isPremultiplied); 73432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 73532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 73632054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject, 73732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 73832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 73932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(*bitmap); 74032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const void* src = bitmap->getPixels(); 74132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 74232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != src) { 74332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE); 74432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 74532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 74632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(abp.pointer(), src, bitmap->getSize()); 74732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 74832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 74932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 75032054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject, 75132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bitmapHandle, jobject jbuffer) { 75232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 75332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp(*bitmap); 75432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik void* dst = bitmap->getPixels(); 75532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 75632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL != dst) { 75732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE); 75832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the java side has already checked that buffer is large enough 75932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik memcpy(dst, abp.pointer(), bitmap->getSize()); 76032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->notifyPixelsChanged(); 76132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 76232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 76332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 76432054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle, 76532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik jlong bm1Handle) { 76632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* bm0 = reinterpret_cast<SkBitmap*>(bm0Handle); 76732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const SkBitmap* bm1 = reinterpret_cast<SkBitmap*>(bm1Handle); 76832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (bm0->width() != bm1->width() || 76932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bm0->height() != bm1->height() || 77032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bm0->config() != bm1->config()) { 77132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 77232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 77332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 77432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp0(*bm0); 77532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockPixels alp1(*bm1); 77632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 77732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // if we can't load the pixels, return false 77832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == bm0->getPixels() || NULL == bm1->getPixels()) { 77932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 78032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 78132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 78232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (bm0->config() == SkBitmap::kIndex8_Config) { 78332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ct0 = bm0->getColorTable(); 78432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkColorTable* ct1 = bm1->getColorTable(); 78532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (NULL == ct0 || NULL == ct1) { 78632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 78732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 78832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (ct0->count() != ct1->count()) { 78932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 79032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 79132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 79232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockColors alc0(ct0); 79332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkAutoLockColors alc1(ct1); 79432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const size_t size = ct0->count() * sizeof(SkPMColor); 79532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (memcmp(alc0.colors(), alc1.colors(), size) != 0) { 79632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 79732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 79832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 79932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 80032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // now compare each scanline. We can't do the entire buffer at once, 80132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // since we don't care about the pixel values that might extend beyond 80232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik // the width (since the scanline might be larger than the logical width) 80332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const int h = bm0->height(); 80432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik const size_t size = bm0->width() * bm0->bytesPerPixel(); 80532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik for (int y = 0; y < h; y++) { 80632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik if (memcmp(bm0->getAddr(0, y), bm1->getAddr(0, y), size) != 0) { 80732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_FALSE; 80832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 80932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik } 81032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return JNI_TRUE; 81132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 81232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 81332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapHandle) { 81432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); 81532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->lockPixels(); 81632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik bitmap->unlockPixels(); 81732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 81832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 81932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik/////////////////////////////////////////////////////////////////////////////// 82032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 82132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#include <android_runtime/AndroidRuntime.h> 82232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 82332054b0b3edb350a5444c47753b2982312dd7ffdChris Craikstatic JNINativeMethod gBitmapMethods[] = { 82432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;", 82532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_creator }, 82632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;", 82732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copy }, 82832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeDestructor", "(J)V", (void*)Bitmap_destructor }, 82932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRecycle", "(J)Z", (void*)Bitmap_recycle }, 83017a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III { "nativeReconfigure", "(JIIIIZ)V", (void*)Bitmap_reconfigure }, 83132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCompress", "(JIILjava/io/OutputStream;[B)Z", 83232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_compress }, 83332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeErase", "(JI)V", (void*)Bitmap_erase }, 83432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes }, 83532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeConfig", "(J)I", (void*)Bitmap_config }, 83632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha }, 83732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSetAlphaAndPremultiplied", "(JZZ)V", (void*)Bitmap_setAlphaAndPremultiplied}, 83832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap }, 83932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap }, 84032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCreateFromParcel", 84132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;", 84232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_createFromParcel }, 84332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeWriteToParcel", "(JZILandroid/os/Parcel;)Z", 84432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_writeToParcel }, 84532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeExtractAlpha", "(JJ[I)Landroid/graphics/Bitmap;", 84632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_extractAlpha }, 84732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeGenerationId", "(J)I", (void*)Bitmap_getGenerationId }, 84832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeGetPixel", "(JIIZ)I", (void*)Bitmap_getPixel }, 84932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeGetPixels", "(J[IIIIIIIZ)V", (void*)Bitmap_getPixels }, 85032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSetPixel", "(JIIIZ)V", (void*)Bitmap_setPixel }, 85132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSetPixels", "(J[IIIIIIIZ)V", (void*)Bitmap_setPixels }, 85232054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsToBuffer", "(JLjava/nio/Buffer;)V", 85332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsToBuffer }, 85432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V", 85532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik (void*)Bitmap_copyPixelsFromBuffer }, 85632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs }, 85732054b0b3edb350a5444c47753b2982312dd7ffdChris Craik { "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw }, 85832054b0b3edb350a5444c47753b2982312dd7ffdChris Craik}; 85932054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 86032054b0b3edb350a5444c47753b2982312dd7ffdChris Craik#define kClassPathName "android/graphics/Bitmap" 86132054b0b3edb350a5444c47753b2982312dd7ffdChris Craik 86232054b0b3edb350a5444c47753b2982312dd7ffdChris Craikint register_android_graphics_Bitmap(JNIEnv* env) 86332054b0b3edb350a5444c47753b2982312dd7ffdChris Craik{ 86432054b0b3edb350a5444c47753b2982312dd7ffdChris Craik return android::AndroidRuntime::registerNativeMethods(env, kClassPathName, 86532054b0b3edb350a5444c47753b2982312dd7ffdChris Craik gBitmapMethods, SK_ARRAY_COUNT(gBitmapMethods)); 86632054b0b3edb350a5444c47753b2982312dd7ffdChris Craik} 867