1 /*
2 NOTE!
3 	The JNI specification states that New<PrimitiveType>Array() do not
4 	throw java exceptions, but many JVMs (e.g. Android's) treat them the
5 	same way as NewObjectArray which may throw e.g. OutOfMemoryError.
6 	So after calling these functions it is as important to call
7 	ExceptionCheck() to check for exceptions as for functions that
8 	are marked as throwing exceptions according to the JNI specification.
9 */
10 
11 #include <jni.h>
12 #ifdef _WIN32
13 #include <windows.h>
14 #else
15 #include <pthread.h>
16 #endif
17 
18 #include "mupdf/fitz.h"
19 #include "mupdf/ucdn.h"
20 #include "mupdf/pdf.h"
21 
22 #include "mupdf_native.h" /* javah generated prototypes */
23 
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #ifdef HAVE_ANDROID
30 #include <android/log.h>
31 #include <android/bitmap.h>
32 #define LOG_TAG "libmupdf"
33 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
34 #define LOGT(...) __android_log_print(ANDROID_LOG_INFO,"alert",__VA_ARGS__)
35 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
36 #else
37 #undef LOGI
38 #undef LOGE
39 #define LOGI(...) do{printf(__VA_ARGS__);putchar('\n');}while(0)
40 #define LOGE(...) do{printf(__VA_ARGS__);putchar('\n');}while(0)
41 #endif
42 
43 #define MY_JNI_VERSION JNI_VERSION_1_6
44 
45 #define FUN(A) Java_com_artifex_mupdf_fitz_ ## A
46 #define PKG "com/artifex/mupdf/fitz/"
47 
48 /* Do our best to avoid type casting warnings. */
49 
50 #define CAST(type, var) (type)pointer_cast(var)
51 
pointer_cast(jlong l)52 static inline void *pointer_cast(jlong l)
53 {
54 	return (void *)(intptr_t)l;
55 }
56 
jlong_cast(const void * p)57 static inline jlong jlong_cast(const void *p)
58 {
59 	return (jlong)(intptr_t)p;
60 }
61 
62 /* Our VM */
63 static JavaVM *jvm = NULL;
64 
65 /* All the cached classes/mids/fids we need. */
66 
67 static jclass cls_Buffer;
68 static jclass cls_ColorSpace;
69 static jclass cls_Context_Version;
70 static jclass cls_Cookie;
71 static jclass cls_Device;
72 static jclass cls_DisplayList;
73 static jclass cls_Document;
74 static jclass cls_DocumentWriter;
75 static jclass cls_FitzInputStream;
76 static jclass cls_FloatArray;
77 static jclass cls_Font;
78 static jclass cls_IOException;
79 static jclass cls_IllegalArgumentException;
80 static jclass cls_Image;
81 static jclass cls_IndexOutOfBoundsException;
82 static jclass cls_IntegerArray;
83 static jclass cls_Link;
84 static jclass cls_Location;
85 static jclass cls_Matrix;
86 static jclass cls_NativeDevice;
87 static jclass cls_NullPointerException;
88 static jclass cls_Object;
89 static jclass cls_OutOfMemoryError;
90 static jclass cls_Outline;
91 static jclass cls_PDFAnnotation;
92 static jclass cls_PDFDocument;
93 static jclass cls_PDFDocument_JsEventListener;
94 static jclass cls_PDFGraftMap;
95 static jclass cls_PDFObject;
96 static jclass cls_PDFPage;
97 static jclass cls_Page;
98 static jclass cls_Path;
99 static jclass cls_PathWalker;
100 static jclass cls_Pixmap;
101 static jclass cls_Point;
102 static jclass cls_Quad;
103 static jclass cls_Rect;
104 static jclass cls_RuntimeException;
105 static jclass cls_SeekableInputStream;
106 static jclass cls_SeekableOutputStream;
107 static jclass cls_SeekableStream;
108 static jclass cls_Shade;
109 static jclass cls_String;
110 static jclass cls_StrokeState;
111 static jclass cls_StructuredText;
112 static jclass cls_StructuredTextWalker;
113 static jclass cls_Text;
114 static jclass cls_TextBlock;
115 static jclass cls_TextChar;
116 static jclass cls_TextLine;
117 static jclass cls_TextWalker;
118 static jclass cls_TryLaterException;
119 static jclass cls_UnsupportedOperationException;
120 static jclass cls_PDFWidget;
121 static jclass cls_PKCS7Signer;
122 static jclass cls_PKCS7Verifier;
123 static jclass cls_PKCS7DesignatedName;
124 static jclass cls_UnsupportedOperationException;
125 
126 static jfieldID fid_Buffer_pointer;
127 static jfieldID fid_ColorSpace_pointer;
128 static jfieldID fid_Context_Version_major;
129 static jfieldID fid_Context_Version_minor;
130 static jfieldID fid_Context_Version_patch;
131 static jfieldID fid_Context_Version_version;
132 static jfieldID fid_Cookie_pointer;
133 static jfieldID fid_Device_pointer;
134 static jfieldID fid_DisplayList_pointer;
135 static jfieldID fid_DocumentWriter_pointer;
136 static jfieldID fid_Document_pointer;
137 static jfieldID fid_FitzInputStream_pointer;
138 static jfieldID fid_FitzInputStream_markpos;
139 static jfieldID fid_FitzInputStream_closed;
140 static jfieldID fid_Font_pointer;
141 static jfieldID fid_Image_pointer;
142 static jfieldID fid_Matrix_a;
143 static jfieldID fid_Matrix_b;
144 static jfieldID fid_Matrix_c;
145 static jfieldID fid_Matrix_d;
146 static jfieldID fid_Matrix_e;
147 static jfieldID fid_Matrix_f;
148 static jfieldID fid_NativeDevice_nativeInfo;
149 static jfieldID fid_NativeDevice_nativeResource;
150 static jfieldID fid_PDFAnnotation_pointer;
151 static jfieldID fid_PDFDocument_pointer;
152 static jfieldID fid_PDFGraftMap_pointer;
153 static jfieldID fid_PDFObject_Null;
154 static jfieldID fid_PDFObject_pointer;
155 static jfieldID fid_PDFPage_pointer;
156 static jfieldID fid_Page_pointer;
157 static jfieldID fid_Path_pointer;
158 static jfieldID fid_Pixmap_pointer;
159 static jfieldID fid_Point_x;
160 static jfieldID fid_Point_y;
161 static jfieldID fid_Quad_ul_x;
162 static jfieldID fid_Quad_ul_y;
163 static jfieldID fid_Quad_ur_x;
164 static jfieldID fid_Quad_ur_y;
165 static jfieldID fid_Quad_ll_x;
166 static jfieldID fid_Quad_ll_y;
167 static jfieldID fid_Quad_lr_x;
168 static jfieldID fid_Quad_lr_y;
169 static jfieldID fid_Rect_x0;
170 static jfieldID fid_Rect_x1;
171 static jfieldID fid_Rect_y0;
172 static jfieldID fid_Rect_y1;
173 static jfieldID fid_Shade_pointer;
174 static jfieldID fid_StrokeState_pointer;
175 static jfieldID fid_StructuredText_pointer;
176 static jfieldID fid_TextBlock_bbox;
177 static jfieldID fid_TextBlock_lines;
178 static jfieldID fid_TextChar_quad;
179 static jfieldID fid_TextChar_c;
180 static jfieldID fid_TextLine_bbox;
181 static jfieldID fid_TextLine_chars;
182 static jfieldID fid_Text_pointer;
183 static jfieldID fid_PDFWidget_fieldFlags;
184 static jfieldID fid_PDFWidget_fieldType;
185 static jfieldID fid_PDFWidget_maxLen;
186 static jfieldID fid_PDFWidget_options;
187 static jfieldID fid_PDFWidget_pointer;
188 static jfieldID fid_PDFWidget_textFormat;
189 static jfieldID fid_PKCS7DesignatedName_cn;
190 static jfieldID fid_PKCS7DesignatedName_c;
191 static jfieldID fid_PKCS7DesignatedName_o;
192 static jfieldID fid_PKCS7DesignatedName_ou;
193 static jfieldID fid_PKCS7DesignatedName_email;
194 static jfieldID fid_PKCS7Signer_pointer;
195 static jfieldID fid_PKCS7Verifier_pointer;
196 
197 static jmethodID mid_ColorSpace_fromPointer;
198 static jmethodID mid_ColorSpace_init;
199 static jmethodID mid_Context_Version_init;
200 static jmethodID mid_Device_beginGroup;
201 static jmethodID mid_Device_beginLayer;
202 static jmethodID mid_Device_beginMask;
203 static jmethodID mid_Device_beginTile;
204 static jmethodID mid_Device_clipImageMask;
205 static jmethodID mid_Device_clipPath;
206 static jmethodID mid_Device_clipStrokePath;
207 static jmethodID mid_Device_clipStrokeText;
208 static jmethodID mid_Device_clipText;
209 static jmethodID mid_Device_endGroup;
210 static jmethodID mid_Device_endLayer;
211 static jmethodID mid_Device_endMask;
212 static jmethodID mid_Device_endTile;
213 static jmethodID mid_Device_fillImage;
214 static jmethodID mid_Device_fillImageMask;
215 static jmethodID mid_Device_fillPath;
216 static jmethodID mid_Device_fillShade;
217 static jmethodID mid_Device_fillText;
218 static jmethodID mid_Device_ignoreText;
219 static jmethodID mid_Device_init;
220 static jmethodID mid_Device_popClip;
221 static jmethodID mid_Device_strokePath;
222 static jmethodID mid_Device_strokeText;
223 static jmethodID mid_DisplayList_init;
224 static jmethodID mid_FitzInputStream_init;
225 static jmethodID mid_Document_init;
226 static jmethodID mid_Font_init;
227 static jmethodID mid_Image_init;
228 static jmethodID mid_Link_init;
229 static jmethodID mid_Location_init;
230 static jmethodID mid_Matrix_init;
231 static jmethodID mid_Object_toString;
232 static jmethodID mid_Outline_init;
233 static jmethodID mid_PDFAnnotation_init;
234 static jmethodID mid_PDFDocument_init;
235 static jmethodID mid_PDFDocument_JsEventListener_onAlert;
236 static jmethodID mid_PDFGraftMap_init;
237 static jmethodID mid_PDFObject_init;
238 static jmethodID mid_PDFPage_init;
239 static jmethodID mid_Page_init;
240 static jmethodID mid_PathWalker_closePath;
241 static jmethodID mid_PathWalker_curveTo;
242 static jmethodID mid_PathWalker_lineTo;
243 static jmethodID mid_PathWalker_moveTo;
244 static jmethodID mid_Path_init;
245 static jmethodID mid_Pixmap_init;
246 static jmethodID mid_Point_init;
247 static jmethodID mid_Quad_init;
248 static jmethodID mid_Rect_init;
249 static jmethodID mid_SeekableInputStream_read;
250 static jmethodID mid_SeekableOutputStream_write;
251 static jmethodID mid_SeekableStream_position;
252 static jmethodID mid_SeekableStream_seek;
253 static jmethodID mid_Shade_init;
254 static jmethodID mid_StrokeState_init;
255 static jmethodID mid_StructuredText_init;
256 static jmethodID mid_StructuredTextWalker_onImageBlock;
257 static jmethodID mid_StructuredTextWalker_beginTextBlock;
258 static jmethodID mid_StructuredTextWalker_endTextBlock;
259 static jmethodID mid_StructuredTextWalker_beginLine;
260 static jmethodID mid_StructuredTextWalker_endLine;
261 static jmethodID mid_StructuredTextWalker_onChar;
262 static jmethodID mid_TextBlock_init;
263 static jmethodID mid_TextChar_init;
264 static jmethodID mid_TextLine_init;
265 static jmethodID mid_TextWalker_showGlyph;
266 static jmethodID mid_Text_init;
267 static jmethodID mid_PDFWidget_init;
268 static jmethodID mid_PKCS7Signer_maxDigest;
269 static jmethodID mid_PKCS7Signer_name;
270 static jmethodID mid_PKCS7Signer_sign;
271 static jmethodID mid_PKCS7Verifier_checkCertificate;
272 static jmethodID mid_PKCS7Verifier_checkDigest;
273 static jmethodID mid_PKCS7DesignatedName_init;
274 
275 #ifdef _WIN32
276 static DWORD context_key;
277 #else
278 static pthread_key_t context_key;
279 #endif
280 static fz_context *base_context;
281 
check_enums()282 static int check_enums()
283 {
284 	int valid = 1;
285 
286 	valid &= com_artifex_mupdf_fitz_Device_BLEND_NORMAL == FZ_BLEND_NORMAL;
287 	valid &= com_artifex_mupdf_fitz_Device_BLEND_MULTIPLY == FZ_BLEND_MULTIPLY;
288 	valid &= com_artifex_mupdf_fitz_Device_BLEND_SCREEN == FZ_BLEND_SCREEN;
289 	valid &= com_artifex_mupdf_fitz_Device_BLEND_OVERLAY == FZ_BLEND_OVERLAY;
290 	valid &= com_artifex_mupdf_fitz_Device_BLEND_DARKEN == FZ_BLEND_DARKEN;
291 	valid &= com_artifex_mupdf_fitz_Device_BLEND_LIGHTEN == FZ_BLEND_LIGHTEN;
292 	valid &= com_artifex_mupdf_fitz_Device_BLEND_COLOR_DODGE == FZ_BLEND_COLOR_DODGE;
293 	valid &= com_artifex_mupdf_fitz_Device_BLEND_COLOR_BURN == FZ_BLEND_COLOR_BURN;
294 	valid &= com_artifex_mupdf_fitz_Device_BLEND_HARD_LIGHT == FZ_BLEND_HARD_LIGHT;
295 	valid &= com_artifex_mupdf_fitz_Device_BLEND_SOFT_LIGHT == FZ_BLEND_SOFT_LIGHT;
296 	valid &= com_artifex_mupdf_fitz_Device_BLEND_DIFFERENCE == FZ_BLEND_DIFFERENCE;
297 	valid &= com_artifex_mupdf_fitz_Device_BLEND_EXCLUSION == FZ_BLEND_EXCLUSION;
298 	valid &= com_artifex_mupdf_fitz_Device_BLEND_HUE == FZ_BLEND_HUE;
299 	valid &= com_artifex_mupdf_fitz_Device_BLEND_SATURATION == FZ_BLEND_SATURATION;
300 	valid &= com_artifex_mupdf_fitz_Device_BLEND_COLOR == FZ_BLEND_COLOR;
301 	valid &= com_artifex_mupdf_fitz_Device_BLEND_LUMINOSITY == FZ_BLEND_LUMINOSITY;
302 
303 	valid &= com_artifex_mupdf_fitz_Font_LATIN == PDF_SIMPLE_ENCODING_LATIN;
304 	valid &= com_artifex_mupdf_fitz_Font_GREEK == PDF_SIMPLE_ENCODING_GREEK;
305 	valid &= com_artifex_mupdf_fitz_Font_CYRILLIC == PDF_SIMPLE_ENCODING_CYRILLIC;
306 
307 	valid &= com_artifex_mupdf_fitz_Font_ADOBE_CNS == FZ_ADOBE_CNS;
308 	valid &= com_artifex_mupdf_fitz_Font_ADOBE_GB == FZ_ADOBE_GB;
309 	valid &= com_artifex_mupdf_fitz_Font_ADOBE_JAPAN == FZ_ADOBE_JAPAN;
310 	valid &= com_artifex_mupdf_fitz_Font_ADOBE_KOREA == FZ_ADOBE_KOREA;
311 
312 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_NONE == PDF_ANNOT_LE_NONE;
313 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_SQUARE == PDF_ANNOT_LE_SQUARE;
314 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_CIRCLE == PDF_ANNOT_LE_CIRCLE;
315 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_DIAMOND == PDF_ANNOT_LE_DIAMOND;
316 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_OPEN_ARROW == PDF_ANNOT_LE_OPEN_ARROW;
317 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_CLOSED_ARROW == PDF_ANNOT_LE_CLOSED_ARROW;
318 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_BUTT == PDF_ANNOT_LE_BUTT;
319 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_R_OPEN_ARROW == PDF_ANNOT_LE_R_OPEN_ARROW;
320 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_R_CLOSED_ARROW == PDF_ANNOT_LE_R_CLOSED_ARROW;
321 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_SLASH == PDF_ANNOT_LE_SLASH;
322 
323 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_TEXT == PDF_ANNOT_TEXT;
324 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_LINK == PDF_ANNOT_LINK;
325 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_FREE_TEXT == PDF_ANNOT_FREE_TEXT;
326 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_LINE == PDF_ANNOT_LINE;
327 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_SQUARE == PDF_ANNOT_SQUARE;
328 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_CIRCLE == PDF_ANNOT_CIRCLE;
329 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_POLYGON == PDF_ANNOT_POLYGON;
330 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_POLY_LINE == PDF_ANNOT_POLY_LINE;
331 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_HIGHLIGHT == PDF_ANNOT_HIGHLIGHT;
332 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_UNDERLINE == PDF_ANNOT_UNDERLINE;
333 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_SQUIGGLY == PDF_ANNOT_SQUIGGLY;
334 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_STRIKE_OUT == PDF_ANNOT_STRIKE_OUT;
335 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_REDACT == PDF_ANNOT_REDACT;
336 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_STAMP == PDF_ANNOT_STAMP;
337 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_CARET == PDF_ANNOT_CARET;
338 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_INK == PDF_ANNOT_INK;
339 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_POPUP == PDF_ANNOT_POPUP;
340 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_FILE_ATTACHMENT == PDF_ANNOT_FILE_ATTACHMENT;
341 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_SOUND == PDF_ANNOT_SOUND;
342 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_MOVIE == PDF_ANNOT_MOVIE;
343 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_RICH_MEDIA == PDF_ANNOT_RICH_MEDIA;
344 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_WIDGET == PDF_ANNOT_WIDGET;
345 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_SCREEN == PDF_ANNOT_SCREEN;
346 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_PRINTER_MARK == PDF_ANNOT_PRINTER_MARK;
347 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_TRAP_NET == PDF_ANNOT_TRAP_NET;
348 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_WATERMARK == PDF_ANNOT_WATERMARK;
349 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_3D == PDF_ANNOT_3D;
350 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_PROJECTION == PDF_ANNOT_PROJECTION;
351 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_UNKNOWN == PDF_ANNOT_UNKNOWN;
352 
353 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_INVISIBLE == PDF_ANNOT_IS_INVISIBLE;
354 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_HIDDEN == PDF_ANNOT_IS_HIDDEN;
355 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_PRINT == PDF_ANNOT_IS_PRINT;
356 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_NO_ZOOM == PDF_ANNOT_IS_NO_ZOOM;
357 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_NO_ROTATE == PDF_ANNOT_IS_NO_ROTATE;
358 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_NO_VIEW == PDF_ANNOT_IS_NO_VIEW;
359 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_READ_ONLY == PDF_ANNOT_IS_READ_ONLY;
360 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_LOCKED == PDF_ANNOT_IS_LOCKED;
361 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_TOGGLE_NO_VIEW == PDF_ANNOT_IS_TOGGLE_NO_VIEW;
362 	valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_LOCKED_CONTENTS == PDF_ANNOT_IS_LOCKED_CONTENTS;
363 
364 	valid &= com_artifex_mupdf_fitz_StrokeState_LINE_CAP_BUTT == FZ_LINECAP_BUTT;
365 	valid &= com_artifex_mupdf_fitz_StrokeState_LINE_CAP_ROUND == FZ_LINECAP_ROUND;
366 	valid &= com_artifex_mupdf_fitz_StrokeState_LINE_CAP_SQUARE == FZ_LINECAP_SQUARE;
367 	valid &= com_artifex_mupdf_fitz_StrokeState_LINE_CAP_TRIANGLE == FZ_LINECAP_TRIANGLE;
368 
369 	valid &= com_artifex_mupdf_fitz_StrokeState_LINE_JOIN_MITER == FZ_LINEJOIN_MITER;
370 	valid &= com_artifex_mupdf_fitz_StrokeState_LINE_JOIN_ROUND == FZ_LINEJOIN_ROUND;
371 	valid &= com_artifex_mupdf_fitz_StrokeState_LINE_JOIN_BEVEL == FZ_LINEJOIN_BEVEL;
372 	valid &= com_artifex_mupdf_fitz_StrokeState_LINE_JOIN_MITER_XPS == FZ_LINEJOIN_MITER_XPS;
373 
374 	valid &= com_artifex_mupdf_fitz_StructuredText_SELECT_CHARS == FZ_SELECT_CHARS;
375 	valid &= com_artifex_mupdf_fitz_StructuredText_SELECT_WORDS == FZ_SELECT_WORDS;
376 	valid &= com_artifex_mupdf_fitz_StructuredText_SELECT_LINES == FZ_SELECT_LINES;
377 
378 	valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_UNKNOWN == PDF_WIDGET_TYPE_UNKNOWN;
379 	valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_BUTTON == PDF_WIDGET_TYPE_BUTTON;
380 	valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_CHECKBOX == PDF_WIDGET_TYPE_CHECKBOX;
381 	valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_COMBOBOX == PDF_WIDGET_TYPE_COMBOBOX;
382 	valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_LISTBOX == PDF_WIDGET_TYPE_LISTBOX;
383 	valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_RADIOBUTTON == PDF_WIDGET_TYPE_RADIOBUTTON;
384 	valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_SIGNATURE == PDF_WIDGET_TYPE_SIGNATURE;
385 	valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_TEXT == PDF_WIDGET_TYPE_TEXT;
386 
387 	valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_NONE == PDF_WIDGET_TX_FORMAT_NONE;
388 	valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_NUMBER == PDF_WIDGET_TX_FORMAT_NUMBER;
389 	valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_SPECIAL == PDF_WIDGET_TX_FORMAT_SPECIAL;
390 	valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_DATE == PDF_WIDGET_TX_FORMAT_DATE;
391 	valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_TIME == PDF_WIDGET_TX_FORMAT_TIME;
392 
393 	valid &= com_artifex_mupdf_fitz_PDFPage_REDACT_IMAGE_NONE == PDF_REDACT_IMAGE_NONE;
394 	valid &= com_artifex_mupdf_fitz_PDFPage_REDACT_IMAGE_REMOVE == PDF_REDACT_IMAGE_REMOVE;
395 	valid &= com_artifex_mupdf_fitz_PDFPage_REDACT_IMAGE_PIXELS == PDF_REDACT_IMAGE_PIXELS;
396 
397 	return valid ? 1 : 0;
398 }
399 
400 /* Helper functions to set the java exception flag. */
401 
jni_throw_imp(JNIEnv * env,jclass cls,const char * mess)402 static void jni_throw_imp(JNIEnv *env, jclass cls, const char *mess)
403 {
404 	(*env)->ThrowNew(env, cls, mess);
405 }
406 
407 #define jni_throw_void(env, info) do { jni_throw_imp(env, info); return; }
408 #define jni_throw(env, info) do { jni_throw_imp(env, info); return 0; }
409 
jni_rethrow_imp(JNIEnv * env,fz_context * ctx)410 static void jni_rethrow_imp(JNIEnv *env, fz_context *ctx)
411 {
412 	if (fz_caught(ctx) == FZ_ERROR_TRYLATER)
413 		jni_throw_imp(env, cls_TryLaterException, fz_caught_message(ctx));
414 	else
415 		jni_throw_imp(env, cls_RuntimeException, fz_caught_message(ctx));
416 }
417 
418 #define jni_rethrow_void(env, ctx) do { jni_rethrow_imp(env, ctx); return; } while (0);
419 #define jni_rethrow(env, ctx) do { jni_rethrow_imp(env, ctx); return 0; } while (0);
420 
jni_throw_run_imp(JNIEnv * env,const char * info)421 static void jni_throw_run_imp(JNIEnv *env, const char *info)
422 {
423 	jni_throw_imp(env, cls_RuntimeException, info);
424 }
425 
426 #define jni_throw_run_void(env, info) do { jni_throw_run_imp(env, info); return; } while (0);
427 #define jni_throw_run(env, info) do { jni_throw_run_imp(env, info); return 0; } while (0);
428 
jni_throw_oom_imp(JNIEnv * env,const char * info)429 static void jni_throw_oom_imp(JNIEnv *env, const char *info)
430 {
431 	jni_throw_imp(env, cls_OutOfMemoryError, info);
432 }
433 
434 #define jni_throw_oom_void(env, info) do { jni_throw_oom_imp(env, info); return; } while (0);
435 #define jni_throw_oom(env, info) do { jni_throw_oom_imp(env, info); return 0; } while (0);
436 
jni_throw_oob_imp(JNIEnv * env,const char * info)437 static void jni_throw_oob_imp(JNIEnv *env, const char *info)
438 {
439 	jni_throw_imp(env, cls_IndexOutOfBoundsException, info);
440 }
441 
442 #define jni_throw_oob_void(env, info) do { jni_throw_oob_imp(env, info); return; } while (0);
443 #define jni_throw_oob(env, info) do { jni_throw_oob_imp(env, info); return 0; } while (0);
444 
jni_throw_arg_imp(JNIEnv * env,const char * info)445 static void jni_throw_arg_imp(JNIEnv *env, const char *info)
446 {
447 	jni_throw_imp(env, cls_IllegalArgumentException, info);
448 }
449 
450 #define jni_throw_arg_void(env, info) do { jni_throw_arg_imp(env, info); return; } while (0);
451 #define jni_throw_arg(env, info) do { jni_throw_arg_imp(env, info); return 0; } while (0);
452 
jni_throw_io_imp(JNIEnv * env,const char * info)453 static void jni_throw_io_imp(JNIEnv *env, const char *info)
454 {
455 	jni_throw_imp(env, cls_IOException, info);
456 }
457 
458 #define jni_throw_io_void(env, info) do { jni_throw_io_imp(env, info); return; } while (0);
459 #define jni_throw_io(env, info) do { jni_throw_io_imp(env, info); return 0; } while (0);
460 
jni_throw_null_imp(JNIEnv * env,const char * info)461 static void jni_throw_null_imp(JNIEnv *env, const char *info)
462 {
463 	jni_throw_imp(env, cls_NullPointerException, info);
464 }
465 
466 #define jni_throw_null_void(env, info) do { jni_throw_null_imp(env, info); return; } while (0);
467 #define jni_throw_null(env, info) do { jni_throw_null_imp(env, info); return 0; } while (0);
468 
jni_throw_uoe_imp(JNIEnv * env,const char * info)469 static void jni_throw_uoe_imp(JNIEnv *env, const char *info)
470 {
471 	jni_throw_imp(env, cls_UnsupportedOperationException, info);
472 }
473 
474 #define jni_throw_uoe_void(env, info) do { jni_throw_uoe_imp(env, info); return; } while (0);
475 #define jni_throw_uoe(env, info) do { jni_throw_uoe_imp(env, info); return 0; } while (0);
476 
477 /* Convert a java exception and throw into fitz. */
478 
fz_throw_java_and_detach_thread(fz_context * ctx,JNIEnv * env,jboolean detach)479 static void fz_throw_java_and_detach_thread(fz_context *ctx, JNIEnv *env, jboolean detach)
480 {
481 	jthrowable ex = (*env)->ExceptionOccurred(env);
482 	if (ex)
483 	{
484 		jobject msg;
485 		(*env)->ExceptionClear(env);
486 		msg = (*env)->CallObjectMethod(env, ex, mid_Object_toString);
487 		if ((*env)->ExceptionCheck(env))
488 			(*env)->ExceptionClear(env);
489 		else if (msg)
490 		{
491 			const char *p = (*env)->GetStringUTFChars(env, msg, NULL);
492 			if (p)
493 			{
494 				char buf[256];
495 				fz_strlcpy(buf, p, sizeof buf);
496 				(*env)->ReleaseStringUTFChars(env, msg, p);
497 				if (detach)
498 					(*jvm)->DetachCurrentThread(jvm);
499 				fz_throw(ctx, FZ_ERROR_GENERIC, "%s", buf);
500 			}
501 		}
502 	}
503 	if (detach)
504 		(*jvm)->DetachCurrentThread(jvm);
505 	fz_throw(ctx, FZ_ERROR_GENERIC, "unknown java error");
506 }
507 
508 #define fz_throw_java(ctx, env) fz_throw_java_and_detach_thread((ctx), (env), JNI_FALSE)
509 
510 #define fz_throw_and_detach_thread(ctx, detach, code, ...) \
511 	do \
512 	{ \
513 		if (detach) \
514 			(*jvm)->DetachCurrentThread(jvm); \
515 		fz_throw((ctx), (code), __VA_ARGS__); \
516 	} while (0)
517 
518 #define fz_rethrow_and_detach_thread(ctx, detach) \
519 	do \
520 	{ \
521 		if (detach) \
522 			(*jvm)->DetachCurrentThread(jvm); \
523 		fz_rethrow(ctx); \
524 	} while (0)
525 
526 typedef struct {
527 	pdf_pkcs7_verifier base;
528 	jobject jverifier;
529 } java_pkcs7_verifier;
530 
531 /* Load classes, field and method IDs. */
532 
533 static const char *current_class_name = NULL;
534 static jclass current_class = NULL;
535 
get_class(int * failed,JNIEnv * env,const char * name)536 static jclass get_class(int *failed, JNIEnv *env, const char *name)
537 {
538 	jclass local;
539 
540 	if (*failed) return NULL;
541 
542 	current_class_name = name;
543 	local = (*env)->FindClass(env, name);
544 	if (!local || (*env)->ExceptionCheck(env))
545 	{
546 		LOGI("Failed to find class %s", name);
547 		*failed = 1;
548 		return NULL;
549 	}
550 
551 	current_class = (*env)->NewGlobalRef(env, local);
552 	if (!current_class)
553 	{
554 		LOGI("Failed to make global ref for %s", name);
555 		*failed = 1;
556 		return NULL;
557 	}
558 
559 	(*env)->DeleteLocalRef(env, local);
560 
561 	return current_class;
562 }
563 
get_field(int * failed,JNIEnv * env,const char * field,const char * sig)564 static jfieldID get_field(int *failed, JNIEnv *env, const char *field, const char *sig)
565 {
566 	jfieldID fid;
567 
568 	if (*failed || !current_class) return NULL;
569 
570 	fid = (*env)->GetFieldID(env, current_class, field, sig);
571 	if (fid == 0 || (*env)->ExceptionCheck(env))
572 	{
573 		LOGI("Failed to get field for %s %s %s", current_class_name, field, sig);
574 		*failed = 1;
575 	}
576 
577 	return fid;
578 }
579 
get_static_field(int * failed,JNIEnv * env,const char * field,const char * sig)580 static jfieldID get_static_field(int *failed, JNIEnv *env, const char *field, const char *sig)
581 {
582 	jfieldID fid;
583 
584 	if (*failed || !current_class) return NULL;
585 
586 	fid = (*env)->GetStaticFieldID(env, current_class, field, sig);
587 	if (fid == 0 || (*env)->ExceptionCheck(env))
588 	{
589 		LOGI("Failed to get static field for %s %s %s", current_class_name, field, sig);
590 		*failed = 1;
591 	}
592 
593 	return fid;
594 }
595 
get_method(int * failed,JNIEnv * env,const char * method,const char * sig)596 static jmethodID get_method(int *failed, JNIEnv *env, const char *method, const char *sig)
597 {
598 	jmethodID mid;
599 
600 	if (*failed || !current_class) return NULL;
601 
602 	mid = (*env)->GetMethodID(env, current_class, method, sig);
603 	if (mid == 0 || (*env)->ExceptionCheck(env))
604 	{
605 		LOGI("Failed to get method for %s %s %s", current_class_name, method, sig);
606 		*failed = 1;
607 	}
608 
609 	return mid;
610 }
611 
get_static_method(int * failed,JNIEnv * env,const char * method,const char * sig)612 static jmethodID get_static_method(int *failed, JNIEnv *env, const char *method, const char *sig)
613 {
614 	jmethodID mid;
615 
616 	if (*failed || !current_class) return NULL;
617 
618 	mid = (*env)->GetStaticMethodID(env, current_class, method, sig);
619 	if (mid == 0 || (*env)->ExceptionCheck(env))
620 	{
621 		LOGI("Failed to get static method for %s %s %s", current_class_name, method, sig);
622 		*failed = 1;
623 	}
624 
625 	return mid;
626 }
627 
find_fids(JNIEnv * env)628 static int find_fids(JNIEnv *env)
629 {
630 	int err = 0;
631 	int getvmErr;
632 
633 	cls_Buffer = get_class(&err, env, PKG"Buffer");
634 	fid_Buffer_pointer = get_field(&err, env, "pointer", "J");
635 
636 	cls_ColorSpace = get_class(&err, env, PKG"ColorSpace");
637 	fid_ColorSpace_pointer = get_field(&err, env, "pointer", "J");
638 	mid_ColorSpace_init = get_method(&err, env, "<init>", "(J)V");
639 	mid_ColorSpace_fromPointer = get_static_method(&err, env, "fromPointer", "(J)L"PKG"ColorSpace;");
640 
641 	cls_Context_Version = get_class(&err, env, PKG"Context$Version");
642 	mid_Context_Version_init = get_method(&err, env, "<init>", "(L"PKG"Context;)V");
643 	fid_Context_Version_major = get_field(&err, env, "major", "I");
644 	fid_Context_Version_minor = get_field(&err, env, "minor", "I");
645 	fid_Context_Version_patch = get_field(&err, env, "patch", "I");
646 	fid_Context_Version_version = get_field(&err, env, "version", "Ljava/lang/String;");
647 
648 	cls_Cookie = get_class(&err, env, PKG"Cookie");
649 	fid_Cookie_pointer = get_field(&err, env, "pointer", "J");
650 
651 	cls_Device = get_class(&err, env, PKG"Device");
652 	fid_Device_pointer = get_field(&err, env, "pointer", "J");
653 	mid_Device_init = get_method(&err, env, "<init>", "(J)V");
654 	mid_Device_fillPath = get_method(&err, env, "fillPath", "(L"PKG"Path;ZL"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
655 	mid_Device_strokePath = get_method(&err, env, "strokePath", "(L"PKG"Path;L"PKG"StrokeState;L"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
656 	mid_Device_clipPath = get_method(&err, env, "clipPath", "(L"PKG"Path;ZL"PKG"Matrix;)V");
657 	mid_Device_clipStrokePath = get_method(&err, env, "clipStrokePath", "(L"PKG"Path;L"PKG"StrokeState;L"PKG"Matrix;)V");
658 	mid_Device_fillText = get_method(&err, env, "fillText", "(L"PKG"Text;L"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
659 	mid_Device_strokeText = get_method(&err, env, "strokeText", "(L"PKG"Text;L"PKG"StrokeState;L"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
660 	mid_Device_clipText = get_method(&err, env, "clipText", "(L"PKG"Text;L"PKG"Matrix;)V");
661 	mid_Device_clipStrokeText = get_method(&err, env, "clipStrokeText", "(L"PKG"Text;L"PKG"StrokeState;L"PKG"Matrix;)V");
662 	mid_Device_ignoreText = get_method(&err, env, "ignoreText", "(L"PKG"Text;L"PKG"Matrix;)V");
663 	mid_Device_fillShade = get_method(&err, env, "fillShade", "(L"PKG"Shade;L"PKG"Matrix;FI)V");
664 	mid_Device_fillImage = get_method(&err, env, "fillImage", "(L"PKG"Image;L"PKG"Matrix;FI)V");
665 	mid_Device_fillImageMask = get_method(&err, env, "fillImageMask", "(L"PKG"Image;L"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
666 	mid_Device_clipImageMask = get_method(&err, env, "clipImageMask", "(L"PKG"Image;L"PKG"Matrix;)V");
667 	mid_Device_popClip = get_method(&err, env, "popClip", "()V");
668 	mid_Device_beginLayer = get_method(&err, env, "beginLayer", "(Ljava/lang/String;)V");
669 	mid_Device_endLayer = get_method(&err, env, "endLayer", "()V");
670 	mid_Device_beginMask = get_method(&err, env, "beginMask", "(L"PKG"Rect;ZL"PKG"ColorSpace;[FI)V");
671 	mid_Device_endMask = get_method(&err, env, "endMask", "()V");
672 	mid_Device_beginGroup = get_method(&err, env, "beginGroup", "(L"PKG"Rect;L"PKG"ColorSpace;ZZIF)V");
673 	mid_Device_endGroup = get_method(&err, env, "endGroup", "()V");
674 	mid_Device_beginTile = get_method(&err, env, "beginTile", "(L"PKG"Rect;L"PKG"Rect;FFL"PKG"Matrix;I)I");
675 	mid_Device_endTile = get_method(&err, env, "endTile", "()V");
676 
677 	cls_DisplayList = get_class(&err, env, PKG"DisplayList");
678 	fid_DisplayList_pointer = get_field(&err, env, "pointer", "J");
679 	mid_DisplayList_init = get_method(&err, env, "<init>", "(J)V");
680 
681 	cls_Document = get_class(&err, env, PKG"Document");
682 	fid_Document_pointer = get_field(&err, env, "pointer", "J");
683 	mid_Document_init = get_method(&err, env, "<init>", "(J)V");
684 
685 	cls_DocumentWriter = get_class(&err, env, PKG"DocumentWriter");
686 	fid_DocumentWriter_pointer = get_field(&err, env, "pointer", "J");
687 
688 	cls_FitzInputStream = get_class(&err, env, PKG"FitzInputStream");
689 	fid_FitzInputStream_pointer = get_field(&err, env, "pointer", "J");
690 	fid_FitzInputStream_markpos = get_field(&err, env, "markpos", "J");
691 	fid_FitzInputStream_closed = get_field(&err, env, "closed", "Z");
692 	mid_FitzInputStream_init = get_method(&err, env, "<init>", "(J)V");
693 
694 	cls_Font = get_class(&err, env, PKG"Font");
695 	fid_Font_pointer = get_field(&err, env, "pointer", "J");
696 	mid_Font_init = get_method(&err, env, "<init>", "(J)V");
697 
698 	cls_Image = get_class(&err, env, PKG"Image");
699 	fid_Image_pointer = get_field(&err, env, "pointer", "J");
700 	mid_Image_init = get_method(&err, env, "<init>", "(J)V");
701 
702 	cls_Link = get_class(&err, env, PKG"Link");
703 	mid_Link_init = get_method(&err, env, "<init>", "(L"PKG"Rect;Ljava/lang/String;)V");
704 
705 	cls_Location = get_class(&err, env, PKG"Location");
706 	mid_Location_init = get_method(&err, env, "<init>", "(IIFF)V");
707 
708 	cls_Matrix = get_class(&err, env, PKG"Matrix");
709 	fid_Matrix_a = get_field(&err, env, "a", "F");
710 	fid_Matrix_b = get_field(&err, env, "b", "F");
711 	fid_Matrix_c = get_field(&err, env, "c", "F");
712 	fid_Matrix_d = get_field(&err, env, "d", "F");
713 	fid_Matrix_e = get_field(&err, env, "e", "F");
714 	fid_Matrix_f = get_field(&err, env, "f", "F");
715 	mid_Matrix_init = get_method(&err, env, "<init>", "(FFFFFF)V");
716 
717 	cls_NativeDevice = get_class(&err, env, PKG"NativeDevice");
718 	fid_NativeDevice_nativeResource = get_field(&err, env, "nativeResource", "Ljava/lang/Object;");
719 	fid_NativeDevice_nativeInfo = get_field(&err, env, "nativeInfo", "J");
720 
721 	cls_Outline = get_class(&err, env, PKG"Outline");
722 	mid_Outline_init = get_method(&err, env, "<init>", "(Ljava/lang/String;Ljava/lang/String;[L"PKG"Outline;)V");
723 
724 	cls_Page = get_class(&err, env, PKG"Page");
725 	fid_Page_pointer = get_field(&err, env, "pointer", "J");
726 	mid_Page_init = get_method(&err, env, "<init>", "(J)V");
727 
728 	cls_Path = get_class(&err, env, PKG"Path");
729 	fid_Path_pointer = get_field(&err, env, "pointer", "J");
730 	mid_Path_init = get_method(&err, env, "<init>", "(J)V");
731 
732 	cls_PathWalker = get_class(&err, env, PKG"PathWalker");
733 	mid_PathWalker_moveTo = get_method(&err, env, "moveTo", "(FF)V");
734 	mid_PathWalker_lineTo = get_method(&err, env, "lineTo", "(FF)V");
735 	mid_PathWalker_curveTo = get_method(&err, env, "curveTo", "(FFFFFF)V");
736 	mid_PathWalker_closePath = get_method(&err, env, "closePath", "()V");
737 
738 	cls_PDFAnnotation = get_class(&err, env, PKG"PDFAnnotation");
739 	fid_PDFAnnotation_pointer = get_field(&err, env, "pointer", "J");
740 	mid_PDFAnnotation_init = get_method(&err, env, "<init>", "(J)V");
741 
742 	cls_PDFDocument = get_class(&err, env, PKG"PDFDocument");
743 	fid_PDFDocument_pointer = get_field(&err, env, "pointer", "J");
744 	mid_PDFDocument_init = get_method(&err, env, "<init>", "(J)V");
745 
746 	cls_PDFDocument_JsEventListener = get_class(&err, env, PKG"PDFDocument$JsEventListener");
747 	mid_PDFDocument_JsEventListener_onAlert = get_method(&err, env, "onAlert", "(Ljava/lang/String;)V");
748 
749 	cls_PDFGraftMap = get_class(&err, env, PKG"PDFGraftMap");
750 	fid_PDFGraftMap_pointer = get_field(&err, env, "pointer", "J");
751 	mid_PDFGraftMap_init = get_method(&err, env, "<init>", "(J)V");
752 
753 	cls_PDFObject = get_class(&err, env, PKG"PDFObject");
754 	fid_PDFObject_pointer = get_field(&err, env, "pointer", "J");
755 	fid_PDFObject_Null = get_static_field(&err, env, "Null", "L"PKG"PDFObject;");
756 	mid_PDFObject_init = get_method(&err, env, "<init>", "(J)V");
757 
758 	cls_PDFPage = get_class(&err, env, PKG"PDFPage");
759 	fid_PDFPage_pointer = get_field(&err, env, "pointer", "J");
760 	mid_PDFPage_init = get_method(&err, env, "<init>", "(J)V");
761 
762 	cls_Pixmap = get_class(&err, env, PKG"Pixmap");
763 	fid_Pixmap_pointer = get_field(&err, env, "pointer", "J");
764 	mid_Pixmap_init = get_method(&err, env, "<init>", "(J)V");
765 
766 	cls_Point = get_class(&err, env, PKG"Point");
767 	mid_Point_init = get_method(&err, env, "<init>", "(FF)V");
768 	fid_Point_x = get_field(&err, env, "x", "F");
769 	fid_Point_y = get_field(&err, env, "y", "F");
770 
771 	cls_Quad = get_class(&err, env, PKG"Quad");
772 	fid_Quad_ul_x = get_field(&err, env, "ul_x", "F");
773 	fid_Quad_ul_y = get_field(&err, env, "ul_y", "F");
774 	fid_Quad_ur_x = get_field(&err, env, "ur_x", "F");
775 	fid_Quad_ur_y = get_field(&err, env, "ur_y", "F");
776 	fid_Quad_ll_x = get_field(&err, env, "ll_x", "F");
777 	fid_Quad_ll_y = get_field(&err, env, "ll_y", "F");
778 	fid_Quad_lr_x = get_field(&err, env, "lr_x", "F");
779 	fid_Quad_lr_y = get_field(&err, env, "lr_y", "F");
780 	mid_Quad_init = get_method(&err, env, "<init>", "(FFFFFFFF)V");
781 
782 	cls_Rect = get_class(&err, env, PKG"Rect");
783 	fid_Rect_x0 = get_field(&err, env, "x0", "F");
784 	fid_Rect_x1 = get_field(&err, env, "x1", "F");
785 	fid_Rect_y0 = get_field(&err, env, "y0", "F");
786 	fid_Rect_y1 = get_field(&err, env, "y1", "F");
787 	mid_Rect_init = get_method(&err, env, "<init>", "(FFFF)V");
788 
789 	cls_SeekableInputStream = get_class(&err, env, PKG"SeekableInputStream");
790 	mid_SeekableInputStream_read = get_method(&err, env, "read", "([B)I");
791 
792 	cls_SeekableOutputStream = get_class(&err, env, PKG"SeekableOutputStream");
793 	mid_SeekableOutputStream_write = get_method(&err, env, "write", "([BII)V");
794 
795 	cls_SeekableStream = get_class(&err, env, PKG"SeekableStream");
796 	mid_SeekableStream_position = get_method(&err, env, "position", "()J");
797 	mid_SeekableStream_seek = get_method(&err, env, "seek", "(JI)J");
798 
799 	cls_Shade = get_class(&err, env, PKG"Shade");
800 	fid_Shade_pointer = get_field(&err, env, "pointer", "J");
801 	mid_Shade_init = get_method(&err, env, "<init>", "(J)V");
802 
803 	cls_String = get_class(&err, env, "java/lang/String");
804 
805 	cls_StrokeState = get_class(&err, env, PKG"StrokeState");
806 	fid_StrokeState_pointer = get_field(&err, env, "pointer", "J");
807 	mid_StrokeState_init = get_method(&err, env, "<init>", "(J)V");
808 
809 	cls_StructuredText = get_class(&err, env, PKG"StructuredText");
810 	fid_StructuredText_pointer = get_field(&err, env, "pointer", "J");
811 	mid_StructuredText_init = get_method(&err, env, "<init>", "(J)V");
812 
813 	cls_StructuredTextWalker = get_class(&err, env, PKG"StructuredTextWalker");
814 	mid_StructuredTextWalker_onImageBlock = get_method(&err, env, "onImageBlock", "(L"PKG"Rect;L"PKG"Matrix;L"PKG"Image;)V");
815 	mid_StructuredTextWalker_beginTextBlock = get_method(&err, env, "beginTextBlock", "(L"PKG"Rect;)V");
816 	mid_StructuredTextWalker_endTextBlock = get_method(&err, env, "endTextBlock", "()V");
817 	mid_StructuredTextWalker_beginLine = get_method(&err, env, "beginLine", "(L"PKG"Rect;I)V");
818 	mid_StructuredTextWalker_endLine = get_method(&err, env, "endLine", "()V");
819 	mid_StructuredTextWalker_onChar = get_method(&err, env, "onChar", "(IL"PKG"Point;L"PKG"Font;FL"PKG"Quad;)V");
820 
821 	cls_Text = get_class(&err, env, PKG"Text");
822 	fid_Text_pointer = get_field(&err, env, "pointer", "J");
823 	mid_Text_init = get_method(&err, env, "<init>", "(J)V");
824 
825 	cls_TextBlock = get_class(&err, env, PKG"StructuredText$TextBlock");
826 	mid_TextBlock_init = get_method(&err, env, "<init>", "(L"PKG"StructuredText;)V");
827 	fid_TextBlock_bbox = get_field(&err, env, "bbox", "L"PKG"Rect;");
828 	fid_TextBlock_lines = get_field(&err, env, "lines", "[L"PKG"StructuredText$TextLine;");
829 
830 	cls_TextChar = get_class(&err, env, PKG"StructuredText$TextChar");
831 	mid_TextChar_init = get_method(&err, env, "<init>", "(L"PKG"StructuredText;)V");
832 	fid_TextChar_quad = get_field(&err, env, "quad", "L"PKG"Quad;");
833 	fid_TextChar_c = get_field(&err, env, "c", "I");
834 
835 	cls_TextLine = get_class(&err, env, PKG"StructuredText$TextLine");
836 	mid_TextLine_init = get_method(&err, env, "<init>", "(L"PKG"StructuredText;)V");
837 	fid_TextLine_bbox = get_field(&err, env, "bbox", "L"PKG"Rect;");
838 	fid_TextLine_chars = get_field(&err, env, "chars", "[L"PKG"StructuredText$TextChar;");
839 
840 	cls_TextWalker = get_class(&err, env, PKG"TextWalker");
841 	mid_TextWalker_showGlyph = get_method(&err, env, "showGlyph", "(L"PKG"Font;L"PKG"Matrix;IIZ)V");
842 
843 	cls_PDFWidget = get_class(&err, env, PKG"PDFWidget");
844 	fid_PDFWidget_pointer = get_field(&err, env, "pointer", "J");
845 	fid_PDFWidget_fieldType = get_field(&err, env, "fieldType", "I");
846 	fid_PDFWidget_textFormat = get_field(&err, env, "textFormat", "I");
847 	fid_PDFWidget_maxLen = get_field(&err, env, "maxLen", "I");
848 	fid_PDFWidget_fieldFlags = get_field(&err, env, "fieldFlags", "I");
849 	fid_PDFWidget_options = get_field(&err, env, "options", "[Ljava/lang/String;");
850 	mid_PDFWidget_init = get_method(&err, env, "<init>", "(J)V");
851 
852 	cls_PKCS7Signer = get_class(&err, env, PKG"PKCS7Signer");
853 	fid_PKCS7Signer_pointer = get_field(&err, env, "pointer", "J");
854 	mid_PKCS7Signer_name = get_method(&err, env, "name", "()L"PKG"PKCS7DesignatedName;");
855 	mid_PKCS7Signer_sign = get_method(&err, env, "sign", "(L"PKG"FitzInputStream;)[B");
856 	mid_PKCS7Signer_maxDigest = get_method(&err, env, "maxDigest", "()I");
857 
858 	cls_PKCS7Verifier = get_class(&err, env, PKG"PKCS7Verifier");
859 	fid_PKCS7Verifier_pointer = get_field(&err, env, "pointer", "J");
860 	mid_PKCS7Verifier_checkCertificate = get_method(&err, env, "checkCertificate", "([B)I");
861 	mid_PKCS7Verifier_checkDigest = get_method(&err, env, "checkDigest", "(L"PKG"FitzInputStream;[B)I");
862 
863 	cls_PKCS7DesignatedName = get_class(&err, env, PKG"PKCS7DesignatedName");
864 	fid_PKCS7DesignatedName_cn = get_field(&err, env, "cn", "Ljava/lang/String;");
865 	fid_PKCS7DesignatedName_c = get_field(&err, env, "c", "Ljava/lang/String;");
866 	fid_PKCS7DesignatedName_o = get_field(&err, env, "o", "Ljava/lang/String;");
867 	fid_PKCS7DesignatedName_ou = get_field(&err, env, "ou", "Ljava/lang/String;");
868 	fid_PKCS7DesignatedName_email = get_field(&err, env, "email", "Ljava/lang/String;");
869 	mid_PKCS7DesignatedName_init = get_method(&err, env, "<init>", "()V");
870 
871 	cls_TryLaterException = get_class(&err, env, PKG"TryLaterException");
872 
873 	/* Standard Java classes */
874 
875 	cls_FloatArray = get_class(&err, env, "[F");
876 	cls_IntegerArray = get_class(&err, env, "[I");
877 
878 	cls_Object = get_class(&err, env, "java/lang/Object");
879 	mid_Object_toString = get_method(&err, env, "toString", "()Ljava/lang/String;");
880 
881 	cls_IndexOutOfBoundsException = get_class(&err, env, "java/lang/IndexOutOfBoundsException");
882 	cls_IllegalArgumentException = get_class(&err, env, "java/lang/IllegalArgumentException");
883 	cls_IOException = get_class(&err, env, "java/io/IOException");
884 	cls_NullPointerException = get_class(&err, env, "java/lang/NullPointerException");
885 	cls_RuntimeException = get_class(&err, env, "java/lang/RuntimeException");
886 	cls_UnsupportedOperationException = get_class(&err, env, "java/lang/UnsupportedOperationException");
887 
888 	cls_OutOfMemoryError = get_class(&err, env, "java/lang/OutOfMemoryError");
889 
890 	if (err)
891 	{
892 		LOGE("one or more class, member or field IDs could not be found");
893 		return -1;
894 	}
895 
896 	/* Get and store the main JVM pointer. We need this in order to get
897 	 * JNIEnv pointers on callback threads. This is specifically
898 	 * guaranteed to be safe to store in a static var. */
899 
900 	getvmErr = (*env)->GetJavaVM(env, &jvm);
901 	if (getvmErr < 0)
902 	{
903 		LOGE("cannot get JVM interface (error %d)", getvmErr);
904 		return -1;
905 	}
906 
907 	return 0;
908 }
909 
910 /* When making callbacks from C to java, we may be called on threads
911  * other than the foreground. As such, we have no JNIEnv. This function
912  * handles getting us the required environment */
jni_attach_thread(fz_context * ctx,jboolean * detach)913 static JNIEnv *jni_attach_thread(fz_context *ctx, jboolean *detach)
914 {
915 	JNIEnv *env = NULL;
916 	int state;
917 
918 	*detach = JNI_FALSE;
919 	state = (*jvm)->GetEnv(jvm, (void *)&env, MY_JNI_VERSION);
920 	if (state == JNI_EDETACHED)
921 	{
922 		*detach = JNI_TRUE;
923 		state = (*jvm)->AttachCurrentThread(jvm, (void *)&env, NULL);
924 	}
925 
926 	if (state != JNI_OK) return NULL;
927 
928 	return env;
929 }
930 
jni_detach_thread(jboolean detach)931 static void jni_detach_thread(jboolean detach)
932 {
933 	if (!detach) return;
934 	(*jvm)->DetachCurrentThread(jvm);
935 }
936 
lose_fids(JNIEnv * env)937 static void lose_fids(JNIEnv *env)
938 {
939 	(*env)->DeleteGlobalRef(env, cls_Buffer);
940 	(*env)->DeleteGlobalRef(env, cls_ColorSpace);
941 	(*env)->DeleteGlobalRef(env, cls_Context_Version);
942 	(*env)->DeleteGlobalRef(env, cls_Cookie);
943 	(*env)->DeleteGlobalRef(env, cls_Device);
944 	(*env)->DeleteGlobalRef(env, cls_DisplayList);
945 	(*env)->DeleteGlobalRef(env, cls_Document);
946 	(*env)->DeleteGlobalRef(env, cls_DocumentWriter);
947 	(*env)->DeleteGlobalRef(env, cls_FitzInputStream);
948 	(*env)->DeleteGlobalRef(env, cls_FloatArray);
949 	(*env)->DeleteGlobalRef(env, cls_Font);
950 	(*env)->DeleteGlobalRef(env, cls_IllegalArgumentException);
951 	(*env)->DeleteGlobalRef(env, cls_Image);
952 	(*env)->DeleteGlobalRef(env, cls_IndexOutOfBoundsException);
953 	(*env)->DeleteGlobalRef(env, cls_IntegerArray);
954 	(*env)->DeleteGlobalRef(env, cls_IOException);
955 	(*env)->DeleteGlobalRef(env, cls_Link);
956 	(*env)->DeleteGlobalRef(env, cls_Location);
957 	(*env)->DeleteGlobalRef(env, cls_Matrix);
958 	(*env)->DeleteGlobalRef(env, cls_NativeDevice);
959 	(*env)->DeleteGlobalRef(env, cls_NullPointerException);
960 	(*env)->DeleteGlobalRef(env, cls_Object);
961 	(*env)->DeleteGlobalRef(env, cls_Outline);
962 	(*env)->DeleteGlobalRef(env, cls_OutOfMemoryError);
963 	(*env)->DeleteGlobalRef(env, cls_Page);
964 	(*env)->DeleteGlobalRef(env, cls_Path);
965 	(*env)->DeleteGlobalRef(env, cls_PathWalker);
966 	(*env)->DeleteGlobalRef(env, cls_PDFAnnotation);
967 	(*env)->DeleteGlobalRef(env, cls_PDFDocument);
968 	(*env)->DeleteGlobalRef(env, cls_PDFDocument_JsEventListener);
969 	(*env)->DeleteGlobalRef(env, cls_PDFPage);
970 	(*env)->DeleteGlobalRef(env, cls_PDFGraftMap);
971 	(*env)->DeleteGlobalRef(env, cls_PDFObject);
972 	(*env)->DeleteGlobalRef(env, cls_Pixmap);
973 	(*env)->DeleteGlobalRef(env, cls_Point);
974 	(*env)->DeleteGlobalRef(env, cls_Quad);
975 	(*env)->DeleteGlobalRef(env, cls_Rect);
976 	(*env)->DeleteGlobalRef(env, cls_RuntimeException);
977 	(*env)->DeleteGlobalRef(env, cls_SeekableStream);
978 	(*env)->DeleteGlobalRef(env, cls_SeekableInputStream);
979 	(*env)->DeleteGlobalRef(env, cls_SeekableOutputStream);
980 	(*env)->DeleteGlobalRef(env, cls_Shade);
981 	(*env)->DeleteGlobalRef(env, cls_String);
982 	(*env)->DeleteGlobalRef(env, cls_StrokeState);
983 	(*env)->DeleteGlobalRef(env, cls_StructuredText);
984 	(*env)->DeleteGlobalRef(env, cls_StructuredTextWalker);
985 	(*env)->DeleteGlobalRef(env, cls_Text);
986 	(*env)->DeleteGlobalRef(env, cls_TextBlock);
987 	(*env)->DeleteGlobalRef(env, cls_TextChar);
988 	(*env)->DeleteGlobalRef(env, cls_TextLine);
989 	(*env)->DeleteGlobalRef(env, cls_TextWalker);
990 	(*env)->DeleteGlobalRef(env, cls_TryLaterException);
991 	(*env)->DeleteGlobalRef(env, cls_UnsupportedOperationException);
992 	(*env)->DeleteGlobalRef(env, cls_PDFWidget);
993 	(*env)->DeleteGlobalRef(env, cls_PKCS7Signer);
994 	(*env)->DeleteGlobalRef(env, cls_PKCS7Verifier);
995 	(*env)->DeleteGlobalRef(env, cls_PKCS7DesignatedName);
996 }
997 
998 
999 JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM * vm,void * reserved)1000 JNI_OnLoad(JavaVM *vm, void *reserved)
1001 {
1002 	JNIEnv *env;
1003 	jint ret;
1004 
1005 	ret = (*vm)->GetEnv(vm, (void **)&env, MY_JNI_VERSION);
1006 	if (ret != JNI_OK)
1007 	{
1008 		LOGE("cannot get JNI interface during load (error %d)", ret);
1009 		return -1;
1010 	}
1011 
1012 	return MY_JNI_VERSION;
1013 }
1014 
JNI_OnUnload(JavaVM * vm,void * reserved)1015 JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
1016 {
1017 	JNIEnv *env;
1018 	jint ret;
1019 
1020 	ret = (*vm)->GetEnv(vm, (void **)&env, MY_JNI_VERSION);
1021 	if (ret != JNI_OK)
1022 	{
1023 		/* If this fails, we're really in trouble! */
1024 		LOGE("cannot get JNI interface during unload (error %d)", ret);
1025 		return;
1026 	}
1027 
1028 	fz_drop_context(base_context);
1029 	base_context = NULL;
1030 	lose_fids(env);
1031 }
1032 
1033 #ifdef HAVE_ANDROID
1034 #include "jni/android/androidfonts.c"
1035 #endif
1036 
1037 #include "jni/wrap.c"
1038 
1039 #include "jni/context.c"
1040 #include "jni/device.c"
1041 #include "jni/nativedevice.c"
1042 
1043 #include "jni/buffer.c"
1044 #include "jni/colorspace.c"
1045 #include "jni/cookie.c"
1046 #include "jni/displaylist.c"
1047 #include "jni/displaylistdevice.c"
1048 #include "jni/document.c"
1049 #include "jni/documentwriter.c"
1050 #include "jni/drawdevice.c"
1051 #include "jni/fitzinputstream.c"
1052 #include "jni/font.c"
1053 #include "jni/image.c"
1054 #include "jni/page.c"
1055 #include "jni/path.c"
1056 #include "jni/pdfannotation.c"
1057 #include "jni/pdfdocument.c"
1058 #include "jni/pdfgraftmap.c"
1059 #include "jni/pdfobject.c"
1060 #include "jni/pdfpage.c"
1061 #include "jni/pdfwidget.c"
1062 #include "jni/pixmap.c"
1063 #include "jni/pkcs7signer.c"
1064 #include "jni/pkcs7verifier.c"
1065 #include "jni/rect.c"
1066 #include "jni/shade.c"
1067 #include "jni/strokestate.c"
1068 #include "jni/structuredtext.c"
1069 #include "jni/text.c"
1070 
1071 #ifdef HAVE_ANDROID
1072 #include "jni/android/androiddrawdevice.c"
1073 #include "jni/android/androidimage.c"
1074 #endif
1075