pix.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * Copyright 2011, Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "common.h"
  17. #include <string.h>
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif /* __cplusplus */
  21. jlong Java_com_googlecode_leptonica_android_Pix_nativeCreatePix(JNIEnv *env, jclass clazz, jint w,
  22. jint h, jint d) {
  23. PIX *pix = pixCreate((l_int32) w, (l_int32) h, (l_int32) d);
  24. return (jlong) pix;
  25. }
  26. jlong Java_com_googlecode_leptonica_android_Pix_nativeCreateFromData(JNIEnv *env, jclass clazz,
  27. jbyteArray data, jint w,
  28. jint h, jint d) {
  29. PIX *pix = pixCreateNoInit((l_int32) w, (l_int32) h, (l_int32) d);
  30. jbyte *data_buffer = env->GetByteArrayElements(data, NULL);
  31. l_uint8 *byte_buffer = (l_uint8 *) data_buffer;
  32. size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix);
  33. memcpy(pixGetData(pix), byte_buffer, size);
  34. env->ReleaseByteArrayElements(data, data_buffer, JNI_ABORT);
  35. return (jlong) pix;
  36. }
  37. jbyteArray Java_com_googlecode_leptonica_android_Pix_nativeGetData(JNIEnv *env, jclass clazz,
  38. jlong nativePix, jbyteArray data) {
  39. PIX *pix = (PIX *) nativePix;
  40. size_t size = 4 * pixGetWpl(pix) * pixGetHeight(pix);
  41. jbyteArray result = env->NewByteArray(size);
  42. if (result == NULL) {
  43. LOGE("Cannot allocate JNI Byte Array");
  44. return NULL;
  45. }
  46. env->SetByteArrayRegion(result, 0, size, (jbyte *)pixGetData(pix));
  47. return result;
  48. }
  49. jlong Java_com_googlecode_leptonica_android_Pix_nativeClone(JNIEnv *env, jclass clazz,
  50. jlong nativePix) {
  51. PIX *pixs = (PIX *) nativePix;
  52. PIX *pixd = pixClone(pixs);
  53. return (jlong) pixd;
  54. }
  55. jlong Java_com_googlecode_leptonica_android_Pix_nativeCopy(JNIEnv *env, jclass clazz, jlong nativePix) {
  56. PIX *pixs = (PIX *) nativePix;
  57. PIX *pixd = pixCopy(NULL, pixs);
  58. return (jlong) pixd;
  59. }
  60. jboolean Java_com_googlecode_leptonica_android_Pix_nativeInvert(JNIEnv *env, jclass clazz,
  61. jlong nativePix) {
  62. PIX *pixs = (PIX *) nativePix;
  63. if (pixInvert(pixs, pixs)) {
  64. return JNI_FALSE;
  65. }
  66. return JNI_TRUE;
  67. }
  68. void Java_com_googlecode_leptonica_android_Pix_nativeDestroy(JNIEnv *env, jclass clazz,
  69. jlong nativePix) {
  70. PIX *pix = (PIX *) nativePix;
  71. pixDestroy(&pix);
  72. }
  73. jboolean Java_com_googlecode_leptonica_android_Pix_nativeGetDimensions(JNIEnv *env, jclass clazz,
  74. jlong nativePix,
  75. jintArray dimensions) {
  76. PIX *pix = (PIX *) nativePix;
  77. jint *dimensionArray = env->GetIntArrayElements(dimensions, NULL);
  78. l_int32 w, h, d;
  79. if (pixGetDimensions(pix, &w, &h, &d)) {
  80. return JNI_FALSE;
  81. }
  82. dimensionArray[0] = w;
  83. dimensionArray[1] = h;
  84. dimensionArray[2] = d;
  85. env->ReleaseIntArrayElements(dimensions, dimensionArray, 0);
  86. return JNI_TRUE;
  87. }
  88. jint Java_com_googlecode_leptonica_android_Pix_nativeGetWidth(JNIEnv *env, jclass clazz,
  89. jlong nativePix) {
  90. PIX *pix = (PIX *) nativePix;
  91. return (jint) pixGetWidth(pix);
  92. }
  93. jint Java_com_googlecode_leptonica_android_Pix_nativeGetRefCount(JNIEnv *env, jclass clazz,
  94. jlong nativePix) {
  95. PIX *pix = (PIX *) nativePix;
  96. return (jint) pixGetRefcount(pix);
  97. }
  98. jint Java_com_googlecode_leptonica_android_Pix_nativeGetHeight(JNIEnv *env, jclass clazz,
  99. jlong nativePix) {
  100. PIX *pix = (PIX *) nativePix;
  101. return (jint) pixGetHeight(pix);
  102. }
  103. jint Java_com_googlecode_leptonica_android_Pix_nativeGetDepth(JNIEnv *env, jclass clazz,
  104. jlong nativePix) {
  105. PIX *pix = (PIX *) nativePix;
  106. return (jint) pixGetDepth(pix);
  107. }
  108. void Java_com_googlecode_leptonica_android_Pix_nativeSetPixel(JNIEnv *env, jclass clazz,
  109. jlong nativePix, jint xCoord,
  110. jint yCoord, jint argbColor) {
  111. PIX *pix = (PIX *) nativePix;
  112. l_int32 d = pixGetDepth(pix);
  113. l_int32 x = (l_int32) xCoord;
  114. l_int32 y = (l_int32) yCoord;
  115. // These shift values are based on RGBA_8888
  116. l_uint8 r = (argbColor >> SK_R32_SHIFT) & 0xFF;
  117. l_uint8 g = (argbColor >> SK_G32_SHIFT) & 0xFF;
  118. l_uint8 b = (argbColor >> SK_B32_SHIFT) & 0xFF;
  119. l_uint8 a = (argbColor >> SK_A32_SHIFT) & 0xFF;
  120. l_uint8 gray = ((r + g + b) / 3) & 0xFF;
  121. l_uint32 color;
  122. switch (d) {
  123. case 1: // 1-bit binary
  124. color = gray > 128 ? 1 : 0;
  125. break;
  126. case 2: // 2-bit grayscale
  127. color = gray >> 6;
  128. break;
  129. case 4: // 4-bit grayscale
  130. color = gray >> 4;
  131. break;
  132. case 8: // 8-bit grayscale
  133. color = gray;
  134. break;
  135. case 24: // 24-bit RGB
  136. SET_DATA_BYTE(&color, COLOR_RED, r);
  137. SET_DATA_BYTE(&color, COLOR_GREEN, g);
  138. SET_DATA_BYTE(&color, COLOR_BLUE, b);
  139. break;
  140. case 32: // 32-bit ARGB
  141. SET_DATA_BYTE(&color, COLOR_RED, r);
  142. SET_DATA_BYTE(&color, COLOR_GREEN, g);
  143. SET_DATA_BYTE(&color, COLOR_BLUE, b);
  144. SET_DATA_BYTE(&color, L_ALPHA_CHANNEL, a);
  145. break;
  146. default: // unsupported
  147. LOGE("Not a supported color depth: %d", d);
  148. color = 0;
  149. break;
  150. }
  151. pixSetPixel(pix, x, y, color);
  152. }
  153. jint Java_com_googlecode_leptonica_android_Pix_nativeGetPixel(JNIEnv *env, jclass clazz,
  154. jlong nativePix, jint xCoord,
  155. jint yCoord) {
  156. PIX *pix = (PIX *) nativePix;
  157. l_int32 d = pixGetDepth(pix);
  158. l_int32 x = (l_int32) xCoord;
  159. l_int32 y = (l_int32) yCoord;
  160. l_uint32 pixel;
  161. l_uint32 color;
  162. l_uint8 a, r, g, b;
  163. pixGetPixel(pix, x, y, &pixel);
  164. switch (d) {
  165. case 1: // 1-bit binary
  166. a = 0xFF;
  167. r = g = b = (pixel == 0 ? 0x00 : 0xFF);
  168. break;
  169. case 2: // 2-bit grayscale
  170. a = 0xFF;
  171. r = g = b = (pixel << 6 | pixel << 4 | pixel);
  172. break;
  173. case 4: // 4-bit grayscale
  174. a = 0xFF;
  175. r = g = b = (pixel << 4 | pixel);
  176. break;
  177. case 8: // 8-bit grayscale
  178. a = 0xFF;
  179. r = g = b = pixel;
  180. break;
  181. case 24: // 24-bit RGB
  182. a = 0xFF;
  183. r = (pixel >> L_RED_SHIFT) & 0xFF;
  184. g = (pixel >> L_GREEN_SHIFT) & 0xFF;
  185. b = (pixel >> L_BLUE_SHIFT) & 0xFF;
  186. break;
  187. case 32: // 32-bit RGBA
  188. r = (pixel >> L_RED_SHIFT) & 0xFF;
  189. g = (pixel >> L_GREEN_SHIFT) & 0xFF;
  190. b = (pixel >> L_BLUE_SHIFT) & 0xFF;
  191. a = (pixel >> L_ALPHA_SHIFT) & 0xFF;
  192. break;
  193. default: // Not supported
  194. LOGE("Not a supported color depth: %d", d);
  195. a = r = g = b = 0x00;
  196. break;
  197. }
  198. color = a << SK_A32_SHIFT;
  199. color |= r << SK_R32_SHIFT;
  200. color |= g << SK_G32_SHIFT;
  201. color |= b << SK_B32_SHIFT;
  202. return (jint) color;
  203. }
  204. #ifdef __cplusplus
  205. }
  206. #endif /* __cplusplus */