load-jbig2.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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 "pixmap-imp.h"
  24. #include <jbig2.h>
  25. struct info
  26. {
  27. int width, height;
  28. int xres, yres;
  29. int pages;
  30. fz_colorspace *cspace;
  31. };
  32. struct fz_jbig2_allocator
  33. {
  34. Jbig2Allocator super;
  35. fz_context *ctx;
  36. };
  37. static void
  38. error_callback(void *data, const char *msg, Jbig2Severity severity, uint32_t seg_idx)
  39. {
  40. fz_context *ctx = data;
  41. if (severity == JBIG2_SEVERITY_FATAL)
  42. fz_warn(ctx, "jbig2dec error: %s (segment %u)", msg, seg_idx);
  43. else if (severity == JBIG2_SEVERITY_WARNING)
  44. fz_warn(ctx, "jbig2dec warning: %s (segment %u)", msg, seg_idx);
  45. #ifdef JBIG2_DEBUG
  46. else if (severity == JBIG2_SEVERITY_INFO)
  47. fz_warn(ctx, "jbig2dec info: %s (segment %u)", msg, seg_idx);
  48. else if (severity == JBIG2_SEVERITY_DEBUG)
  49. fz_warn(ctx, "jbig2dec debug: %s (segment %u)", msg, seg_idx);
  50. #endif
  51. }
  52. static void *fz_jbig2_alloc(Jbig2Allocator *allocator, size_t size)
  53. {
  54. fz_context *ctx = ((struct fz_jbig2_allocator *) allocator)->ctx;
  55. return fz_malloc_no_throw(ctx, size);
  56. }
  57. static void fz_jbig2_free(Jbig2Allocator *allocator, void *p)
  58. {
  59. fz_context *ctx = ((struct fz_jbig2_allocator *) allocator)->ctx;
  60. fz_free(ctx, p);
  61. }
  62. static void *fz_jbig2_realloc(Jbig2Allocator *allocator, void *p, size_t size)
  63. {
  64. fz_context *ctx = ((struct fz_jbig2_allocator *) allocator)->ctx;
  65. if (size == 0)
  66. {
  67. fz_free(ctx, p);
  68. return NULL;
  69. }
  70. if (p == NULL)
  71. return Memento_label(fz_malloc(ctx, size), "jbig2_realloc");
  72. return Memento_label(fz_realloc_no_throw(ctx, p, size), "jbig2_realloc");
  73. }
  74. static fz_pixmap *
  75. jbig2_read_image(fz_context *ctx, struct info *jbig2, const unsigned char *buf, size_t len, int only_metadata, int subimage)
  76. {
  77. Jbig2Ctx *jctx = NULL;
  78. Jbig2Image *page = NULL;
  79. struct fz_jbig2_allocator allocator;
  80. fz_pixmap *pix = NULL;
  81. allocator.super.alloc = fz_jbig2_alloc;
  82. allocator.super.free = fz_jbig2_free;
  83. allocator.super.realloc = fz_jbig2_realloc;
  84. allocator.ctx = ctx;
  85. fz_var(jctx);
  86. fz_var(page);
  87. fz_var(pix);
  88. fz_try(ctx)
  89. {
  90. jctx = jbig2_ctx_new((Jbig2Allocator *) &allocator, 0, NULL, error_callback, ctx);
  91. if (jctx == NULL)
  92. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot create jbig2 context");
  93. if (jbig2_data_in(jctx, buf, len) < 0)
  94. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot decode jbig2 image");
  95. if (jbig2_complete_page(jctx) < 0)
  96. fz_throw(ctx, FZ_ERROR_LIBRARY, "cannot complete jbig2 image");
  97. if (only_metadata && subimage < 0)
  98. {
  99. while ((page = jbig2_page_out(jctx)) != NULL)
  100. {
  101. jbig2_release_page(jctx, page);
  102. jbig2->pages++;
  103. }
  104. }
  105. else if (only_metadata && subimage >= 0)
  106. {
  107. while ((page = jbig2_page_out(jctx)) != NULL && subimage > 0)
  108. {
  109. jbig2_release_page(jctx, page);
  110. subimage--;
  111. }
  112. if (page == NULL)
  113. fz_throw(ctx, FZ_ERROR_LIBRARY, "no jbig2 image decoded");
  114. jbig2->cspace = fz_device_gray(ctx);
  115. jbig2->width = page->width;
  116. jbig2->height = page->height;
  117. jbig2->xres = 72;
  118. jbig2->yres = 72;
  119. }
  120. else if (subimage >= 0)
  121. {
  122. while ((page = jbig2_page_out(jctx)) != NULL && subimage > 0)
  123. {
  124. jbig2_release_page(jctx, page);
  125. subimage--;
  126. }
  127. if (page == NULL)
  128. fz_throw(ctx, FZ_ERROR_LIBRARY, "no jbig2 image decoded");
  129. jbig2->cspace = fz_device_gray(ctx);
  130. jbig2->width = page->width;
  131. jbig2->height = page->height;
  132. jbig2->xres = 72;
  133. jbig2->yres = 72;
  134. pix = fz_new_pixmap(ctx, jbig2->cspace, jbig2->width, jbig2->height, NULL, 0);
  135. fz_unpack_tile(ctx, pix, page->data, 1, 1, page->stride, 0);
  136. fz_invert_pixmap(ctx, pix);
  137. }
  138. }
  139. fz_always(ctx)
  140. {
  141. jbig2_release_page(jctx, page);
  142. jbig2_ctx_free(jctx);
  143. }
  144. fz_catch(ctx)
  145. {
  146. fz_drop_pixmap(ctx, pix);
  147. fz_rethrow(ctx);
  148. }
  149. return pix;
  150. }
  151. int
  152. fz_load_jbig2_subimage_count(fz_context *ctx, const unsigned char *buf, size_t len)
  153. {
  154. struct info jbig2 = { 0 };
  155. int subimage_count = 0;
  156. fz_try(ctx)
  157. {
  158. jbig2_read_image(ctx, &jbig2, buf, len, 1, -1);
  159. subimage_count = jbig2.pages;
  160. }
  161. fz_catch(ctx)
  162. fz_rethrow(ctx);
  163. return subimage_count;
  164. }
  165. void
  166. fz_load_jbig2_info_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep, int subimage)
  167. {
  168. struct info jbig2 = { 0 };
  169. jbig2_read_image(ctx, &jbig2, buf, len, 1, subimage);
  170. *cspacep = fz_keep_colorspace(ctx, jbig2.cspace);
  171. *wp = jbig2.width;
  172. *hp = jbig2.height;
  173. *xresp = jbig2.xres;
  174. *yresp = jbig2.yres;
  175. }
  176. fz_pixmap *
  177. fz_load_jbig2_subimage(fz_context *ctx, const unsigned char *buf, size_t len, int subimage)
  178. {
  179. struct info jbig2 = { 0 };
  180. return jbig2_read_image(ctx, &jbig2, buf, len, 0, subimage);
  181. }
  182. fz_pixmap *
  183. fz_load_jbig2(fz_context *ctx, const unsigned char *buf, size_t len)
  184. {
  185. return fz_load_jbig2_subimage(ctx, buf, len, 0);
  186. }
  187. void
  188. fz_load_jbig2_info(fz_context *ctx, const unsigned char *buf, size_t len, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep)
  189. {
  190. fz_load_jbig2_info_subimage(ctx, buf, len, wp, hp, xresp, yresp, cspacep, 0);
  191. }