]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/blob - QRScanner/mobile/jni/thirdparty/jbig2dec/jbig2.c
Add MuPDF native source codes
[hornmich/skoda-qr-demo.git] / QRScanner / mobile / jni / thirdparty / jbig2dec / jbig2.c
1 /* Copyright (C) 2001-2012 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.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16 /*
17     jbig2dec
18 */
19
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include "os_types.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <string.h>
30
31 #include "jbig2.h"
32 #include "jbig2_priv.h"
33
34 static void *
35 jbig2_default_alloc (Jbig2Allocator *allocator, size_t size)
36 {
37   return malloc (size);
38 }
39
40 static void
41 jbig2_default_free (Jbig2Allocator *allocator, void *p)
42 {
43   free (p);
44 }
45
46 static void *
47 jbig2_default_realloc (Jbig2Allocator *allocator, void *p, size_t size)
48 {
49   return realloc (p, size);
50 }
51
52 static Jbig2Allocator jbig2_default_allocator =
53 {
54   jbig2_default_alloc,
55   jbig2_default_free,
56   jbig2_default_realloc
57 };
58
59 void *
60 jbig2_alloc (Jbig2Allocator *allocator, size_t size, size_t num)
61 {
62   /* check for integer multiplication overflow */
63   if (num > 0 && size >= (size_t)-0x100 / num)
64     return NULL;
65   return allocator->alloc(allocator, size * num);
66 }
67
68 void
69 jbig2_free (Jbig2Allocator *allocator, void *p)
70 {
71   allocator->free (allocator, p);
72 }
73
74 void *
75 jbig2_realloc (Jbig2Allocator *allocator, void *p, size_t size, size_t num)
76 {
77   /* check for integer multiplication overflow */
78   if (num > 0 && size >= (size_t)-0x100 / num)
79     return NULL;
80   return allocator->realloc(allocator, p, size * num);
81 }
82
83 static int
84 jbig2_default_error(void *data, const char *msg,
85                     Jbig2Severity severity, int32_t seg_idx)
86 {
87     /* report only fatal errors by default */
88     if (severity == JBIG2_SEVERITY_FATAL) {
89         fprintf(stderr, "jbig2 decoder FATAL ERROR: %s", msg);
90         if (seg_idx != -1) fprintf(stderr, " (segment 0x%02x)", seg_idx);
91         fprintf(stderr, "\n");
92         fflush(stderr);
93     }
94
95     return 0;
96 }
97
98 int
99 jbig2_error(Jbig2Ctx *ctx, Jbig2Severity severity, int32_t segment_number,
100              const char *fmt, ...)
101 {
102   char buf[1024];
103   va_list ap;
104   int n;
105   int code;
106
107   va_start (ap, fmt);
108   n = vsnprintf (buf, sizeof(buf), fmt, ap);
109   va_end (ap);
110   if (n < 0 || n == sizeof(buf))
111     strncpy (buf, "jbig2_error: error in generating error string", sizeof(buf));
112   code = ctx->error_callback (ctx->error_callback_data, buf, severity, segment_number);
113   if (severity == JBIG2_SEVERITY_FATAL)
114     code = -1;
115   return code;
116 }
117
118 Jbig2Ctx *
119 jbig2_ctx_new (Jbig2Allocator *allocator,
120                Jbig2Options options,
121                Jbig2GlobalCtx *global_ctx,
122                Jbig2ErrorCallback error_callback,
123                void *error_callback_data)
124 {
125   Jbig2Ctx *result;
126
127   if (allocator == NULL)
128       allocator = &jbig2_default_allocator;
129   if (error_callback == NULL)
130       error_callback = &jbig2_default_error;
131
132   result = (Jbig2Ctx*)jbig2_alloc(allocator, sizeof(Jbig2Ctx), 1);
133   if (result == NULL) {
134     error_callback(error_callback_data, "initial context allocation failed!",
135                     JBIG2_SEVERITY_FATAL, -1);
136     return result;
137   }
138
139   result->allocator = allocator;
140   result->options = options;
141   result->global_ctx = (const Jbig2Ctx *)global_ctx;
142   result->error_callback = error_callback;
143   result->error_callback_data = error_callback_data;
144
145   result->state = (options & JBIG2_OPTIONS_EMBEDDED) ?
146     JBIG2_FILE_SEQUENTIAL_HEADER :
147     JBIG2_FILE_HEADER;
148
149   result->buf = NULL;
150
151   result->n_segments = 0;
152   result->n_segments_max = 16;
153   result->segments = jbig2_new(result, Jbig2Segment*, result->n_segments_max);
154   if (result->segments == NULL) {
155     error_callback(error_callback_data, "initial segments allocation failed!",
156         JBIG2_SEVERITY_FATAL, -1);
157     jbig2_free(allocator, result);
158     return result;
159   }
160   result->segment_index = 0;
161
162   result->current_page = 0;
163   result->max_page_index = 4;
164   result->pages = jbig2_new(result, Jbig2Page, result->max_page_index);
165   if (result->pages == NULL) {
166     error_callback(error_callback_data, "initial pages allocation failed!",
167         JBIG2_SEVERITY_FATAL, -1);
168     jbig2_free(allocator, result->segments);
169     jbig2_free(allocator, result);
170     return result;
171   }
172   {
173     int index;
174     for (index = 0; index < result->max_page_index; index++) {
175         result->pages[index].state = JBIG2_PAGE_FREE;
176         result->pages[index].number = 0;
177         result->pages[index].image = NULL;
178     }
179   }
180
181   return result;
182 }
183
184 #define get_uint16(bptr)\
185   (((bptr)[0] << 8) | (bptr)[1])
186 #define get_int16(bptr)\
187   (((int)get_uint16(bptr) ^ 0x8000) - 0x8000)
188
189 int16_t
190 jbig2_get_int16(const byte *bptr)
191 {       
192     return get_int16(bptr);
193 }
194
195 uint16_t
196 jbig2_get_uint16(const byte *bptr)
197 {       
198     return get_uint16(bptr);
199 }
200
201 int32_t
202 jbig2_get_int32(const byte *bptr)
203 {       
204     return ((int32_t)get_int16(bptr) << 16) | get_uint16(bptr + 2);
205 }
206
207 uint32_t
208 jbig2_get_uint32(const byte *bptr)
209 {       
210     return ((uint32_t)get_uint16(bptr) << 16) | get_uint16(bptr + 2);
211 }
212
213
214 /**
215  * jbig2_data_in: submit data for decoding
216  * @ctx: The jbig2dec decoder context
217  * @data: a pointer to the data buffer
218  * @size: the size of the data buffer in bytes
219  *
220  * Copies the specified data into internal storage and attempts
221  * to (continue to) parse it as part of a jbig2 data stream.
222  *
223  * Return code: 0 on success
224  *             -1 if there is a parsing error, or whatever
225  *                the error handling callback returns
226  **/
227 int
228 jbig2_data_in (Jbig2Ctx *ctx, const unsigned char *data, size_t size)
229 {
230   const size_t initial_buf_size = 1024;
231
232   if (ctx->buf == NULL)
233     {
234       size_t buf_size = initial_buf_size;
235
236       do
237         buf_size <<= 1;
238       while (buf_size < size);
239       ctx->buf = jbig2_new(ctx, byte, buf_size);
240       if (ctx->buf == NULL)
241       {
242           return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
243               "failed to allocate ctx->buf in jbig2_data_in");
244       }
245       ctx->buf_size = buf_size;
246       ctx->buf_rd_ix = 0;
247       ctx->buf_wr_ix = 0;
248     }
249   else if (ctx->buf_wr_ix + size > ctx->buf_size)
250     {
251       if (ctx->buf_rd_ix <= (ctx->buf_size >> 1) &&
252           ctx->buf_wr_ix - ctx->buf_rd_ix + size <= ctx->buf_size)
253         {
254           memmove(ctx->buf, ctx->buf + ctx->buf_rd_ix,
255                   ctx->buf_wr_ix - ctx->buf_rd_ix);
256         }
257       else
258         {
259           byte *buf;
260           size_t buf_size = initial_buf_size;
261
262           do
263             buf_size <<= 1;
264           while (buf_size < ctx->buf_wr_ix - ctx->buf_rd_ix + size);
265           buf = jbig2_new(ctx, byte, buf_size);
266       if (buf == NULL)
267       {
268           return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
269               "failed to allocate buf in jbig2_data_in");
270       }
271           memcpy(buf, ctx->buf + ctx->buf_rd_ix,
272                   ctx->buf_wr_ix - ctx->buf_rd_ix);
273           jbig2_free(ctx->allocator, ctx->buf);
274           ctx->buf = buf;
275           ctx->buf_size = buf_size;
276         }
277       ctx->buf_wr_ix -= ctx->buf_rd_ix;
278       ctx->buf_rd_ix = 0;
279     }
280   memcpy(ctx->buf + ctx->buf_wr_ix, data, size);
281   ctx->buf_wr_ix += size;
282
283   /* data has now been added to buffer */
284
285   for (;;)
286     {
287       const byte jbig2_id_string[8] = { 0x97, 0x4a, 0x42, 0x32, 0x0d, 0x0a, 0x1a, 0x0a };
288       Jbig2Segment *segment;
289       size_t header_size;
290       int code;
291
292       switch (ctx->state)
293         {
294         case JBIG2_FILE_HEADER:
295           /* D.4.1 */
296           if (ctx->buf_wr_ix - ctx->buf_rd_ix < 9)
297             return 0;
298           if (memcmp(ctx->buf + ctx->buf_rd_ix, jbig2_id_string, 8))
299             return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
300                                "Not a JBIG2 file header");
301           /* D.4.2 */
302           ctx->file_header_flags = ctx->buf[ctx->buf_rd_ix + 8];
303           if (ctx->file_header_flags & 0xFC) {
304             jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
305                 "reserved bits (2-7) of file header flags are not zero (0x%02x)", ctx->file_header_flags);
306           }
307           /* D.4.3 */
308           if (!(ctx->file_header_flags & 2)) /* number of pages is known */
309             {
310               if (ctx->buf_wr_ix - ctx->buf_rd_ix < 13)
311                 return 0;
312               ctx->n_pages = jbig2_get_uint32(ctx->buf + ctx->buf_rd_ix + 9);
313               ctx->buf_rd_ix += 13;
314               if (ctx->n_pages == 1)
315                 jbig2_error(ctx, JBIG2_SEVERITY_INFO, -1, "file header indicates a single page document");
316               else
317                 jbig2_error(ctx, JBIG2_SEVERITY_INFO, -1, "file header indicates a %d page document", ctx->n_pages);
318             }
319           else /* number of pages not known */
320             {
321               ctx->n_pages=0;
322               ctx->buf_rd_ix += 9;
323             }
324           /* determine the file organization based on the flags - D.4.2 again */
325           if (ctx->file_header_flags & 1)
326             {
327               ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
328               jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "file header indicates sequential organization");
329             }
330           else
331             {
332               ctx->state = JBIG2_FILE_RANDOM_HEADERS;
333               jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1, "file header indicates random-access organization");
334
335             }
336           break;
337         case JBIG2_FILE_SEQUENTIAL_HEADER:
338         case JBIG2_FILE_RANDOM_HEADERS:
339           segment = jbig2_parse_segment_header(ctx, ctx->buf + ctx->buf_rd_ix,
340                                           ctx->buf_wr_ix - ctx->buf_rd_ix,
341                                           &header_size);
342           if (segment == NULL)
343             return 0; /* need more data */
344           ctx->buf_rd_ix += header_size;
345
346           if (ctx->n_segments == ctx->n_segments_max)
347               ctx->segments = jbig2_renew(ctx, ctx->segments, Jbig2Segment*,
348                   (ctx->n_segments_max <<= 2));
349
350           ctx->segments[ctx->n_segments++] = segment;
351           if (ctx->state == JBIG2_FILE_RANDOM_HEADERS)
352             {
353               if ((segment->flags & 63) == 51) /* end of file */
354                 ctx->state = JBIG2_FILE_RANDOM_BODIES;
355             }
356           else /* JBIG2_FILE_SEQUENTIAL_HEADER */
357             ctx->state = JBIG2_FILE_SEQUENTIAL_BODY;
358           break;
359         case JBIG2_FILE_SEQUENTIAL_BODY:
360         case JBIG2_FILE_RANDOM_BODIES:
361           segment = ctx->segments[ctx->segment_index];
362           if (segment->data_length > ctx->buf_wr_ix - ctx->buf_rd_ix)
363             return 0; /* need more data */
364           code = jbig2_parse_segment(ctx, segment, ctx->buf + ctx->buf_rd_ix);
365           ctx->buf_rd_ix += segment->data_length;
366           ctx->segment_index++;
367           if (ctx->state == JBIG2_FILE_RANDOM_BODIES)
368             {
369               if (ctx->segment_index == ctx->n_segments)
370                 ctx->state = JBIG2_FILE_EOF;
371             }
372           else /* JBIG2_FILE_SEQUENCIAL_BODY */
373             {
374               ctx->state = JBIG2_FILE_SEQUENTIAL_HEADER;
375             }
376           if (code < 0)
377             {
378               ctx->state = JBIG2_FILE_EOF;
379               return code;
380             }
381           break;
382         case JBIG2_FILE_EOF:
383           if (ctx->buf_rd_ix == ctx->buf_wr_ix)
384             return 0;
385           return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
386                       "Garbage beyond end of file");
387         }
388     }
389 }
390
391 void
392 jbig2_ctx_free (Jbig2Ctx *ctx)
393 {
394   Jbig2Allocator *ca = ctx->allocator;
395   int i;
396
397   jbig2_free(ca, ctx->buf);
398   if (ctx->segments != NULL) {
399     for (i = 0; i < ctx->n_segments; i++)
400       jbig2_free_segment(ctx, ctx->segments[i]);
401     jbig2_free(ca, ctx->segments);
402   }
403
404   if (ctx->pages != NULL) {
405     for (i = 0; i <= ctx->current_page; i++)
406       if (ctx->pages[i].image != NULL)
407         jbig2_image_release(ctx, ctx->pages[i].image);
408     jbig2_free(ca, ctx->pages);
409   }
410
411   jbig2_free(ca, ctx);
412 }
413
414 Jbig2GlobalCtx *jbig2_make_global_ctx (Jbig2Ctx *ctx)
415 {
416   return (Jbig2GlobalCtx *)ctx;
417 }
418
419 void jbig2_global_ctx_free(Jbig2GlobalCtx *global_ctx)
420 {
421   jbig2_ctx_free((Jbig2Ctx *)global_ctx);
422 }
423
424
425 /* I'm not committed to keeping the word stream interface. It's handy
426    when you think you may be streaming your input, but if you're not
427    (as is currently the case), it just adds complexity.
428 */
429
430 typedef struct {
431   Jbig2WordStream super;
432   const byte *data;
433   size_t size;
434 } Jbig2WordStreamBuf;
435
436 static int
437 jbig2_word_stream_buf_get_next_word(Jbig2WordStream *self, int offset,
438   uint32_t *word)
439 {
440   Jbig2WordStreamBuf *z = (Jbig2WordStreamBuf *)self;
441   const byte *data = z->data;
442   uint32_t result;
443
444   if (offset + 4 < z->size)
445     result = (data[offset] << 24) | (data[offset + 1] << 16) |
446       (data[offset + 2] << 8) | data[offset + 3];
447   else if (offset >= z->size)
448     return -1;
449   else
450     {
451       int i;
452
453       result = 0;
454       for (i = 0; i < z->size - offset; i++)
455         result |= data[offset + i] << ((3 - i) << 3);
456     }
457   *word = result;
458   return 0;
459 }
460
461 Jbig2WordStream *
462 jbig2_word_stream_buf_new(Jbig2Ctx *ctx, const byte *data, size_t size)
463 {
464   Jbig2WordStreamBuf *result = jbig2_new(ctx, Jbig2WordStreamBuf, 1);
465   if (result == NULL)
466   {
467       jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
468           "failed to allocate Jbig2WordStreamBuf in jbig2_word_stream_buf_new");
469       return NULL;
470   }
471
472   result->super.get_next_word = jbig2_word_stream_buf_get_next_word;
473   result->data = data;
474   result->size = size;
475
476   return &result->super;
477 }
478
479 void
480 jbig2_word_stream_buf_free(Jbig2Ctx *ctx, Jbig2WordStream *ws)
481 {
482   jbig2_free(ctx->allocator, ws);
483 }