PageRenderTime 85ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/core/jni/android/graphics/Bitmap.cpp

https://bitbucket.org/droidandy/derrick-spencer
C++ | 684 lines | 553 code | 107 blank | 24 comment | 112 complexity | 153c6f5fd42a6a9192a61d64f6283382 MD5 | raw file
Possible License(s): LGPL-2.1, CC0-1.0, BSD-3-Clause
  1. #include "SkBitmap.h"
  2. #include "SkPixelRef.h"
  3. #include "SkImageEncoder.h"
  4. #include "SkColorPriv.h"
  5. #include "GraphicsJNI.h"
  6. #include "SkDither.h"
  7. #include "SkUnPreMultiply.h"
  8. #include <binder/Parcel.h>
  9. #include "android_util_Binder.h"
  10. #include "android_nio_utils.h"
  11. #include "CreateJavaOutputStreamAdaptor.h"
  12. #include <jni.h>
  13. #include <Caches.h>
  14. #if 0
  15. #define TRACE_BITMAP(code) code
  16. #else
  17. #define TRACE_BITMAP(code)
  18. #endif
  19. ///////////////////////////////////////////////////////////////////////////////
  20. // Conversions to/from SkColor, for get/setPixels, and the create method, which
  21. // is basically like setPixels
  22. typedef void (*FromColorProc)(void* dst, const SkColor src[], int width,
  23. int x, int y);
  24. static void FromColor_D32(void* dst, const SkColor src[], int width,
  25. int, int) {
  26. SkPMColor* d = (SkPMColor*)dst;
  27. for (int i = 0; i < width; i++) {
  28. *d++ = SkPreMultiplyColor(*src++);
  29. }
  30. }
  31. static void FromColor_D565(void* dst, const SkColor src[], int width,
  32. int x, int y) {
  33. uint16_t* d = (uint16_t*)dst;
  34. DITHER_565_SCAN(y);
  35. for (int stop = x + width; x < stop; x++) {
  36. SkColor c = *src++;
  37. *d++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c),
  38. DITHER_VALUE(x));
  39. }
  40. }
  41. static void FromColor_D4444(void* dst, const SkColor src[], int width,
  42. int x, int y) {
  43. SkPMColor16* d = (SkPMColor16*)dst;
  44. DITHER_4444_SCAN(y);
  45. for (int stop = x + width; x < stop; x++) {
  46. SkPMColor c = SkPreMultiplyColor(*src++);
  47. *d++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));
  48. // *d++ = SkPixel32ToPixel4444(c);
  49. }
  50. }
  51. // can return NULL
  52. static FromColorProc ChooseFromColorProc(SkBitmap::Config config) {
  53. switch (config) {
  54. case SkBitmap::kARGB_8888_Config:
  55. return FromColor_D32;
  56. case SkBitmap::kARGB_4444_Config:
  57. return FromColor_D4444;
  58. case SkBitmap::kRGB_565_Config:
  59. return FromColor_D565;
  60. default:
  61. break;
  62. }
  63. return NULL;
  64. }
  65. bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors,
  66. int srcOffset, int srcStride,
  67. int x, int y, int width, int height,
  68. const SkBitmap& dstBitmap) {
  69. SkAutoLockPixels alp(dstBitmap);
  70. void* dst = dstBitmap.getPixels();
  71. FromColorProc proc = ChooseFromColorProc(dstBitmap.config());
  72. if (NULL == dst || NULL == proc) {
  73. return false;
  74. }
  75. const jint* array = env->GetIntArrayElements(srcColors, NULL);
  76. const SkColor* src = (const SkColor*)array + srcOffset;
  77. // reset to to actual choice from caller
  78. dst = dstBitmap.getAddr(x, y);
  79. // now copy/convert each scanline
  80. for (int y = 0; y < height; y++) {
  81. proc(dst, src, width, x, y);
  82. src += srcStride;
  83. dst = (char*)dst + dstBitmap.rowBytes();
  84. }
  85. dstBitmap.notifyPixelsChanged();
  86. env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array),
  87. JNI_ABORT);
  88. return true;
  89. }
  90. //////////////////// ToColor procs
  91. typedef void (*ToColorProc)(SkColor dst[], const void* src, int width,
  92. SkColorTable*);
  93. static void ToColor_S32_Alpha(SkColor dst[], const void* src, int width,
  94. SkColorTable*) {
  95. SkASSERT(width > 0);
  96. const SkPMColor* s = (const SkPMColor*)src;
  97. do {
  98. *dst++ = SkUnPreMultiply::PMColorToColor(*s++);
  99. } while (--width != 0);
  100. }
  101. static void ToColor_S32_Opaque(SkColor dst[], const void* src, int width,
  102. SkColorTable*) {
  103. SkASSERT(width > 0);
  104. const SkPMColor* s = (const SkPMColor*)src;
  105. do {
  106. SkPMColor c = *s++;
  107. *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
  108. SkGetPackedB32(c));
  109. } while (--width != 0);
  110. }
  111. static void ToColor_S4444_Alpha(SkColor dst[], const void* src, int width,
  112. SkColorTable*) {
  113. SkASSERT(width > 0);
  114. const SkPMColor16* s = (const SkPMColor16*)src;
  115. do {
  116. *dst++ = SkUnPreMultiply::PMColorToColor(SkPixel4444ToPixel32(*s++));
  117. } while (--width != 0);
  118. }
  119. static void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width,
  120. SkColorTable*) {
  121. SkASSERT(width > 0);
  122. const SkPMColor* s = (const SkPMColor*)src;
  123. do {
  124. SkPMColor c = SkPixel4444ToPixel32(*s++);
  125. *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
  126. SkGetPackedB32(c));
  127. } while (--width != 0);
  128. }
  129. static void ToColor_S565(SkColor dst[], const void* src, int width,
  130. SkColorTable*) {
  131. SkASSERT(width > 0);
  132. const uint16_t* s = (const uint16_t*)src;
  133. do {
  134. uint16_t c = *s++;
  135. *dst++ = SkColorSetRGB(SkPacked16ToR32(c), SkPacked16ToG32(c),
  136. SkPacked16ToB32(c));
  137. } while (--width != 0);
  138. }
  139. static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width,
  140. SkColorTable* ctable) {
  141. SkASSERT(width > 0);
  142. const uint8_t* s = (const uint8_t*)src;
  143. const SkPMColor* colors = ctable->lockColors();
  144. do {
  145. *dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
  146. } while (--width != 0);
  147. ctable->unlockColors(false);
  148. }
  149. static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
  150. SkColorTable* ctable) {
  151. SkASSERT(width > 0);
  152. const uint8_t* s = (const uint8_t*)src;
  153. const SkPMColor* colors = ctable->lockColors();
  154. do {
  155. SkPMColor c = colors[*s++];
  156. *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
  157. SkGetPackedB32(c));
  158. } while (--width != 0);
  159. ctable->unlockColors(false);
  160. }
  161. // can return NULL
  162. static ToColorProc ChooseToColorProc(const SkBitmap& src) {
  163. switch (src.config()) {
  164. case SkBitmap::kARGB_8888_Config:
  165. return src.isOpaque() ? ToColor_S32_Opaque : ToColor_S32_Alpha;
  166. case SkBitmap::kARGB_4444_Config:
  167. return src.isOpaque() ? ToColor_S4444_Opaque : ToColor_S4444_Alpha;
  168. case SkBitmap::kRGB_565_Config:
  169. return ToColor_S565;
  170. case SkBitmap::kIndex8_Config:
  171. if (src.getColorTable() == NULL) {
  172. return NULL;
  173. }
  174. return src.isOpaque() ? ToColor_SI8_Opaque : ToColor_SI8_Alpha;
  175. default:
  176. break;
  177. }
  178. return NULL;
  179. }
  180. ///////////////////////////////////////////////////////////////////////////////
  181. ///////////////////////////////////////////////////////////////////////////////
  182. static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
  183. int offset, int stride, int width, int height,
  184. SkBitmap::Config config, jboolean isMutable) {
  185. if (NULL != jColors) {
  186. size_t n = env->GetArrayLength(jColors);
  187. if (n < SkAbs32(stride) * (size_t)height) {
  188. doThrowAIOOBE(env);
  189. return NULL;
  190. }
  191. }
  192. SkBitmap bitmap;
  193. bitmap.setConfig(config, width, height);
  194. jbyteArray buff = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL);
  195. if (NULL == buff) {
  196. return NULL;
  197. }
  198. if (jColors != NULL) {
  199. GraphicsJNI::SetPixels(env, jColors, offset, stride,
  200. 0, 0, width, height, bitmap);
  201. }
  202. return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff, isMutable, NULL);
  203. }
  204. static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,
  205. SkBitmap::Config dstConfig, jboolean isMutable) {
  206. SkBitmap result;
  207. JavaPixelAllocator allocator(env);
  208. if (!src->copyTo(&result, dstConfig, &allocator)) {
  209. return NULL;
  210. }
  211. return GraphicsJNI::createBitmap(env, new SkBitmap(result), allocator.getStorageObj(), isMutable, NULL);
  212. }
  213. static void Bitmap_destructor(JNIEnv* env, jobject, SkBitmap* bitmap) {
  214. #ifdef USE_OPENGL_RENDERER
  215. if (android::uirenderer::Caches::hasInstance()) {
  216. android::uirenderer::Caches::getInstance().resourceCache.destructor(bitmap);
  217. return;
  218. }
  219. #endif // USE_OPENGL_RENDERER
  220. delete bitmap;
  221. }
  222. static void Bitmap_recycle(JNIEnv* env, jobject, SkBitmap* bitmap) {
  223. #ifdef USE_OPENGL_RENDERER
  224. if (android::uirenderer::Caches::hasInstance()) {
  225. android::uirenderer::Caches::getInstance().resourceCache.recycle(bitmap);
  226. return;
  227. }
  228. #endif // USE_OPENGL_RENDERER
  229. bitmap->setPixels(NULL, NULL);
  230. }
  231. // These must match the int values in Bitmap.java
  232. enum JavaEncodeFormat {
  233. kJPEG_JavaEncodeFormat = 0,
  234. kPNG_JavaEncodeFormat = 1,
  235. kWEBP_JavaEncodeFormat = 2
  236. };
  237. static bool Bitmap_compress(JNIEnv* env, jobject clazz, SkBitmap* bitmap,
  238. int format, int quality,
  239. jobject jstream, jbyteArray jstorage) {
  240. SkImageEncoder::Type fm;
  241. switch (format) {
  242. case kJPEG_JavaEncodeFormat:
  243. fm = SkImageEncoder::kJPEG_Type;
  244. break;
  245. case kPNG_JavaEncodeFormat:
  246. fm = SkImageEncoder::kPNG_Type;
  247. break;
  248. case kWEBP_JavaEncodeFormat:
  249. fm = SkImageEncoder::kWEBP_Type;
  250. break;
  251. default:
  252. return false;
  253. }
  254. bool success = false;
  255. SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
  256. if (NULL != strm) {
  257. SkImageEncoder* encoder = SkImageEncoder::Create(fm);
  258. if (NULL != encoder) {
  259. success = encoder->encodeStream(strm, *bitmap, quality);
  260. delete encoder;
  261. }
  262. delete strm;
  263. }
  264. return success;
  265. }
  266. static void Bitmap_erase(JNIEnv* env, jobject, SkBitmap* bitmap, jint color) {
  267. bitmap->eraseColor(color);
  268. }
  269. static int Bitmap_width(JNIEnv* env, jobject, SkBitmap* bitmap) {
  270. return bitmap->width();
  271. }
  272. static int Bitmap_height(JNIEnv* env, jobject, SkBitmap* bitmap) {
  273. return bitmap->height();
  274. }
  275. static int Bitmap_rowBytes(JNIEnv* env, jobject, SkBitmap* bitmap) {
  276. return bitmap->rowBytes();
  277. }
  278. static int Bitmap_config(JNIEnv* env, jobject, SkBitmap* bitmap) {
  279. return bitmap->config();
  280. }
  281. static int Bitmap_getGenerationId(JNIEnv* env, jobject, SkBitmap* bitmap) {
  282. return bitmap->getGenerationID();
  283. }
  284. static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap) {
  285. return !bitmap->isOpaque();
  286. }
  287. static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap,
  288. jboolean hasAlpha) {
  289. bitmap->setIsOpaque(!hasAlpha);
  290. }
  291. ///////////////////////////////////////////////////////////////////////////////
  292. static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
  293. if (parcel == NULL) {
  294. SkDebugf("-------- unparcel parcel is NULL\n");
  295. return NULL;
  296. }
  297. android::Parcel* p = android::parcelForJavaObject(env, parcel);
  298. const bool isMutable = p->readInt32() != 0;
  299. const SkBitmap::Config config = (SkBitmap::Config)p->readInt32();
  300. const int width = p->readInt32();
  301. const int height = p->readInt32();
  302. const int rowBytes = p->readInt32();
  303. const int density = p->readInt32();
  304. if (SkBitmap::kARGB_8888_Config != config &&
  305. SkBitmap::kRGB_565_Config != config &&
  306. SkBitmap::kARGB_4444_Config != config &&
  307. SkBitmap::kIndex8_Config != config &&
  308. SkBitmap::kA8_Config != config) {
  309. SkDebugf("Bitmap_createFromParcel unknown config: %d\n", config);
  310. return NULL;
  311. }
  312. SkBitmap* bitmap = new SkBitmap;
  313. bitmap->setConfig(config, width, height, rowBytes);
  314. SkColorTable* ctable = NULL;
  315. if (config == SkBitmap::kIndex8_Config) {
  316. int count = p->readInt32();
  317. if (count > 0) {
  318. size_t size = count * sizeof(SkPMColor);
  319. const SkPMColor* src = (const SkPMColor*)p->readInplace(size);
  320. ctable = new SkColorTable(src, count);
  321. }
  322. }
  323. jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable);
  324. if (NULL == buffer) {
  325. SkSafeUnref(ctable);
  326. delete bitmap;
  327. return NULL;
  328. }
  329. SkSafeUnref(ctable);
  330. size_t size = bitmap->getSize();
  331. android::Parcel::ReadableBlob blob;
  332. android::status_t status = p->readBlob(size, &blob);
  333. if (status) {
  334. doThrowRE(env, "Could not read bitmap from parcel blob.");
  335. delete bitmap;
  336. return NULL;
  337. }
  338. bitmap->lockPixels();
  339. memcpy(bitmap->getPixels(), blob.data(), size);
  340. bitmap->unlockPixels();
  341. blob.release();
  342. return GraphicsJNI::createBitmap(env, bitmap, buffer, isMutable, NULL, density);
  343. }
  344. static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
  345. const SkBitmap* bitmap,
  346. jboolean isMutable, jint density,
  347. jobject parcel) {
  348. if (parcel == NULL) {
  349. SkDebugf("------- writeToParcel null parcel\n");
  350. return false;
  351. }
  352. android::Parcel* p = android::parcelForJavaObject(env, parcel);
  353. p->writeInt32(isMutable);
  354. p->writeInt32(bitmap->config());
  355. p->writeInt32(bitmap->width());
  356. p->writeInt32(bitmap->height());
  357. p->writeInt32(bitmap->rowBytes());
  358. p->writeInt32(density);
  359. if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {
  360. SkColorTable* ctable = bitmap->getColorTable();
  361. if (ctable != NULL) {
  362. int count = ctable->count();
  363. p->writeInt32(count);
  364. memcpy(p->writeInplace(count * sizeof(SkPMColor)),
  365. ctable->lockColors(), count * sizeof(SkPMColor));
  366. ctable->unlockColors(false);
  367. } else {
  368. p->writeInt32(0); // indicate no ctable
  369. }
  370. }
  371. size_t size = bitmap->getSize();
  372. android::Parcel::WritableBlob blob;
  373. android::status_t status = p->writeBlob(size, &blob);
  374. if (status) {
  375. doThrowRE(env, "Could not write bitmap to parcel blob.");
  376. return false;
  377. }
  378. bitmap->lockPixels();
  379. const void* pSrc = bitmap->getPixels();
  380. if (pSrc == NULL) {
  381. memset(blob.data(), 0, size);
  382. } else {
  383. memcpy(blob.data(), pSrc, size);
  384. }
  385. bitmap->unlockPixels();
  386. blob.release();
  387. return true;
  388. }
  389. static jobject Bitmap_extractAlpha(JNIEnv* env, jobject clazz,
  390. const SkBitmap* src, const SkPaint* paint,
  391. jintArray offsetXY) {
  392. SkIPoint offset;
  393. SkBitmap* dst = new SkBitmap;
  394. JavaPixelAllocator allocator(env);
  395. src->extractAlpha(dst, paint, &allocator, &offset);
  396. // If Skia can't allocate pixels for destination bitmap, it resets
  397. // it, that is set its pixels buffer to NULL, and zero width and height.
  398. if (dst->getPixels() == NULL && src->getPixels() != NULL) {
  399. delete dst;
  400. doThrowOOME(env, "failed to allocate pixels for alpha");
  401. return NULL;
  402. }
  403. if (offsetXY != 0 && env->GetArrayLength(offsetXY) >= 2) {
  404. int* array = env->GetIntArrayElements(offsetXY, NULL);
  405. array[0] = offset.fX;
  406. array[1] = offset.fY;
  407. env->ReleaseIntArrayElements(offsetXY, array, 0);
  408. }
  409. return GraphicsJNI::createBitmap(env, dst, allocator.getStorageObj(), true, NULL);
  410. }
  411. ///////////////////////////////////////////////////////////////////////////////
  412. static int Bitmap_getPixel(JNIEnv* env, jobject, const SkBitmap* bitmap,
  413. int x, int y) {
  414. SkAutoLockPixels alp(*bitmap);
  415. ToColorProc proc = ChooseToColorProc(*bitmap);
  416. if (NULL == proc) {
  417. return 0;
  418. }
  419. const void* src = bitmap->getAddr(x, y);
  420. if (NULL == src) {
  421. return 0;
  422. }
  423. SkColor dst[1];
  424. proc(dst, src, 1, bitmap->getColorTable());
  425. return dst[0];
  426. }
  427. static void Bitmap_getPixels(JNIEnv* env, jobject, const SkBitmap* bitmap,
  428. jintArray pixelArray, int offset, int stride,
  429. int x, int y, int width, int height) {
  430. SkAutoLockPixels alp(*bitmap);
  431. ToColorProc proc = ChooseToColorProc(*bitmap);
  432. if (NULL == proc) {
  433. return;
  434. }
  435. const void* src = bitmap->getAddr(x, y);
  436. if (NULL == src) {
  437. return;
  438. }
  439. SkColorTable* ctable = bitmap->getColorTable();
  440. jint* dst = env->GetIntArrayElements(pixelArray, NULL);
  441. SkColor* d = (SkColor*)dst + offset;
  442. while (--height >= 0) {
  443. proc(d, src, width, ctable);
  444. d += stride;
  445. src = (void*)((const char*)src + bitmap->rowBytes());
  446. }
  447. env->ReleaseIntArrayElements(pixelArray, dst, 0);
  448. }
  449. ///////////////////////////////////////////////////////////////////////////////
  450. static void Bitmap_setPixel(JNIEnv* env, jobject, const SkBitmap* bitmap,
  451. int x, int y, SkColor color) {
  452. SkAutoLockPixels alp(*bitmap);
  453. if (NULL == bitmap->getPixels()) {
  454. return;
  455. }
  456. FromColorProc proc = ChooseFromColorProc(bitmap->config());
  457. if (NULL == proc) {
  458. return;
  459. }
  460. proc(bitmap->getAddr(x, y), &color, 1, x, y);
  461. bitmap->notifyPixelsChanged();
  462. }
  463. static void Bitmap_setPixels(JNIEnv* env, jobject, const SkBitmap* bitmap,
  464. jintArray pixelArray, int offset, int stride,
  465. int x, int y, int width, int height) {
  466. GraphicsJNI::SetPixels(env, pixelArray, offset, stride,
  467. x, y, width, height, *bitmap);
  468. }
  469. static void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject,
  470. const SkBitmap* bitmap, jobject jbuffer) {
  471. SkAutoLockPixels alp(*bitmap);
  472. const void* src = bitmap->getPixels();
  473. if (NULL != src) {
  474. android::AutoBufferPointer abp(env, jbuffer, JNI_TRUE);
  475. // the java side has already checked that buffer is large enough
  476. memcpy(abp.pointer(), src, bitmap->getSize());
  477. }
  478. }
  479. static void Bitmap_copyPixelsFromBuffer(JNIEnv* env, jobject,
  480. const SkBitmap* bitmap, jobject jbuffer) {
  481. SkAutoLockPixels alp(*bitmap);
  482. void* dst = bitmap->getPixels();
  483. if (NULL != dst) {
  484. android::AutoBufferPointer abp(env, jbuffer, JNI_FALSE);
  485. // the java side has already checked that buffer is large enough
  486. memcpy(dst, abp.pointer(), bitmap->getSize());
  487. bitmap->notifyPixelsChanged();
  488. }
  489. }
  490. static bool Bitmap_sameAs(JNIEnv* env, jobject, const SkBitmap* bm0,
  491. const SkBitmap* bm1) {
  492. if (bm0->width() != bm1->width() ||
  493. bm0->height() != bm1->height() ||
  494. bm0->config() != bm1->config()) {
  495. return false;
  496. }
  497. SkAutoLockPixels alp0(*bm0);
  498. SkAutoLockPixels alp1(*bm1);
  499. // if we can't load the pixels, return false
  500. if (NULL == bm0->getPixels() || NULL == bm1->getPixels()) {
  501. return false;
  502. }
  503. if (bm0->config() == SkBitmap::kIndex8_Config) {
  504. SkColorTable* ct0 = bm0->getColorTable();
  505. SkColorTable* ct1 = bm1->getColorTable();
  506. if (NULL == ct0 || NULL == ct1) {
  507. return false;
  508. }
  509. if (ct0->count() != ct1->count()) {
  510. return false;
  511. }
  512. SkAutoLockColors alc0(ct0);
  513. SkAutoLockColors alc1(ct1);
  514. const size_t size = ct0->count() * sizeof(SkPMColor);
  515. if (memcmp(alc0.colors(), alc1.colors(), size) != 0) {
  516. return false;
  517. }
  518. }
  519. // now compare each scanline. We can't do the entire buffer at once,
  520. // since we don't care about the pixel values that might extend beyond
  521. // the width (since the scanline might be larger than the logical width)
  522. const int h = bm0->height();
  523. const size_t size = bm0->width() * bm0->bytesPerPixel();
  524. for (int y = 0; y < h; y++) {
  525. if (memcmp(bm0->getAddr(0, y), bm1->getAddr(0, y), size) != 0) {
  526. return false;
  527. }
  528. }
  529. return true;
  530. }
  531. static void Bitmap_prepareToDraw(JNIEnv* env, jobject, SkBitmap* bitmap) {
  532. bitmap->lockPixels();
  533. bitmap->unlockPixels();
  534. }
  535. ///////////////////////////////////////////////////////////////////////////////
  536. #include <android_runtime/AndroidRuntime.h>
  537. static JNINativeMethod gBitmapMethods[] = {
  538. { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;",
  539. (void*)Bitmap_creator },
  540. { "nativeCopy", "(IIZ)Landroid/graphics/Bitmap;",
  541. (void*)Bitmap_copy },
  542. { "nativeDestructor", "(I)V", (void*)Bitmap_destructor },
  543. { "nativeRecycle", "(I)V", (void*)Bitmap_recycle },
  544. { "nativeCompress", "(IIILjava/io/OutputStream;[B)Z",
  545. (void*)Bitmap_compress },
  546. { "nativeErase", "(II)V", (void*)Bitmap_erase },
  547. { "nativeWidth", "(I)I", (void*)Bitmap_width },
  548. { "nativeHeight", "(I)I", (void*)Bitmap_height },
  549. { "nativeRowBytes", "(I)I", (void*)Bitmap_rowBytes },
  550. { "nativeConfig", "(I)I", (void*)Bitmap_config },
  551. { "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha },
  552. { "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha },
  553. { "nativeCreateFromParcel",
  554. "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",
  555. (void*)Bitmap_createFromParcel },
  556. { "nativeWriteToParcel", "(IZILandroid/os/Parcel;)Z",
  557. (void*)Bitmap_writeToParcel },
  558. { "nativeExtractAlpha", "(II[I)Landroid/graphics/Bitmap;",
  559. (void*)Bitmap_extractAlpha },
  560. { "nativeGenerationId", "(I)I", (void*)Bitmap_getGenerationId },
  561. { "nativeGetPixel", "(III)I", (void*)Bitmap_getPixel },
  562. { "nativeGetPixels", "(I[IIIIIII)V", (void*)Bitmap_getPixels },
  563. { "nativeSetPixel", "(IIII)V", (void*)Bitmap_setPixel },
  564. { "nativeSetPixels", "(I[IIIIIII)V", (void*)Bitmap_setPixels },
  565. { "nativeCopyPixelsToBuffer", "(ILjava/nio/Buffer;)V",
  566. (void*)Bitmap_copyPixelsToBuffer },
  567. { "nativeCopyPixelsFromBuffer", "(ILjava/nio/Buffer;)V",
  568. (void*)Bitmap_copyPixelsFromBuffer },
  569. { "nativeSameAs", "(II)Z", (void*)Bitmap_sameAs },
  570. { "nativePrepareToDraw", "(I)V", (void*)Bitmap_prepareToDraw },
  571. };
  572. #define kClassPathName "android/graphics/Bitmap"
  573. int register_android_graphics_Bitmap(JNIEnv* env)
  574. {
  575. return android::AndroidRuntime::registerNativeMethods(env, kClassPathName,
  576. gBitmapMethods, SK_ARRAY_COUNT(gBitmapMethods));
  577. }