filter-dct.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. // Copyright (C) 2004-2023 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 <stdio.h>
  24. #include <jpeglib.h>
  25. #ifndef SHARE_JPEG
  26. typedef void * backing_store_ptr;
  27. #include "jmemcust.h"
  28. #endif
  29. typedef struct
  30. {
  31. fz_stream *chain;
  32. fz_stream *jpegtables;
  33. fz_stream *curr_stm;
  34. fz_context *ctx;
  35. int color_transform;
  36. int invert_cmyk; /* has inverted CMYK polarity */
  37. int init;
  38. int stride;
  39. int l2factor;
  40. unsigned char *scanline;
  41. unsigned char *rp, *wp;
  42. struct jpeg_decompress_struct cinfo;
  43. struct jpeg_source_mgr srcmgr;
  44. struct jpeg_error_mgr errmgr;
  45. jmp_buf jb;
  46. char msg[JMSG_LENGTH_MAX];
  47. unsigned char buffer[4096];
  48. } fz_dctd;
  49. #ifdef SHARE_JPEG
  50. #define JZ_DCT_STATE_FROM_CINFO(c) (fz_dctd *)((c)->client_data)
  51. static void fz_dct_mem_init(struct jpeg_decompress_struct *cinfo, fz_dctd *state)
  52. {
  53. cinfo->client_data = state;
  54. }
  55. #define fz_dct_mem_term(cinfo)
  56. #else /* SHARE_JPEG */
  57. #define JZ_DCT_STATE_FROM_CINFO(c) (fz_dctd *)(GET_CUST_MEM_DATA(c)->priv)
  58. static void *
  59. fz_dct_mem_alloc(j_common_ptr cinfo, size_t size)
  60. {
  61. fz_dctd *state = JZ_DCT_STATE_FROM_CINFO(cinfo);
  62. return Memento_label(fz_malloc_no_throw(state->ctx, size), "dct_alloc");
  63. }
  64. static void
  65. fz_dct_mem_free(j_common_ptr cinfo, void *object, size_t size)
  66. {
  67. fz_dctd *state = JZ_DCT_STATE_FROM_CINFO(cinfo);
  68. fz_free(state->ctx, object);
  69. }
  70. static void
  71. fz_dct_mem_init(struct jpeg_decompress_struct *cinfo, fz_dctd *state)
  72. {
  73. jpeg_cust_mem_data *custmptr;
  74. custmptr = fz_malloc_struct(state->ctx, jpeg_cust_mem_data);
  75. if (!jpeg_cust_mem_init(custmptr, (void *) state, NULL, NULL, NULL,
  76. fz_dct_mem_alloc, fz_dct_mem_free,
  77. fz_dct_mem_alloc, fz_dct_mem_free, NULL))
  78. {
  79. fz_free(state->ctx, custmptr);
  80. fz_throw(state->ctx, FZ_ERROR_LIBRARY, "cannot initialize custom JPEG memory handler");
  81. }
  82. cinfo->client_data = custmptr;
  83. }
  84. static void
  85. fz_dct_mem_term(struct jpeg_decompress_struct *cinfo)
  86. {
  87. if (cinfo->client_data)
  88. {
  89. fz_dctd *state = JZ_DCT_STATE_FROM_CINFO(cinfo);
  90. fz_free(state->ctx, cinfo->client_data);
  91. cinfo->client_data = NULL;
  92. }
  93. }
  94. #endif /* SHARE_JPEG */
  95. static void error_exit_dct(j_common_ptr cinfo)
  96. {
  97. char msg[JMSG_LENGTH_MAX];
  98. fz_dctd *state = JZ_DCT_STATE_FROM_CINFO(cinfo);
  99. fz_context *ctx = state->ctx;
  100. cinfo->err->format_message(cinfo, msg);
  101. fz_throw(ctx, FZ_ERROR_LIBRARY, "jpeg error: %s", msg);
  102. }
  103. static void output_message_dct(j_common_ptr cinfo)
  104. {
  105. /* swallow message */
  106. }
  107. static void init_source_dct(j_decompress_ptr cinfo)
  108. {
  109. /* nothing to do */
  110. }
  111. static void term_source_dct(j_decompress_ptr cinfo)
  112. {
  113. /* nothing to do */
  114. }
  115. static boolean fill_input_buffer_dct(j_decompress_ptr cinfo)
  116. {
  117. static unsigned char eoi[2] = { 0xFF, JPEG_EOI };
  118. struct jpeg_source_mgr *src = cinfo->src;
  119. fz_dctd *state = JZ_DCT_STATE_FROM_CINFO(cinfo);
  120. fz_context *ctx = state->ctx;
  121. fz_stream *curr_stm = state->curr_stm;
  122. curr_stm->rp = curr_stm->wp;
  123. fz_try(ctx)
  124. {
  125. src->bytes_in_buffer = fz_available(ctx, curr_stm, 1);
  126. }
  127. fz_catch(ctx)
  128. {
  129. /* Since fz_available swallows all other errors, the only errors that can
  130. * bubble up to here are TRYLATER and exception stack overflow.
  131. * Ignore this catastrophic failure and treat it as end of file.
  132. * NOTE: We do NOT handle TRYLATER here.
  133. */
  134. src->next_input_byte = eoi;
  135. src->bytes_in_buffer = 2;
  136. return 1;
  137. }
  138. src->next_input_byte = curr_stm->rp;
  139. if (src->bytes_in_buffer == 0)
  140. {
  141. fz_warn(state->ctx, "premature end of file in jpeg");
  142. src->next_input_byte = eoi;
  143. src->bytes_in_buffer = 2;
  144. }
  145. return 1;
  146. }
  147. static void skip_input_data_dct(j_decompress_ptr cinfo, long num_bytes)
  148. {
  149. struct jpeg_source_mgr *src = cinfo->src;
  150. if (num_bytes > 0)
  151. {
  152. while ((size_t)num_bytes > src->bytes_in_buffer)
  153. {
  154. num_bytes -= (long)src->bytes_in_buffer;
  155. (void) src->fill_input_buffer(cinfo);
  156. }
  157. src->next_input_byte += num_bytes;
  158. src->bytes_in_buffer -= num_bytes;
  159. }
  160. }
  161. /* Invert CMYK polarity if it is a standalone JPEG file.
  162. * For JPEG images embedded in PDF files, the CMYK data is normal.
  163. * For JPEG images created by Photoshop, the CMYK data is inverted.
  164. */
  165. static void invert_cmyk(unsigned char *p, int n)
  166. {
  167. int i;
  168. for (i = 0; i < n; ++i)
  169. p[i] = 255 - p[i];
  170. }
  171. static int
  172. next_dctd(fz_context *ctx, fz_stream *stm, size_t max)
  173. {
  174. fz_dctd *state = stm->state;
  175. j_decompress_ptr cinfo = &state->cinfo;
  176. unsigned char *p = state->buffer;
  177. unsigned char *ep;
  178. int c;
  179. if (max > sizeof(state->buffer))
  180. max = sizeof(state->buffer);
  181. ep = state->buffer + max;
  182. fz_try(ctx)
  183. {
  184. if (!state->init)
  185. {
  186. state->init = 1;
  187. /* Skip over any stray whitespace at the start of the stream */
  188. while ((c = fz_peek_byte(ctx, state->chain)) == '\n' || c == '\r' || c == ' ')
  189. (void)fz_read_byte(ctx, state->chain);
  190. jpeg_create_decompress(cinfo);
  191. cinfo->src = &state->srcmgr;
  192. cinfo->src->init_source = init_source_dct;
  193. cinfo->src->fill_input_buffer = fill_input_buffer_dct;
  194. cinfo->src->skip_input_data = skip_input_data_dct;
  195. cinfo->src->resync_to_restart = jpeg_resync_to_restart;
  196. cinfo->src->term_source = term_source_dct;
  197. /* optionally load additional JPEG tables first */
  198. if (state->jpegtables)
  199. {
  200. state->curr_stm = state->jpegtables;
  201. cinfo->src->next_input_byte = state->curr_stm->rp;
  202. cinfo->src->bytes_in_buffer = state->curr_stm->wp - state->curr_stm->rp;
  203. jpeg_read_header(cinfo, 0);
  204. state->curr_stm->rp = state->curr_stm->wp - state->cinfo.src->bytes_in_buffer;
  205. state->curr_stm = state->chain;
  206. }
  207. cinfo->src->next_input_byte = state->curr_stm->rp;
  208. cinfo->src->bytes_in_buffer = state->curr_stm->wp - state->curr_stm->rp;
  209. jpeg_read_header(cinfo, 1);
  210. /* Adobe APP marker overrides ColorTransform from PDF */
  211. if (cinfo->saw_Adobe_marker)
  212. state->color_transform = cinfo->Adobe_transform;
  213. /* Disable JPEG color transformations if ColorTransform is 0.
  214. * This is usually handled by libjpeg, but since PDF can override
  215. * the default behavior if the Adobe APP marker is missing
  216. * we must do it here as well.
  217. */
  218. if (state->color_transform == 0)
  219. {
  220. if (cinfo->num_components == 3)
  221. cinfo->jpeg_color_space = JCS_RGB;
  222. if (cinfo->num_components == 4)
  223. cinfo->jpeg_color_space = JCS_CMYK;
  224. }
  225. cinfo->scale_num = 8/(1<<state->l2factor);
  226. cinfo->scale_denom = 8;
  227. jpeg_start_decompress(cinfo);
  228. state->stride = cinfo->output_width * cinfo->output_components;
  229. state->scanline = Memento_label(fz_malloc(ctx, state->stride), "dct_scanline");
  230. state->rp = state->scanline;
  231. state->wp = state->scanline;
  232. }
  233. while (state->rp < state->wp && p < ep)
  234. *p++ = *state->rp++;
  235. while (p < ep)
  236. {
  237. if (cinfo->output_scanline == cinfo->output_height)
  238. break;
  239. if (p + state->stride <= ep)
  240. {
  241. jpeg_read_scanlines(cinfo, &p, 1);
  242. if (state->invert_cmyk && cinfo->num_components == 4)
  243. invert_cmyk(p, state->stride);
  244. p += state->stride;
  245. }
  246. else
  247. {
  248. jpeg_read_scanlines(cinfo, &state->scanline, 1);
  249. if (state->invert_cmyk && cinfo->num_components == 4)
  250. invert_cmyk(state->scanline, state->stride);
  251. state->rp = state->scanline;
  252. state->wp = state->scanline + state->stride;
  253. }
  254. while (state->rp < state->wp && p < ep)
  255. *p++ = *state->rp++;
  256. }
  257. stm->rp = state->buffer;
  258. stm->wp = p;
  259. stm->pos += (p - state->buffer);
  260. }
  261. fz_catch(ctx)
  262. {
  263. if (cinfo->src)
  264. state->curr_stm->rp = state->curr_stm->wp - cinfo->src->bytes_in_buffer;
  265. fz_rethrow(ctx);
  266. }
  267. if (p == stm->rp)
  268. return EOF;
  269. return *stm->rp++;
  270. }
  271. static void
  272. close_dctd(fz_context *ctx, void *state_)
  273. {
  274. fz_dctd *state = (fz_dctd *)state_;
  275. if (state->init)
  276. {
  277. /* We call jpeg_abort rather than the more usual
  278. * jpeg_finish_decompress here. This has the same effect,
  279. * but doesn't spew warnings if we didn't read enough data etc.
  280. * Annoyingly jpeg_abort can throw
  281. */
  282. fz_try(ctx)
  283. jpeg_abort((j_common_ptr)&state->cinfo);
  284. fz_catch(ctx)
  285. {
  286. /* Ignore any errors here */
  287. }
  288. jpeg_destroy_decompress(&state->cinfo);
  289. }
  290. fz_dct_mem_term(&state->cinfo);
  291. if (state->cinfo.src)
  292. state->curr_stm->rp = state->curr_stm->wp - state->cinfo.src->bytes_in_buffer;
  293. fz_free(ctx, state->scanline);
  294. fz_drop_stream(ctx, state->chain);
  295. fz_drop_stream(ctx, state->jpegtables);
  296. fz_free(ctx, state);
  297. }
  298. fz_stream *
  299. fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int invert_cmyk, int l2factor, fz_stream *jpegtables)
  300. {
  301. fz_dctd *state = fz_malloc_struct(ctx, fz_dctd);
  302. j_decompress_ptr cinfo = &state->cinfo;
  303. state->ctx = ctx;
  304. fz_try(ctx)
  305. fz_dct_mem_init(cinfo, state);
  306. fz_catch(ctx)
  307. {
  308. fz_free(ctx, state);
  309. fz_rethrow(ctx);
  310. }
  311. state->color_transform = color_transform;
  312. state->invert_cmyk = invert_cmyk;
  313. state->init = 0;
  314. state->l2factor = l2factor;
  315. state->chain = fz_keep_stream(ctx, chain);
  316. state->jpegtables = fz_keep_stream(ctx, jpegtables);
  317. state->curr_stm = state->chain;
  318. cinfo->src = NULL;
  319. cinfo->err = &state->errmgr;
  320. jpeg_std_error(cinfo->err);
  321. cinfo->err->output_message = output_message_dct;
  322. cinfo->err->error_exit = error_exit_dct;
  323. return fz_new_stream(ctx, state, next_dctd, close_dctd);
  324. }