blob: 7143a8abb056bf58bf967abf7251767476a8aa58 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001#include "SkBitmap.h"
Patrick Dubroye4ac2d62010-12-01 11:23:13 -08002#include "SkPixelRef.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003#include "SkImageEncoder.h"
4#include "SkColorPriv.h"
5#include "GraphicsJNI.h"
6#include "SkDither.h"
7#include "SkUnPreMultiply.h"
Leon Scroggins IIIca320212013-08-20 17:59:39 -04008#include "SkStream.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009
Mathias Agopian07952722009-05-19 19:08:10 -070010#include <binder/Parcel.h>
Romain Guy713e1bb2012-10-16 18:44:09 -070011#include "android_os_Parcel.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012#include "android_util_Binder.h"
13#include "android_nio_utils.h"
14#include "CreateJavaOutputStreamAdaptor.h"
15
16#include <jni.h>
17
Romain Guy9aaa8262010-09-08 15:15:43 -070018#include <Caches.h>
19
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020#if 0
21 #define TRACE_BITMAP(code) code
22#else
23 #define TRACE_BITMAP(code)
24#endif
25
26///////////////////////////////////////////////////////////////////////////////
27// Conversions to/from SkColor, for get/setPixels, and the create method, which
28// is basically like setPixels
29
30typedef void (*FromColorProc)(void* dst, const SkColor src[], int width,
31 int x, int y);
32
33static void FromColor_D32(void* dst, const SkColor src[], int width,
34 int, int) {
35 SkPMColor* d = (SkPMColor*)dst;
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +080036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 for (int i = 0; i < width; i++) {
38 *d++ = SkPreMultiplyColor(*src++);
39 }
40}
41
Chris Craik1abf5d62013-08-16 12:47:03 -070042static void FromColor_D32_Raw(void* dst, const SkColor src[], int width,
43 int, int) {
44 // SkColor's ordering may be different from SkPMColor
45 if (SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER) {
46 memcpy(dst, src, width * sizeof(SkColor));
47 return;
48 }
49
50 // order isn't same, repack each pixel manually
51 SkPMColor* d = (SkPMColor*)dst;
52 for (int i = 0; i < width; i++) {
53 SkColor c = *src++;
54 *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),
55 SkColorGetG(c), SkColorGetB(c));
56 }
57}
58
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059static void FromColor_D565(void* dst, const SkColor src[], int width,
60 int x, int y) {
61 uint16_t* d = (uint16_t*)dst;
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +080062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 DITHER_565_SCAN(y);
64 for (int stop = x + width; x < stop; x++) {
65 SkColor c = *src++;
66 *d++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c),
67 DITHER_VALUE(x));
68 }
69}
70
71static void FromColor_D4444(void* dst, const SkColor src[], int width,
72 int x, int y) {
73 SkPMColor16* d = (SkPMColor16*)dst;
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +080074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 DITHER_4444_SCAN(y);
76 for (int stop = x + width; x < stop; x++) {
Chris Craik1abf5d62013-08-16 12:47:03 -070077 SkPMColor pmc = SkPreMultiplyColor(*src++);
78 *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));
79// *d++ = SkPixel32ToPixel4444(pmc);
80 }
81}
82
83static void FromColor_D4444_Raw(void* dst, const SkColor src[], int width,
84 int x, int y) {
85 SkPMColor16* d = (SkPMColor16*)dst;
86
87 DITHER_4444_SCAN(y);
88 for (int stop = x + width; x < stop; x++) {
89 SkColor c = *src++;
90
91 // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied
92 SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),
93 SkColorGetG(c), SkColorGetB(c));
94 *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));
95// *d++ = SkPixel32ToPixel4444(pmc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 }
97}
98
99// can return NULL
Chris Craik1abf5d62013-08-16 12:47:03 -0700100static FromColorProc ChooseFromColorProc(SkBitmap::Config config, bool isPremultiplied) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 switch (config) {
102 case SkBitmap::kARGB_8888_Config:
Chris Craik1abf5d62013-08-16 12:47:03 -0700103 return isPremultiplied ? FromColor_D32 : FromColor_D32_Raw;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 case SkBitmap::kARGB_4444_Config:
Chris Craik1abf5d62013-08-16 12:47:03 -0700105 return isPremultiplied ? FromColor_D4444 : FromColor_D4444_Raw;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 case SkBitmap::kRGB_565_Config:
107 return FromColor_D565;
108 default:
109 break;
110 }
111 return NULL;
112}
113
Chris Craik1abf5d62013-08-16 12:47:03 -0700114bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride,
115 int x, int y, int width, int height,
116 const SkBitmap& dstBitmap, bool isPremultiplied) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 SkAutoLockPixels alp(dstBitmap);
118 void* dst = dstBitmap.getPixels();
Chris Craik1abf5d62013-08-16 12:47:03 -0700119 FromColorProc proc = ChooseFromColorProc(dstBitmap.config(), isPremultiplied);
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 if (NULL == dst || NULL == proc) {
122 return false;
123 }
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 const jint* array = env->GetIntArrayElements(srcColors, NULL);
126 const SkColor* src = (const SkColor*)array + srcOffset;
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 // reset to to actual choice from caller
129 dst = dstBitmap.getAddr(x, y);
130 // now copy/convert each scanline
131 for (int y = 0; y < height; y++) {
132 proc(dst, src, width, x, y);
133 src += srcStride;
134 dst = (char*)dst + dstBitmap.rowBytes();
135 }
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800136
Romain Guy1a81aea2011-03-21 15:24:51 -0700137 dstBitmap.notifyPixelsChanged();
138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array),
140 JNI_ABORT);
141 return true;
142}
143
144//////////////////// ToColor procs
145
146typedef void (*ToColorProc)(SkColor dst[], const void* src, int width,
147 SkColorTable*);
148
149static void ToColor_S32_Alpha(SkColor dst[], const void* src, int width,
150 SkColorTable*) {
151 SkASSERT(width > 0);
152 const SkPMColor* s = (const SkPMColor*)src;
153 do {
154 *dst++ = SkUnPreMultiply::PMColorToColor(*s++);
155 } while (--width != 0);
156}
157
Chris Craik1abf5d62013-08-16 12:47:03 -0700158static void ToColor_S32_Raw(SkColor dst[], const void* src, int width,
159 SkColorTable*) {
160 SkASSERT(width > 0);
161 const SkPMColor* s = (const SkPMColor*)src;
162 do {
163 SkPMColor c = *s++;
164 *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
165 SkGetPackedG32(c), SkGetPackedB32(c));
166 } while (--width != 0);
167}
168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169static void ToColor_S32_Opaque(SkColor dst[], const void* src, int width,
170 SkColorTable*) {
171 SkASSERT(width > 0);
172 const SkPMColor* s = (const SkPMColor*)src;
173 do {
174 SkPMColor c = *s++;
175 *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
176 SkGetPackedB32(c));
177 } while (--width != 0);
178}
179
180static void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width,
181 SkColorTable*) {
182 SkASSERT(width > 0);
183 const SkPMColor16* s = (const SkPMColor16*)src;
184 do {
185 *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++));
186 } while (--width != 0);
187}
188
Chris Craik1abf5d62013-08-16 12:47:03 -0700189static void ToColor_S4444_Raw(SkColor dst[], const void* src, int width,
190 SkColorTable*) {
191 SkASSERT(width > 0);
192 const SkPMColor16* s = (const SkPMColor16*)src;
193 do {
194 SkPMColor c = SkPixel4444ToPixel32(*s++);
195 *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
196 SkGetPackedG32(c), SkGetPackedB32(c));
197 } while (--width != 0);
198}
199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200static void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width,
201 SkColorTable*) {
202 SkASSERT(width > 0);
Keun young Park038953d2012-10-12 11:36:13 -0700203 const SkPMColor16* s = (const SkPMColor16*)src;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 do {
205 SkPMColor c = SkPixel4444ToPixel32(*s++);
206 *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
207 SkGetPackedB32(c));
208 } while (--width != 0);
209}
210
211static void ToColor_S565(SkColor dst[], const void* src, int width,
212 SkColorTable*) {
213 SkASSERT(width > 0);
214 const uint16_t* s = (const uint16_t*)src;
215 do {
216 uint16_t c = *s++;
217 *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c),
218 SkPacked16ToB32(c));
219 } while (--width != 0);
220}
221
222static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width,
223 SkColorTable* ctable) {
224 SkASSERT(width > 0);
225 const uint8_t* s = (const uint8_t*)src;
226 const SkPMColor* colors = ctable->lockColors();
227 do {
228 *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
229 } while (--width != 0);
230 ctable->unlockColors(false);
231}
232
Chris Craik1abf5d62013-08-16 12:47:03 -0700233static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
234 SkColorTable* ctable) {
235 SkASSERT(width > 0);
236 const uint8_t* s = (const uint8_t*)src;
237 const SkPMColor* colors = ctable->lockColors();
238 do {
239 SkPMColor c = colors[*s++];
240 *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
241 SkGetPackedG32(c), SkGetPackedB32(c));
242 } while (--width != 0);
243 ctable->unlockColors(false);
244}
245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
247 SkColorTable* ctable) {
248 SkASSERT(width > 0);
249 const uint8_t* s = (const uint8_t*)src;
250 const SkPMColor* colors = ctable->lockColors();
251 do {
252 SkPMColor c = colors[*s++];
253 *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
254 SkGetPackedB32(c));
255 } while (--width != 0);
256 ctable->unlockColors(false);
257}
258
259// can return NULL
Chris Craik1abf5d62013-08-16 12:47:03 -0700260static ToColorProc ChooseToColorProc(const SkBitmap& src, bool isPremultiplied) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 switch (src.config()) {
262 case SkBitmap::kARGB_8888_Config:
Chris Craik1abf5d62013-08-16 12:47:03 -0700263 if (src.isOpaque()) return ToColor_S32_Opaque;
264 return isPremultiplied ? ToColor_S32_Alpha : ToColor_S32_Raw;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 case SkBitmap::kARGB_4444_Config:
Chris Craik1abf5d62013-08-16 12:47:03 -0700266 if (src.isOpaque()) return ToColor_S4444_Opaque;
267 return isPremultiplied ? ToColor_S4444_Alpha : ToColor_S4444_Raw;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 case SkBitmap::kRGB_565_Config:
269 return ToColor_S565;
270 case SkBitmap::kIndex8_Config:
271 if (src.getColorTable() == NULL) {
272 return NULL;
273 }
Chris Craik1abf5d62013-08-16 12:47:03 -0700274 if (src.isOpaque()) return ToColor_SI8_Opaque;
275 return isPremultiplied ? ToColor_SI8_Raw : ToColor_SI8_Alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 default:
277 break;
278 }
279 return NULL;
280}
281
282///////////////////////////////////////////////////////////////////////////////
283///////////////////////////////////////////////////////////////////////////////
284
Chris Craik1abf5d62013-08-16 12:47:03 -0700285static int getPremulBitmapCreateFlags(bool isMutable) {
286 int flags = GraphicsJNI::kBitmapCreateFlag_Premultiplied;
287 if (isMutable) flags |= GraphicsJNI::kBitmapCreateFlag_Mutable;
288 return flags;
289}
290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
Ashok Bhata0398432014-01-20 20:08:01 +0000292 jint offset, jint stride, jint width, jint height,
293 jint configHandle, jboolean isMutable) {
294 SkBitmap::Config config = static_cast<SkBitmap::Config>(configHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 if (NULL != jColors) {
296 size_t n = env->GetArrayLength(jColors);
297 if (n < SkAbs32(stride) * (size_t)height) {
298 doThrowAIOOBE(env);
299 return NULL;
300 }
301 }
302
Romain Guy3ed72782013-08-15 12:54:53 -0700303 // ARGB_4444 is a deprecated format, convert automatically to 8888
304 if (config == SkBitmap::kARGB_4444_Config) {
305 config = SkBitmap::kARGB_8888_Config;
306 }
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800307
Romain Guy3ed72782013-08-15 12:54:53 -0700308 SkBitmap bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 bitmap.setConfig(config, width, height);
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800310
311 jbyteArray buff = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL);
312 if (NULL == buff) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 return NULL;
314 }
315
316 if (jColors != NULL) {
Chris Craik1abf5d62013-08-16 12:47:03 -0700317 GraphicsJNI::SetPixels(env, jColors, offset, stride,
318 0, 0, width, height, bitmap, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 }
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800320
Chris Craik1abf5d62013-08-16 12:47:03 -0700321 return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff,
322 getPremulBitmapCreateFlags(isMutable), NULL, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323}
324
Ashok Bhata0398432014-01-20 20:08:01 +0000325static jobject Bitmap_copy(JNIEnv* env, jobject, jlong srcHandle,
326 jint dstConfigHandle, jboolean isMutable) {
327 const SkBitmap* src = reinterpret_cast<SkBitmap*>(srcHandle);
328 SkBitmap::Config dstConfig = static_cast<SkBitmap::Config>(dstConfigHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 SkBitmap result;
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800330 JavaPixelAllocator allocator(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331
332 if (!src->copyTo(&result, dstConfig, &allocator)) {
333 return NULL;
334 }
Chris Craik1abf5d62013-08-16 12:47:03 -0700335 return GraphicsJNI::createBitmap(env, new SkBitmap(result), allocator.getStorageObj(),
336 getPremulBitmapCreateFlags(isMutable), NULL, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337}
338
Ashok Bhata0398432014-01-20 20:08:01 +0000339static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) {
340 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Romain Guy9aaa8262010-09-08 15:15:43 -0700341#ifdef USE_OPENGL_RENDERER
Romain Guya2341a92010-09-08 18:04:33 -0700342 if (android::uirenderer::Caches::hasInstance()) {
Chet Haase5c13d892010-10-08 08:37:55 -0700343 android::uirenderer::Caches::getInstance().resourceCache.destructor(bitmap);
Chet Haase27f0b172010-10-22 08:52:33 -0700344 return;
Romain Guya2341a92010-09-08 18:04:33 -0700345 }
Chet Haase27f0b172010-10-22 08:52:33 -0700346#endif // USE_OPENGL_RENDERER
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 delete bitmap;
348}
349
Ashok Bhata0398432014-01-20 20:08:01 +0000350static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) {
351 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Chet Haase5c13d892010-10-08 08:37:55 -0700352#ifdef USE_OPENGL_RENDERER
353 if (android::uirenderer::Caches::hasInstance()) {
Ashok Bhata0398432014-01-20 20:08:01 +0000354 bool result;
355 result = android::uirenderer::Caches::getInstance().resourceCache.recycle(bitmap);
356 return result ? JNI_TRUE : JNI_FALSE;
Chet Haase5c13d892010-10-08 08:37:55 -0700357 }
Chet Haase5c13d892010-10-08 08:37:55 -0700358#endif // USE_OPENGL_RENDERER
Chet Haase27f0b172010-10-22 08:52:33 -0700359 bitmap->setPixels(NULL, NULL);
Ashok Bhata0398432014-01-20 20:08:01 +0000360 return JNI_TRUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361}
362
Ashok Bhata0398432014-01-20 20:08:01 +0000363static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle,
364 jint width, jint height, jint configHandle, jint allocSize) {
365 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
366 SkBitmap::Config config = static_cast<SkBitmap::Config>(configHandle);
Chris Craikc84d2032013-07-12 19:35:52 -0700367 if (width * height * SkBitmap::ComputeBytesPerPixel(config) > allocSize) {
368 // done in native as there's no way to get BytesPerPixel in Java
369 doThrowIAE(env, "Bitmap not large enough to support new configuration");
370 return;
371 }
Chris Craikc84d2032013-07-12 19:35:52 -0700372 SkPixelRef* ref = bitmap->pixelRef();
373 SkSafeRef(ref);
374 bitmap->setConfig(config, width, height);
375 bitmap->setPixelRef(ref);
376
377 // notifyPixelsChanged will increment the generation ID even though the actual pixel data
378 // hasn't been touched. This signals the renderer that the bitmap (including width, height,
379 // and config) has changed.
380 ref->notifyPixelsChanged();
381 SkSafeUnref(ref);
382}
383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384// These must match the int values in Bitmap.java
385enum JavaEncodeFormat {
386 kJPEG_JavaEncodeFormat = 0,
Vikas Arora2305ac92011-06-23 13:11:13 +0530387 kPNG_JavaEncodeFormat = 1,
388 kWEBP_JavaEncodeFormat = 2
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389};
390
Ashok Bhata0398432014-01-20 20:08:01 +0000391static jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle,
392 jint format, jint quality,
393 jobject jstream, jbyteArray jstorage) {
394 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 SkImageEncoder::Type fm;
396
397 switch (format) {
398 case kJPEG_JavaEncodeFormat:
399 fm = SkImageEncoder::kJPEG_Type;
400 break;
401 case kPNG_JavaEncodeFormat:
402 fm = SkImageEncoder::kPNG_Type;
403 break;
Vikas Arora2305ac92011-06-23 13:11:13 +0530404 case kWEBP_JavaEncodeFormat:
405 fm = SkImageEncoder::kWEBP_Type;
406 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 default:
Ashok Bhata0398432014-01-20 20:08:01 +0000408 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 }
410
411 bool success = false;
Michal Stawinski35ef5672012-07-08 12:25:45 +0200412 if (NULL != bitmap) {
413 SkAutoLockPixels alp(*bitmap);
414
415 if (NULL == bitmap->getPixels()) {
Ashok Bhata0398432014-01-20 20:08:01 +0000416 return JNI_FALSE;
Michal Stawinski35ef5672012-07-08 12:25:45 +0200417 }
418
419 SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
420 if (NULL == strm) {
Ashok Bhata0398432014-01-20 20:08:01 +0000421 return JNI_FALSE;
Michal Stawinski35ef5672012-07-08 12:25:45 +0200422 }
423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 SkImageEncoder* encoder = SkImageEncoder::Create(fm);
425 if (NULL != encoder) {
426 success = encoder->encodeStream(strm, *bitmap, quality);
427 delete encoder;
428 }
429 delete strm;
430 }
Ashok Bhata0398432014-01-20 20:08:01 +0000431 return success ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432}
433
Ashok Bhata0398432014-01-20 20:08:01 +0000434static void Bitmap_erase(JNIEnv* env, jobject, jlong bitmapHandle, jint color) {
435 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 bitmap->eraseColor(color);
437}
438
Ashok Bhata0398432014-01-20 20:08:01 +0000439static jint Bitmap_rowBytes(JNIEnv* env, jobject, jlong bitmapHandle) {
440 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
441 return static_cast<jint>(bitmap->rowBytes());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442}
443
Ashok Bhata0398432014-01-20 20:08:01 +0000444static jint Bitmap_config(JNIEnv* env, jobject, jlong bitmapHandle) {
445 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
446 return static_cast<jint>(bitmap->config());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447}
448
Ashok Bhata0398432014-01-20 20:08:01 +0000449static jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) {
450 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
451 return static_cast<jint>(bitmap->getGenerationID());
Romain Guy0bbae082010-06-15 18:03:40 -0700452}
453
Ashok Bhata0398432014-01-20 20:08:01 +0000454static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, jlong bitmapHandle) {
455 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
456 return !bitmap->isOpaque() ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457}
458
Ashok Bhata0398432014-01-20 20:08:01 +0000459static void Bitmap_setHasAlpha(JNIEnv* env, jobject, jlong bitmapHandle,
Mike Reeda78b0a22009-10-07 11:38:05 -0700460 jboolean hasAlpha) {
Ashok Bhata0398432014-01-20 20:08:01 +0000461 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Mike Reeda78b0a22009-10-07 11:38:05 -0700462 bitmap->setIsOpaque(!hasAlpha);
463}
464
Ashok Bhata0398432014-01-20 20:08:01 +0000465static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, jlong bitmapHandle) {
466 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
467 return bitmap->hasHardwareMipMap() ? JNI_TRUE : JNI_FALSE;
Romain Guy713e1bb2012-10-16 18:44:09 -0700468}
469
Ashok Bhata0398432014-01-20 20:08:01 +0000470static void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle,
Romain Guy713e1bb2012-10-16 18:44:09 -0700471 jboolean hasMipMap) {
Ashok Bhata0398432014-01-20 20:08:01 +0000472 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Romain Guy713e1bb2012-10-16 18:44:09 -0700473 bitmap->setHasHardwareMipMap(hasMipMap);
474}
475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476///////////////////////////////////////////////////////////////////////////////
477
478static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
479 if (parcel == NULL) {
480 SkDebugf("-------- unparcel parcel is NULL\n");
481 return NULL;
482 }
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 android::Parcel* p = android::parcelForJavaObject(env, parcel);
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 const bool isMutable = p->readInt32() != 0;
487 const SkBitmap::Config config = (SkBitmap::Config)p->readInt32();
488 const int width = p->readInt32();
489 const int height = p->readInt32();
490 const int rowBytes = p->readInt32();
Dianne Hackbornde0dfb72009-09-23 14:09:34 -0700491 const int density = p->readInt32();
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 if (SkBitmap::kARGB_8888_Config != config &&
494 SkBitmap::kRGB_565_Config != config &&
495 SkBitmap::kARGB_4444_Config != config &&
496 SkBitmap::kIndex8_Config != config &&
497 SkBitmap::kA8_Config != config) {
498 SkDebugf("Bitmap_createFromParcel unknown config: %d\n", config);
499 return NULL;
500 }
501
502 SkBitmap* bitmap = new SkBitmap;
503
504 bitmap->setConfig(config, width, height, rowBytes);
505
506 SkColorTable* ctable = NULL;
507 if (config == SkBitmap::kIndex8_Config) {
508 int count = p->readInt32();
509 if (count > 0) {
510 size_t size = count * sizeof(SkPMColor);
511 const SkPMColor* src = (const SkPMColor*)p->readInplace(size);
512 ctable = new SkColorTable(src, count);
513 }
514 }
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800515
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800516 jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable);
517 if (NULL == buffer) {
Derek Sollenberger6062c592011-02-22 13:55:04 -0500518 SkSafeUnref(ctable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 delete bitmap;
520 return NULL;
521 }
522
Derek Sollenberger6062c592011-02-22 13:55:04 -0500523 SkSafeUnref(ctable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524
525 size_t size = bitmap->getSize();
Jeff Brown6579a9d2011-09-23 21:17:56 -0700526
527 android::Parcel::ReadableBlob blob;
528 android::status_t status = p->readBlob(size, &blob);
529 if (status) {
530 doThrowRE(env, "Could not read bitmap from parcel blob.");
531 delete bitmap;
532 return NULL;
533 }
534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 bitmap->lockPixels();
Jeff Brown6579a9d2011-09-23 21:17:56 -0700536 memcpy(bitmap->getPixels(), blob.data(), size);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 bitmap->unlockPixels();
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800538
Jeff Brown6579a9d2011-09-23 21:17:56 -0700539 blob.release();
Chris Craik1abf5d62013-08-16 12:47:03 -0700540
541 return GraphicsJNI::createBitmap(env, bitmap, buffer, getPremulBitmapCreateFlags(isMutable),
542 NULL, NULL, density);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543}
544
545static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
Ashok Bhata0398432014-01-20 20:08:01 +0000546 jlong bitmapHandle,
Dianne Hackbornde0dfb72009-09-23 14:09:34 -0700547 jboolean isMutable, jint density,
548 jobject parcel) {
Ashok Bhata0398432014-01-20 20:08:01 +0000549 const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 if (parcel == NULL) {
551 SkDebugf("------- writeToParcel null parcel\n");
Ashok Bhata0398432014-01-20 20:08:01 +0000552 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 }
554
555 android::Parcel* p = android::parcelForJavaObject(env, parcel);
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 p->writeInt32(isMutable);
558 p->writeInt32(bitmap->config());
559 p->writeInt32(bitmap->width());
560 p->writeInt32(bitmap->height());
561 p->writeInt32(bitmap->rowBytes());
Dianne Hackbornde0dfb72009-09-23 14:09:34 -0700562 p->writeInt32(density);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563
564 if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {
565 SkColorTable* ctable = bitmap->getColorTable();
566 if (ctable != NULL) {
567 int count = ctable->count();
568 p->writeInt32(count);
569 memcpy(p->writeInplace(count * sizeof(SkPMColor)),
570 ctable->lockColors(), count * sizeof(SkPMColor));
571 ctable->unlockColors(false);
572 } else {
573 p->writeInt32(0); // indicate no ctable
574 }
575 }
576
577 size_t size = bitmap->getSize();
Jeff Brown6579a9d2011-09-23 21:17:56 -0700578
579 android::Parcel::WritableBlob blob;
580 android::status_t status = p->writeBlob(size, &blob);
581 if (status) {
582 doThrowRE(env, "Could not write bitmap to parcel blob.");
Ashok Bhata0398432014-01-20 20:08:01 +0000583 return JNI_FALSE;
Jeff Brown6579a9d2011-09-23 21:17:56 -0700584 }
585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 bitmap->lockPixels();
Jack Palevichdee4cb02010-12-13 11:13:32 -0800587 const void* pSrc = bitmap->getPixels();
Jack Palevichdee4cb02010-12-13 11:13:32 -0800588 if (pSrc == NULL) {
Jeff Brown6579a9d2011-09-23 21:17:56 -0700589 memset(blob.data(), 0, size);
Jack Palevichdee4cb02010-12-13 11:13:32 -0800590 } else {
Jeff Brown6579a9d2011-09-23 21:17:56 -0700591 memcpy(blob.data(), pSrc, size);
Jack Palevichdee4cb02010-12-13 11:13:32 -0800592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 bitmap->unlockPixels();
Jeff Brown6579a9d2011-09-23 21:17:56 -0700594
595 blob.release();
Ashok Bhata0398432014-01-20 20:08:01 +0000596 return JNI_TRUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597}
598
599static jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz,
Ashok Bhata0398432014-01-20 20:08:01 +0000600 jlong srcHandle, jlong paintHandle,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 jintArray offsetXY) {
Ashok Bhata0398432014-01-20 20:08:01 +0000602 const SkBitmap* src = reinterpret_cast<SkBitmap*>(srcHandle);
603 const SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 SkIPoint offset;
605 SkBitmap* dst = new SkBitmap;
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800606 JavaPixelAllocator allocator(env);
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800607
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800608 src->extractAlpha(dst, paint, &allocator, &offset);
Eric Hassoldef7be262011-02-23 16:46:11 -0800609 // If Skia can't allocate pixels for destination bitmap, it resets
610 // it, that is set its pixels buffer to NULL, and zero width and height.
611 if (dst->getPixels() == NULL && src->getPixels() != NULL) {
612 delete dst;
613 doThrowOOME(env, "failed to allocate pixels for alpha");
614 return NULL;
615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) {
617 int* array = env->GetIntArrayElements(offsetXY, NULL);
618 array[0] = offset.fX;
619 array[1] = offset.fY;
620 env->ReleaseIntArrayElements(offsetXY, array, 0);
621 }
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800622
Chris Craik1abf5d62013-08-16 12:47:03 -0700623 return GraphicsJNI::createBitmap(env, dst, allocator.getStorageObj(),
624 GraphicsJNI::kBitmapCreateFlag_Mutable, NULL, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625}
626
627///////////////////////////////////////////////////////////////////////////////
628
Ashok Bhata0398432014-01-20 20:08:01 +0000629static jint Bitmap_getPixel(JNIEnv* env, jobject, jlong bitmapHandle,
630 jint x, jint y, jboolean isPremultiplied) {
631 const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632 SkAutoLockPixels alp(*bitmap);
633
Chris Craik1abf5d62013-08-16 12:47:03 -0700634 ToColorProc proc = ChooseToColorProc(*bitmap, isPremultiplied);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 if (NULL == proc) {
636 return 0;
637 }
638 const void* src = bitmap->getAddr(x, y);
639 if (NULL == src) {
640 return 0;
641 }
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643 SkColor dst[1];
644 proc(dst, src, 1, bitmap->getColorTable());
Ashok Bhata0398432014-01-20 20:08:01 +0000645 return static_cast<jint>(dst[0]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646}
647
Ashok Bhata0398432014-01-20 20:08:01 +0000648static void Bitmap_getPixels(JNIEnv* env, jobject, jlong bitmapHandle,
649 jintArray pixelArray, jint offset, jint stride,
650 jint x, jint y, jint width, jint height, jboolean isPremultiplied) {
651 const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 SkAutoLockPixels alp(*bitmap);
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800653
Chris Craik1abf5d62013-08-16 12:47:03 -0700654 ToColorProc proc = ChooseToColorProc(*bitmap, isPremultiplied);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 if (NULL == proc) {
656 return;
657 }
658 const void* src = bitmap->getAddr(x, y);
659 if (NULL == src) {
660 return;
661 }
662
663 SkColorTable* ctable = bitmap->getColorTable();
664 jint* dst = env->GetIntArrayElements(pixelArray, NULL);
665 SkColor* d = (SkColor*)dst + offset;
666 while (--height >= 0) {
667 proc(d, src, width, ctable);
668 d += stride;
669 src = (void*)((const char*)src + bitmap->rowBytes());
670 }
671 env->ReleaseIntArrayElements(pixelArray, dst, 0);
672}
673
674///////////////////////////////////////////////////////////////////////////////
675
Ashok Bhata0398432014-01-20 20:08:01 +0000676static void Bitmap_setPixel(JNIEnv* env, jobject, jlong bitmapHandle,
677 jint x, jint y, jint colorHandle, jboolean isPremultiplied) {
678 const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
679 SkColor color = static_cast<SkColor>(colorHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 SkAutoLockPixels alp(*bitmap);
681 if (NULL == bitmap->getPixels()) {
682 return;
683 }
684
Chris Craik1abf5d62013-08-16 12:47:03 -0700685 FromColorProc proc = ChooseFromColorProc(bitmap->config(), isPremultiplied);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 if (NULL == proc) {
687 return;
688 }
689
690 proc(bitmap->getAddr(x, y), &color, 1, x, y);
Romain Guy1a81aea2011-03-21 15:24:51 -0700691 bitmap->notifyPixelsChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692}
693
Ashok Bhata0398432014-01-20 20:08:01 +0000694static void Bitmap_setPixels(JNIEnv* env, jobject, jlong bitmapHandle,
695 jintArray pixelArray, jint offset, jint stride,
696 jint x, jint y, jint width, jint height, jboolean isPremultiplied) {
697 const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698 GraphicsJNI::SetPixels(env, pixelArray, offset, stride,
Chris Craik1abf5d62013-08-16 12:47:03 -0700699 x, y, width, height, *bitmap, isPremultiplied);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700}
701
702static void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject,
Ashok Bhata0398432014-01-20 20:08:01 +0000703 jlong bitmapHandle, jobject jbuffer) {
704 const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705 SkAutoLockPixels alp(*bitmap);
706 const void* src = bitmap->getPixels();
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 if (NULL != src) {
709 android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE);
710
711 // the java side has already checked that buffer is large enough
712 memcpy(abp.pointer(), src, bitmap->getSize());
713 }
714}
715
716static void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject,
Ashok Bhata0398432014-01-20 20:08:01 +0000717 jlong bitmapHandle, jobject jbuffer) {
718 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800719 SkAutoLockPixels alp(*bitmap);
720 void* dst = bitmap->getPixels();
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 if (NULL != dst) {
723 android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE);
724 // the java side has already checked that buffer is large enough
725 memcpy(dst, abp.pointer(), bitmap->getSize());
Romain Guy2c183fa2011-10-18 17:56:06 -0700726 bitmap->notifyPixelsChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 }
728}
729
Ashok Bhata0398432014-01-20 20:08:01 +0000730static jboolean Bitmap_sameAs(JNIEnv* env, jobject, jlong bm0Handle,
731 jlong bm1Handle) {
732 const SkBitmap* bm0 = reinterpret_cast<SkBitmap*>(bm0Handle);
733 const SkBitmap* bm1 = reinterpret_cast<SkBitmap*>(bm1Handle);
Mike Reed76d1e012010-03-05 17:42:30 -0500734 if (bm0->width() != bm1->width() ||
735 bm0->height() != bm1->height() ||
736 bm0->config() != bm1->config()) {
Ashok Bhata0398432014-01-20 20:08:01 +0000737 return JNI_FALSE;
Mike Reed76d1e012010-03-05 17:42:30 -0500738 }
739
740 SkAutoLockPixels alp0(*bm0);
741 SkAutoLockPixels alp1(*bm1);
742
743 // if we can't load the pixels, return false
744 if (NULL == bm0->getPixels() || NULL == bm1->getPixels()) {
Ashok Bhata0398432014-01-20 20:08:01 +0000745 return JNI_FALSE;
Mike Reed76d1e012010-03-05 17:42:30 -0500746 }
747
748 if (bm0->config() == SkBitmap::kIndex8_Config) {
749 SkColorTable* ct0 = bm0->getColorTable();
750 SkColorTable* ct1 = bm1->getColorTable();
751 if (NULL == ct0 || NULL == ct1) {
Ashok Bhata0398432014-01-20 20:08:01 +0000752 return JNI_FALSE;
Mike Reed76d1e012010-03-05 17:42:30 -0500753 }
754 if (ct0->count() != ct1->count()) {
Ashok Bhata0398432014-01-20 20:08:01 +0000755 return JNI_FALSE;
Mike Reed76d1e012010-03-05 17:42:30 -0500756 }
757
758 SkAutoLockColors alc0(ct0);
759 SkAutoLockColors alc1(ct1);
760 const size_t size = ct0->count() * sizeof(SkPMColor);
761 if (memcmp(alc0.colors(), alc1.colors(), size) != 0) {
Ashok Bhata0398432014-01-20 20:08:01 +0000762 return JNI_FALSE;
Mike Reed76d1e012010-03-05 17:42:30 -0500763 }
764 }
765
766 // now compare each scanline. We can't do the entire buffer at once,
767 // since we don't care about the pixel values that might extend beyond
768 // the width (since the scanline might be larger than the logical width)
769 const int h = bm0->height();
770 const size_t size = bm0->width() * bm0->bytesPerPixel();
771 for (int y = 0; y < h; y++) {
772 if (memcmp(bm0->getAddr(0, y), bm1->getAddr(0, y), size) != 0) {
Ashok Bhata0398432014-01-20 20:08:01 +0000773 return JNI_FALSE;
Mike Reed76d1e012010-03-05 17:42:30 -0500774 }
775 }
Ashok Bhata0398432014-01-20 20:08:01 +0000776 return JNI_TRUE;
Mike Reed76d1e012010-03-05 17:42:30 -0500777}
778
Ashok Bhata0398432014-01-20 20:08:01 +0000779static void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapHandle) {
780 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800781 bitmap->lockPixels();
782 bitmap->unlockPixels();
783}
784
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785///////////////////////////////////////////////////////////////////////////////
786
787#include <android_runtime/AndroidRuntime.h>
788
789static JNINativeMethod gBitmapMethods[] = {
790 { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;",
791 (void*)Bitmap_creator },
Ashok Bhata0398432014-01-20 20:08:01 +0000792 { "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 (void*)Bitmap_copy },
Ashok Bhata0398432014-01-20 20:08:01 +0000794 { "nativeDestructor", "(J)V", (void*)Bitmap_destructor },
795 { "nativeRecycle", "(J)Z", (void*)Bitmap_recycle },
796 { "nativeReconfigure", "(JIIII)V", (void*)Bitmap_reconfigure },
797 { "nativeCompress", "(JIILjava/io/OutputStream;[B)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 (void*)Bitmap_compress },
Ashok Bhata0398432014-01-20 20:08:01 +0000799 { "nativeErase", "(JI)V", (void*)Bitmap_erase },
800 { "nativeRowBytes", "(J)I", (void*)Bitmap_rowBytes },
801 { "nativeConfig", "(J)I", (void*)Bitmap_config },
802 { "nativeHasAlpha", "(J)Z", (void*)Bitmap_hasAlpha },
803 { "nativeSetHasAlpha", "(JZ)V", (void*)Bitmap_setHasAlpha },
804 { "nativeHasMipMap", "(J)Z", (void*)Bitmap_hasMipMap },
805 { "nativeSetHasMipMap", "(JZ)V", (void*)Bitmap_setHasMipMap },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 { "nativeCreateFromParcel",
807 "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",
808 (void*)Bitmap_createFromParcel },
Ashok Bhata0398432014-01-20 20:08:01 +0000809 { "nativeWriteToParcel", "(JZILandroid/os/Parcel;)Z",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 (void*)Bitmap_writeToParcel },
Ashok Bhata0398432014-01-20 20:08:01 +0000811 { "nativeExtractAlpha", "(JJ[I)Landroid/graphics/Bitmap;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 (void*)Bitmap_extractAlpha },
Ashok Bhata0398432014-01-20 20:08:01 +0000813 { "nativeGenerationId", "(J)I", (void*)Bitmap_getGenerationId },
814 { "nativeGetPixel", "(JIIZ)I", (void*)Bitmap_getPixel },
815 { "nativeGetPixels", "(J[IIIIIIIZ)V", (void*)Bitmap_getPixels },
816 { "nativeSetPixel", "(JIIIZ)V", (void*)Bitmap_setPixel },
817 { "nativeSetPixels", "(J[IIIIIIIZ)V", (void*)Bitmap_setPixels },
818 { "nativeCopyPixelsToBuffer", "(JLjava/nio/Buffer;)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 (void*)Bitmap_copyPixelsToBuffer },
Ashok Bhata0398432014-01-20 20:08:01 +0000820 { "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V",
Wei-Ta Chen8cdcb122009-06-18 19:14:38 +0800821 (void*)Bitmap_copyPixelsFromBuffer },
Ashok Bhata0398432014-01-20 20:08:01 +0000822 { "nativeSameAs", "(JJ)Z", (void*)Bitmap_sameAs },
823 { "nativePrepareToDraw", "(J)V", (void*)Bitmap_prepareToDraw },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824};
825
826#define kClassPathName "android/graphics/Bitmap"
827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828int register_android_graphics_Bitmap(JNIEnv* env)
829{
830 return android::AndroidRuntime::registerNativeMethods(env, kClassPathName,
831 gBitmapMethods, SK_ARRAY_COUNT(gBitmapMethods));
832}