pixmap.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. // Copyright (C) 2004-2025 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. /* Pixmap interface */
  23. JNIEXPORT void JNICALL
  24. FUN(Pixmap_finalize)(JNIEnv *env, jobject self)
  25. {
  26. fz_context *ctx = get_context(env);
  27. fz_pixmap *pixmap = from_Pixmap_safe(env, self);
  28. if (!ctx || !pixmap) return;
  29. (*env)->SetLongField(env, self, fid_Pixmap_pointer, 0);
  30. fz_drop_pixmap(ctx, pixmap);
  31. }
  32. JNIEXPORT jlong JNICALL
  33. FUN(Pixmap_newNative)(JNIEnv *env, jobject self, jobject jcs, jint x, jint y, jint w, jint h, jboolean alpha)
  34. {
  35. fz_context *ctx = get_context(env);
  36. fz_colorspace *cs = from_ColorSpace(env, jcs);
  37. fz_pixmap *pixmap = NULL;
  38. if (!ctx || !cs) return 0;
  39. fz_try(ctx)
  40. {
  41. pixmap = fz_new_pixmap(ctx, cs, w, h, NULL, alpha);
  42. pixmap->x = x;
  43. pixmap->y = y;
  44. }
  45. fz_catch(ctx)
  46. jni_rethrow(env, ctx);
  47. return jlong_cast(pixmap);
  48. }
  49. JNIEXPORT jlong JNICALL
  50. FUN(Pixmap_newNativeFromColorAndMask)(JNIEnv *env, jobject self, jobject jcolor, jobject jmask)
  51. {
  52. fz_context *ctx = get_context(env);
  53. fz_pixmap *color = from_Pixmap_safe(env, jcolor);
  54. fz_pixmap *mask = from_Pixmap_safe(env, jmask);
  55. fz_pixmap *pixmap = NULL;
  56. if (!ctx) return 0;
  57. if (!jcolor) jni_throw_arg(env, "color must not be null");
  58. if (!jmask) jni_throw_arg(env, "mask must not be null");
  59. fz_try(ctx)
  60. pixmap = fz_new_pixmap_from_color_and_mask(ctx, color, mask);
  61. fz_catch(ctx)
  62. jni_rethrow(env, ctx);
  63. return jlong_cast(pixmap);
  64. }
  65. JNIEXPORT void JNICALL
  66. FUN(Pixmap_clear)(JNIEnv *env, jobject self)
  67. {
  68. fz_context *ctx = get_context(env);
  69. fz_pixmap *pixmap = from_Pixmap(env, self);
  70. if (!ctx || !pixmap) return;
  71. fz_try(ctx)
  72. fz_clear_pixmap(ctx, pixmap);
  73. fz_catch(ctx)
  74. jni_rethrow_void(env, ctx);
  75. }
  76. JNIEXPORT void JNICALL
  77. FUN(Pixmap_clearWithValue)(JNIEnv *env, jobject self, jint value)
  78. {
  79. fz_context *ctx = get_context(env);
  80. fz_pixmap *pixmap = from_Pixmap(env, self);
  81. if (!ctx || !pixmap) return;
  82. fz_try(ctx)
  83. fz_clear_pixmap_with_value(ctx, pixmap, value);
  84. fz_catch(ctx)
  85. jni_rethrow_void(env, ctx);
  86. }
  87. JNIEXPORT jobject JNICALL
  88. FUN(Pixmap_asPNG)(JNIEnv *env, jobject self)
  89. {
  90. fz_context *ctx = get_context(env);
  91. fz_pixmap *pixmap = from_Pixmap(env, self);
  92. fz_buffer *buf = NULL;
  93. if (!ctx || !pixmap) return NULL;
  94. fz_try(ctx)
  95. buf = fz_new_buffer_from_pixmap_as_png(ctx, pixmap, fz_default_color_params);
  96. fz_catch(ctx)
  97. jni_rethrow(env, ctx);
  98. return to_Buffer_safe_own(ctx, env, buf);
  99. }
  100. JNIEXPORT jobject JNICALL
  101. FUN(Pixmap_asJPEG)(JNIEnv *env, jobject self, jint quality, jboolean invert_cmyk)
  102. {
  103. fz_context *ctx = get_context(env);
  104. fz_pixmap *pixmap = from_Pixmap(env, self);
  105. fz_buffer *buf = NULL;
  106. if (!ctx || !pixmap) return NULL;
  107. fz_try(ctx)
  108. buf = fz_new_buffer_from_pixmap_as_jpeg(ctx, pixmap, fz_default_color_params, quality, invert_cmyk);
  109. fz_catch(ctx)
  110. jni_rethrow(env, ctx);
  111. return to_Buffer_safe_own(ctx, env, buf);
  112. }
  113. JNIEXPORT jobject JNICALL
  114. FUN(Pixmap_asPAM)(JNIEnv *env, jobject self)
  115. {
  116. fz_context *ctx = get_context(env);
  117. fz_pixmap *pixmap = from_Pixmap(env, self);
  118. fz_buffer *buf = NULL;
  119. if (!ctx || !pixmap) return NULL;
  120. fz_try(ctx)
  121. buf = fz_new_buffer_from_pixmap_as_pam(ctx, pixmap, fz_default_color_params);
  122. fz_catch(ctx)
  123. jni_rethrow(env, ctx);
  124. return to_Buffer_safe_own(ctx, env, buf);
  125. }
  126. JNIEXPORT jobject JNICALL
  127. FUN(Pixmap_asPNM)(JNIEnv *env, jobject self)
  128. {
  129. fz_context *ctx = get_context(env);
  130. fz_pixmap *pixmap = from_Pixmap(env, self);
  131. fz_buffer *buf = NULL;
  132. if (!ctx || !pixmap) return NULL;
  133. fz_try(ctx)
  134. buf = fz_new_buffer_from_pixmap_as_pnm(ctx, pixmap, fz_default_color_params);
  135. fz_catch(ctx)
  136. jni_rethrow(env, ctx);
  137. return to_Buffer_safe_own(ctx, env, buf);
  138. }
  139. JNIEXPORT jobject JNICALL
  140. FUN(Pixmap_asPBM)(JNIEnv *env, jobject self)
  141. {
  142. fz_context *ctx = get_context(env);
  143. fz_pixmap *pixmap = from_Pixmap(env, self);
  144. fz_buffer *buf = NULL;
  145. if (!ctx || !pixmap) return NULL;
  146. fz_try(ctx)
  147. buf = fz_new_buffer_from_pixmap_as_pbm(ctx, pixmap, fz_default_color_params);
  148. fz_catch(ctx)
  149. jni_rethrow(env, ctx);
  150. return to_Buffer_safe_own(ctx, env, buf);
  151. }
  152. JNIEXPORT jobject JNICALL
  153. FUN(Pixmap_asPKM)(JNIEnv *env, jobject self)
  154. {
  155. fz_context *ctx = get_context(env);
  156. fz_pixmap *pixmap = from_Pixmap(env, self);
  157. fz_buffer *buf = NULL;
  158. if (!ctx || !pixmap) return NULL;
  159. fz_try(ctx)
  160. buf = fz_new_buffer_from_pixmap_as_pkm(ctx, pixmap, fz_default_color_params);
  161. fz_catch(ctx)
  162. jni_rethrow(env, ctx);
  163. return to_Buffer_safe_own(ctx, env, buf);
  164. }
  165. JNIEXPORT jobject JNICALL
  166. FUN(Pixmap_asJPX)(JNIEnv *env, jobject self, jint quality)
  167. {
  168. fz_context *ctx = get_context(env);
  169. fz_pixmap *pixmap = from_Pixmap(env, self);
  170. fz_buffer *buf = NULL;
  171. if (!ctx || !pixmap) return NULL;
  172. fz_try(ctx)
  173. buf = fz_new_buffer_from_pixmap_as_jpx(ctx, pixmap, fz_default_color_params, quality);
  174. fz_catch(ctx)
  175. jni_rethrow(env, ctx);
  176. return to_Buffer_safe_own(ctx, env, buf);
  177. }
  178. JNIEXPORT void JNICALL
  179. FUN(Pixmap_saveAsPNG)(JNIEnv *env, jobject self, jstring jfilename)
  180. {
  181. fz_context *ctx = get_context(env);
  182. fz_pixmap *pixmap = from_Pixmap(env, self);
  183. const char *filename = "null";
  184. if (!ctx || !pixmap) return;
  185. if (!jfilename) jni_throw_arg_void(env, "filename must not be null");
  186. filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
  187. if (!filename) return;
  188. fz_try(ctx)
  189. fz_save_pixmap_as_png(ctx, pixmap, filename);
  190. fz_always(ctx)
  191. (*env)->ReleaseStringUTFChars(env, jfilename, filename);
  192. fz_catch(ctx)
  193. jni_rethrow_void(env, ctx);
  194. }
  195. JNIEXPORT void JNICALL
  196. FUN(Pixmap_saveAsJPEG)(JNIEnv *env, jobject self, jstring jfilename, jint quality)
  197. {
  198. fz_context *ctx = get_context(env);
  199. fz_pixmap *pixmap = from_Pixmap(env, self);
  200. const char *filename = "null";
  201. if (!ctx || !pixmap) return;
  202. if (!jfilename) jni_throw_arg_void(env, "filename must not be null");
  203. filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
  204. if (!filename) return;
  205. fz_try(ctx)
  206. fz_save_pixmap_as_jpeg(ctx, pixmap, filename, quality);
  207. fz_always(ctx)
  208. (*env)->ReleaseStringUTFChars(env, jfilename, filename);
  209. fz_catch(ctx)
  210. jni_rethrow_void(env, ctx);
  211. }
  212. JNIEXPORT void JNICALL
  213. FUN(Pixmap_saveAsPAM)(JNIEnv *env, jobject self, jstring jfilename)
  214. {
  215. fz_context *ctx = get_context(env);
  216. fz_pixmap *pixmap = from_Pixmap(env, self);
  217. const char *filename = "null";
  218. if (!ctx || !pixmap) return;
  219. if (!jfilename) jni_throw_arg_void(env, "filename must not be null");
  220. filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
  221. if (!filename) return;
  222. fz_try(ctx)
  223. fz_save_pixmap_as_pam(ctx, pixmap, filename);
  224. fz_always(ctx)
  225. (*env)->ReleaseStringUTFChars(env, jfilename, filename);
  226. fz_catch(ctx)
  227. jni_rethrow_void(env, ctx);
  228. }
  229. JNIEXPORT void JNICALL
  230. FUN(Pixmap_saveAsPNM)(JNIEnv *env, jobject self, jstring jfilename)
  231. {
  232. fz_context *ctx = get_context(env);
  233. fz_pixmap *pixmap = from_Pixmap(env, self);
  234. const char *filename = "null";
  235. if (!ctx || !pixmap) return;
  236. if (!jfilename) jni_throw_arg_void(env, "filename must not be null");
  237. filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
  238. if (!filename) return;
  239. fz_try(ctx)
  240. fz_save_pixmap_as_pnm(ctx, pixmap, filename);
  241. fz_always(ctx)
  242. (*env)->ReleaseStringUTFChars(env, jfilename, filename);
  243. fz_catch(ctx)
  244. jni_rethrow_void(env, ctx);
  245. }
  246. JNIEXPORT void JNICALL
  247. FUN(Pixmap_saveAsPBM)(JNIEnv *env, jobject self, jstring jfilename)
  248. {
  249. fz_context *ctx = get_context(env);
  250. fz_pixmap *pixmap = from_Pixmap(env, self);
  251. const char *filename = "null";
  252. if (!ctx || !pixmap) return;
  253. if (!jfilename) jni_throw_arg_void(env, "filename must not be null");
  254. filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
  255. if (!filename) return;
  256. fz_try(ctx)
  257. fz_save_pixmap_as_pbm(ctx, pixmap, filename);
  258. fz_always(ctx)
  259. (*env)->ReleaseStringUTFChars(env, jfilename, filename);
  260. fz_catch(ctx)
  261. jni_rethrow_void(env, ctx);
  262. }
  263. JNIEXPORT void JNICALL
  264. FUN(Pixmap_saveAsPKM)(JNIEnv *env, jobject self, jstring jfilename)
  265. {
  266. fz_context *ctx = get_context(env);
  267. fz_pixmap *pixmap = from_Pixmap(env, self);
  268. const char *filename = "null";
  269. if (!ctx || !pixmap) return;
  270. if (!jfilename) jni_throw_arg_void(env, "filename must not be null");
  271. filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
  272. if (!filename) return;
  273. fz_try(ctx)
  274. fz_save_pixmap_as_pkm(ctx, pixmap, filename);
  275. fz_always(ctx)
  276. (*env)->ReleaseStringUTFChars(env, jfilename, filename);
  277. fz_catch(ctx)
  278. jni_rethrow_void(env, ctx);
  279. }
  280. JNIEXPORT void JNICALL
  281. FUN(Pixmap_saveAsJPX)(JNIEnv *env, jobject self, jstring jfilename, jint quality)
  282. {
  283. fz_context *ctx = get_context(env);
  284. fz_pixmap *pixmap = from_Pixmap(env, self);
  285. const char *filename = "null";
  286. if (!ctx || !pixmap) return;
  287. if (!jfilename) jni_throw_arg_void(env, "filename must not be null");
  288. filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
  289. if (!filename) return;
  290. fz_try(ctx)
  291. fz_save_pixmap_as_jpx(ctx, pixmap, filename, quality);
  292. fz_always(ctx)
  293. (*env)->ReleaseStringUTFChars(env, jfilename, filename);
  294. fz_catch(ctx)
  295. jni_rethrow_void(env, ctx);
  296. }
  297. JNIEXPORT jint JNICALL
  298. FUN(Pixmap_getX)(JNIEnv *env, jobject self)
  299. {
  300. fz_pixmap *pixmap = from_Pixmap(env, self);
  301. return pixmap ? pixmap->x : 0;
  302. }
  303. JNIEXPORT jint JNICALL
  304. FUN(Pixmap_getY)(JNIEnv *env, jobject self)
  305. {
  306. fz_pixmap *pixmap = from_Pixmap(env, self);
  307. return pixmap ? pixmap->y : 0;
  308. }
  309. JNIEXPORT jint JNICALL
  310. FUN(Pixmap_getWidth)(JNIEnv *env, jobject self)
  311. {
  312. fz_pixmap *pixmap = from_Pixmap(env, self);
  313. return pixmap ? pixmap->w : 0;
  314. }
  315. JNIEXPORT jint JNICALL
  316. FUN(Pixmap_getHeight)(JNIEnv *env, jobject self)
  317. {
  318. fz_pixmap *pixmap = from_Pixmap(env, self);
  319. return pixmap ? pixmap->h : 0;
  320. }
  321. JNIEXPORT jint JNICALL
  322. FUN(Pixmap_getNumberOfComponents)(JNIEnv *env, jobject self)
  323. {
  324. fz_pixmap *pixmap = from_Pixmap(env, self);
  325. return pixmap ? pixmap->n : 0;
  326. }
  327. JNIEXPORT jboolean JNICALL
  328. FUN(Pixmap_getAlpha)(JNIEnv *env, jobject self)
  329. {
  330. fz_pixmap *pixmap = from_Pixmap(env, self);
  331. return pixmap && pixmap->alpha ? JNI_TRUE : JNI_FALSE;
  332. }
  333. JNIEXPORT jint JNICALL
  334. FUN(Pixmap_getStride)(JNIEnv *env, jobject self)
  335. {
  336. fz_pixmap *pixmap = from_Pixmap(env, self);
  337. return pixmap ? pixmap->stride : 0;
  338. }
  339. JNIEXPORT jobject JNICALL
  340. FUN(Pixmap_getColorSpace)(JNIEnv *env, jobject self)
  341. {
  342. fz_context *ctx = get_context(env);
  343. fz_pixmap *pixmap = from_Pixmap(env, self);
  344. fz_colorspace *cs;
  345. if (!ctx | !pixmap) return NULL;
  346. fz_try(ctx)
  347. cs = fz_pixmap_colorspace(ctx, pixmap);
  348. fz_catch(ctx)
  349. jni_rethrow(env, ctx);
  350. return to_ColorSpace_safe(ctx, env, cs);
  351. }
  352. JNIEXPORT jbyteArray JNICALL
  353. FUN(Pixmap_getSamples)(JNIEnv *env, jobject self)
  354. {
  355. fz_context *ctx = get_context(env);
  356. fz_pixmap *pixmap = from_Pixmap(env, self);
  357. int size = pixmap->h * pixmap->stride;
  358. jbyteArray arr;
  359. if (!ctx | !pixmap) return NULL;
  360. arr = (*env)->NewByteArray(env, size);
  361. if (!arr || (*env)->ExceptionCheck(env)) jni_throw_run(env, "cannot create byte array");
  362. (*env)->SetByteArrayRegion(env, arr, 0, size, (const jbyte *)pixmap->samples);
  363. if ((*env)->ExceptionCheck(env)) return NULL;
  364. return arr;
  365. }
  366. JNIEXPORT jbyte JNICALL
  367. FUN(Pixmap_getSample)(JNIEnv *env, jobject self, jint x, jint y, jint k)
  368. {
  369. fz_context *ctx = get_context(env);
  370. fz_pixmap *pixmap = from_Pixmap(env, self);
  371. if (!ctx | !pixmap) return 0;
  372. if (x < 0 || x >= pixmap->w) jni_throw_oob(env, "x out of range");
  373. if (y < 0 || y >= pixmap->h) jni_throw_oob(env, "y out of range");
  374. if (k < 0 || k >= pixmap->n) jni_throw_oob(env, "k out of range");
  375. return pixmap->samples[(x + y * pixmap->w) * pixmap->n + k];
  376. }
  377. JNIEXPORT jintArray JNICALL
  378. FUN(Pixmap_getPixels)(JNIEnv *env, jobject self)
  379. {
  380. fz_context *ctx = get_context(env);
  381. fz_pixmap *pixmap = from_Pixmap(env, self);
  382. int size = pixmap->w * pixmap->h;
  383. jintArray arr;
  384. if (!ctx | !pixmap) return NULL;
  385. if (pixmap->n != 4 || !pixmap->alpha)
  386. jni_throw_run(env, "invalid colorspace for getPixels (must be RGB/BGR with alpha)");
  387. if (size * 4 != pixmap->h * pixmap->stride)
  388. jni_throw_run(env, "invalid stride for getPixels");
  389. arr = (*env)->NewIntArray(env, size);
  390. if (!arr || (*env)->ExceptionCheck(env)) return NULL;
  391. (*env)->SetIntArrayRegion(env, arr, 0, size, (const jint *)pixmap->samples);
  392. if ((*env)->ExceptionCheck(env)) return NULL;
  393. return arr;
  394. }
  395. JNIEXPORT jint JNICALL
  396. FUN(Pixmap_getXResolution)(JNIEnv *env, jobject self)
  397. {
  398. fz_pixmap *pixmap = from_Pixmap(env, self);
  399. return pixmap ? pixmap->xres : 0;
  400. }
  401. JNIEXPORT jint JNICALL
  402. FUN(Pixmap_getYResolution)(JNIEnv *env, jobject self)
  403. {
  404. fz_pixmap *pixmap = from_Pixmap(env, self);
  405. return pixmap ? pixmap->yres : 0;
  406. }
  407. JNIEXPORT void JNICALL
  408. FUN(Pixmap_invert)(JNIEnv *env, jobject self)
  409. {
  410. fz_context *ctx = get_context(env);
  411. fz_pixmap *pixmap = from_Pixmap(env, self);
  412. if (!ctx || !pixmap) return;
  413. fz_try(ctx)
  414. fz_invert_pixmap(ctx, pixmap);
  415. fz_catch(ctx)
  416. jni_rethrow_void(env, ctx);
  417. }
  418. JNIEXPORT void JNICALL
  419. FUN(Pixmap_invertLuminance)(JNIEnv *env, jobject self)
  420. {
  421. fz_context *ctx = get_context(env);
  422. fz_pixmap *pixmap = from_Pixmap(env, self);
  423. if (!ctx || !pixmap) return;
  424. fz_try(ctx)
  425. fz_invert_pixmap_luminance(ctx, pixmap);
  426. fz_catch(ctx)
  427. jni_rethrow_void(env, ctx);
  428. }
  429. JNIEXPORT void JNICALL
  430. FUN(Pixmap_gamma)(JNIEnv *env, jobject self, jfloat gamma)
  431. {
  432. fz_context *ctx = get_context(env);
  433. fz_pixmap *pixmap = from_Pixmap(env, self);
  434. if (!ctx || !pixmap) return;
  435. fz_try(ctx)
  436. fz_gamma_pixmap(ctx, pixmap, gamma);
  437. fz_catch(ctx)
  438. jni_rethrow_void(env, ctx);
  439. }
  440. JNIEXPORT void JNICALL
  441. FUN(Pixmap_tint)(JNIEnv *env, jobject self, jint black, jint white)
  442. {
  443. fz_context *ctx = get_context(env);
  444. fz_pixmap *pixmap = from_Pixmap(env, self);
  445. if (!ctx || !pixmap) return;
  446. fz_try(ctx)
  447. fz_tint_pixmap(ctx, pixmap, black, white);
  448. fz_catch(ctx)
  449. jni_rethrow_void(env, ctx);
  450. }
  451. JNIEXPORT void JNICALL
  452. FUN(Pixmap_setResolution)(JNIEnv *env, jobject self, jint xres, jint yres)
  453. {
  454. fz_context *ctx = get_context(env);
  455. fz_pixmap *pixmap = from_Pixmap(env, self);
  456. if (!ctx || !pixmap) return;
  457. fz_try(ctx)
  458. fz_set_pixmap_resolution(ctx, pixmap, xres, yres);
  459. fz_catch(ctx)
  460. jni_rethrow_void(env, ctx);
  461. }
  462. JNIEXPORT jobject JNICALL
  463. FUN(Pixmap_convertToColorSpace)(JNIEnv *env, jobject self, jobject jcs, jobject jproof, jobject jdefaultcs, jint jcolorparams, jboolean keep_alpha)
  464. {
  465. fz_context *ctx = get_context(env);
  466. fz_pixmap *pixmap = from_Pixmap(env, self);
  467. fz_colorspace *cs = from_ColorSpace(env, jcs);
  468. fz_colorspace *proof = from_ColorSpace(env, jproof);
  469. fz_default_colorspaces *default_cs = from_DefaultColorSpaces(env, jdefaultcs);
  470. fz_color_params color_params = from_ColorParams_safe(env, jcolorparams);
  471. fz_pixmap *dst = NULL;
  472. if (!ctx || !pixmap) return NULL;
  473. if (!cs) jni_throw_arg(env, "destination colorspace must not be null");
  474. fz_try(ctx)
  475. dst = fz_convert_pixmap(ctx, pixmap, cs, proof, default_cs, color_params, keep_alpha);
  476. fz_catch(ctx)
  477. jni_rethrow(env, ctx);
  478. return to_Pixmap_safe_own(ctx, env, dst);
  479. }
  480. JNIEXPORT jobject JNICALL
  481. FUN(Pixmap_computeMD5)(JNIEnv *env, jobject self)
  482. {
  483. fz_context *ctx = get_context(env);
  484. fz_pixmap *pixmap = from_Pixmap(env, self);
  485. unsigned char digest[16] = { 0 };
  486. jbyteArray arr;
  487. if (!ctx || !pixmap) return NULL;
  488. fz_try(ctx)
  489. fz_md5_pixmap(ctx, pixmap, digest);
  490. fz_catch(ctx)
  491. jni_rethrow(env, ctx);
  492. arr = (*env)->NewByteArray(env, 16);
  493. if (!arr || (*env)->ExceptionCheck(env)) jni_throw_run(env, "cannot create byte array");
  494. (*env)->SetByteArrayRegion(env, arr, 0, 16, (const jbyte *)digest);
  495. if ((*env)->ExceptionCheck(env)) return NULL;
  496. return arr;
  497. }
  498. JNIEXPORT jlong JNICALL
  499. FUN(Pixmap_newNativeDeskew)(JNIEnv *env, jobject self, jfloat ang, jint border)
  500. {
  501. fz_context *ctx = get_context(env);
  502. fz_pixmap *pixmap = from_Pixmap(env, self);
  503. fz_pixmap *dest;
  504. if (!ctx || !pixmap) return 0;
  505. fz_try(ctx)
  506. dest = fz_deskew_pixmap(ctx, pixmap, ang, border);
  507. fz_catch(ctx)
  508. jni_rethrow(env, ctx);
  509. return jlong_cast(dest);
  510. }
  511. JNIEXPORT jfloat JNICALL
  512. FUN(Pixmap_detectSkew)(JNIEnv *env, jobject self)
  513. {
  514. fz_context *ctx = get_context(env);
  515. fz_pixmap *pixmap = from_Pixmap(env, self);
  516. float ang;
  517. if (!ctx || !pixmap) return 0;
  518. fz_try(ctx)
  519. ang = fz_detect_skew(ctx, pixmap);
  520. fz_catch(ctx)
  521. jni_rethrow(env, ctx);
  522. return (jfloat)ang;
  523. }
  524. JNIEXPORT jfloatArray JNICALL
  525. FUN(Pixmap_detectDocument)(JNIEnv *env, jobject self)
  526. {
  527. fz_context *ctx = get_context(env);
  528. fz_pixmap *pixmap = from_Pixmap(env, self);
  529. fz_point points[4];
  530. int found;
  531. if (!ctx || !pixmap) return NULL;
  532. fz_try(ctx)
  533. found = fz_detect_document(ctx, &points[0], pixmap);
  534. fz_catch(ctx)
  535. jni_rethrow(env, ctx);
  536. if (!found)
  537. return NULL;
  538. return to_floatArray(ctx, env, (float *)&points[0], 8);
  539. }
  540. JNIEXPORT jobject JNICALL
  541. FUN(Pixmap_warp)(JNIEnv *env, jobject self, jobject jpoints, jint width, jint height)
  542. {
  543. fz_context *ctx = get_context(env);
  544. fz_pixmap *pixmap = from_Pixmap(env, self);
  545. jobject jpoint;
  546. fz_point points[4] = { 0 };
  547. fz_pixmap *dest = NULL;
  548. jsize n, i;
  549. if (!ctx || !pixmap) return NULL;
  550. if (!jpoints) jni_throw_arg(env, "points not be null");
  551. n = (*env)->GetArrayLength(env, jpoints);
  552. if (n != 4) jni_throw_arg(env, "points must have exactly eight elements");
  553. for (i = 0; i < n; i++)
  554. {
  555. jpoint = (*env)->GetObjectArrayElement(env, jpoints, i);
  556. points[i].x = (*env)->GetFloatField(env, jpoint, fid_Point_x);
  557. points[i].y = (*env)->GetFloatField(env, jpoint, fid_Point_y);
  558. }
  559. fz_try(ctx)
  560. dest = fz_warp_pixmap(ctx, pixmap, points, width, height);
  561. fz_catch(ctx)
  562. jni_rethrow(env, ctx);
  563. return to_Pixmap_safe_own(ctx, env, dest);
  564. }
  565. JNIEXPORT jobject JNICALL
  566. FUN(Pixmap_autowarp)(JNIEnv *env, jobject self, jobject jpoints)
  567. {
  568. fz_context *ctx = get_context(env);
  569. fz_pixmap *pixmap = from_Pixmap(env, self);
  570. jobject jpoint;
  571. fz_point points[4] = { 0 };
  572. fz_pixmap *dest = NULL;
  573. jsize n, i;
  574. if (!ctx || !pixmap) return NULL;
  575. if (!jpoints) jni_throw_arg(env, "points not be null");
  576. n = (*env)->GetArrayLength(env, jpoints);
  577. if (n != 4) jni_throw_arg(env, "points must have exactly eight elements");
  578. for (i = 0; i < n; i++)
  579. {
  580. jpoint = (*env)->GetObjectArrayElement(env, jpoints, i);
  581. points[i].x = (*env)->GetFloatField(env, jpoint, fid_Point_x);
  582. points[i].y = (*env)->GetFloatField(env, jpoint, fid_Point_y);
  583. }
  584. fz_try(ctx)
  585. dest = fz_autowarp_pixmap(ctx, pixmap, points);
  586. fz_catch(ctx)
  587. jni_rethrow(env, ctx);
  588. return to_Pixmap_safe_own(ctx, env, dest);
  589. }
  590. JNIEXPORT jobject JNICALL
  591. FUN(Pixmap_decodeBarcode)(JNIEnv *env, jobject self, jfloat rotate)
  592. {
  593. fz_context *ctx = get_context(env);
  594. fz_pixmap *pixmap = from_Pixmap(env, self);
  595. fz_barcode_type type = FZ_BARCODE_NONE;
  596. char *contents = NULL;
  597. jobject jcontents;
  598. jobject jbarcodeinfo;
  599. if (!ctx || !pixmap)
  600. return NULL;
  601. fz_try(ctx)
  602. contents = fz_decode_barcode_from_pixmap(ctx, &type, pixmap, rotate);
  603. fz_catch(ctx)
  604. jni_rethrow(env, ctx);
  605. jcontents = (*env)->NewStringUTF(env, contents);
  606. fz_free(ctx, contents);
  607. if (!jcontents || (*env)->ExceptionCheck(env))
  608. return NULL;
  609. jbarcodeinfo = (*env)->NewObject(env, cls_BarcodeInfo, mid_BarcodeInfo_init, type, jcontents);
  610. if (!jbarcodeinfo || (*env)->ExceptionCheck(env))
  611. return NULL;
  612. return jbarcodeinfo;
  613. }
  614. JNIEXPORT jobject JNICALL
  615. FUN(Pixmap_encodeBarcode)(JNIEnv *env, jobject self, jint barcode_type, jstring jcontents, jint size, jint ec, jboolean quiet, jboolean hrt)
  616. {
  617. fz_context *ctx = get_context(env);
  618. const char *contents = NULL;
  619. fz_pixmap *pix = NULL;
  620. if (!ctx)
  621. return NULL;
  622. contents = (*env)->GetStringUTFChars(env, jcontents, NULL);
  623. if (!contents) jni_throw_run(env, "cannot get characters in contents string");
  624. fz_try(ctx)
  625. pix = fz_new_barcode_pixmap(ctx, barcode_type, contents, size, ec, quiet, hrt);
  626. fz_always(ctx)
  627. if (contents)
  628. (*env)->ReleaseStringUTFChars(env, jcontents, contents);
  629. fz_catch(ctx)
  630. jni_rethrow(env, ctx);
  631. return to_Pixmap_safe_own(ctx, env, pix);
  632. }