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