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