pdf-image.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. // Copyright (C) 2004-2025 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 "mupdf/pdf.h"
  24. #include <string.h>
  25. static fz_image *pdf_load_jpx(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int forcemask);
  26. static fz_image *
  27. pdf_load_jpx_imp(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *dict, fz_stream *cstm, int forcemask)
  28. {
  29. fz_image *image = pdf_load_jpx(ctx, doc, dict, forcemask);
  30. if (forcemask)
  31. {
  32. fz_pixmap_image *cimg = (fz_pixmap_image *)image;
  33. fz_pixmap *mask_pixmap;
  34. fz_pixmap *tile = fz_pixmap_image_tile(ctx, cimg);
  35. if (tile->n != 1)
  36. {
  37. fz_pixmap *gray = fz_convert_pixmap(ctx, tile, fz_device_gray(ctx), NULL, NULL, fz_default_color_params, 0);
  38. fz_drop_pixmap(ctx, tile);
  39. tile = gray;
  40. }
  41. mask_pixmap = fz_alpha_from_gray(ctx, tile);
  42. fz_drop_pixmap(ctx, tile);
  43. fz_set_pixmap_image_tile(ctx, cimg, mask_pixmap);
  44. }
  45. return image;
  46. }
  47. static fz_image *
  48. pdf_load_image_imp(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *dict, fz_stream *cstm, int forcemask)
  49. {
  50. fz_image *image = NULL;
  51. pdf_obj *obj, *res;
  52. int w, h, bpc, n;
  53. int imagemask;
  54. int interpolate;
  55. int indexed;
  56. fz_image *mask = NULL; /* explicit mask/soft mask image */
  57. int use_colorkey = 0;
  58. fz_colorspace *colorspace = NULL;
  59. float decode[FZ_MAX_COLORS * 2];
  60. int colorkey[FZ_MAX_COLORS * 2];
  61. int stride;
  62. pdf_obj *intent;
  63. int i;
  64. fz_compressed_buffer *buffer;
  65. /* special case for JPEG2000 images */
  66. if (pdf_is_jpx_image(ctx, dict))
  67. return pdf_load_jpx_imp(ctx, doc, rdb, dict, cstm, forcemask);
  68. w = pdf_to_int(ctx, pdf_dict_geta(ctx, dict, PDF_NAME(Width), PDF_NAME(W)));
  69. h = pdf_to_int(ctx, pdf_dict_geta(ctx, dict, PDF_NAME(Height), PDF_NAME(H)));
  70. bpc = pdf_to_int(ctx, pdf_dict_geta(ctx, dict, PDF_NAME(BitsPerComponent), PDF_NAME(BPC)));
  71. if (bpc == 0)
  72. bpc = 8;
  73. imagemask = pdf_to_bool(ctx, pdf_dict_geta(ctx, dict, PDF_NAME(ImageMask), PDF_NAME(IM)));
  74. interpolate = pdf_to_bool(ctx, pdf_dict_geta(ctx, dict, PDF_NAME(Interpolate), PDF_NAME(I)));
  75. intent = pdf_dict_get(ctx, dict, PDF_NAME(Intent));
  76. indexed = 0;
  77. use_colorkey = 0;
  78. if (imagemask)
  79. bpc = 1;
  80. if (w <= 0)
  81. fz_throw(ctx, FZ_ERROR_SYNTAX, "image width is zero (or less)");
  82. if (h <= 0)
  83. fz_throw(ctx, FZ_ERROR_SYNTAX, "image height is zero (or less)");
  84. if (bpc <= 0)
  85. fz_throw(ctx, FZ_ERROR_SYNTAX, "image depth is zero (or less)");
  86. if (bpc > 16)
  87. fz_throw(ctx, FZ_ERROR_SYNTAX, "image depth is too large: %d", bpc);
  88. if (SIZE_MAX / w < (size_t)(bpc+7)/8)
  89. fz_throw(ctx, FZ_ERROR_SYNTAX, "image is too large");
  90. if (SIZE_MAX / h < w * (size_t)((bpc+7)/8))
  91. fz_throw(ctx, FZ_ERROR_SYNTAX, "image is too large");
  92. fz_var(mask);
  93. fz_var(image);
  94. fz_var(colorspace);
  95. fz_try(ctx)
  96. {
  97. obj = pdf_dict_geta(ctx, dict, PDF_NAME(ColorSpace), PDF_NAME(CS));
  98. if (obj && !imagemask && !forcemask)
  99. {
  100. /* colorspace resource lookup is only done for inline images */
  101. if (pdf_is_name(ctx, obj))
  102. {
  103. res = pdf_dict_get(ctx, pdf_dict_get(ctx, rdb, PDF_NAME(ColorSpace)), obj);
  104. if (res)
  105. obj = res;
  106. }
  107. colorspace = pdf_load_colorspace(ctx, obj);
  108. indexed = fz_colorspace_is_indexed(ctx, colorspace);
  109. n = fz_colorspace_n(ctx, colorspace);
  110. }
  111. else
  112. {
  113. n = 1;
  114. }
  115. if (SIZE_MAX / n < h * ((size_t)w) * ((bpc+7)/8))
  116. fz_throw(ctx, FZ_ERROR_SYNTAX, "image is too large");
  117. obj = pdf_dict_geta(ctx, dict, PDF_NAME(Decode), PDF_NAME(D));
  118. if (obj)
  119. {
  120. for (i = 0; i < n * 2; i++)
  121. decode[i] = pdf_array_get_real(ctx, obj, i);
  122. }
  123. else if (fz_colorspace_is_lab(ctx, colorspace))
  124. {
  125. decode[0] = 0;
  126. decode[1] = 100;
  127. decode[2] = -128;
  128. decode[3] = 127;
  129. decode[4] = -128;
  130. decode[5] = 127;
  131. }
  132. else
  133. {
  134. float maxval = indexed ? (1 << bpc) - 1 : 1;
  135. for (i = 0; i < n * 2; i++)
  136. decode[i] = i & 1 ? maxval : 0;
  137. }
  138. obj = pdf_dict_get(ctx, dict, PDF_NAME(SMask));
  139. if (!pdf_is_dict(ctx, obj))
  140. obj = pdf_dict_get(ctx, dict, PDF_NAME(Mask));
  141. if (pdf_is_dict(ctx, obj))
  142. {
  143. /* Not allowed for inline images or soft masks */
  144. if (cstm)
  145. fz_warn(ctx, "Ignoring invalid inline image soft mask");
  146. else if (forcemask)
  147. fz_warn(ctx, "Ignoring recursive image soft mask");
  148. else
  149. {
  150. mask = pdf_load_image_imp(ctx, doc, rdb, obj, NULL, 1);
  151. obj = pdf_dict_get(ctx, obj, PDF_NAME(Matte));
  152. if (pdf_is_array(ctx, obj))
  153. {
  154. use_colorkey = 1;
  155. for (i = 0; i < n; i++)
  156. colorkey[i] = fz_clamp(pdf_array_get_real(ctx, obj, i), 0, 1) * 255;
  157. }
  158. }
  159. }
  160. else if (pdf_is_array(ctx, obj))
  161. {
  162. use_colorkey = 1;
  163. for (i = 0; i < n * 2; i++)
  164. {
  165. if (!pdf_is_int(ctx, pdf_array_get(ctx, obj, i)))
  166. {
  167. fz_warn(ctx, "invalid value in color key mask");
  168. use_colorkey = 0;
  169. }
  170. colorkey[i] = pdf_array_get_int(ctx, obj, i);
  171. }
  172. }
  173. /* Do we load from a ref, or do we load an inline stream? */
  174. if (cstm == NULL)
  175. {
  176. /* Just load the compressed image data now and we can decode it on demand. */
  177. size_t worst_case = w * (size_t)h;
  178. worst_case = (worst_case * bpc + 7) >> 3;
  179. if (colorspace)
  180. worst_case *= colorspace->n;
  181. buffer = pdf_load_compressed_stream(ctx, doc, pdf_to_num(ctx, dict), worst_case);
  182. image = fz_new_image_from_compressed_buffer(ctx, w, h, bpc, colorspace, 96, 96, interpolate, imagemask, decode, use_colorkey ? colorkey : NULL, buffer, mask);
  183. }
  184. else
  185. {
  186. /* Inline stream */
  187. stride = (w * n * bpc + 7) / 8;
  188. image = fz_new_image_from_compressed_buffer(ctx, w, h, bpc, colorspace, 96, 96, interpolate, imagemask, decode, use_colorkey ? colorkey : NULL, NULL, mask);
  189. pdf_load_compressed_inline_image(ctx, doc, dict, stride * h, cstm, indexed, (fz_compressed_image *)image);
  190. }
  191. if (pdf_name_eq(ctx, intent, PDF_NAME(Perceptual)))
  192. image->has_intent = 1, image->intent = FZ_RI_PERCEPTUAL;
  193. else if (pdf_name_eq(ctx, intent, PDF_NAME(AbsoluteColorimetric)))
  194. image->has_intent = 1, image->intent = FZ_RI_ABSOLUTE_COLORIMETRIC;
  195. else if (pdf_name_eq(ctx, intent, PDF_NAME(RelativeColorimetric)))
  196. image->has_intent = 1, image->intent = FZ_RI_RELATIVE_COLORIMETRIC;
  197. else if (pdf_name_eq(ctx, intent, PDF_NAME(Saturation)))
  198. image->has_intent = 1, image->intent = FZ_RI_SATURATION;
  199. }
  200. fz_always(ctx)
  201. {
  202. fz_drop_colorspace(ctx, colorspace);
  203. fz_drop_image(ctx, mask);
  204. }
  205. fz_catch(ctx)
  206. {
  207. fz_drop_image(ctx, image);
  208. fz_rethrow(ctx);
  209. }
  210. return image;
  211. }
  212. fz_image *
  213. pdf_load_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *dict, fz_stream *file)
  214. {
  215. return pdf_load_image_imp(ctx, doc, rdb, dict, file, 0);
  216. }
  217. int
  218. pdf_is_jpx_image(fz_context *ctx, pdf_obj *dict)
  219. {
  220. pdf_obj *filter;
  221. int i, n;
  222. filter = pdf_dict_get(ctx, dict, PDF_NAME(Filter));
  223. if (pdf_name_eq(ctx, filter, PDF_NAME(JPXDecode)))
  224. return 1;
  225. n = pdf_array_len(ctx, filter);
  226. for (i = 0; i < n; i++)
  227. if (pdf_name_eq(ctx, pdf_array_get(ctx, filter, i), PDF_NAME(JPXDecode)))
  228. return 1;
  229. return 0;
  230. }
  231. static fz_image *
  232. pdf_load_jpx(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int forcemask)
  233. {
  234. fz_buffer *buf = NULL;
  235. fz_colorspace *colorspace = NULL;
  236. fz_pixmap *pix = NULL;
  237. pdf_obj *obj;
  238. fz_image *mask = NULL;
  239. fz_image *img = NULL;
  240. fz_var(pix);
  241. fz_var(buf);
  242. fz_var(colorspace);
  243. fz_var(mask);
  244. buf = pdf_load_stream(ctx, dict);
  245. /* FIXME: We can't handle decode arrays for indexed images currently */
  246. fz_try(ctx)
  247. {
  248. unsigned char *data;
  249. size_t len;
  250. obj = pdf_dict_get(ctx, dict, PDF_NAME(ColorSpace));
  251. if (obj)
  252. colorspace = pdf_load_colorspace(ctx, obj);
  253. len = fz_buffer_storage(ctx, buf, &data);
  254. pix = fz_load_jpx(ctx, data, len, colorspace);
  255. obj = pdf_dict_geta(ctx, dict, PDF_NAME(SMask), PDF_NAME(Mask));
  256. if (pdf_is_dict(ctx, obj))
  257. {
  258. if (forcemask)
  259. fz_warn(ctx, "Ignoring recursive JPX soft mask");
  260. else
  261. mask = pdf_load_image_imp(ctx, doc, NULL, obj, NULL, 1);
  262. }
  263. obj = pdf_dict_geta(ctx, dict, PDF_NAME(Decode), PDF_NAME(D));
  264. if (obj && !fz_colorspace_is_indexed(ctx, colorspace))
  265. {
  266. float decode[FZ_MAX_COLORS * 2];
  267. int i;
  268. for (i = 0; i < pix->n * 2; i++)
  269. decode[i] = pdf_array_get_real(ctx, obj, i);
  270. fz_decode_tile(ctx, pix, decode);
  271. }
  272. img = fz_new_image_from_pixmap(ctx, pix, mask);
  273. }
  274. fz_always(ctx)
  275. {
  276. fz_drop_image(ctx, mask);
  277. fz_drop_pixmap(ctx, pix);
  278. fz_drop_colorspace(ctx, colorspace);
  279. fz_drop_buffer(ctx, buf);
  280. }
  281. fz_catch(ctx)
  282. {
  283. fz_morph_error(ctx, FZ_ERROR_FORMAT, FZ_ERROR_SYNTAX);
  284. fz_morph_error(ctx, FZ_ERROR_LIBRARY, FZ_ERROR_SYNTAX);
  285. fz_rethrow(ctx);
  286. }
  287. return img;
  288. }
  289. fz_image *
  290. pdf_load_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
  291. {
  292. fz_image *image;
  293. if ((image = pdf_find_item(ctx, fz_drop_image_imp, dict)) != NULL)
  294. return image;
  295. image = pdf_load_image_imp(ctx, doc, NULL, dict, NULL, 0);
  296. pdf_store_item(ctx, dict, image, fz_image_size(ctx, image));
  297. return image;
  298. }
  299. struct jbig2_segment_header {
  300. int number;
  301. int flags;
  302. /* referred-to-segment numbers */
  303. int page;
  304. uint32_t length;
  305. };
  306. /* coverity[-tainted_data_return] */
  307. static uint32_t getu32(const unsigned char *data)
  308. {
  309. return ((uint32_t)data[0]<<24) | ((uint32_t)data[1]<<16) | ((uint32_t)data[2]<<8) | (uint32_t)data[3];
  310. }
  311. static size_t
  312. pdf_parse_jbig2_segment_header(fz_context *ctx,
  313. const unsigned char *data, const unsigned char *end,
  314. struct jbig2_segment_header *info)
  315. {
  316. uint32_t rts;
  317. size_t n = 5;
  318. if (data + 11 > end) return 0;
  319. info->number = getu32(data);
  320. info->flags = data[4];
  321. rts = (data[5] >> 5) & 0x7;
  322. if (rts == 7)
  323. {
  324. rts = getu32(data+5) & 0x1FFFFFFF;
  325. n += 4 + (rts + 1) / 8;
  326. }
  327. else
  328. {
  329. n += 1;
  330. }
  331. if (info->number <= 256)
  332. n += rts;
  333. else if (info->number <= 65536)
  334. n += rts * 2;
  335. else
  336. n += rts * 4;
  337. if (info->flags & 0x40)
  338. {
  339. if (data + n + 4 > end) return 0;
  340. info->page = getu32(data+n);
  341. n += 4;
  342. }
  343. else
  344. {
  345. if (data + n + 1 > end) return 0;
  346. info->page = data[n];
  347. n += 1;
  348. }
  349. if (data + n + 4 > end) return 0;
  350. info->length = getu32(data+n);
  351. return n + 4;
  352. }
  353. static void
  354. pdf_copy_jbig2_segments(fz_context *ctx, fz_buffer *output, const unsigned char *data, size_t size, int page)
  355. {
  356. struct jbig2_segment_header info;
  357. const unsigned char *end = data + size;
  358. size_t n;
  359. int type;
  360. while (data < end)
  361. {
  362. n = pdf_parse_jbig2_segment_header(ctx, data, end, &info);
  363. if (n == 0)
  364. fz_throw(ctx, FZ_ERROR_FORMAT, "truncated jbig2 segment header");
  365. /* omit end of page, end of file, and segments for other pages */
  366. type = (info.flags & 63);
  367. if (type == 49 || type == 51 || (info.page > 0 && info.page != page))
  368. {
  369. data += n;
  370. data += info.length;
  371. }
  372. else
  373. {
  374. fz_append_data(ctx, output, data, n);
  375. data += n;
  376. if (data + info.length > end)
  377. fz_throw(ctx, FZ_ERROR_FORMAT, "truncated jbig2 segment data");
  378. fz_append_data(ctx, output, data, info.length);
  379. data += info.length;
  380. }
  381. }
  382. }
  383. static void
  384. pdf_copy_jbig2_random_segments(fz_context *ctx, fz_buffer *output, const unsigned char *data, size_t size, int page)
  385. {
  386. struct jbig2_segment_header info;
  387. const unsigned char *header = data;
  388. const unsigned char *header_end;
  389. const unsigned char *end = data + size;
  390. size_t n;
  391. int type;
  392. /* Skip headers until end-of-file segment is found. */
  393. while (data < end)
  394. {
  395. n = pdf_parse_jbig2_segment_header(ctx, data, end, &info);
  396. if (n == 0)
  397. fz_throw(ctx, FZ_ERROR_FORMAT, "truncated jbig2 segment header");
  398. data += n;
  399. if ((info.flags & 63) == 51)
  400. break;
  401. }
  402. if (data >= end)
  403. fz_throw(ctx, FZ_ERROR_FORMAT, "truncated jbig2 segment header");
  404. /* Copy segment headers and segment data */
  405. header_end = data;
  406. while (data < end && header < header_end)
  407. {
  408. n = pdf_parse_jbig2_segment_header(ctx, header, header_end, &info);
  409. if (n == 0)
  410. fz_throw(ctx, FZ_ERROR_FORMAT, "truncated jbig2 segment header");
  411. /* omit end of page, end of file, and segments for other pages */
  412. type = (info.flags & 63);
  413. if (type == 49 || type == 51 || (info.page > 0 && info.page != page))
  414. {
  415. header += n;
  416. data += info.length;
  417. }
  418. else
  419. {
  420. fz_append_data(ctx, output, header, n);
  421. header += n;
  422. if (data + info.length > end)
  423. fz_throw(ctx, FZ_ERROR_FORMAT, "truncated jbig2 segment data");
  424. fz_append_data(ctx, output, data, info.length);
  425. data += info.length;
  426. }
  427. }
  428. }
  429. static fz_buffer *
  430. pdf_jbig2_stream_from_file(fz_context *ctx, fz_buffer *input, fz_jbig2_globals *globals_, int page)
  431. {
  432. fz_buffer *globals = fz_jbig2_globals_data(ctx, globals_);
  433. size_t globals_size = globals ? globals->len : 0;
  434. fz_buffer *output;
  435. int flags;
  436. size_t header = 9;
  437. if (input->len < 9)
  438. return NULL; /* not enough data! */
  439. flags = input->data[8];
  440. if ((flags & 2) == 0)
  441. {
  442. if (input->len < 13)
  443. return NULL; /* not enough data! */
  444. header = 13;
  445. }
  446. output = fz_new_buffer(ctx, input->len + globals_size);
  447. fz_try(ctx)
  448. {
  449. if (globals_size > 0)
  450. fz_append_buffer(ctx, output, globals);
  451. if ((flags & 1) == 0)
  452. pdf_copy_jbig2_random_segments(ctx, output, input->data + header, input->len - header, page);
  453. else
  454. pdf_copy_jbig2_segments(ctx, output, input->data + header, input->len - header, page);
  455. }
  456. fz_catch(ctx)
  457. {
  458. fz_drop_buffer(ctx, output);
  459. fz_rethrow(ctx);
  460. }
  461. return output;
  462. }
  463. pdf_obj *
  464. pdf_add_image(fz_context *ctx, pdf_document *doc, fz_image *image)
  465. {
  466. fz_pixmap *pixmap = NULL;
  467. pdf_obj *imobj = NULL;
  468. pdf_obj *dp;
  469. fz_buffer *buffer = NULL;
  470. fz_compressed_buffer *cbuffer;
  471. fz_pixmap *smask_pixmap = NULL;
  472. fz_image *smask_image = NULL;
  473. int i, n;
  474. fz_var(pixmap);
  475. fz_var(buffer);
  476. fz_var(imobj);
  477. fz_var(smask_pixmap);
  478. fz_var(smask_image);
  479. pdf_begin_operation(ctx, doc, "Add image");
  480. fz_try(ctx)
  481. {
  482. /* If we can maintain compression, do so */
  483. cbuffer = fz_compressed_image_buffer(ctx, image);
  484. imobj = pdf_add_new_dict(ctx, doc, 3);
  485. dp = pdf_dict_put_dict(ctx, imobj, PDF_NAME(DecodeParms), 3);
  486. pdf_dict_put(ctx, imobj, PDF_NAME(Type), PDF_NAME(XObject));
  487. pdf_dict_put(ctx, imobj, PDF_NAME(Subtype), PDF_NAME(Image));
  488. if (cbuffer)
  489. {
  490. fz_compression_params *cp = &cbuffer->params;
  491. switch (cp->type)
  492. {
  493. default:
  494. goto unknown_compression;
  495. case FZ_IMAGE_RAW:
  496. break;
  497. case FZ_IMAGE_JPEG:
  498. pdf_dict_put(ctx, imobj, PDF_NAME(Filter), PDF_NAME(DCTDecode));
  499. if (cp->u.jpeg.color_transform >= 0)
  500. pdf_dict_put_int(ctx, dp, PDF_NAME(ColorTransform), cp->u.jpeg.color_transform);
  501. if (cp->u.jpeg.invert_cmyk && image->n == 4)
  502. {
  503. pdf_obj *arr;
  504. arr = pdf_dict_put_array(ctx, imobj, PDF_NAME(Decode), 8);
  505. pdf_array_push_int(ctx, arr, 1);
  506. pdf_array_push_int(ctx, arr, 0);
  507. pdf_array_push_int(ctx, arr, 1);
  508. pdf_array_push_int(ctx, arr, 0);
  509. pdf_array_push_int(ctx, arr, 1);
  510. pdf_array_push_int(ctx, arr, 0);
  511. pdf_array_push_int(ctx, arr, 1);
  512. pdf_array_push_int(ctx, arr, 0);
  513. }
  514. break;
  515. case FZ_IMAGE_JPX:
  516. if (cp->u.jpx.smask_in_data)
  517. pdf_dict_put_int(ctx, dp, PDF_NAME(SMaskInData), cp->u.jpx.smask_in_data);
  518. pdf_dict_put(ctx, imobj, PDF_NAME(Filter), PDF_NAME(JPXDecode));
  519. break;
  520. case FZ_IMAGE_JBIG2:
  521. if (cp->u.jbig2.embedded && cp->u.jbig2.globals)
  522. {
  523. pdf_obj *globals_ref = pdf_add_new_dict(ctx, doc, 1);
  524. pdf_dict_put_drop(ctx, dp, PDF_NAME(JBIG2Globals), globals_ref);
  525. pdf_update_stream(ctx, doc, globals_ref, fz_jbig2_globals_data(ctx, cp->u.jbig2.globals), 0);
  526. }
  527. else
  528. {
  529. buffer = pdf_jbig2_stream_from_file(ctx, cbuffer->buffer,
  530. cp->u.jbig2.globals,
  531. 1);
  532. if (!buffer)
  533. goto unknown_compression;
  534. }
  535. pdf_dict_put(ctx, imobj, PDF_NAME(Filter), PDF_NAME(JBIG2Decode));
  536. break;
  537. case FZ_IMAGE_FAX:
  538. if (cp->u.fax.columns)
  539. pdf_dict_put_int(ctx, dp, PDF_NAME(Columns), cp->u.fax.columns);
  540. if (cp->u.fax.rows)
  541. pdf_dict_put_int(ctx, dp, PDF_NAME(Rows), cp->u.fax.rows);
  542. if (cp->u.fax.k)
  543. pdf_dict_put_int(ctx, dp, PDF_NAME(K), cp->u.fax.k);
  544. if (cp->u.fax.end_of_line)
  545. pdf_dict_put_bool(ctx, dp, PDF_NAME(EndOfLine), cp->u.fax.end_of_line);
  546. if (cp->u.fax.encoded_byte_align)
  547. pdf_dict_put_bool(ctx, dp, PDF_NAME(EncodedByteAlign), cp->u.fax.encoded_byte_align);
  548. if (cp->u.fax.end_of_block)
  549. pdf_dict_put_bool(ctx, dp, PDF_NAME(EndOfBlock), cp->u.fax.end_of_block);
  550. if (cp->u.fax.black_is_1)
  551. pdf_dict_put_bool(ctx, dp, PDF_NAME(BlackIs1), cp->u.fax.black_is_1);
  552. if (cp->u.fax.damaged_rows_before_error)
  553. pdf_dict_put_int(ctx, dp, PDF_NAME(DamagedRowsBeforeError), cp->u.fax.damaged_rows_before_error);
  554. pdf_dict_put(ctx, imobj, PDF_NAME(Filter), PDF_NAME(CCITTFaxDecode));
  555. break;
  556. case FZ_IMAGE_FLATE:
  557. if (cp->u.flate.columns)
  558. pdf_dict_put_int(ctx, dp, PDF_NAME(Columns), cp->u.flate.columns);
  559. if (cp->u.flate.colors)
  560. pdf_dict_put_int(ctx, dp, PDF_NAME(Colors), cp->u.flate.colors);
  561. if (cp->u.flate.predictor)
  562. pdf_dict_put_int(ctx, dp, PDF_NAME(Predictor), cp->u.flate.predictor);
  563. if (cp->u.flate.bpc)
  564. pdf_dict_put_int(ctx, dp, PDF_NAME(BitsPerComponent), cp->u.flate.bpc);
  565. pdf_dict_put(ctx, imobj, PDF_NAME(Filter), PDF_NAME(FlateDecode));
  566. break;
  567. case FZ_IMAGE_BROTLI:
  568. if (cp->u.brotli.columns)
  569. pdf_dict_put_int(ctx, dp, PDF_NAME(Columns), cp->u.brotli.columns);
  570. if (cp->u.brotli.colors)
  571. pdf_dict_put_int(ctx, dp, PDF_NAME(Colors), cp->u.brotli.colors);
  572. if (cp->u.brotli.predictor)
  573. pdf_dict_put_int(ctx, dp, PDF_NAME(Predictor), cp->u.brotli.predictor);
  574. if (cp->u.brotli.bpc)
  575. pdf_dict_put_int(ctx, dp, PDF_NAME(BitsPerComponent), cp->u.brotli.bpc);
  576. pdf_dict_put(ctx, imobj, PDF_NAME(Filter), PDF_NAME(BrotliDecode));
  577. break;
  578. case FZ_IMAGE_LZW:
  579. if (cp->u.lzw.columns)
  580. pdf_dict_put_int(ctx, dp, PDF_NAME(Columns), cp->u.lzw.columns);
  581. if (cp->u.lzw.colors)
  582. pdf_dict_put_int(ctx, dp, PDF_NAME(Colors), cp->u.lzw.colors);
  583. if (cp->u.lzw.predictor)
  584. pdf_dict_put_int(ctx, dp, PDF_NAME(Predictor), cp->u.lzw.predictor);
  585. if (cp->u.lzw.early_change)
  586. pdf_dict_put_int(ctx, dp, PDF_NAME(EarlyChange), cp->u.lzw.early_change);
  587. if (cp->u.lzw.bpc)
  588. pdf_dict_put_int(ctx, dp, PDF_NAME(BitsPerComponent), cp->u.lzw.bpc);
  589. pdf_dict_put(ctx, imobj, PDF_NAME(Filter), PDF_NAME(LZWDecode));
  590. break;
  591. case FZ_IMAGE_RLD:
  592. pdf_dict_put(ctx, imobj, PDF_NAME(Filter), PDF_NAME(RunLengthDecode));
  593. break;
  594. }
  595. if (!pdf_dict_len(ctx, dp))
  596. pdf_dict_del(ctx, imobj, PDF_NAME(DecodeParms));
  597. pdf_dict_put_int(ctx, imobj, PDF_NAME(BitsPerComponent), image->bpc);
  598. pdf_dict_put_int(ctx, imobj, PDF_NAME(Width), image->w);
  599. pdf_dict_put_int(ctx, imobj, PDF_NAME(Height), image->h);
  600. if (!buffer)
  601. buffer = fz_keep_buffer(ctx, cbuffer->buffer);
  602. if (image->use_decode)
  603. {
  604. pdf_obj *ary = pdf_dict_put_array(ctx, imobj, PDF_NAME(Decode), image->n * 2);
  605. for (i = 0; i < image->n * 2; ++i)
  606. pdf_array_push_real(ctx, ary, image->decode[i]);
  607. }
  608. }
  609. else
  610. {
  611. unknown_compression:
  612. pixmap = fz_get_pixmap_from_image(ctx, image, NULL, NULL, NULL, NULL);
  613. n = pixmap->n - pixmap->alpha - pixmap->s; /* number of colorants */
  614. if (n == 0)
  615. n = 1; /* treat pixmaps with only alpha or spots as grayscale */
  616. pdf_dict_put_int(ctx, imobj, PDF_NAME(Width), pixmap->w);
  617. pdf_dict_put_int(ctx, imobj, PDF_NAME(Height), pixmap->h);
  618. if (fz_is_pixmap_monochrome(ctx, pixmap))
  619. {
  620. int stride = (image->w + 7) / 8;
  621. int h = pixmap->h;
  622. int w = pixmap->w;
  623. unsigned char *s = pixmap->samples;
  624. unsigned char *d = fz_calloc(ctx, h, stride);
  625. buffer = fz_new_buffer_from_data(ctx, d, (size_t)h * stride);
  626. pdf_dict_put_int(ctx, imobj, PDF_NAME(BitsPerComponent), 1);
  627. while (h--)
  628. {
  629. int x;
  630. for (x = 0; x < w; ++x)
  631. if (s[x] > 0)
  632. d[x>>3] |= 1 << (7 - (x & 7));
  633. s += pixmap->stride;
  634. d += stride;
  635. }
  636. }
  637. else
  638. {
  639. size_t size = (size_t)pixmap->w * n;
  640. int h = pixmap->h;
  641. unsigned char *s = pixmap->samples;
  642. unsigned char *d = Memento_label(fz_malloc(ctx, size * h), "pdf_image_samples");
  643. buffer = fz_new_buffer_from_data(ctx, d, size * h);
  644. pdf_dict_put_int(ctx, imobj, PDF_NAME(BitsPerComponent), 8);
  645. if (n == pixmap->n)
  646. {
  647. /* If we use all channels, we can copy the data as is. */
  648. while (h--)
  649. {
  650. memcpy(d, s, size);
  651. d += size;
  652. s += pixmap->stride;
  653. }
  654. }
  655. else
  656. {
  657. size_t line_skip;
  658. int skip;
  659. /* Need to extract the alpha into a SMask and remove spot planes. */
  660. /* TODO: convert spots to colors. */
  661. if (pixmap->alpha && !image->mask)
  662. {
  663. smask_pixmap = fz_new_pixmap_from_alpha_channel(ctx, pixmap);
  664. smask_image = fz_new_image_from_pixmap(ctx, smask_pixmap, NULL);
  665. pdf_dict_put_drop(ctx, imobj, PDF_NAME(SMask), pdf_add_image(ctx, doc, smask_image));
  666. fz_drop_image(ctx, smask_image);
  667. smask_image = NULL;
  668. fz_drop_pixmap(ctx, smask_pixmap);
  669. smask_pixmap = NULL;
  670. }
  671. line_skip = pixmap->stride - pixmap->w * (size_t)pixmap->n;
  672. skip = pixmap->n - n;
  673. if (pixmap->alpha)
  674. {
  675. int n1 = pixmap->n-1;
  676. while (h--)
  677. {
  678. int w = pixmap->w;
  679. while (w--)
  680. {
  681. int a = s[n1];
  682. int inva = a ? 255 * 256 / a : 0;
  683. int k;
  684. for (k = 0; k < n; k++)
  685. *d++ = (*s++ * inva) >> 8;
  686. s += skip;
  687. }
  688. s += line_skip;
  689. }
  690. }
  691. else
  692. {
  693. while (h--)
  694. {
  695. int w = pixmap->w;
  696. while (w--)
  697. {
  698. int k;
  699. for (k = 0; k < n; ++k)
  700. *d++ = *s++;
  701. s += skip;
  702. }
  703. s += line_skip;
  704. }
  705. }
  706. }
  707. }
  708. }
  709. if (image->imagemask)
  710. {
  711. pdf_dict_put_bool(ctx, imobj, PDF_NAME(ImageMask), 1);
  712. }
  713. else
  714. {
  715. fz_colorspace *cs = pixmap ? pixmap->colorspace : image->colorspace;
  716. pdf_dict_put_drop(ctx, imobj, PDF_NAME(ColorSpace), pdf_add_colorspace(ctx, doc, cs));
  717. }
  718. if (image->mask)
  719. {
  720. if (image->mask->imagemask)
  721. pdf_dict_put_drop(ctx, imobj, PDF_NAME(Mask), pdf_add_image(ctx, doc, image->mask));
  722. else
  723. pdf_dict_put_drop(ctx, imobj, PDF_NAME(SMask), pdf_add_image(ctx, doc, image->mask));
  724. }
  725. pdf_update_stream(ctx, doc, imobj, buffer, 1);
  726. pdf_end_operation(ctx, doc);
  727. }
  728. fz_always(ctx)
  729. {
  730. fz_drop_image(ctx, smask_image);
  731. fz_drop_pixmap(ctx, smask_pixmap);
  732. fz_drop_pixmap(ctx, pixmap);
  733. fz_drop_buffer(ctx, buffer);
  734. }
  735. fz_catch(ctx)
  736. {
  737. pdf_drop_obj(ctx, imobj);
  738. pdf_abandon_operation(ctx, doc);
  739. fz_rethrow(ctx);
  740. }
  741. return imobj;
  742. }