gdevpdfi.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292
  1. /* Copyright (C) 1996, 2000, 2002 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gdevpdfi.c,v 1.73 2005/08/29 18:21:57 igor Exp $ */
  14. /* Image handling for PDF-writing driver */
  15. #include "memory_.h"
  16. #include "math_.h"
  17. #include "gx.h"
  18. #include "gserrors.h"
  19. #include "gsdevice.h"
  20. #include "gsflip.h"
  21. #include "gsstate.h"
  22. #include "gscolor2.h"
  23. #include "gdevpdfx.h"
  24. #include "gdevpdfg.h"
  25. #include "gdevpdfo.h" /* for data stream */
  26. #include "gxcspace.h"
  27. #include "gximage3.h"
  28. #include "gximag3x.h"
  29. #include "gsiparm4.h"
  30. #include "gxdcolor.h"
  31. #include "gxpcolor.h"
  32. #include "gxcolor2.h"
  33. #include "gxhldevc.h"
  34. /* Forward references */
  35. private image_enum_proc_plane_data(pdf_image_plane_data);
  36. private image_enum_proc_end_image(pdf_image_end_image);
  37. private image_enum_proc_end_image(pdf_image_end_image_object);
  38. private image_enum_proc_end_image(pdf_image_end_image_object2);
  39. private image_enum_proc_end_image(pdf_image_end_image_cvd);
  40. private IMAGE3_MAKE_MID_PROC(pdf_image3_make_mid);
  41. private IMAGE3_MAKE_MCDE_PROC(pdf_image3_make_mcde);
  42. private IMAGE3X_MAKE_MID_PROC(pdf_image3x_make_mid);
  43. private IMAGE3X_MAKE_MCDE_PROC(pdf_image3x_make_mcde);
  44. private const gx_image_enum_procs_t pdf_image_enum_procs = {
  45. pdf_image_plane_data,
  46. pdf_image_end_image
  47. };
  48. private const gx_image_enum_procs_t pdf_image_object_enum_procs = {
  49. pdf_image_plane_data,
  50. pdf_image_end_image_object
  51. };
  52. private const gx_image_enum_procs_t pdf_image_object_enum_procs2 = {
  53. pdf_image_plane_data,
  54. pdf_image_end_image_object2
  55. };
  56. private const gx_image_enum_procs_t pdf_image_cvd_enum_procs = {
  57. gx_image1_plane_data,
  58. pdf_image_end_image_cvd,
  59. gx_image1_flush
  60. };
  61. /* ---------------- Driver procedures ---------------- */
  62. /* Define the structure for keeping track of progress through an image. */
  63. typedef struct pdf_image_enum_s {
  64. gx_image_enum_common;
  65. gs_memory_t *memory;
  66. int width;
  67. int bits_per_pixel; /* bits per pixel (per plane) */
  68. int rows_left;
  69. pdf_image_writer writer;
  70. gs_matrix mat;
  71. } pdf_image_enum;
  72. gs_private_st_composite(st_pdf_image_enum, pdf_image_enum, "pdf_image_enum",
  73. pdf_image_enum_enum_ptrs, pdf_image_enum_reloc_ptrs);
  74. /* GC procedures */
  75. private ENUM_PTRS_WITH(pdf_image_enum_enum_ptrs, pdf_image_enum *pie)
  76. if (index < pdf_image_writer_max_ptrs) {
  77. gs_ptr_type_t ret =
  78. ENUM_USING(st_pdf_image_writer, &pie->writer, sizeof(pie->writer),
  79. index);
  80. if (ret == 0) /* don't stop early */
  81. ENUM_RETURN(0);
  82. return ret;
  83. }
  84. return ENUM_USING_PREFIX(st_gx_image_enum_common,
  85. pdf_image_writer_max_ptrs);
  86. ENUM_PTRS_END
  87. private RELOC_PTRS_WITH(pdf_image_enum_reloc_ptrs, pdf_image_enum *pie)
  88. {
  89. RELOC_USING(st_pdf_image_writer, &pie->writer, sizeof(pie->writer));
  90. RELOC_USING(st_gx_image_enum_common, vptr, size);
  91. }
  92. RELOC_PTRS_END
  93. /*
  94. * Test whether we can write an image in-line. This is always true,
  95. * because we only support PDF 1.2 and later.
  96. */
  97. private bool
  98. can_write_image_in_line(const gx_device_pdf *pdev, const gs_image_t *pim)
  99. {
  100. return true;
  101. }
  102. /*
  103. * Convert a Type 4 image to a Type 1 masked image if possible.
  104. * Type 1 masked images are more compact, and are supported in all PDF
  105. * versions, whereas general masked images require PDF 1.3 or higher.
  106. * Also, Acrobat 5 for Windows has a bug that causes an error for images
  107. * with a color-key mask, at least for 1-bit-deep images using an Indexed
  108. * color space.
  109. */
  110. private int
  111. color_is_black_or_white(gx_device *dev, const gx_drawing_color *pdcolor)
  112. {
  113. return (!color_is_pure(pdcolor) ? -1 :
  114. gx_dc_pure_color(pdcolor) == gx_device_black(dev) ? 0 :
  115. gx_dc_pure_color(pdcolor) == gx_device_white(dev) ? 1 : -1);
  116. }
  117. private int
  118. pdf_convert_image4_to_image1(gx_device_pdf *pdev,
  119. const gs_imager_state *pis,
  120. const gx_drawing_color *pbcolor,
  121. const gs_image4_t *pim4, gs_image_t *pim1,
  122. gx_drawing_color *pdcolor)
  123. {
  124. if (pim4->BitsPerComponent == 1 &&
  125. (pim4->MaskColor_is_range ?
  126. pim4->MaskColor[0] | pim4->MaskColor[1] :
  127. pim4->MaskColor[0]) <= 1
  128. ) {
  129. gx_device *const dev = (gx_device *)pdev;
  130. const gs_color_space *pcs = pim4->ColorSpace;
  131. bool write_1s = !pim4->MaskColor[0];
  132. gs_client_color cc;
  133. int code;
  134. /*
  135. * Prepare the drawing color. (pdf_prepare_imagemask will set it.)
  136. * This is the other color in the image (the one that isn't the
  137. * mask key), taking Decode into account.
  138. */
  139. cc.paint.values[0] = pim4->Decode[(int)write_1s];
  140. cc.pattern = 0;
  141. code = pcs->type->remap_color(&cc, pcs, pdcolor, pis, dev,
  142. gs_color_select_texture);
  143. if (code < 0)
  144. return code;
  145. /*
  146. * The PDF imaging model doesn't support RasterOp. We can convert a
  147. * Type 4 image to a Type 1 imagemask only if the effective RasterOp
  148. * passes through the source color unchanged. "Effective" means we
  149. * take into account CombineWithColor, and whether the source and/or
  150. * texture are black, white, or neither.
  151. */
  152. {
  153. gs_logical_operation_t lop = pis->log_op;
  154. int black_or_white = color_is_black_or_white(dev, pdcolor);
  155. switch (black_or_white) {
  156. case 0: lop = lop_know_S_0(lop); break;
  157. case 1: lop = lop_know_S_1(lop); break;
  158. default: DO_NOTHING;
  159. }
  160. if (pim4->CombineWithColor)
  161. switch (color_is_black_or_white(dev, pbcolor)) {
  162. case 0: lop = lop_know_T_0(lop); break;
  163. case 1: lop = lop_know_T_1(lop); break;
  164. default: DO_NOTHING;
  165. }
  166. else
  167. lop = lop_know_T_0(lop);
  168. switch (lop_rop(lop)) {
  169. case rop3_0:
  170. if (black_or_white != 0)
  171. return -1;
  172. break;
  173. case rop3_1:
  174. if (black_or_white != 1)
  175. return -1;
  176. break;
  177. case rop3_S:
  178. break;
  179. default:
  180. return -1;
  181. }
  182. if ((lop & lop_S_transparent) && black_or_white == 1)
  183. return -1;
  184. }
  185. /* All conditions are met. Convert to a masked image. */
  186. gs_image_t_init_mask_adjust(pim1, write_1s, false);
  187. #define COPY_ELEMENT(e) pim1->e = pim4->e
  188. COPY_ELEMENT(ImageMatrix);
  189. COPY_ELEMENT(Width);
  190. COPY_ELEMENT(Height);
  191. pim1->BitsPerComponent = 1;
  192. /* not Decode */
  193. COPY_ELEMENT(Interpolate);
  194. pim1->format = gs_image_format_chunky; /* BPC = 1, doesn't matter */
  195. #undef COPY_ELEMENT
  196. return 0;
  197. }
  198. return -1; /* arbitrary <0 */
  199. }
  200. private int
  201. pdf_begin_image_data_decoded(gx_device_pdf *pdev, int num_components, const gs_range_t *pranges, int i,
  202. gs_pixel_image_t *pi, cos_value_t *cs_value, pdf_image_enum *pie)
  203. {
  204. if (pranges) {
  205. /* Rescale the Decode values for the image data. */
  206. const gs_range_t *pr = pranges;
  207. float *decode = pi->Decode;
  208. int j;
  209. for (j = 0; j < num_components; ++j, ++pr, decode += 2) {
  210. double vmin = decode[0], vmax = decode[1];
  211. double base = pr->rmin, factor = pr->rmax - base;
  212. decode[1] = (vmax - vmin) / factor + (vmin - base);
  213. decode[0] = vmin - base;
  214. }
  215. }
  216. return pdf_begin_image_data(pdev, &pie->writer, pi, cs_value, i);
  217. }
  218. /*
  219. * Start processing an image. This procedure takes extra arguments because
  220. * it has to do something slightly different for the parts of an ImageType 3
  221. * image.
  222. */
  223. typedef enum {
  224. PDF_IMAGE_DEFAULT,
  225. PDF_IMAGE_TYPE3_MASK, /* no in-line, don't render */
  226. PDF_IMAGE_TYPE3_DATA /* no in-line */
  227. } pdf_typed_image_context_t;
  228. private int
  229. pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis,
  230. const gs_matrix *pmat, const gs_image_common_t *pic,
  231. const gs_int_rect * prect,
  232. const gx_drawing_color * pdcolor,
  233. const gx_clip_path * pcpath, gs_memory_t * mem,
  234. gx_image_enum_common_t ** pinfo,
  235. pdf_typed_image_context_t context)
  236. {
  237. cos_dict_t *pnamed = 0;
  238. const gs_pixel_image_t *pim;
  239. int code, i;
  240. pdf_image_enum *pie;
  241. gs_image_format_t format;
  242. const gs_color_space *pcs;
  243. gs_color_space cs_gray_temp;
  244. cos_value_t cs_value;
  245. int num_components;
  246. bool is_mask = false, in_line = false;
  247. gs_int_rect rect;
  248. /*
  249. * We define this union because psdf_setup_image_filters may alter the
  250. * gs_pixel_image_t part, but pdf_begin_image_data must also have access
  251. * to the type-specific parameters.
  252. */
  253. union iu_ {
  254. gs_pixel_image_t pixel; /* we may change some components */
  255. gs_image1_t type1;
  256. gs_image3_t type3;
  257. gs_image3x_t type3x;
  258. gs_image4_t type4;
  259. } image[4];
  260. int width, height;
  261. const gs_range_t *pranges = 0;
  262. const pdf_color_space_names_t *names;
  263. bool convert_to_process_colors = false;
  264. pdf_lcvd_t *cvd = NULL;
  265. /*
  266. * Pop the image name from the NI stack. We must do this, to keep the
  267. * stack in sync, even if it turns out we can't handle the image.
  268. */
  269. {
  270. cos_value_t ni_value;
  271. if (cos_array_unadd(pdev->NI_stack, &ni_value) >= 0)
  272. pnamed = (cos_dict_t *)ni_value.contents.object;
  273. }
  274. /* An initialization for pdf_end_and_do_image :
  275. We need to delay adding the "Mask" entry into a type 3 image dictionary
  276. until the mask is completed due to equal image merging. */
  277. pdev->image_mask_id = gs_no_id;
  278. /* Check for the image types we can handle. */
  279. switch (pic->type->index) {
  280. case 1: {
  281. const gs_image_t *pim1 = (const gs_image_t *)pic;
  282. if (pim1->Alpha != gs_image_alpha_none)
  283. goto nyi;
  284. is_mask = pim1->ImageMask;
  285. if (is_mask) {
  286. /* If parameters are invalid, use the default implementation. */
  287. if (pdcolor->type != &gx_dc_pattern)
  288. if (pim1->BitsPerComponent != 1 ||
  289. !((pim1->Decode[0] == 0.0 && pim1->Decode[1] == 1.0) ||
  290. (pim1->Decode[0] == 1.0 && pim1->Decode[1] == 0.0))
  291. )
  292. goto nyi;
  293. }
  294. in_line = context == PDF_IMAGE_DEFAULT &&
  295. can_write_image_in_line(pdev, pim1);
  296. image[0].type1 = *pim1;
  297. break;
  298. }
  299. case 3: {
  300. const gs_image3_t *pim3 = (const gs_image3_t *)pic;
  301. gs_image3_t pim3a;
  302. const gs_image_common_t *pic1 = pic;
  303. gs_matrix m, mi;
  304. const gs_matrix *pmat1 = pmat;
  305. pdev->image_mask_is_SMask = false;
  306. if (pdev->CompatibilityLevel < 1.2)
  307. goto nyi;
  308. if (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
  309. prect->q.x == pim3->Width &&
  310. prect->q.y == pim3->Height))
  311. goto nyi;
  312. if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
  313. gs_make_identity(&m);
  314. pmat1 = &m;
  315. m.tx = floor(pis->ctm.tx + 0.5); /* Round the origin against the image size distorsions */
  316. m.ty = floor(pis->ctm.ty + 0.5);
  317. pim3a = *pim3;
  318. gs_matrix_invert(&pim3a.ImageMatrix, &mi);
  319. gs_make_identity(&pim3a.ImageMatrix);
  320. if (pim3a.Width < pim3a.MaskDict.Width && pim3a.Width > 0) {
  321. int sx = (pim3a.MaskDict.Width + pim3a.Width - 1) / pim3a.Width;
  322. gs_matrix_scale(&mi, 1.0 / sx, 1, &mi);
  323. gs_matrix_scale(&pim3a.ImageMatrix, 1.0 / sx, 1, &pim3a.ImageMatrix);
  324. }
  325. if (pim3a.Height < pim3a.MaskDict.Height && pim3a.Height > 0) {
  326. int sy = (pim3a.MaskDict.Height + pim3a.Height - 1) / pim3a.Height;
  327. gs_matrix_scale(&mi, 1, 1.0 / sy, &mi);
  328. gs_matrix_scale(&pim3a.ImageMatrix, 1, 1.0 / sy, &pim3a.ImageMatrix);
  329. }
  330. gs_matrix_multiply(&mi, &pim3a.MaskDict.ImageMatrix, &pim3a.MaskDict.ImageMatrix);
  331. pic1 = (gs_image_common_t *)&pim3a;
  332. /* Setting pdev->converting_image_matrix to communicate with pdf_image3_make_mcde. */
  333. gs_matrix_multiply(&mi, &ctm_only(pis), &pdev->converting_image_matrix);
  334. }
  335. /*
  336. * We handle ImageType 3 images in a completely different way:
  337. * the default implementation sets up the enumerator.
  338. */
  339. return gx_begin_image3_generic((gx_device *)pdev, pis, pmat1, pic1,
  340. prect, pdcolor, pcpath, mem,
  341. pdf_image3_make_mid,
  342. pdf_image3_make_mcde, pinfo);
  343. }
  344. case IMAGE3X_IMAGETYPE: {
  345. /* See ImageType3 above for more information. */
  346. const gs_image3x_t *pim3x = (const gs_image3x_t *)pic;
  347. if (pdev->CompatibilityLevel < 1.4)
  348. goto nyi;
  349. if (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
  350. prect->q.x == pim3x->Width &&
  351. prect->q.y == pim3x->Height))
  352. goto nyi;
  353. pdev->image_mask_is_SMask = true;
  354. return gx_begin_image3x_generic((gx_device *)pdev, pis, pmat, pic,
  355. prect, pdcolor, pcpath, mem,
  356. pdf_image3x_make_mid,
  357. pdf_image3x_make_mcde, pinfo);
  358. }
  359. case 4: {
  360. /* Try to convert the image to a plain masked image. */
  361. gx_drawing_color icolor;
  362. pdev->image_mask_is_SMask = false;
  363. if (pdf_convert_image4_to_image1(pdev, pis, pdcolor,
  364. (const gs_image4_t *)pic,
  365. &image[0].type1, &icolor) >= 0) {
  366. gs_state *pgs = (gs_state *)gx_hld_get_gstate_ptr(pis);
  367. if (pgs == NULL)
  368. return_error(gs_error_unregistered); /* Must not happen. */
  369. /* Undo the pop of the NI stack if necessary. */
  370. if (pnamed)
  371. cos_array_add_object(pdev->NI_stack, COS_OBJECT(pnamed));
  372. /* HACK: temporary patch the color space, to allow
  373. pdf_prepare_imagemask to write the right color for the imagemask. */
  374. code = gs_gsave(pgs);
  375. if (code < 0)
  376. return code;
  377. code = gs_setcolorspace(pgs, ((const gs_image4_t *)pic)->ColorSpace);
  378. if (code < 0)
  379. return code;
  380. code = pdf_begin_typed_image(pdev, pis, pmat,
  381. (gs_image_common_t *)&image[0].type1,
  382. prect, &icolor, pcpath, mem,
  383. pinfo, context);
  384. if (code < 0)
  385. return code;
  386. return gs_grestore(pgs);
  387. }
  388. /* No luck. Masked images require PDF 1.3 or higher. */
  389. if (pdev->CompatibilityLevel < 1.2)
  390. goto nyi;
  391. if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
  392. gs_matrix m, m1, mi;
  393. gs_image4_t pi4 = *(const gs_image4_t *)pic;
  394. gs_make_identity(&m1);
  395. gs_matrix_invert(&pic->ImageMatrix, &mi);
  396. gs_matrix_multiply(&mi, &ctm_only(pis), &m);
  397. code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
  398. true, 0, 0, pi4.Width, pi4.Height, false);
  399. if (code < 0)
  400. return code;
  401. cvd->mdev.is_open = true; /* fixme: same as above. */
  402. cvd->mask->is_open = true; /* fixme: same as above. */
  403. cvd->mask_is_empty = false;
  404. code = (*dev_proc(cvd->mask, fill_rectangle))((gx_device *)cvd->mask,
  405. 0, 0, cvd->mask->width, cvd->mask->height, (gx_color_index)0);
  406. if (code < 0)
  407. return code;
  408. gx_device_retain((gx_device *)cvd, true);
  409. gx_device_retain((gx_device *)cvd->mask, true);
  410. gs_make_identity(&pi4.ImageMatrix);
  411. code = gx_default_begin_typed_image((gx_device *)cvd,
  412. pis, &m1, (gs_image_common_t *)&pi4, prect, pdcolor, NULL, mem, pinfo);
  413. if (code < 0)
  414. return code;
  415. (*pinfo)->procs = &pdf_image_cvd_enum_procs;
  416. return 0;
  417. }
  418. image[0].type4 = *(const gs_image4_t *)pic;
  419. break;
  420. }
  421. default:
  422. goto nyi;
  423. }
  424. pim = (const gs_pixel_image_t *)pic;
  425. format = pim->format;
  426. switch (format) {
  427. case gs_image_format_chunky:
  428. case gs_image_format_component_planar:
  429. break;
  430. default:
  431. goto nyi;
  432. }
  433. /* AR5 on Windows doesn't support 0-size images. Skipping. */
  434. if (pim->Width == 0 || pim->Height == 0)
  435. goto nyi;
  436. /* PDF doesn't support images with more than 8 bits per component. */
  437. if (pim->BitsPerComponent > 8)
  438. goto nyi;
  439. pcs = pim->ColorSpace;
  440. num_components = (is_mask ? 1 : gs_color_space_num_components(pcs));
  441. if (pdf_must_put_clip_path(pdev, pcpath))
  442. code = pdf_unclip(pdev);
  443. else
  444. code = pdf_open_page(pdev, PDF_IN_STREAM);
  445. if (code < 0)
  446. return code;
  447. if (context == PDF_IMAGE_TYPE3_MASK) {
  448. /*
  449. * The soft mask for an ImageType 3x image uses a DevicePixel
  450. * color space, which pdf_color_space() can't handle. Patch it
  451. * to DeviceGray here.
  452. */
  453. gs_cspace_init_DeviceGray(pdev->memory, &cs_gray_temp);
  454. pcs = &cs_gray_temp;
  455. } else if (is_mask)
  456. code = pdf_prepare_imagemask(pdev, pis, pdcolor);
  457. else
  458. code = pdf_prepare_image(pdev, pis);
  459. if (code < 0)
  460. goto nyi;
  461. code = pdf_put_clip_path(pdev, pcpath);
  462. if (code < 0)
  463. return code;
  464. if (prect)
  465. rect = *prect;
  466. else {
  467. rect.p.x = rect.p.y = 0;
  468. rect.q.x = pim->Width, rect.q.y = pim->Height;
  469. }
  470. pie = gs_alloc_struct(mem, pdf_image_enum, &st_pdf_image_enum,
  471. "pdf_begin_image");
  472. if (pie == 0)
  473. return_error(gs_error_VMerror);
  474. memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
  475. *pinfo = (gx_image_enum_common_t *) pie;
  476. gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim,
  477. ((pdev->CompatibilityLevel >= 1.3) ?
  478. (context == PDF_IMAGE_TYPE3_MASK ?
  479. &pdf_image_object_enum_procs :
  480. &pdf_image_enum_procs) :
  481. context == PDF_IMAGE_TYPE3_MASK ?
  482. &pdf_image_object_enum_procs :
  483. context == PDF_IMAGE_TYPE3_DATA ?
  484. &pdf_image_object_enum_procs2 :
  485. &pdf_image_enum_procs),
  486. (gx_device *)pdev, num_components, format);
  487. pie->memory = mem;
  488. width = rect.q.x - rect.p.x;
  489. pie->width = width;
  490. height = rect.q.y - rect.p.y;
  491. pie->bits_per_pixel =
  492. pim->BitsPerComponent * num_components / pie->num_planes;
  493. pie->rows_left = height;
  494. if (pnamed != 0) /* Don't in-line the image if it is named. */
  495. in_line = false;
  496. else {
  497. double nbytes = (double)(((ulong) pie->width * pie->bits_per_pixel + 7) >> 3) *
  498. pie->num_planes * pie->rows_left;
  499. in_line &= (nbytes < pdev->MaxInlineImageSize);
  500. }
  501. if (rect.p.x != 0 || rect.p.y != 0 ||
  502. rect.q.x != pim->Width || rect.q.y != pim->Height ||
  503. (is_mask && pim->CombineWithColor)
  504. /* Color space setup used to be done here: see SRZB comment below. */
  505. ) {
  506. gs_free_object(mem, pie, "pdf_begin_image");
  507. goto nyi;
  508. }
  509. if (pmat == 0)
  510. pmat = &ctm_only(pis);
  511. {
  512. gs_matrix mat;
  513. gs_matrix bmat;
  514. int code;
  515. pdf_make_bitmap_matrix(&bmat, -rect.p.x, -rect.p.y,
  516. pim->Width, pim->Height, height);
  517. if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
  518. (code = gs_matrix_multiply(&bmat, &mat, &mat)) < 0 ||
  519. (code = gs_matrix_multiply(&mat, pmat, &pie->mat)) < 0
  520. ) {
  521. gs_free_object(mem, pie, "pdf_begin_image");
  522. return code;
  523. }
  524. /* AR3,AR4 show no image when CTM is singular; AR5 reports an error */
  525. if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx) {
  526. gs_free_object(mem, pie, "pdf_begin_image");
  527. goto nyi;
  528. }
  529. }
  530. pdf_image_writer_init(&pie->writer);
  531. pie->writer.alt_writer_count = (in_line ||
  532. (pim->Width <= 64 && pim->Height <= 64) ||
  533. pdev->transfer_not_identity ? 1 : 2);
  534. image[1] = image[0];
  535. names = (in_line ? &pdf_color_space_names_short : &pdf_color_space_names);
  536. if (psdf_is_converting_image_to_RGB((gx_device_psdf *)pdev, pis, pim)) {
  537. /* psdf_setup_image_filters may change the color space
  538. * (in case of pdev->params.ConvertCMYKImagesToRGB == true).
  539. * Account it here.
  540. */
  541. cos_c_string_value(&cs_value, names->DeviceRGB);
  542. } else if (!is_mask) {
  543. code = pdf_color_space(pdev, &cs_value, &pranges,
  544. pcs,
  545. names, in_line);
  546. if (code < 0) {
  547. const char *sname;
  548. convert_to_process_colors = true;
  549. switch (pdev->pcm_color_info_index) {
  550. case gs_color_space_index_DeviceGray: sname = names->DeviceGray; break;
  551. case gs_color_space_index_DeviceRGB: sname = names->DeviceRGB; break;
  552. case gs_color_space_index_DeviceCMYK: sname = names->DeviceCMYK; break;
  553. default:
  554. eprintf("Unsupported ProcessColorModel.");
  555. return_error(gs_error_undefined);
  556. }
  557. cos_c_string_value(&cs_value, sname);
  558. }
  559. }
  560. if ((code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
  561. height, pnamed, in_line)) < 0 ||
  562. /*
  563. * Some regrettable PostScript code (such as LanguageLevel 1 output
  564. * from Microsoft's PSCRIPT.DLL driver) misuses the transfer
  565. * function to accomplish the equivalent of indexed color.
  566. * Downsampling (well, only averaging) or JPEG compression are not
  567. * compatible with this. Play it safe by using only lossless
  568. * filters if the transfer function(s) is/are other than the
  569. * identity.
  570. */
  571. (code = (pie->writer.alt_writer_count == 1 ?
  572. psdf_setup_lossless_filters((gx_device_psdf *) pdev,
  573. &pie->writer.binary[0],
  574. &image[0].pixel) :
  575. psdf_setup_image_filters((gx_device_psdf *) pdev,
  576. &pie->writer.binary[0], &image[0].pixel,
  577. pmat, pis, true))) < 0
  578. )
  579. goto fail;
  580. if (convert_to_process_colors) {
  581. code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
  582. (gx_device_psdf *)pdev, &image[0].pixel, pis,
  583. pdev->pcm_color_info_index);
  584. if (code < 0)
  585. goto fail;
  586. }
  587. if (pie->writer.alt_writer_count > 1) {
  588. code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]);
  589. if (code)
  590. goto fail;
  591. code = psdf_setup_image_filters((gx_device_psdf *) pdev,
  592. &pie->writer.binary[1], &image[1].pixel,
  593. pmat, pis, false);
  594. if (code == gs_error_rangecheck) {
  595. /* setup_image_compression rejected the alternative compression. */
  596. pie->writer.alt_writer_count = 1;
  597. memset(pie->writer.binary + 1, 0, sizeof(pie->writer.binary[1]));
  598. memset(pie->writer.binary + 2, 0, sizeof(pie->writer.binary[1]));
  599. } else if (code)
  600. goto fail;
  601. else if (convert_to_process_colors) {
  602. code = psdf_setup_image_colors_filter(&pie->writer.binary[1],
  603. (gx_device_psdf *)pdev, &image[1].pixel, pis,
  604. pdev->pcm_color_info_index);
  605. if (code < 0)
  606. goto fail;
  607. }
  608. }
  609. for (i = 0; i < pie->writer.alt_writer_count; i++) {
  610. code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
  611. &image[i].pixel, &cs_value, pie);
  612. if (code < 0)
  613. goto fail;
  614. }
  615. if (pie->writer.alt_writer_count == 2) {
  616. psdf_setup_compression_chooser(&pie->writer.binary[2],
  617. (gx_device_psdf *)pdev, pim->Width, pim->Height,
  618. num_components, pim->BitsPerComponent);
  619. pie->writer.alt_writer_count = 3;
  620. }
  621. if (pic->type->index == 4 && pdev->CompatibilityLevel < 1.3) {
  622. int i;
  623. /* Create a stream for writing the mask. */
  624. i = pie->writer.alt_writer_count;
  625. gs_image_t_init_mask_adjust((gs_image_t *)&image[i].type1, true, false);
  626. image[i].type1.Width = image[0].pixel.Width;
  627. image[i].type1.Height = image[0].pixel.Height;
  628. /* Won't use image[2]. */
  629. code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
  630. height, NULL, false);
  631. if (code)
  632. goto fail;
  633. code = psdf_setup_image_filters((gx_device_psdf *) pdev,
  634. &pie->writer.binary[i], &image[i].pixel,
  635. pmat, pis, true);
  636. if (code < 0)
  637. goto fail;
  638. psdf_setup_image_to_mask_filter(&pie->writer.binary[i],
  639. (gx_device_psdf *)pdev, pim->Width, pim->Height,
  640. num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
  641. code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
  642. &image[i].pixel, &cs_value, pie);
  643. if (code < 0)
  644. goto fail;
  645. ++pie->writer.alt_writer_count;
  646. /* Note : Possible values for alt_writer_count are 1,2,3, 4.
  647. 1 means no alternative streams.
  648. 2 means the main image stream and a mask stream while converting
  649. an Image Type 4.
  650. 3 means the main image steram, alternative image compression stream,
  651. and the compression chooser.
  652. 4 meams 3 and a mask stream while convertingh an Image Type 4.
  653. */
  654. }
  655. return 0;
  656. fail:
  657. /****** SHOULD FREE STRUCTURES AND CLEAN UP HERE ******/
  658. /* Fall back to the default implementation. */
  659. nyi:
  660. return gx_default_begin_typed_image
  661. ((gx_device *)pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
  662. pinfo);
  663. }
  664. int
  665. gdev_pdf_begin_typed_image(gx_device * dev, const gs_imager_state * pis,
  666. const gs_matrix *pmat, const gs_image_common_t *pic,
  667. const gs_int_rect * prect,
  668. const gx_drawing_color * pdcolor,
  669. const gx_clip_path * pcpath, gs_memory_t * mem,
  670. gx_image_enum_common_t ** pinfo)
  671. {
  672. return pdf_begin_typed_image((gx_device_pdf *)dev, pis, pmat, pic, prect,
  673. pdcolor, pcpath, mem, pinfo,
  674. PDF_IMAGE_DEFAULT);
  675. }
  676. /* ---------------- All images ---------------- */
  677. /* Process the next piece of an image. */
  678. private int
  679. pdf_image_plane_data_alt(gx_image_enum_common_t * info,
  680. const gx_image_plane_t * planes, int height,
  681. int *rows_used, int alt_writer_index)
  682. {
  683. pdf_image_enum *pie = (pdf_image_enum *) info;
  684. int h = height;
  685. int y;
  686. /****** DOESN'T HANDLE IMAGES WITH VARYING WIDTH PER PLANE ******/
  687. uint width_bits = pie->width * pie->plane_depths[0];
  688. /****** DOESN'T HANDLE NON-ZERO data_x CORRECTLY ******/
  689. uint bcount = (width_bits + 7) >> 3;
  690. uint ignore;
  691. int nplanes = pie->num_planes;
  692. int status = 0;
  693. if (h > pie->rows_left)
  694. h = pie->rows_left;
  695. for (y = 0; y < h; ++y) {
  696. if (nplanes > 1) {
  697. /*
  698. * We flip images in blocks, and each block except the last one
  699. * must contain an integral number of pixels. The easiest way
  700. * to meet this condition is for all blocks except the last to
  701. * be a multiple of 3 source bytes (guaranteeing an integral
  702. * number of 1/2/4/8/12-bit samples), i.e., 3*nplanes flipped
  703. * bytes. This requires a buffer of at least
  704. * 3*GS_IMAGE_MAX_COMPONENTS bytes.
  705. */
  706. int pi;
  707. uint count = bcount;
  708. uint offset = 0;
  709. #define ROW_BYTES max(200 /*arbitrary*/, 3 * GS_IMAGE_MAX_COMPONENTS)
  710. const byte *bit_planes[GS_IMAGE_MAX_COMPONENTS];
  711. int block_bytes = ROW_BYTES / (3 * nplanes) * 3;
  712. byte row[ROW_BYTES];
  713. for (pi = 0; pi < nplanes; ++pi)
  714. bit_planes[pi] = planes[pi].data + planes[pi].raster * y;
  715. while (count) {
  716. uint flip_count;
  717. uint flipped_count;
  718. if (count >= block_bytes) {
  719. flip_count = block_bytes;
  720. flipped_count = block_bytes * nplanes;
  721. } else {
  722. flip_count = count;
  723. flipped_count =
  724. (width_bits % (block_bytes * 8) * nplanes + 7) >> 3;
  725. }
  726. image_flip_planes(row, bit_planes, offset, flip_count,
  727. nplanes, pie->plane_depths[0]);
  728. status = sputs(pie->writer.binary[alt_writer_index].strm, row,
  729. flipped_count, &ignore);
  730. if (status < 0)
  731. break;
  732. offset += flip_count;
  733. count -= flip_count;
  734. }
  735. } else {
  736. status = sputs(pie->writer.binary[alt_writer_index].strm,
  737. planes[0].data + planes[0].raster * y, bcount,
  738. &ignore);
  739. }
  740. if (status < 0)
  741. break;
  742. }
  743. *rows_used = h;
  744. if (status < 0)
  745. return_error(gs_error_ioerror);
  746. return !pie->rows_left;
  747. #undef ROW_BYTES
  748. }
  749. private int
  750. pdf_image_plane_data(gx_image_enum_common_t * info,
  751. const gx_image_plane_t * planes, int height,
  752. int *rows_used)
  753. {
  754. pdf_image_enum *pie = (pdf_image_enum *) info;
  755. int i;
  756. for (i = 0; i < pie->writer.alt_writer_count; i++) {
  757. int code = pdf_image_plane_data_alt(info, planes, height, rows_used, i);
  758. if (code)
  759. return code;
  760. }
  761. pie->rows_left -= *rows_used;
  762. if (pie->writer.alt_writer_count > 2)
  763. pdf_choose_compression(&pie->writer, false);
  764. return !pie->rows_left;
  765. }
  766. private int
  767. use_image_as_pattern(gx_device_pdf *pdev, pdf_resource_t *pres1,
  768. const gs_matrix *pmat, gs_id id)
  769. { /* See also dump_image in gdevpdfd.c . */
  770. gs_imager_state s;
  771. gs_pattern1_instance_t inst;
  772. cos_value_t v;
  773. const pdf_resource_t *pres;
  774. int code;
  775. memset(&s, 0, sizeof(s));
  776. s.ctm.xx = pmat->xx;
  777. s.ctm.xy = pmat->xy;
  778. s.ctm.yx = pmat->yx;
  779. s.ctm.yy = pmat->yy;
  780. s.ctm.tx = pmat->tx;
  781. s.ctm.ty = pmat->ty;
  782. memset(&inst, 0, sizeof(inst));
  783. inst.saved = (gs_state *)&s; /* HACK : will use s.ctm only. */
  784. inst.template.PaintType = 1;
  785. inst.template.TilingType = 1;
  786. inst.template.BBox.p.x = inst.template.BBox.p.y = 0;
  787. inst.template.BBox.q.x = 1;
  788. inst.template.BBox.q.y = 1;
  789. inst.template.XStep = 2; /* Set 2 times bigger step against artifacts. */
  790. inst.template.YStep = 2;
  791. code = (*dev_proc(pdev, pattern_manage))((gx_device *)pdev,
  792. id, &inst, pattern_manage__start_accum);
  793. if (code >= 0)
  794. pprintld1(pdev->strm, "/R%ld Do\n", pdf_resource_id(pres1));
  795. pres = pdev->accumulating_substream_resource;
  796. if (code >= 0)
  797. code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres1);
  798. if (code >= 0)
  799. code = (*dev_proc(pdev, pattern_manage))((gx_device *)pdev,
  800. id, &inst, pattern_manage__finish_accum);
  801. if (code >= 0)
  802. code = (*dev_proc(pdev, pattern_manage))((gx_device *)pdev,
  803. id, &inst, pattern_manage__load);
  804. if (code >= 0) {
  805. stream_puts(pdev->strm, "q ");
  806. code = pdf_cs_Pattern_colored(pdev, &v);
  807. }
  808. if (code >= 0) {
  809. cos_value_write(&v, pdev);
  810. pprintld1(pdev->strm, " cs /R%ld scn ", pdf_resource_id(pres));
  811. }
  812. if (code >= 0) {
  813. /* The image offset weas broken in gx_begin_image3_generic,
  814. (see 'origin' in there).
  815. As a temporary hack use the offset of the image.
  816. fixme : This isn't generally correct,
  817. because the mask may be "transpozed" against the image. */
  818. gs_matrix m = pdev->converting_image_matrix;
  819. m.tx = pmat->tx;
  820. m.ty = pmat->ty;
  821. code = pdf_do_image_by_id(pdev, pdev->image_mask_scale,
  822. &m, true, pdev->image_mask_id);
  823. stream_puts(pdev->strm, "Q\n");
  824. }
  825. return code;
  826. }
  827. typedef enum {
  828. USE_AS_MASK,
  829. USE_AS_IMAGE,
  830. USE_AS_PATTERN
  831. } pdf_image_usage_t;
  832. /* Close PDF image and do it. */
  833. private int
  834. pdf_end_and_do_image(gx_device_pdf *pdev, pdf_image_writer *piw,
  835. const gs_matrix *mat, gs_id ps_bitmap_id, pdf_image_usage_t do_image)
  836. {
  837. int code = pdf_end_write_image(pdev, piw);
  838. pdf_resource_t *pres = piw->pres;
  839. switch (code) {
  840. default:
  841. return code; /* error */
  842. case 1:
  843. code = 0;
  844. break;
  845. case 0:
  846. if (do_image == USE_AS_IMAGE) {
  847. if (pdev->image_mask_id != gs_no_id) {
  848. char buf[20];
  849. sprintf(buf, "%ld 0 R", pdev->image_mask_id);
  850. code = cos_dict_put_string_copy((cos_dict_t *)pres->object,
  851. pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf);
  852. if (code < 0)
  853. return code;
  854. }
  855. if (pdev->image_mask_skip)
  856. code = 0;
  857. else
  858. code = pdf_do_image(pdev, pres, mat, true);
  859. } else if (do_image == USE_AS_MASK) {
  860. /* Provide data for pdf_do_image_by_id, which will be called through
  861. use_image_as_pattern during the next call to this function.
  862. See pdf_do_image about the meaning of 'scale'. */
  863. const pdf_x_object_t *const pxo = (const pdf_x_object_t *)pres;
  864. pdev->image_mask_scale = (double)pxo->data_height / pxo->height;
  865. pdev->image_mask_id = pdf_resource_id(pres);
  866. pdev->converting_image_matrix = *mat;
  867. } else if (do_image == USE_AS_PATTERN)
  868. code = use_image_as_pattern(pdev, pres, mat, ps_bitmap_id);
  869. }
  870. return code;
  871. }
  872. /* Clean up by releasing the buffers. */
  873. private int
  874. pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
  875. pdf_image_usage_t do_image)
  876. {
  877. gx_device_pdf *pdev = (gx_device_pdf *)info->dev;
  878. pdf_image_enum *pie = (pdf_image_enum *)info;
  879. int height = pie->writer.height;
  880. int data_height = height - pie->rows_left;
  881. int code = 0;
  882. if (pie->writer.pres)
  883. ((pdf_x_object_t *)pie->writer.pres)->data_height = data_height;
  884. else if (data_height > 0)
  885. pdf_put_image_matrix(pdev, &pie->mat, (double)data_height / height);
  886. if (data_height > 0) {
  887. code = pdf_complete_image_data(pdev, &pie->writer, data_height,
  888. pie->width, pie->bits_per_pixel);
  889. if (code < 0)
  890. return code;
  891. code = pdf_end_image_binary(pdev, &pie->writer, data_height);
  892. /* The call above possibly decreases pie->writer.alt_writer_count in 2. */
  893. if (code < 0)
  894. return code;
  895. if (pie->writer.alt_writer_count == 2) {
  896. /* We're converting a type 4 image into an imagemask with a pattern color. */
  897. /* Since the type 3 image writes the mask first, do so here. */
  898. pdf_image_writer writer = pie->writer;
  899. writer.binary[0] = pie->writer.binary[1];
  900. writer.pres = pie->writer.pres_mask;
  901. writer.alt_writer_count = 1;
  902. memset(&pie->writer.binary[1], 0, sizeof(pie->writer.binary[1]));
  903. pie->writer.alt_writer_count--; /* For GC. */
  904. pie->writer.pres_mask = 0; /* For GC. */
  905. code = pdf_end_image_binary(pdev, &writer, data_height);
  906. if (code < 0)
  907. return code;
  908. code = pdf_end_and_do_image(pdev, &writer, &pie->mat, info->id, USE_AS_MASK);
  909. if (code < 0)
  910. return code;
  911. code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, USE_AS_PATTERN);
  912. } else
  913. code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, do_image);
  914. pie->writer.alt_writer_count--; /* For GC. */
  915. }
  916. gs_free_object(pie->memory, pie, "pdf_end_image");
  917. return code;
  918. }
  919. /* End a normal image, drawing it. */
  920. private int
  921. pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last)
  922. {
  923. return pdf_image_end_image_data(info, draw_last, USE_AS_IMAGE);
  924. }
  925. /* End an image converted with pdf_lcvd_t. */
  926. private int
  927. pdf_image_end_image_cvd(gx_image_enum_common_t * info, bool draw_last)
  928. { pdf_lcvd_t *cvd = (pdf_lcvd_t *)info->dev;
  929. int code = pdf_dump_converted_image(cvd->pdev, cvd);
  930. int code1 = gx_image1_end_image(info, draw_last);
  931. int code2 = gs_closedevice((gx_device *)cvd->mask);
  932. int code3 = gs_closedevice((gx_device *)cvd);
  933. gs_free_object(cvd->mask->memory, (gx_device *)cvd->mask, "pdf_image_end_image_cvd");
  934. gs_free_object(cvd->mdev.memory, (gx_device *)cvd, "pdf_image_end_image_cvd");
  935. return code < 0 ? code : code1 < 0 ? code1 : code2 < 0 ? code2 : code3;
  936. }
  937. /* ---------------- Type 3/3x images ---------------- */
  938. /*
  939. * For both types of masked images, we create temporary dummy (null) devices
  940. * that forward the begin_typed_image call to the implementation above.
  941. */
  942. private int
  943. pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem)
  944. {
  945. gx_device *fdev;
  946. int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem);
  947. if (code < 0)
  948. return code;
  949. gx_device_set_target((gx_device_forward *)fdev, tdev);
  950. *pmxdev = fdev;
  951. return 0;
  952. }
  953. /* End the mask of an ImageType 3 image, not drawing it. */
  954. private int
  955. pdf_image_end_image_object(gx_image_enum_common_t * info, bool draw_last)
  956. {
  957. return pdf_image_end_image_data(info, draw_last, USE_AS_MASK);
  958. }
  959. /* End the data of an ImageType 3 image, converting it into pattern. */
  960. private int
  961. pdf_image_end_image_object2(gx_image_enum_common_t * info, bool draw_last)
  962. {
  963. return pdf_image_end_image_data(info, draw_last, USE_AS_PATTERN);
  964. }
  965. /* ---------------- Type 3 images ---------------- */
  966. /* Implement the mask image device. */
  967. private dev_proc_begin_typed_image(pdf_mid_begin_typed_image);
  968. private int
  969. pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
  970. gs_memory_t *mem)
  971. {
  972. gx_device_pdf *pdev = (gx_device_pdf *)dev;
  973. if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
  974. gs_matrix m;
  975. pdf_lcvd_t *cvd = NULL;
  976. int code;
  977. gs_make_identity(&m);
  978. code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
  979. true, 0, 0, width, height, true);
  980. if (code < 0)
  981. return code;
  982. cvd->mask->target = (gx_device *)cvd; /* Temporary, just to communicate with
  983. pdf_image3_make_mcde. The latter will reset it. */
  984. cvd->mask_is_empty = false;
  985. *pmidev = (gx_device *)cvd->mask;
  986. return 0;
  987. } else {
  988. int code = pdf_make_mxd(pmidev, dev, mem);
  989. if (code < 0)
  990. return code;
  991. set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
  992. return 0;
  993. }
  994. }
  995. private int
  996. pdf_mid_begin_typed_image(gx_device * dev, const gs_imager_state * pis,
  997. const gs_matrix *pmat, const gs_image_common_t *pic,
  998. const gs_int_rect * prect,
  999. const gx_drawing_color * pdcolor,
  1000. const gx_clip_path * pcpath, gs_memory_t * mem,
  1001. gx_image_enum_common_t ** pinfo)
  1002. {
  1003. /* The target of the null device is the pdfwrite device. */
  1004. gx_device_pdf *const pdev = (gx_device_pdf *)
  1005. ((gx_device_null *)dev)->target;
  1006. return pdf_begin_typed_image
  1007. (pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, pinfo,
  1008. PDF_IMAGE_TYPE3_MASK);
  1009. }
  1010. /* Implement the mask clip device. */
  1011. private int
  1012. pdf_image3_make_mcde(gx_device *dev, const gs_imager_state *pis,
  1013. const gs_matrix *pmat, const gs_image_common_t *pic,
  1014. const gs_int_rect *prect, const gx_drawing_color *pdcolor,
  1015. const gx_clip_path *pcpath, gs_memory_t *mem,
  1016. gx_image_enum_common_t **pinfo,
  1017. gx_device **pmcdev, gx_device *midev,
  1018. gx_image_enum_common_t *pminfo,
  1019. const gs_int_point *origin)
  1020. {
  1021. int code;
  1022. gx_device_pdf *pdev = (gx_device_pdf *)dev;
  1023. if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
  1024. /* pdf_image3_make_mid must set midev with a pdf_lcvd_t instance.*/
  1025. pdf_lcvd_t *cvd = (pdf_lcvd_t *)((gx_device_memory *)midev)->target;
  1026. ((gx_device_memory *)midev)->target = NULL;
  1027. cvd->m = pdev->converting_image_matrix;
  1028. cvd->mdev.mapped_x = origin->x;
  1029. cvd->mdev.mapped_y = origin->y;
  1030. *pmcdev = (gx_device *)&cvd->mdev;
  1031. code = gx_default_begin_typed_image
  1032. ((gx_device *)&cvd->mdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
  1033. pinfo);
  1034. } else {
  1035. code = pdf_make_mxd(pmcdev, midev, mem);
  1036. if (code < 0)
  1037. return code;
  1038. code = pdf_begin_typed_image
  1039. ((gx_device_pdf *)dev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
  1040. pinfo, PDF_IMAGE_TYPE3_DATA);
  1041. }
  1042. /* Due to equal image merging, we delay the adding of the "Mask" entry into
  1043. a type 3 image dictionary until the mask is completed.
  1044. Will do in pdf_end_and_do_image.*/
  1045. return 0;
  1046. }
  1047. /* ---------------- Type 3x images ---------------- */
  1048. /* Implement the mask image device. */
  1049. private int
  1050. pdf_image3x_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
  1051. int depth, gs_memory_t *mem)
  1052. {
  1053. int code = pdf_make_mxd(pmidev, dev, mem);
  1054. if (code < 0)
  1055. return code;
  1056. set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
  1057. return 0;
  1058. }
  1059. /* Implement the mask clip device. */
  1060. private int
  1061. pdf_image3x_make_mcde(gx_device *dev, const gs_imager_state *pis,
  1062. const gs_matrix *pmat, const gs_image_common_t *pic,
  1063. const gs_int_rect *prect,
  1064. const gx_drawing_color *pdcolor,
  1065. const gx_clip_path *pcpath, gs_memory_t *mem,
  1066. gx_image_enum_common_t **pinfo,
  1067. gx_device **pmcdev, gx_device *midev[2],
  1068. gx_image_enum_common_t *pminfo[2],
  1069. const gs_int_point origin[2],
  1070. const gs_image3x_t *pim)
  1071. {
  1072. int code;
  1073. pdf_image_enum *pmie;
  1074. pdf_image_enum *pmce;
  1075. cos_stream_t *pmcs;
  1076. int i;
  1077. const gs_image3x_mask_t *pixm;
  1078. if (midev[0]) {
  1079. if (midev[1])
  1080. return_error(gs_error_rangecheck);
  1081. i = 0, pixm = &pim->Opacity;
  1082. } else if (midev[1])
  1083. i = 1, pixm = &pim->Shape;
  1084. else
  1085. return_error(gs_error_rangecheck);
  1086. code = pdf_make_mxd(pmcdev, midev[i], mem);
  1087. if (code < 0)
  1088. return code;
  1089. code = pdf_begin_typed_image
  1090. ((gx_device_pdf *)dev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
  1091. pinfo, PDF_IMAGE_TYPE3_DATA);
  1092. if (code < 0)
  1093. return code;
  1094. if ((*pinfo)->procs != &pdf_image_enum_procs) {
  1095. /* We couldn't handle the image. Bail out. */
  1096. gx_image_end(*pinfo, false);
  1097. gs_free_object(mem, *pmcdev, "pdf_image3x_make_mcde");
  1098. return_error(gs_error_rangecheck);
  1099. }
  1100. pmie = (pdf_image_enum *)pminfo[i];
  1101. pmce = (pdf_image_enum *)(*pinfo);
  1102. pmcs = (cos_stream_t *)pmce->writer.pres->object;
  1103. /*
  1104. * Add the SMask entry to the image dictionary, and, if needed,
  1105. * the Matte entry to the mask dictionary.
  1106. */
  1107. if (pixm->has_Matte) {
  1108. int num_components =
  1109. gs_color_space_num_components(pim->ColorSpace);
  1110. code = cos_dict_put_c_key_floats(
  1111. (cos_dict_t *)pmie->writer.pres->object,
  1112. "/Matte", pixm->Matte,
  1113. num_components);
  1114. if (code < 0)
  1115. return code;
  1116. }
  1117. return cos_dict_put_c_key_object(cos_stream_dict(pmcs), "/SMask",
  1118. pmie->writer.pres->object);
  1119. }
  1120. pdf_resource_t *pdf_substitute_pattern(pdf_resource_t *pres)
  1121. {
  1122. pdf_pattern_t *ppat = (pdf_pattern_t *)pres;
  1123. return (pdf_resource_t *)(ppat->substitute != 0 ? ppat->substitute : ppat);
  1124. }
  1125. private int
  1126. check_unsubstituted2(gx_device_pdf * pdev, pdf_resource_t *pres0, pdf_resource_t *pres1)
  1127. {
  1128. pdf_pattern_t *ppat = (pdf_pattern_t *)pres0;
  1129. return ppat->substitute == NULL;
  1130. }
  1131. private int
  1132. check_unsubstituted1(gx_device_pdf * pdev, pdf_resource_t *pres0)
  1133. {
  1134. pdf_pattern_t *ppat = (pdf_pattern_t *)pres0;
  1135. return ppat->substitute != NULL;
  1136. }
  1137. /*
  1138. The pattern management device method.
  1139. See gxdevcli.h about return codes.
  1140. */
  1141. int
  1142. gdev_pdf_pattern_manage(gx_device *pdev1, gx_bitmap_id id,
  1143. gs_pattern1_instance_t *pinst, pattern_manage_t function)
  1144. {
  1145. gx_device_pdf *pdev = (gx_device_pdf *)pdev1;
  1146. int code;
  1147. pdf_resource_t *pres, *pres1;
  1148. switch (function) {
  1149. case pattern_manage__can_accum:
  1150. return 1;
  1151. case pattern_manage__start_accum:
  1152. code = pdf_enter_substream(pdev, resourcePattern, id, &pres, false,
  1153. pdev->CompressFonts/* Have no better switch.*/);
  1154. if (code < 0)
  1155. return code;
  1156. pres->rid = id;
  1157. code = pdf_store_pattern1_params(pdev, pres, pinst);
  1158. if (code < 0)
  1159. return code;
  1160. return 1;
  1161. case pattern_manage__finish_accum:
  1162. code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
  1163. if (code < 0)
  1164. return code;
  1165. pres = pres1 = pdev->accumulating_substream_resource;
  1166. code = pdf_exit_substream(pdev);
  1167. if (code < 0)
  1168. return code;
  1169. if (pdev->substituted_pattern_count > 300 &&
  1170. pdev->substituted_pattern_drop_page != pdev->next_page) { /* arbitrary */
  1171. pdf_drop_resources(pdev, resourcePattern, check_unsubstituted1);
  1172. pdev->substituted_pattern_count = 0;
  1173. pdev->substituted_pattern_drop_page = pdev->next_page;
  1174. }
  1175. code = pdf_find_same_resource(pdev, resourcePattern, &pres, check_unsubstituted2);
  1176. if (code < 0)
  1177. return code;
  1178. if (code > 0) {
  1179. pdf_pattern_t *ppat = (pdf_pattern_t *)pres1;
  1180. code = pdf_cancel_resource(pdev, pres1, resourcePattern);
  1181. if (code < 0)
  1182. return code;
  1183. /* Do not remove pres1, because it keeps the substitution. */
  1184. ppat->substitute = (pdf_pattern_t *)pres;
  1185. pres->where_used |= pdev->used_mask;
  1186. pdev->substituted_pattern_count++;
  1187. } else if (pres->object->id < 0)
  1188. pdf_reserve_object_id(pdev, pres, 0);
  1189. return 1;
  1190. case pattern_manage__load:
  1191. pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, id);
  1192. if (pres == 0)
  1193. return gs_error_undefined;
  1194. pres = pdf_substitute_pattern(pres);
  1195. code = pdf_add_resource(pdev, pdev->substream_Resources, "/Pattern", pres);
  1196. if (code < 0)
  1197. return code;
  1198. return 1;
  1199. case pattern_manage__shading_area:
  1200. return 0;
  1201. }
  1202. return_error(gs_error_unregistered);
  1203. }