1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* jbig2decode filter implementation -- hooks in libjbig2dec */
18 
19 #include "stdint_.h"
20 #include "memory_.h"
21 #include "stdio_.h" /* sprintf() for debug output */
22 
23 #include "gserrors.h"
24 #include "gdebug.h"
25 #include "strimpl.h"
26 #include "sjbig2.h"
27 #include <limits.h>                     /* UINT_MAX */
28 
29 /* stream implementation */
30 
31 /* The /JBIG2Decode filter is a fairly memory intensive one to begin with,
32    particularly in the initial jbig2dec library implementation. Furthermore,
33    as a PDF 1.4 feature, we can assume a fairly large (host-level) machine.
34    We therefore dispense with the normal Ghostscript memory discipline and
35    let the library allocate all its resources on the heap. The pointers to
36    these are not enumerated and so will not be garbage collected. We rely
37    on our release() proc being called to deallocate state.
38  */
39 
40 private_st_jbig2decode_state();	/* creates a gc object for our state, defined in sjbig2.h */
41 
42 /* error callback for jbig2 decoder */
43 static void
s_jbig2decode_error(void * callback_data,const char * msg,Jbig2Severity severity,int32_t seg_idx)44 s_jbig2decode_error(void *callback_data, const char *msg, Jbig2Severity severity,
45                int32_t seg_idx)
46 {
47     s_jbig2_callback_data_t *error_data = (s_jbig2_callback_data_t *)callback_data;
48     const char *type;
49     char segment[22];
50 
51     switch (severity) {
52         case JBIG2_SEVERITY_DEBUG:
53             type = "DEBUG"; break;;
54         case JBIG2_SEVERITY_INFO:
55             type = "info"; break;;
56         case JBIG2_SEVERITY_WARNING:
57             type = "WARNING"; break;;
58         case JBIG2_SEVERITY_FATAL:
59             type = "FATAL ERROR decoding image:";
60             /* pass the fatal error upstream if possible */
61             if (error_data != NULL) error_data->error = gs_error_ioerror;
62             break;;
63         default: type = "unknown message:"; break;;
64     }
65     if (seg_idx == -1) segment[0] = '\0';
66     else gs_sprintf(segment, "(segment 0x%02x)", seg_idx);
67 
68     if (error_data)
69     {
70         char *message;
71         int len;
72 
73         len = snprintf(NULL, 0, "jbig2dec %s %s %s", type, msg, segment);
74         if (len < 0)
75             return;
76 
77         message = (char *)gs_alloc_bytes(error_data->memory, len + 1, "sjbig2decode_error(message)");
78         if (message == NULL)
79             return;
80 
81         len = snprintf(message, len + 1, "jbig2dec %s %s %s", type, msg, segment);
82         if (len < 0)
83         {
84             gs_free_object(error_data->memory, message, "s_jbig2decode_error(message)");
85             return;
86         }
87 
88         if (error_data->last_message != NULL && strcmp(message, error_data->last_message)) {
89             if (error_data->repeats > 1)
90             {
91                 if (error_data->severity == JBIG2_SEVERITY_FATAL || error_data->severity == JBIG2_SEVERITY_WARNING) {
92                     dmlprintf1(error_data->memory, "jbig2dec last message repeated %ld times\n", error_data->repeats);
93                 } else {
94                     if_debug1m('w', error_data->memory, "[w] jbig2dec last message repeated %ld times\n", error_data->repeats);
95                 }
96             }
97             gs_free_object(error_data->memory, error_data->last_message, "s_jbig2decode_error(last_message)");
98             if (severity == JBIG2_SEVERITY_FATAL || severity == JBIG2_SEVERITY_WARNING) {
99                 dmlprintf1(error_data->memory, "%s\n", message);
100             } else {
101                 if_debug1m('w', error_data->memory, "[w] %s\n", message);
102             }
103             error_data->last_message = message;
104             error_data->severity = severity;
105             error_data->type = type;
106             error_data->repeats = 0;
107         }
108         else if (error_data->last_message != NULL) {
109             error_data->repeats++;
110             if (error_data->repeats % 1000000 == 0)
111             {
112                 if (error_data->severity == JBIG2_SEVERITY_FATAL || error_data->severity == JBIG2_SEVERITY_WARNING) {
113                     dmlprintf1(error_data->memory, "jbig2dec last message repeated %ld times so far\n", error_data->repeats);
114                 } else {
115                     if_debug1m('w', error_data->memory, "[w] jbig2dec last message repeated %ld times so far\n", error_data->repeats);
116                 }
117             }
118             gs_free_object(error_data->memory, message, "s_jbig2decode_error(message)");
119         }
120         else if (error_data->last_message == NULL) {
121             if (severity == JBIG2_SEVERITY_FATAL || severity == JBIG2_SEVERITY_WARNING) {
122                 dmlprintf1(error_data->memory, "%s\n", message);
123             } else {
124                 if_debug1m('w', error_data->memory, "[w] %s\n", message);
125             }
126             error_data->last_message = message;
127             error_data->severity = severity;
128             error_data->type = type;
129             error_data->repeats = 0;
130         }
131     }
132     else
133     {
134 /*
135         FIXME s_jbig2_callback_data_t should be updated so that jbig2_ctx_new is not called
136         with a NULL argument (see jbig2.h) and we never reach here with a NULL state
137 */
138         if (severity == JBIG2_SEVERITY_FATAL) {
139             dlprintf3("jbig2dec %s %s %s\n", type, msg, segment);
140         } else {
141             if_debug3('w', "[w] jbig2dec %s %s %s\n", type, msg, segment);
142         }
143     }
144 }
145 
146 static void
s_jbig2decode_flush_errors(void * callback_data)147 s_jbig2decode_flush_errors(void *callback_data)
148 {
149     s_jbig2_callback_data_t *error_data = (s_jbig2_callback_data_t *)callback_data;
150 
151     if (error_data == NULL)
152         return;
153 
154     if (error_data->last_message != NULL) {
155         if (error_data->repeats > 1)
156         {
157             if (error_data->severity == JBIG2_SEVERITY_FATAL || error_data->severity == JBIG2_SEVERITY_WARNING) {
158                 dmlprintf1(error_data->memory, "jbig2dec last message repeated %ld times\n", error_data->repeats);
159             } else {
160                 if_debug1m('w', error_data->memory, "[w] jbig2dec last message repeated %ld times\n", error_data->repeats);
161             }
162         }
163         gs_free_object(error_data->memory, error_data->last_message, "s_jbig2decode_error(last_message)");
164         error_data->last_message = NULL;
165         error_data->repeats = 0;
166     }
167 }
168 
169 /* invert the bits in a buffer */
170 /* jbig2 and postscript have different senses of what pixel
171    value is black, so we must invert the image */
172 static void
s_jbig2decode_invert_buffer(unsigned char * buf,int length)173 s_jbig2decode_invert_buffer(unsigned char *buf, int length)
174 {
175     int i;
176 
177     for (i = 0; i < length; i++)
178         *buf++ ^= 0xFF;
179 }
180 
181 typedef struct {
182         Jbig2Allocator allocator;
183         gs_memory_t *mem;
184 } s_jbig2decode_allocator_t;
185 
s_jbig2decode_alloc(Jbig2Allocator * _allocator,size_t size)186 static void *s_jbig2decode_alloc(Jbig2Allocator *_allocator, size_t size)
187 {
188         s_jbig2decode_allocator_t *allocator = (s_jbig2decode_allocator_t *) _allocator;
189         if (size > UINT_MAX)
190             return NULL;
191         return gs_alloc_bytes(allocator->mem, size, "s_jbig2decode_alloc");
192 }
193 
s_jbig2decode_free(Jbig2Allocator * _allocator,void * p)194 static void s_jbig2decode_free(Jbig2Allocator *_allocator, void *p)
195 {
196         s_jbig2decode_allocator_t *allocator = (s_jbig2decode_allocator_t *) _allocator;
197         gs_free_object(allocator->mem, p, "s_jbig2decode_free");
198 }
199 
s_jbig2decode_realloc(Jbig2Allocator * _allocator,void * p,size_t size)200 static void *s_jbig2decode_realloc(Jbig2Allocator *_allocator, void *p, size_t size)
201 {
202         s_jbig2decode_allocator_t *allocator = (s_jbig2decode_allocator_t *) _allocator;
203         if (size > UINT_MAX)
204             return NULL;
205         return gs_resize_object(allocator->mem, p, size, "s_jbig2decode_realloc");
206 }
207 
208 /* parse a globals stream packed into a gs_bytestring for us by the postscript
209    layer and stuff the resulting context into a pointer for use in later decoding */
210 int
s_jbig2decode_make_global_data(gs_memory_t * mem,byte * data,uint length,void ** result)211 s_jbig2decode_make_global_data(gs_memory_t *mem, byte *data, uint length, void **result)
212 {
213     Jbig2Ctx *ctx = NULL;
214     int code;
215     s_jbig2decode_allocator_t *allocator;
216 
217     /* the cvision encoder likes to include empty global streams */
218     if (length == 0) {
219         if_debug0('w', "[w] ignoring zero-length jbig2 global stream.\n");
220         *result = NULL;
221         return 0;
222     }
223 
224     allocator = (s_jbig2decode_allocator_t *) gs_alloc_bytes(mem,
225             sizeof (s_jbig2decode_allocator_t), "s_jbig2_make_global_data");
226     if (allocator == NULL) {
227         *result = NULL;
228         return_error(gs_error_VMerror);
229     }
230 
231     allocator->allocator.alloc = s_jbig2decode_alloc;
232     allocator->allocator.free = s_jbig2decode_free;
233     allocator->allocator.realloc = s_jbig2decode_realloc;
234     allocator->mem = mem;
235 
236     /* allocate a context with which to parse our global segments */
237     ctx = jbig2_ctx_new((Jbig2Allocator *) allocator, JBIG2_OPTIONS_EMBEDDED,
238                             NULL, s_jbig2decode_error, NULL);
239     if (ctx == NULL) {
240         gs_free_object(mem, allocator, "s_jbig2_make_global_data");
241         return_error(gs_error_VMerror);
242     }
243 
244     /* parse the global bitstream */
245     code = jbig2_data_in(ctx, data, length);
246     if (code) {
247         /* error parsing the global stream */
248         allocator = (s_jbig2decode_allocator_t *) jbig2_ctx_free(ctx);
249         gs_free_object(allocator->mem, allocator, "s_jbig2_make_global_data");
250         *result = NULL;
251         return_error(gs_error_ioerror);
252     }
253 
254     /* canonize and store our global state */
255     *result = jbig2_make_global_ctx(ctx);
256 
257     return 0; /* todo: check for allocation failure */
258 }
259 
260 /* release a global ctx pointer */
261 void
s_jbig2decode_free_global_data(void * data)262 s_jbig2decode_free_global_data(void *data)
263 {
264     Jbig2GlobalCtx *global_ctx = (Jbig2GlobalCtx*)data;
265     s_jbig2decode_allocator_t *allocator;
266 
267     allocator = (s_jbig2decode_allocator_t *) jbig2_global_ctx_free(global_ctx);
268 
269     gs_free_object(allocator->mem, allocator, "s_jbig2decode_free_global_data");
270 }
271 
272 /* store a global ctx pointer in our state structure.
273  * If "gd" is NULL, then this library must free the global context.
274  * If not-NULL, then it will be memory managed by caller, for example,
275  * garbage collected in the case of the PS interpreter.
276  * Currently gpdf will use NULL, and the PDF implemented in the gs interpreter would use
277  * the garbage collection.
278  */
279 int
s_jbig2decode_set_global_data(stream_state * ss,s_jbig2_global_data_t * gd,void * global_ctx)280 s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gd, void *global_ctx)
281 {
282     stream_jbig2decode_state *state = (stream_jbig2decode_state*)ss;
283     state->global_struct = gd;
284     state->global_ctx = global_ctx;
285     return 0;
286 }
287 
288 /* initialize the steam.
289    this involves allocating the context structures, and
290    initializing the global context from the /JBIG2Globals object reference
291  */
292 static int
s_jbig2decode_init(stream_state * ss)293 s_jbig2decode_init(stream_state * ss)
294 {
295     stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss;
296     Jbig2GlobalCtx *global_ctx = state->global_ctx; /* may be NULL */
297     int code = 0;
298     s_jbig2decode_allocator_t *allocator = NULL;
299 
300     state->callback_data = (s_jbig2_callback_data_t *)gs_alloc_bytes(
301                                                 ss->memory->non_gc_memory,
302                                                 sizeof(s_jbig2_callback_data_t),
303 						"s_jbig2decode_init(callback_data)");
304     if (state->callback_data) {
305         state->callback_data->memory = ss->memory->non_gc_memory;
306         state->callback_data->error = 0;
307         state->callback_data->last_message = NULL;
308         state->callback_data->repeats = 0;
309 
310         allocator = (s_jbig2decode_allocator_t *) gs_alloc_bytes(ss->memory->non_gc_memory, sizeof (s_jbig2decode_allocator_t), "s_jbig2decode_init(allocator)");
311         if (allocator == NULL) {
312                 s_jbig2decode_error(state->callback_data, "failed to allocate custom jbig2dec allocator", JBIG2_SEVERITY_FATAL, -1);
313         }
314         else {
315                 allocator->allocator.alloc = s_jbig2decode_alloc;
316                 allocator->allocator.free = s_jbig2decode_free;
317                 allocator->allocator.realloc = s_jbig2decode_realloc;
318                 allocator->mem = ss->memory->non_gc_memory;
319 
320                 /* initialize the decoder with the parsed global context if any */
321                 state->decode_ctx = jbig2_ctx_new((Jbig2Allocator *) allocator, JBIG2_OPTIONS_EMBEDDED,
322                              global_ctx, s_jbig2decode_error, state->callback_data);
323 
324                 if (state->decode_ctx == NULL) {
325                         gs_free_object(allocator->mem, allocator, "s_jbig2decode_release");
326                 }
327 
328         }
329 
330         code = state->callback_data->error;
331     }
332     else {
333         code = gs_error_VMerror;
334     }
335     state->image = 0;
336 
337 
338     return_error (code);
339 }
340 
341 /* process a section of the input and return any decoded data.
342    see strimpl.h for return codes.
343  */
344 static int
s_jbig2decode_process(stream_state * ss,stream_cursor_read * pr,stream_cursor_write * pw,bool last)345 s_jbig2decode_process(stream_state * ss, stream_cursor_read * pr,
346                   stream_cursor_write * pw, bool last)
347 {
348     stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss;
349     Jbig2Image *image = state->image;
350     long in_size = pr->limit - pr->ptr;
351     long out_size = pw->limit - pw->ptr;
352     int status = 0;
353 
354     /* there will only be a single page image,
355        so pass all data in before looking for any output.
356        note that the gs stream library expects offset-by-one
357        indexing of the buffers, while jbig2dec uses normal 0 indexes */
358     if (in_size > 0) {
359         /* pass all available input to the decoder */
360         jbig2_data_in(state->decode_ctx, pr->ptr + 1, in_size);
361         pr->ptr += in_size;
362         /* simulate end-of-page segment */
363         if (last == 1) {
364             jbig2_complete_page(state->decode_ctx);
365         }
366         /* handle fatal decoding errors reported through our callback */
367         if (state->callback_data->error) return state->callback_data->error;
368     }
369     if (out_size > 0) {
370         if (image == NULL) {
371             /* see if a page image in available */
372             image = jbig2_page_out(state->decode_ctx);
373             if (image != NULL) {
374                 state->image = image;
375                 state->offset = 0;
376             }
377         }
378         if (image != NULL) {
379             /* copy data out of the decoded image, if any */
380             long image_size = image->height*image->stride;
381             long usable = min(image_size - state->offset, out_size);
382             memcpy(pw->ptr + 1, image->data + state->offset, usable);
383             s_jbig2decode_invert_buffer(pw->ptr + 1, usable);
384             state->offset += usable;
385             pw->ptr += usable;
386             status = (state->offset < image_size) ? 1 : 0;
387         }
388     }
389 
390     return status;
391 }
392 
393 /* stream release.
394    free all our decoder state.
395  */
396 static void
s_jbig2decode_release(stream_state * ss)397 s_jbig2decode_release(stream_state *ss)
398 {
399     stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss;
400 
401     if (state->decode_ctx) {
402         s_jbig2decode_allocator_t *allocator = NULL;
403 
404         if (state->image) jbig2_release_page(state->decode_ctx, state->image);
405 	state->image = NULL;
406         s_jbig2decode_flush_errors(state->callback_data);
407         allocator = (s_jbig2decode_allocator_t *) jbig2_ctx_free(state->decode_ctx);
408 	state->decode_ctx = NULL;
409 
410         gs_free_object(allocator->mem, allocator, "s_jbig2decode_release");
411     }
412     if (state->callback_data) {
413         gs_memory_t *mem = state->callback_data->memory;
414         gs_free_object(state->callback_data->memory, state->callback_data->last_message, "s_jbig2decode_release(message)");
415         gs_free_object(mem, state->callback_data, "s_jbig2decode_release(callback_data)");
416 	state->callback_data = NULL;
417     }
418     if (state->global_struct != NULL) {
419         /* the interpreter calls jbig2decode_free_global_data() separately */
420     } else {
421         /* We are responsible for freeing global context */
422         if (state->global_ctx) {
423             s_jbig2decode_free_global_data(state->global_ctx);
424             state->global_ctx = NULL;
425         }
426     }
427 }
428 
429 void
s_jbig2decode_finalize(const gs_memory_t * cmem,void * vptr)430 s_jbig2decode_finalize(const gs_memory_t *cmem, void *vptr)
431 {
432     (void)cmem;
433 
434     s_jbig2decode_release((stream_state *)vptr);
435 }
436 
437 /* set stream defaults.
438    this hook exists to avoid confusing the gc with bogus
439    pointers. we use it similarly just to NULL all the pointers.
440    (could just be done in _init?)
441  */
442 static void
s_jbig2decode_set_defaults(stream_state * ss)443 s_jbig2decode_set_defaults(stream_state *ss)
444 {
445     stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss;
446 
447     /* state->global_ctx is not owned by us */
448     state->global_struct = NULL;
449     state->global_ctx = NULL;
450     state->decode_ctx = NULL;
451     state->image = NULL;
452     state->offset = 0;
453     state->callback_data = NULL;
454 }
455 
456 /* stream template */
457 const stream_template s_jbig2decode_template = {
458     &st_jbig2decode_state,
459     s_jbig2decode_init,
460     s_jbig2decode_process,
461     1, 1, /* min in and out buffer sizes we can handle --should be ~32k,64k for efficiency? */
462     s_jbig2decode_release,
463     s_jbig2decode_set_defaults
464 };
465