filter-jbig2.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // Copyright (C) 2004-2021 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. #include "mupdf/fitz.h"
  23. #include <jbig2.h>
  24. typedef struct
  25. {
  26. Jbig2Allocator alloc;
  27. fz_context *ctx;
  28. } fz_jbig2_allocators;
  29. struct fz_jbig2_globals
  30. {
  31. fz_storable storable;
  32. Jbig2GlobalCtx *gctx;
  33. fz_jbig2_allocators alloc;
  34. fz_buffer *data;
  35. };
  36. typedef struct
  37. {
  38. fz_stream *chain;
  39. Jbig2Ctx *ctx;
  40. fz_jbig2_allocators alloc;
  41. fz_jbig2_globals *gctx;
  42. Jbig2Image *page;
  43. int idx;
  44. unsigned char buffer[4096];
  45. } fz_jbig2d;
  46. fz_jbig2_globals *
  47. fz_keep_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals)
  48. {
  49. return fz_keep_storable(ctx, &globals->storable);
  50. }
  51. void
  52. fz_drop_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals)
  53. {
  54. fz_drop_storable(ctx, &globals->storable);
  55. }
  56. static void
  57. close_jbig2d(fz_context *ctx, void *state_)
  58. {
  59. fz_jbig2d *state = state_;
  60. if (state->page)
  61. jbig2_release_page(state->ctx, state->page);
  62. fz_drop_jbig2_globals(ctx, state->gctx);
  63. jbig2_ctx_free(state->ctx);
  64. fz_drop_stream(ctx, state->chain);
  65. fz_free(ctx, state);
  66. }
  67. static int
  68. next_jbig2d(fz_context *ctx, fz_stream *stm, size_t len)
  69. {
  70. fz_jbig2d *state = stm->state;
  71. unsigned char tmp[4096];
  72. unsigned char *buf = state->buffer;
  73. unsigned char *p = buf;
  74. unsigned char *ep;
  75. unsigned char *s;
  76. int x, w;
  77. size_t n;
  78. if (len > sizeof(state->buffer))
  79. len = sizeof(state->buffer);
  80. ep = buf + len;
  81. if (!state->page)
  82. {
  83. while (1)
  84. {
  85. n = fz_read(ctx, state->chain, tmp, sizeof tmp);
  86. if (n == 0)
  87. break;
  88. if (jbig2_data_in(state->ctx, tmp, n) < 0)
  89. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot decode jbig2 image");
  90. }
  91. if (jbig2_complete_page(state->ctx) < 0)
  92. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot complete jbig2 image");
  93. state->page = jbig2_page_out(state->ctx);
  94. if (!state->page)
  95. fz_throw(ctx, FZ_ERROR_LIBRARY, "no jbig2 image decoded");
  96. }
  97. s = state->page->data;
  98. w = state->page->height * state->page->stride;
  99. x = state->idx;
  100. while (p < ep && x < w)
  101. *p++ = s[x++] ^ 0xff;
  102. state->idx = x;
  103. stm->rp = buf;
  104. stm->wp = p;
  105. if (p == buf)
  106. return EOF;
  107. stm->pos += p - buf;
  108. return *stm->rp++;
  109. }
  110. static void
  111. error_callback(void *data, const char *msg, Jbig2Severity severity, uint32_t seg_idx)
  112. {
  113. fz_context *ctx = data;
  114. if (severity == JBIG2_SEVERITY_FATAL)
  115. fz_warn(ctx, "jbig2dec error: %s (segment %u)", msg, seg_idx);
  116. else if (severity == JBIG2_SEVERITY_WARNING)
  117. fz_warn(ctx, "jbig2dec warning: %s (segment %u)", msg, seg_idx);
  118. #ifdef JBIG2_DEBUG
  119. else if (severity == JBIG2_SEVERITY_INFO)
  120. fz_warn(ctx, "jbig2dec info: %s (segment %u)", msg, seg_idx);
  121. else if (severity == JBIG2_SEVERITY_DEBUG)
  122. fz_warn(ctx, "jbig2dec debug: %s (segment %u)", msg, seg_idx);
  123. #endif
  124. }
  125. static void *fz_jbig2_alloc(Jbig2Allocator *allocator, size_t size)
  126. {
  127. fz_context *ctx = ((fz_jbig2_allocators *) allocator)->ctx;
  128. return Memento_label(fz_malloc_no_throw(ctx, size), "jbig2_alloc");
  129. }
  130. static void fz_jbig2_free(Jbig2Allocator *allocator, void *p)
  131. {
  132. fz_context *ctx = ((fz_jbig2_allocators *) allocator)->ctx;
  133. fz_free(ctx, p);
  134. }
  135. static void *fz_jbig2_realloc(Jbig2Allocator *allocator, void *p, size_t size)
  136. {
  137. fz_context *ctx = ((fz_jbig2_allocators *) allocator)->ctx;
  138. if (size == 0)
  139. {
  140. fz_free(ctx, p);
  141. return NULL;
  142. }
  143. if (p == NULL)
  144. return Memento_label(fz_malloc(ctx, size), "jbig2_realloc");
  145. return Memento_label(fz_realloc_no_throw(ctx, p, size), "jbig2_realloc");
  146. }
  147. fz_jbig2_globals *
  148. fz_load_jbig2_globals(fz_context *ctx, fz_buffer *buf)
  149. {
  150. fz_jbig2_globals *globals;
  151. Jbig2Ctx *jctx;
  152. if (buf == NULL || buf->data == NULL || buf->len == 0)
  153. return NULL;
  154. globals = fz_malloc_struct(ctx, fz_jbig2_globals);
  155. globals->alloc.ctx = ctx;
  156. globals->alloc.alloc.alloc = fz_jbig2_alloc;
  157. globals->alloc.alloc.free = fz_jbig2_free;
  158. globals->alloc.alloc.realloc = fz_jbig2_realloc;
  159. jctx = jbig2_ctx_new((Jbig2Allocator *) &globals->alloc, JBIG2_OPTIONS_EMBEDDED, NULL, error_callback, ctx);
  160. if (!jctx)
  161. {
  162. fz_free(ctx, globals);
  163. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot allocate jbig2 globals context");
  164. }
  165. if (jbig2_data_in(jctx, buf->data, buf->len) < 0)
  166. {
  167. jbig2_global_ctx_free(jbig2_make_global_ctx(jctx));
  168. fz_free(ctx, globals);
  169. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot decode jbig2 globals");
  170. }
  171. FZ_INIT_STORABLE(globals, 1, fz_drop_jbig2_globals_imp);
  172. globals->gctx = jbig2_make_global_ctx(jctx);
  173. globals->data = fz_keep_buffer(ctx, buf);
  174. return globals;
  175. }
  176. void
  177. fz_drop_jbig2_globals_imp(fz_context *ctx, fz_storable *globals_)
  178. {
  179. fz_jbig2_globals *globals = (fz_jbig2_globals *)globals_;
  180. globals->alloc.ctx = ctx;
  181. jbig2_global_ctx_free(globals->gctx);
  182. fz_drop_buffer(ctx, globals->data);
  183. fz_free(ctx, globals);
  184. }
  185. fz_stream *
  186. fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals, int embedded)
  187. {
  188. fz_jbig2d *state = NULL;
  189. Jbig2Options options;
  190. fz_var(state);
  191. state = fz_malloc_struct(ctx, fz_jbig2d);
  192. state->gctx = fz_keep_jbig2_globals(ctx, globals);
  193. state->alloc.ctx = ctx;
  194. state->alloc.alloc.alloc = fz_jbig2_alloc;
  195. state->alloc.alloc.free = fz_jbig2_free;
  196. state->alloc.alloc.realloc = fz_jbig2_realloc;
  197. options = 0;
  198. if (embedded)
  199. options |= JBIG2_OPTIONS_EMBEDDED;
  200. state->ctx = jbig2_ctx_new((Jbig2Allocator *) &state->alloc, options, globals ? globals->gctx : NULL, error_callback, ctx);
  201. if (state->ctx == NULL)
  202. {
  203. fz_drop_jbig2_globals(ctx, state->gctx);
  204. fz_free(ctx, state);
  205. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot allocate jbig2 context");
  206. }
  207. state->page = NULL;
  208. state->idx = 0;
  209. state->chain = fz_keep_stream(ctx, chain);
  210. return fz_new_stream(ctx, state, next_jbig2d, close_jbig2d);
  211. }
  212. fz_buffer *
  213. fz_jbig2_globals_data(fz_context *ctx, fz_jbig2_globals *globals)
  214. {
  215. return globals ? globals->data : NULL;
  216. }