1 /* Copyright (C) 2001-2019 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,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
13 CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Image handling for PDF-writing driver */
18 #include "memory_.h"
19 #include "math_.h"
20 #include "gx.h"
21 #include "gserrors.h"
22 #include "gsdevice.h"
23 #include "gsflip.h"
24 #include "gsstate.h"
25 #include "gscolor2.h"
26 #include "gdevpdfx.h"
27 #include "gdevpdfg.h"
28 #include "gdevpdfo.h" /* for data stream */
29 #include "gxcspace.h"
30 #include "gximage3.h"
31 #include "gximag3x.h"
32 #include "gsiparm4.h"
33 #include "gxdcolor.h"
34 #include "gxpcolor.h"
35 #include "gxcolor2.h"
36 #include "gxhldevc.h"
37 #include "gxdevsop.h"
38 #include "gsicc_manage.h"
39 #include "gsform1.h"
40 #include "gxpath.h"
41
42 /* Forward references */
43 static image_enum_proc_plane_data(pdf_image_plane_data);
44 static image_enum_proc_end_image(pdf_image_end_image);
45 static image_enum_proc_end_image(pdf_image_end_image_object);
46 static image_enum_proc_end_image(pdf_image_end_image_object2);
47 static image_enum_proc_end_image(pdf_image_end_image_cvd);
48 static IMAGE3_MAKE_MID_PROC(pdf_image3_make_mid);
49 static IMAGE3_MAKE_MCDE_PROC(pdf_image3_make_mcde);
50 static IMAGE3X_MAKE_MID_PROC(pdf_image3x_make_mid);
51 static IMAGE3X_MAKE_MCDE_PROC(pdf_image3x_make_mcde);
52
53 static const gx_image_enum_procs_t pdf_image_enum_procs = {
54 pdf_image_plane_data,
55 pdf_image_end_image
56 };
57 static const gx_image_enum_procs_t pdf_image_object_enum_procs = {
58 pdf_image_plane_data,
59 pdf_image_end_image_object
60 };
61 static const gx_image_enum_procs_t pdf_image_object_enum_procs2 = {
62 pdf_image_plane_data,
63 pdf_image_end_image_object2
64 };
65 static const gx_image_enum_procs_t pdf_image_cvd_enum_procs = {
66 gx_image1_plane_data,
67 pdf_image_end_image_cvd,
68 gx_image1_flush
69 };
70
71 /* ---------------- Driver procedures ---------------- */
72
73 /* Define the structure for keeping track of progress through an image. */
74 typedef struct pdf_image_enum_s {
75 gx_image_enum_common;
76 int width;
77 int bits_per_pixel; /* bits per pixel (per plane) */
78 int rows_left;
79 pdf_image_writer writer;
80 gs_matrix mat;
81 gs_color_space_index initial_colorspace;
82 int JPEG_PassThrough;
83 } pdf_image_enum;
84 gs_private_st_composite(st_pdf_image_enum, pdf_image_enum, "pdf_image_enum",
85 pdf_image_enum_enum_ptrs, pdf_image_enum_reloc_ptrs);
86 /* GC procedures */
87 static ENUM_PTRS_WITH(pdf_image_enum_enum_ptrs, pdf_image_enum *pie)
88 if (index < pdf_image_writer_max_ptrs) {
89 gs_ptr_type_t ret =
90 ENUM_USING(st_pdf_image_writer, &pie->writer, sizeof(pie->writer),
91 index);
92
93 if (ret == 0) /* don't stop early */
94 ENUM_RETURN(0);
95 return ret;
96 }
97 return ENUM_USING_PREFIX(st_gx_image_enum_common,
98 pdf_image_writer_max_ptrs);
99 ENUM_PTRS_END
RELOC_PTRS_WITH(pdf_image_enum_reloc_ptrs,pdf_image_enum * pie)100 static RELOC_PTRS_WITH(pdf_image_enum_reloc_ptrs, pdf_image_enum *pie)
101 {
102 RELOC_USING(st_pdf_image_writer, &pie->writer, sizeof(pie->writer));
103 RELOC_USING(st_gx_image_enum_common, vptr, size);
104 }
105 RELOC_PTRS_END
106
107 /*
108 * Test whether we can write an image in-line. This is always true,
109 * because we only support PDF 1.2 and later.
110 */
111 static bool
can_write_image_in_line(const gx_device_pdf * pdev,const gs_image_t * pim)112 can_write_image_in_line(const gx_device_pdf *pdev, const gs_image_t *pim)
113 {
114 return true;
115 }
116
117 /*
118 * Convert a Type 4 image to a Type 1 masked image if possible.
119 * Type 1 masked images are more compact, and are supported in all PDF
120 * versions, whereas general masked images require PDF 1.3 or higher.
121 * Also, Acrobat 5 for Windows has a bug that causes an error for images
122 * with a color-key mask, at least for 1-bit-deep images using an Indexed
123 * color space.
124 */
125 static int
color_is_black_or_white(gx_device * dev,const gx_drawing_color * pdcolor)126 color_is_black_or_white(gx_device *dev, const gx_drawing_color *pdcolor)
127 {
128 return (!color_is_pure(pdcolor) ? -1 :
129 gx_dc_pure_color(pdcolor) == gx_device_black(dev) ? 0 :
130 gx_dc_pure_color(pdcolor) == gx_device_white(dev) ? 1 : -1);
131 }
132 static int
pdf_convert_image4_to_image1(gx_device_pdf * pdev,const gs_gstate * pgs,const gx_drawing_color * pbcolor,const gs_image4_t * pim4,gs_image_t * pim1,gx_drawing_color * pdcolor)133 pdf_convert_image4_to_image1(gx_device_pdf *pdev,
134 const gs_gstate *pgs,
135 const gx_drawing_color *pbcolor,
136 const gs_image4_t *pim4, gs_image_t *pim1,
137 gx_drawing_color *pdcolor)
138 {
139 if (pim4->BitsPerComponent == 1 &&
140 pim4->ColorSpace->type->num_components(pim4->ColorSpace) == 1 &&
141 (pim4->MaskColor_is_range ?
142 pim4->MaskColor[0] | pim4->MaskColor[1] :
143 pim4->MaskColor[0]) <= 1
144 ) {
145 gx_device *const dev = (gx_device *)pdev;
146 const gs_color_space *pcs = pim4->ColorSpace;
147 bool write_1s = !pim4->MaskColor[0];
148 gs_client_color cc;
149 int code;
150
151 /*
152 * Prepare the drawing color. (pdf_prepare_imagemask will set it.)
153 * This is the other color in the image (the one that isn't the
154 * mask key), taking Decode into account.
155 */
156
157 cc.paint.values[0] = pim4->Decode[(int)write_1s];
158 cc.pattern = 0;
159 code = pcs->type->remap_color(&cc, pcs, pdcolor, pgs, dev,
160 gs_color_select_texture);
161 if (code < 0)
162 return code;
163
164 /*
165 * The PDF imaging model doesn't support RasterOp. We can convert a
166 * Type 4 image to a Type 1 imagemask only if the effective RasterOp
167 * passes through the source color unchanged. "Effective" means we
168 * take into account CombineWithColor, and whether the source and/or
169 * texture are black, white, or neither.
170 */
171 {
172 gs_logical_operation_t lop = pgs->log_op;
173 int black_or_white = color_is_black_or_white(dev, pdcolor);
174
175 lop = lop_sanitize(lop);
176
177 switch (black_or_white) {
178 case 0: lop = lop_know_S_0(lop); break;
179 case 1: lop = lop_know_S_1(lop); break;
180 default: DO_NOTHING;
181 }
182 if (pim4->CombineWithColor)
183 switch (color_is_black_or_white(dev, pbcolor)) {
184 case 0: lop = lop_know_T_0(lop); break;
185 case 1: lop = lop_know_T_1(lop); break;
186 default: DO_NOTHING;
187 }
188 else
189 lop = lop_know_T_0(lop);
190 switch (lop_rop(lop)) {
191 case rop3_0:
192 if (black_or_white != 0)
193 return -1;
194 break;
195 case rop3_1:
196 if (black_or_white != 1)
197 return -1;
198 break;
199 case rop3_S:
200 break;
201 default:
202 return -1;
203 }
204 }
205
206 /* All conditions are met. Convert to a masked image. */
207
208 gs_image_t_init_mask_adjust(pim1, write_1s, false);
209 #define COPY_ELEMENT(e) pim1->e = pim4->e
210 COPY_ELEMENT(ImageMatrix);
211 COPY_ELEMENT(Width);
212 COPY_ELEMENT(Height);
213 pim1->BitsPerComponent = 1;
214 /* not Decode */
215 COPY_ELEMENT(Interpolate);
216 pim1->format = gs_image_format_chunky; /* BPC = 1, doesn't matter */
217 #undef COPY_ELEMENT
218 return 0;
219 }
220 return -1; /* arbitrary <0 */
221 }
222
223 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)224 pdf_begin_image_data_decoded(gx_device_pdf *pdev, int num_components, const gs_range_t *pranges, int i,
225 gs_pixel_image_t *pi, cos_value_t *cs_value, pdf_image_enum *pie)
226 {
227
228 if (pranges) {
229 /* Rescale the Decode values for the image data. */
230 const gs_range_t *pr = pranges;
231 float *decode = pi->Decode;
232 int j;
233
234 for (j = 0; j < num_components; ++j, ++pr, decode += 2) {
235 double vmin = decode[0], vmax = decode[1];
236 double base = pr->rmin, factor = pr->rmax - base;
237
238 decode[1] = (vmax - vmin) / factor + (vmin - base);
239 decode[0] = vmin - base;
240 }
241 }
242 return pdf_begin_image_data(pdev, &pie->writer, pi, cs_value, i);
243 }
244
245 static int
make_device_color_space(gx_device_pdf * pdev,gs_color_space_index output_cspace_index,gs_color_space ** ppcs)246 make_device_color_space(gx_device_pdf *pdev,
247 gs_color_space_index output_cspace_index,
248 gs_color_space **ppcs)
249 {
250 gs_color_space *cs;
251 gs_memory_t *mem = pdev->v_memory;
252
253 switch (output_cspace_index) {
254 case gs_color_space_index_DeviceGray:
255 cs = gs_cspace_new_DeviceGray(mem);
256 break;
257 case gs_color_space_index_DeviceRGB:
258 cs = gs_cspace_new_DeviceRGB(mem);
259 break;
260 case gs_color_space_index_DeviceCMYK:
261 cs = gs_cspace_new_DeviceCMYK(mem);
262 break;
263 default:
264 /* Notify the user and terminate.
265 Don't emit rangecheck becuause it would fall back
266 to a default implementation (rasterisation).
267 */
268 emprintf(mem, "Unsupported ProcessColorModel");
269 return_error(gs_error_undefined);
270 }
271
272 if (cs == NULL)
273 return_error(gs_error_VMerror);
274
275 *ppcs = cs;
276 return 0;
277 }
278
279 /*
280 * Start processing an image. This procedure takes extra arguments because
281 * it has to do something slightly different for the parts of an ImageType 3
282 * image.
283 */
284 typedef enum {
285 PDF_IMAGE_DEFAULT,
286 PDF_IMAGE_TYPE3_MASK, /* no in-line, don't render */
287 PDF_IMAGE_TYPE3_DATA /* no in-line */
288 } pdf_typed_image_context_t;
289
290 /*
291 * We define this union because psdf_setup_image_filters may alter the
292 * gs_pixel_image_t part, but pdf_begin_image_data must also have access
293 * to the type-specific parameters.
294 */
295 typedef union image_union_s {
296 gs_pixel_image_t pixel; /* we may change some components */
297 gs_image1_t type1;
298 gs_image3_t type3;
299 gs_image3x_t type3x;
300 gs_image4_t type4;
301 } image_union_t;
302
303 static int pdf_begin_typed_image(gx_device_pdf *pdev,
304 const gs_gstate * pgs, const gs_matrix *pmat,
305 const gs_image_common_t *pic, const gs_int_rect * prect,
306 const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
307 gs_memory_t * mem, gx_image_enum_common_t ** pinfo,
308 pdf_typed_image_context_t context);
309
setup_type1_image(gx_device_pdf * pdev,const gs_image_common_t * pic,const gx_drawing_color * pdcolor,image_union_t * image,pdf_typed_image_context_t context)310 static int setup_type1_image(gx_device_pdf *pdev, const gs_image_common_t *pic,
311 const gx_drawing_color * pdcolor, image_union_t *image,
312 pdf_typed_image_context_t context)
313 {
314 const gs_image_t *pim1 = (const gs_image_t *)pic;
315
316 if (pim1->Alpha != gs_image_alpha_none)
317 return -1;
318 if (pim1->ImageMask) {
319 /* If parameters are invalid, use the fallback implementation. */
320 if (!(gx_dc_is_pattern1_color(pdcolor)))
321 if (pim1->BitsPerComponent != 1 ||
322 !((pim1->Decode[0] == 0.0 && pim1->Decode[1] == 1.0) ||
323 (pim1->Decode[0] == 1.0 && pim1->Decode[1] == 0.0))
324 )
325 return -1;
326 }
327 image[0].type1 = *pim1;
328 /* If we can write in-line then make it so */
329 return (context == PDF_IMAGE_DEFAULT &&
330 can_write_image_in_line(pdev, pim1));
331 }
332
setup_type3_image(gx_device_pdf * pdev,const gs_gstate * pgs,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,image_union_t * image)333 static int setup_type3_image(gx_device_pdf *pdev, const gs_gstate * pgs,
334 const gs_matrix *pmat, const gs_image_common_t *pic,
335 const gs_int_rect * prect,
336 const gx_drawing_color * pdcolor,
337 const gx_clip_path * pcpath, gs_memory_t * mem,
338 gx_image_enum_common_t ** pinfo,
339 image_union_t *image)
340 {
341 const gs_image3_t *pim3 = (const gs_image3_t *)pic;
342 gs_image3_t pim3a;
343 const gs_image_common_t *pic1 = pic;
344 gs_matrix m, mi;
345 const gs_matrix *pmat1 = pmat;
346 int code;
347
348 if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
349 code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
350 if (code < 0)
351 return code;
352 if (pdf_must_put_clip_path(pdev, pcpath))
353 code = pdf_unclip(pdev);
354 else
355 code = pdf_open_page(pdev, PDF_IN_STREAM);
356 if (code < 0)
357 return code;
358 code = pdf_put_clip_path(pdev, pcpath);
359 if (code < 0)
360 return code;
361 gs_make_identity(&m);
362 pmat1 = &m;
363 m.tx = floor(pgs->ctm.tx + 0.5); /* Round the origin against the image size distorsions */
364 m.ty = floor(pgs->ctm.ty + 0.5);
365 pim3a = *pim3;
366 code = gs_matrix_invert(&pim3a.ImageMatrix, &mi);
367 if (code < 0)
368 return code;
369 gs_make_identity(&pim3a.ImageMatrix);
370 if (pim3a.Width < pim3a.MaskDict.Width && pim3a.Width > 0) {
371 int sx = (pim3a.MaskDict.Width + pim3a.Width - 1) / pim3a.Width;
372
373 gs_matrix_scale(&mi, 1.0 / sx, 1, &mi);
374 gs_matrix_scale(&pim3a.ImageMatrix, 1.0 / sx, 1, &pim3a.ImageMatrix);
375 }
376 if (pim3a.Height < pim3a.MaskDict.Height && pim3a.Height > 0) {
377 int sy = (pim3a.MaskDict.Height + pim3a.Height - 1) / pim3a.Height;
378
379 gs_matrix_scale(&mi, 1, 1.0 / sy, &mi);
380 gs_matrix_scale(&pim3a.ImageMatrix, 1, 1.0 / sy, &pim3a.ImageMatrix);
381 }
382 gs_matrix_multiply(&mi, &pim3a.MaskDict.ImageMatrix, &pim3a.MaskDict.ImageMatrix);
383 pic1 = (gs_image_common_t *)&pim3a;
384 /* Setting pdev->converting_image_matrix to communicate with pdf_image3_make_mcde. */
385 gs_matrix_multiply(&mi, &ctm_only(pgs), &pdev->converting_image_matrix);
386 }
387 /*
388 * We handle ImageType 3 images in a completely different way:
389 * the default implementation sets up the enumerator.
390 */
391 return gx_begin_image3_generic((gx_device *)pdev, pgs, pmat1, pic1,
392 prect, pdcolor, pcpath, mem,
393 pdf_image3_make_mid,
394 pdf_image3_make_mcde, pinfo);
395 }
396
convert_type4_image(gx_device_pdf * pdev,const gs_gstate * pgs,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,cos_dict_t * pnamed)397 static int convert_type4_image(gx_device_pdf *pdev, const gs_gstate * pgs,
398 const gs_matrix *pmat, const gs_image_common_t *pic,
399 const gs_int_rect * prect,
400 const gx_drawing_color * pdcolor,
401 const gx_clip_path * pcpath, gs_memory_t * mem,
402 gx_image_enum_common_t ** pinfo,
403 pdf_typed_image_context_t context, image_union_t *image,
404 cos_dict_t *pnamed)
405 {
406 /* Try to convert the image to a plain masked image. */
407 gx_drawing_color icolor;
408 int code;
409
410 pdev->image_mask_is_SMask = false;
411 if (pdf_convert_image4_to_image1(pdev, pgs, pdcolor,
412 (const gs_image4_t *)pic,
413 &image[0].type1, &icolor) >= 0) {
414 if (pgs == NULL)
415 return_error(gs_error_unregistered); /* Must not happen. */
416
417 /* Undo the pop of the NI stack if necessary. */
418 if (pnamed)
419 cos_array_add_object(pdev->NI_stack, COS_OBJECT(pnamed));
420 /* HACK: temporary patch the color space, to allow
421 pdf_prepare_imagemask to write the right color for the imagemask. */
422 code = gs_gsave((gs_gstate *)pgs);
423 if (code < 0)
424 return code;
425 /* {csrc}: const cast warning */
426 code = gs_setcolorspace((gs_gstate *)pgs, ((const gs_image4_t *)pic)->ColorSpace);
427 if (code < 0)
428 return code;
429 code = pdf_begin_typed_image(pdev, pgs, pmat,
430 (gs_image_common_t *)&image[0].type1,
431 prect, &icolor, pcpath, mem,
432 pinfo, context);
433 if (code < 0)
434 return code;
435 return gs_grestore((gs_gstate *)pgs);
436 }
437 return 1;
438 }
439
convert_type4_to_masked_image(gx_device_pdf * pdev,const gs_gstate * pgs,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)440 static int convert_type4_to_masked_image(gx_device_pdf *pdev, const gs_gstate * pgs,
441 const gs_image_common_t *pic,
442 const gs_int_rect * prect,
443 const gx_drawing_color * pdcolor,
444 const gx_clip_path * pcpath, gs_memory_t * mem,
445 gx_image_enum_common_t ** pinfo)
446 {
447 gs_matrix m, m1, mi;
448 gs_image4_t pi4 = *(const gs_image4_t *)pic;
449 int code;
450 pdf_lcvd_t *cvd = NULL;
451
452 code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
453 if (code < 0)
454 return code;
455 if (pdf_must_put_clip_path(pdev, pcpath))
456 code = pdf_unclip(pdev);
457 else
458 code = pdf_open_page(pdev, PDF_IN_STREAM);
459 if (code < 0)
460 return code;
461 code = pdf_put_clip_path(pdev, pcpath);
462 if (code < 0)
463 return code;
464 gs_make_identity(&m1);
465 code = gs_matrix_invert(&pic->ImageMatrix, &mi);
466 if (code < 0)
467 return code;
468 gs_matrix_multiply(&mi, &ctm_only(pgs), &m);
469 code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
470 true, 0, 0, pi4.Width, pi4.Height, false);
471 if (code < 0)
472 return code;
473 cvd->mdev.is_open = true; /* fixme: same as above. */
474 cvd->mask->is_open = true; /* fixme: same as above. */
475 cvd->mask_is_empty = false;
476 code = (*dev_proc(cvd->mask, fill_rectangle))((gx_device *)cvd->mask,
477 0, 0, cvd->mask->width, cvd->mask->height, (gx_color_index)0);
478 if (code < 0)
479 return code;
480 gx_device_retain((gx_device *)cvd, true);
481 gx_device_retain((gx_device *)cvd->mask, true);
482 gs_make_identity(&pi4.ImageMatrix);
483 code = gx_default_begin_typed_image((gx_device *)cvd,
484 pgs, &m1, (gs_image_common_t *)&pi4, prect, pdcolor, NULL, mem, pinfo);
485 if (code < 0)
486 return code;
487 (*pinfo)->procs = &pdf_image_cvd_enum_procs;
488 return 0;
489 }
490
setup_image_process_colorspace(gx_device_pdf * pdev,image_union_t * image,gs_color_space ** pcs_orig,const char * sname,cos_value_t * cs_value)491 static int setup_image_process_colorspace(gx_device_pdf *pdev, image_union_t *image, gs_color_space **pcs_orig,
492 const char *sname, cos_value_t *cs_value)
493 {
494 int code;
495 gs_color_space *pcs_device = NULL;
496
497 cos_c_string_value(cs_value, sname);
498 *pcs_orig = image->pixel.ColorSpace;
499 code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
500 if (code < 0)
501 return code;
502 image->pixel.ColorSpace = pcs_device;
503 return 0;
504 }
505
506 /* 0 = write unchanged
507 1 = convert to process
508 2 = write as ICC
509 3 = convert base space (Separation)
510 4 = convert base space (DeviceN)
511 */
setup_image_colorspace(gx_device_pdf * pdev,image_union_t * image,const gs_color_space * pcs,gs_color_space ** pcs_orig,const pdf_color_space_names_t * names,cos_value_t * cs_value)512 static int setup_image_colorspace(gx_device_pdf *pdev, image_union_t *image, const gs_color_space *pcs, gs_color_space **pcs_orig,
513 const pdf_color_space_names_t *names, cos_value_t *cs_value)
514 {
515 int code=0;
516 gs_color_space_index csi;
517 gs_color_space_index csi2;
518 const gs_color_space *pcs2 = pcs;
519
520 csi = csi2 = gs_color_space_get_index(pcs);
521 if (csi == gs_color_space_index_ICC) {
522 csi2 = gsicc_get_default_type(pcs->cmm_icc_profile_data);
523 }
524 /* Figure out what to do if we are outputting to really ancient versions of PDF */
525 /* NB ps2write sets CompatibilityLevel to 1.2 so we cater for it here */
526 if (pdev->CompatibilityLevel <= 1.2) {
527
528 /* If we have an /Indexed space, we need to look at the base space */
529 if (csi2 == gs_color_space_index_Indexed) {
530 pcs2 = pcs->base_space;
531 csi2 = gs_color_space_get_index(pcs2);
532 }
533
534 switch (csi2) {
535 case gs_color_space_index_DeviceGray:
536 if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
537 pdev->params.ColorConversionStrategy == ccs_Gray) {
538 return 0;
539 }
540 else {
541 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
542 if (code < 0)
543 return code;
544 return 1;
545 }
546 break;
547 case gs_color_space_index_DeviceRGB:
548 if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
549 pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB)
550 return 0;
551 else {
552 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
553 if (code < 0)
554 return code;
555 return 1;
556 }
557 break;
558 case gs_color_space_index_DeviceCMYK:
559 if ((pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
560 pdev->params.ColorConversionStrategy == ccs_CMYK) && !pdev->params.ConvertCMYKImagesToRGB)
561 return 0;
562 else {
563 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
564 if (code < 0)
565 return code;
566 return 1;
567 }
568 break;
569 case gs_color_space_index_CIEA:
570 case gs_color_space_index_CIEABC:
571 case gs_color_space_index_CIEDEF:
572 case gs_color_space_index_CIEDEFG:
573 case gs_color_space_index_Separation:
574 if (pdev->ForOPDFRead) {
575 switch (pdev->params.ColorConversionStrategy) {
576 case ccs_ByObjectType:
577 /* Object type not implemented yet */
578 case ccs_UseDeviceIndependentColorForImages:
579 /* If only correcting images, then leave unchanged */
580 case ccs_LeaveColorUnchanged:
581 if (csi2 == gs_color_space_index_Separation)
582 return 0;
583 /* Fall through and convert CIE to the device space */
584 default:
585 switch (pdev->pcm_color_info_index) {
586 case gs_color_space_index_DeviceGray:
587 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
588 break;
589 case gs_color_space_index_DeviceRGB:
590 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
591 break;
592 case gs_color_space_index_DeviceCMYK:
593 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
594 break;
595 default:
596 emprintf(pdev->memory, "Unsupported ProcessColorModel.");
597 return_error(gs_error_undefined);
598 }
599 if (code < 0)
600 return code;
601 return 1;
602 break;
603 }
604 }
605 else
606 *pcs_orig = (gs_color_space *)pcs;
607 return 1;
608 break;
609
610 case gs_color_space_index_ICC:
611 /* Note that if csi is ICC, check to see if this was one of
612 the default substitutes that we introduced for DeviceGray,
613 DeviceRGB or DeviceCMYK. If it is, then just write
614 the default color. Depending upon the flavor of PDF,
615 or other options, we may want to actually have all
616 the colors defined by ICC profiles and not do the following
617 substituion of the Device space. */
618 csi2 = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
619
620 switch (csi2) {
621 case gs_color_space_index_DeviceGray:
622 if (pdev->params.ColorConversionStrategy == ccs_Gray ||
623 pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
624 return 0;
625 break;
626 case gs_color_space_index_DeviceRGB:
627 if (pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB ||
628 pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
629 return 0;
630 break;
631 case gs_color_space_index_DeviceCMYK:
632 if (pdev->params.ColorConversionStrategy == ccs_CMYK ||
633 pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
634 return 0;
635 break;
636 default:
637 break;
638 }
639 /* Fall through for non-handled cases */
640 case gs_color_space_index_DeviceN:
641 case gs_color_space_index_DevicePixel:
642 case gs_color_space_index_Indexed:
643 switch (pdev->pcm_color_info_index) {
644 case gs_color_space_index_DeviceGray:
645 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
646 break;
647 case gs_color_space_index_DeviceRGB:
648 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
649 break;
650 case gs_color_space_index_DeviceCMYK:
651 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
652 break;
653 default:
654 emprintf(pdev->memory, "Unsupported ProcessColorModel.");
655 return_error(gs_error_undefined);
656 }
657 if (code < 0)
658 return code;
659 return 1;
660 break;
661 default:
662 return (gs_note_error(gs_error_rangecheck));
663 break;
664 }
665 } else {
666 int strategy = pdev->params.ColorConversionStrategy;
667
668 if (pdev->params.TransferFunctionInfo == tfi_Apply && pdev->transfer_not_identity && csi2 == gs_color_space_index_Indexed) {
669 csi = gs_color_space_get_index(pcs->base_space);
670 if (csi == gs_color_space_index_ICC) {
671 csi = gsicc_get_default_type(pcs->base_space->cmm_icc_profile_data);
672 }
673 /* If its still not a base space, make it the ProcessCOlorModel of the device */
674 if (csi > gs_color_space_index_DeviceCMYK)
675 csi = pdev->pcm_color_info_index;
676 switch(csi) {
677 case gs_color_space_index_DeviceGray:
678 strategy = ccs_Gray;
679 break;
680 case gs_color_space_index_DeviceRGB:
681 strategy = ccs_RGB;
682 break;
683 case gs_color_space_index_DeviceCMYK:
684 strategy = ccs_CMYK;
685 break;
686 default:
687 break;
688 }
689 }
690
691 switch(strategy) {
692 case ccs_ByObjectType:
693 /* Object type not implemented yet */
694 case ccs_UseDeviceIndependentColorForImages:
695 /* If only correcting images, then leave unchanged */
696 case ccs_LeaveColorUnchanged:
697 return 0;
698 break;
699 case ccs_UseDeviceIndependentColor:
700 return 2;
701 break;
702 case ccs_CMYK:
703 switch(csi2) {
704 case gs_color_space_index_DeviceGray:
705 case gs_color_space_index_DeviceCMYK:
706 return 0;
707 break;
708 case gs_color_space_index_Separation:
709 pcs2 = pcs;
710 while (pcs2->base_space)
711 pcs2 = pcs2->base_space;
712 csi = gs_color_space_get_index(pcs2);
713 if (csi == gs_color_space_index_ICC)
714 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
715 if (csi == gs_color_space_index_DeviceCMYK)
716 return 0;
717 else
718 return 3;
719 break;
720 case gs_color_space_index_DeviceN:
721 pcs2 = pcs;
722 while (pcs2->base_space)
723 pcs2 = pcs2->base_space;
724 csi = gs_color_space_get_index(pcs2);
725 if (csi == gs_color_space_index_ICC)
726 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
727 if (csi == gs_color_space_index_DeviceCMYK)
728 return 0;
729 else
730 return 4;
731 break;
732 case gs_color_space_index_Indexed:
733 pcs2 = pcs->base_space;
734 csi = gs_color_space_get_index(pcs2);
735 if (csi == gs_color_space_index_ICC)
736 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
737 switch(csi) {
738 case gs_color_space_index_DeviceGray:
739 case gs_color_space_index_DeviceCMYK:
740 return 0;
741 break;
742 case gs_color_space_index_Separation:
743 pcs2 = pcs;
744 while (pcs2->base_space)
745 pcs2 = pcs2->base_space;
746 csi = gs_color_space_get_index(pcs2);
747 if (csi == gs_color_space_index_ICC)
748 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
749 if (csi == gs_color_space_index_DeviceCMYK)
750 return 0;
751 else
752 return 3;
753 break;
754 case gs_color_space_index_DeviceN:
755 pcs2 = pcs;
756 while (pcs2->base_space)
757 pcs2 = pcs2->base_space;
758 csi = gs_color_space_get_index(pcs2);
759 if (csi == gs_color_space_index_ICC)
760 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
761 if (csi == gs_color_space_index_DeviceCMYK)
762 return 0;
763 else
764 return 4;
765 break;
766 default:
767 switch (pdev->pcm_color_info_index) {
768 case gs_color_space_index_DeviceGray:
769 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
770 break;
771 case gs_color_space_index_DeviceRGB:
772 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
773 break;
774 case gs_color_space_index_DeviceCMYK:
775 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
776 break;
777 default:
778 emprintf(pdev->memory, "Unsupported ProcessColorModel.");
779 return_error(gs_error_undefined);
780 }
781 if (code < 0)
782 return code;
783 return 1;
784 break;
785 }
786 break;
787 default:
788 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
789 if (code < 0)
790 return code;
791 return 1;
792 break;
793 }
794 break;
795 case ccs_Gray:
796 switch(csi2) {
797 case gs_color_space_index_DeviceGray:
798 return 0;
799 break;
800 case gs_color_space_index_Separation:
801 pcs2 = pcs;
802 while (pcs2->base_space)
803 pcs2 = pcs2->base_space;
804 csi = gs_color_space_get_index(pcs2);
805 if (csi == gs_color_space_index_ICC)
806 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
807 if (csi == gs_color_space_index_DeviceGray)
808 return 0;
809 else
810 return 3;
811 break;
812 case gs_color_space_index_DeviceN:
813 pcs2 = pcs;
814 while (pcs2->base_space)
815 pcs2 = pcs2->base_space;
816 csi = gs_color_space_get_index(pcs2);
817 if (csi == gs_color_space_index_ICC)
818 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
819 if (csi == gs_color_space_index_DeviceGray)
820 return 0;
821 else
822 return 4;
823 break;
824 case gs_color_space_index_Indexed:
825 pcs2 = pcs->base_space;
826 csi = gs_color_space_get_index(pcs2);
827 if (csi == gs_color_space_index_ICC)
828 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
829 switch(csi) {
830 case gs_color_space_index_DeviceGray:
831 return 0;
832 break;
833 case gs_color_space_index_Separation:
834 pcs2 = pcs;
835 while (pcs2->base_space)
836 pcs2 = pcs2->base_space;
837 csi = gs_color_space_get_index(pcs2);
838 if (csi == gs_color_space_index_ICC)
839 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
840 if (csi == gs_color_space_index_DeviceGray)
841 return 0;
842 else
843 return 3;
844 break;
845 case gs_color_space_index_DeviceN:
846 pcs2 = pcs;
847 while (pcs2->base_space)
848 pcs2 = pcs2->base_space;
849 csi = gs_color_space_get_index(pcs2);
850 if (csi == gs_color_space_index_ICC)
851 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
852 if (csi == gs_color_space_index_DeviceGray)
853 return 0;
854 else
855 return 4;
856 break;
857 default:
858 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
859 if (code < 0)
860 return code;
861 return 1;
862 break;
863 }
864 break;
865 default:
866 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
867 if (code < 0)
868 return code;
869 return 1;
870 break;
871 }
872 break;
873 case ccs_sRGB:
874 case ccs_RGB:
875 switch(csi2) {
876 case gs_color_space_index_DeviceGray:
877 case gs_color_space_index_DeviceRGB:
878 return 0;
879 break;
880 case gs_color_space_index_Separation:
881 pcs2 = pcs;
882 while (pcs2->base_space)
883 pcs2 = pcs2->base_space;
884 csi = gs_color_space_get_index(pcs2);
885 if (csi == gs_color_space_index_ICC)
886 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
887 if (csi == gs_color_space_index_DeviceRGB)
888 return 0;
889 else
890 return 3;
891 break;
892 case gs_color_space_index_DeviceN:
893 pcs2 = pcs;
894 while (pcs2->base_space)
895 pcs2 = pcs2->base_space;
896 csi = gs_color_space_get_index(pcs2);
897 if (csi == gs_color_space_index_ICC)
898 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
899 if (csi == gs_color_space_index_DeviceRGB)
900 return 0;
901 else
902 return 4;
903 break;
904 case gs_color_space_index_Indexed:
905 pcs2 = pcs->base_space;
906 csi = gs_color_space_get_index(pcs2);
907 if (csi == gs_color_space_index_ICC)
908 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
909 switch(csi) {
910 case gs_color_space_index_DeviceGray:
911 case gs_color_space_index_DeviceRGB:
912 return 0;
913 break;
914 case gs_color_space_index_Separation:
915 pcs2 = pcs;
916 while (pcs2->base_space)
917 pcs2 = pcs2->base_space;
918 csi = gs_color_space_get_index(pcs2);
919 if (csi == gs_color_space_index_ICC)
920 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
921 if (csi == gs_color_space_index_DeviceRGB)
922 return 0;
923 else
924 return 3;
925 break;
926 case gs_color_space_index_DeviceN:
927 pcs2 = pcs;
928 while (pcs2->base_space)
929 pcs2 = pcs2->base_space;
930 csi = gs_color_space_get_index(pcs2);
931 if (csi == gs_color_space_index_ICC)
932 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
933 if (csi == gs_color_space_index_DeviceRGB)
934 return 0;
935 else
936 return 4;
937 break;
938 default:
939 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
940 if (code < 0)
941 return code;
942 return 1;
943 break;
944 }
945 break;
946 default:
947 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
948 if (code < 0)
949 return code;
950 return 1;
951 break;
952 }
953 break;
954 default:
955 break;
956 }
957 }
958 return 0;
959 }
960
961 static int
pdf_begin_typed_image(gx_device_pdf * pdev,const gs_gstate * pgs,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)962 pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
963 const gs_matrix *pmat, const gs_image_common_t *pic,
964 const gs_int_rect * prect,
965 const gx_drawing_color * pdcolor,
966 const gx_clip_path * pcpath, gs_memory_t * mem,
967 gx_image_enum_common_t ** pinfo,
968 pdf_typed_image_context_t context)
969 {
970 int code, i;
971 unsigned int use_fallback = 0, in_line = 0, is_mask = 0,
972 force_lossless = 0, convert_to_process_colors = 0;
973 int width, height;
974 cos_dict_t *pnamed = 0;
975 image_union_t *image;
976 const gs_pixel_image_t *pim;
977 gs_int_rect rect;
978 gs_image_format_t format;
979 const gs_color_space *pcs;
980 int num_components;
981 pdf_image_enum *pie;
982 const pdf_color_space_names_t *names;
983 gs_color_space *pcs_orig = NULL;
984 gs_color_space *pcs_device = NULL;
985 cos_value_t cs_value;
986 const gs_range_t *pranges = 0;
987
988 image = (image_union_t *)gs_malloc(mem->non_gc_memory, 4,
989 sizeof(image_union_t), "pdf_begin_typed_image(image)");
990 if (image == 0)
991 return_error(gs_error_VMerror);
992
993 /*
994 * Pop the image name from the NI stack. We must do this, to keep the
995 * stack in sync, even if it turns out we can't handle the image.
996 */
997 {
998 cos_value_t ni_value;
999
1000 if (cos_array_unadd(pdev->NI_stack, &ni_value) >= 0)
1001 pnamed = (cos_dict_t *)ni_value.contents.object;
1002 }
1003
1004 /* An initialization for pdf_end_and_do_image :
1005 We need to delay adding the "Mask" entry into a type 3 image dictionary
1006 until the mask is completed due to equal image merging. */
1007 pdev->image_mask_id = gs_no_id;
1008
1009 /* Check for the image types we can handle. */
1010 switch (pic->type->index) {
1011 case 1:
1012 is_mask = ((const gs_image_t *)pic)->ImageMask;
1013 code = setup_type1_image(pdev, pic, pdcolor, image, context);
1014 if (code < 0) {
1015 use_fallback = 1;
1016 }
1017 else
1018 in_line = code;
1019 break;
1020
1021 case 3:
1022 /* Currently we can't handle images with masks, because we have two
1023 * image enumerators, and the JPEG passthrough is stored at the device
1024 * level, not the enumerator level. This means that when we skip the
1025 * image data (because its handled as JPEG) we also skip the mask data,
1026 * which is no use at all. FIXME: not sure how but if possible I
1027 * should fix this. Probably need to store the PassThrough in the
1028 * enumerator, and then store a pointer to the enumerator in the
1029 * device in place of the flag, so that when we get JPEG data supplied
1030 * we know where to send it. Of course, that won't work if we ever end
1031 * up in the situation where we have two JPEG sources at the same time.....
1032 * That can probably be handled with some judicious work in the DCTDecode
1033 * structure, to hold some reference to the particular stream that
1034 * should get the data. But lets get the simple code working first.
1035 */
1036 pdev->JPEG_PassThrough = 0;
1037 pdev->image_mask_is_SMask = false;
1038 if (pdev->CompatibilityLevel < 1.2 ||
1039 (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
1040 prect->q.x == ((const gs_image3_t *)pic)->Width &&
1041 prect->q.y == ((const gs_image3_t *)pic)->Height))) {
1042 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1043 "pdf_begin_typed_image(image)");
1044 return (gx_default_begin_typed_image((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor,
1045 pcpath, mem, pinfo));
1046 }
1047 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1048 "pdf_begin_typed_image(image)");
1049 return (setup_type3_image(pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, image));
1050 break;
1051
1052 case IMAGE3X_IMAGETYPE:
1053 pdev->JPEG_PassThrough = 0;
1054 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1055 "pdf_begin_typed_image(image)");
1056 if (pdev->CompatibilityLevel < 1.4 ||
1057 (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
1058 prect->q.x == ((const gs_image3x_t *)pic)->Width &&
1059 prect->q.y == ((const gs_image3x_t *)pic)->Height))) {
1060 return (gx_default_begin_typed_image((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor,
1061 pcpath, mem, pinfo));
1062 }
1063 pdev->image_mask_is_SMask = true;
1064 return gx_begin_image3x_generic((gx_device *)pdev, pgs, pmat, pic,
1065 prect, pdcolor, pcpath, mem,
1066 pdf_image3x_make_mid,
1067 pdf_image3x_make_mcde, pinfo);
1068 break;
1069
1070 case 4:
1071 pdev->JPEG_PassThrough = 0;
1072 code = convert_type4_image(pdev, pgs, pmat, pic, prect, pdcolor,
1073 pcpath, mem, pinfo, context, image, pnamed);
1074 if (code < 0) {
1075 use_fallback = 1;
1076 }
1077 if (code == 0) {
1078 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1079 "pdf_begin_typed_image(image)");
1080 return code;
1081 }
1082 /* No luck. Masked images require PDF 1.3 or higher. */
1083 if (pdev->CompatibilityLevel < 1.2) {
1084 use_fallback = 1;
1085 }
1086 if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
1087 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1088 "pdf_begin_typed_image(image)");
1089 return (convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
1090 pcpath, mem,pinfo));
1091 }
1092 image[0].type4 = *(const gs_image4_t *)pic;
1093 break;
1094
1095 default:
1096 use_fallback = 1;
1097 break;
1098 }
1099
1100 pim = (const gs_pixel_image_t *)pic;
1101 format = pim->format;
1102 switch (format) {
1103 case gs_image_format_chunky:
1104 case gs_image_format_component_planar:
1105 break;
1106 default:
1107 use_fallback = 1;
1108 }
1109 /* AR5 on Windows doesn't support 0-size images. Skipping. */
1110 if (pim->Width == 0 || pim->Height == 0)
1111 use_fallback = 1;
1112 /* PDF doesn't support images with more than 8 bits per component. */
1113 switch (pim->BitsPerComponent) {
1114 case 1:
1115 case 2:
1116 case 4:
1117 case 8:
1118 break;
1119 case 12:
1120 case 16:
1121 break;
1122 default:
1123 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1124 "pdf_begin_typed_image(image)");
1125 return_error(gs_error_rangecheck);
1126 }
1127 if (prect)
1128 rect = *prect;
1129 else {
1130 rect.p.x = rect.p.y = 0;
1131 rect.q.x = pim->Width, rect.q.y = pim->Height;
1132 }
1133 if (rect.p.x != 0 || rect.p.y != 0 ||
1134 rect.q.x != pim->Width || rect.q.y != pim->Height ||
1135 (is_mask && pim->CombineWithColor))
1136 use_fallback = 1;
1137
1138 if (pdev->Eps2Write) {
1139 gs_rect sbox, dbox, *Box;
1140 gs_point corners[4];
1141 gs_fixed_rect ibox;
1142 gs_matrix * pmat1 = (gs_matrix *)pmat;
1143 gs_matrix mat;
1144
1145 if (!pdev->accumulating_charproc)
1146 Box = &pdev->BBox;
1147 else
1148 Box = &pdev->charproc_BBox;
1149 if (pmat1 == 0)
1150 pmat1 = (gs_matrix *)&ctm_only(pgs);
1151 if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 ||
1152 (code = gs_matrix_multiply(&mat, pmat1, &mat)) < 0)
1153 return code;
1154 sbox.p.x = rect.p.x;
1155 sbox.p.y = rect.p.y;
1156 sbox.q.x = rect.q.x;
1157 sbox.q.y = rect.q.y;
1158 gs_bbox_transform_only(&sbox, &mat, corners);
1159 gs_points_bbox(corners, &dbox);
1160 ibox.p.x = float2fixed(dbox.p.x);
1161 ibox.p.y = float2fixed(dbox.p.y);
1162 ibox.q.x = float2fixed(dbox.q.x);
1163 ibox.q.y = float2fixed(dbox.q.y);
1164 if (pcpath != NULL &&
1165 !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y,
1166 ibox.q.x, ibox.q.y)
1167 ) {
1168 /* Let the target do the drawing, but drive two triangles */
1169 /* through the clipping path to get an accurate bounding box. */
1170 gx_device_clip cdev;
1171 gx_drawing_color devc;
1172
1173 fixed x0 = float2fixed(corners[0].x), y0 = float2fixed(corners[0].y);
1174 fixed bx2 = float2fixed(corners[2].x) - x0, by2 = float2fixed(corners[2].y) - y0;
1175
1176 pdev->AccumulatingBBox++;
1177 gx_make_clip_device_on_stack(&cdev, pcpath, (gx_device *)pdev);
1178 set_nonclient_dev_color(&devc, gx_device_black((gx_device *)pdev)); /* any non-white color will do */
1179 gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1180 float2fixed(corners[1].x) - x0,
1181 float2fixed(corners[1].y) - y0,
1182 bx2, by2, &devc, lop_default);
1183 gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1184 float2fixed(corners[3].x) - x0,
1185 float2fixed(corners[3].y) - y0,
1186 bx2, by2, &devc, lop_default);
1187 pdev->AccumulatingBBox--;
1188 } else {
1189 /* Just use the bounding box. */
1190 float x0, y0, x1, y1;
1191 x0 = fixed2float(ibox.p.x) / (pdev->HWResolution[0] / 72.0);
1192 y0 = fixed2float(ibox.p.y) / (pdev->HWResolution[1] / 72.0);
1193 x1 = fixed2float(ibox.q.x) / (pdev->HWResolution[0] / 72.0);
1194 y1 = fixed2float(ibox.q.y) / (pdev->HWResolution[1] / 72.0);
1195 if (Box->p.x > x0)
1196 Box->p.x = x0;
1197 if (Box->p.y > y0)
1198 Box->p.y = y0;
1199 if (Box->q.x < x1)
1200 Box->q.x = x1;
1201 if (Box->q.y < y1)
1202 Box->q.y = y1;
1203 }
1204 }
1205
1206 if (use_fallback) {
1207 pdev->JPEG_PassThrough = 0;
1208 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1209 "pdf_begin_typed_image(image)");
1210 return gx_default_begin_typed_image
1211 ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
1212 pinfo);
1213 }
1214
1215 pcs = pim->ColorSpace;
1216 num_components = (is_mask ? 1 : gs_color_space_num_components(pcs));
1217
1218 code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
1219 if (code < 0)
1220 return code;
1221 if (pdf_must_put_clip_path(pdev, pcpath))
1222 code = pdf_unclip(pdev);
1223 else
1224 code = pdf_open_page(pdev, PDF_IN_STREAM);
1225 if (code < 0) {
1226 pdev->JPEG_PassThrough = 0;
1227 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1228 "pdf_begin_typed_image(image)");
1229 return gx_default_begin_typed_image
1230 ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
1231 pinfo);
1232 }
1233
1234 if (context == PDF_IMAGE_TYPE3_MASK) {
1235 /*
1236 * The soft mask for an ImageType 3x image uses a DevicePixel
1237 * color space, which pdf_color_space() can't handle. Patch it
1238 * to DeviceGray here.
1239 */
1240 /* {csrc} make sure this gets freed */
1241 pcs = gs_cspace_new_DeviceGray(pdev->memory);
1242 if (pcs == NULL)
1243 code = gs_note_error(gs_error_VMerror);
1244 } else if (is_mask)
1245 code = pdf_prepare_imagemask(pdev, pgs, pdcolor);
1246 else
1247 code = pdf_prepare_image(pdev, pgs);
1248 if (code < 0) {
1249 pdev->JPEG_PassThrough = 0;
1250 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1251 "pdf_begin_typed_image(image)");
1252 return gx_default_begin_typed_image
1253 ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
1254 pinfo);
1255 }
1256
1257 pie = gs_alloc_struct(mem, pdf_image_enum, &st_pdf_image_enum,
1258 "pdf_begin_image");
1259 if (pie == 0) {
1260 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1261 "pdf_begin_typed_image(image)");
1262 return_error(gs_error_VMerror);
1263 }
1264 memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
1265 *pinfo = (gx_image_enum_common_t *) pie;
1266 gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim,
1267 ((pdev->CompatibilityLevel >= 1.3) ?
1268 (context == PDF_IMAGE_TYPE3_MASK ?
1269 &pdf_image_object_enum_procs :
1270 &pdf_image_enum_procs) :
1271 context == PDF_IMAGE_TYPE3_MASK ?
1272 &pdf_image_object_enum_procs :
1273 context == PDF_IMAGE_TYPE3_DATA ?
1274 &pdf_image_object_enum_procs2 :
1275 &pdf_image_enum_procs),
1276 (gx_device *)pdev, num_components, format);
1277 pie->memory = mem;
1278 width = rect.q.x - rect.p.x;
1279 pie->width = width;
1280 height = rect.q.y - rect.p.y;
1281 pie->bits_per_pixel =
1282 pim->BitsPerComponent * num_components / pie->num_planes;
1283 pie->rows_left = height;
1284 if (pnamed != 0) /* Don't in-line the image if it is named. */
1285 in_line = false;
1286 else {
1287 double nbytes = (double)(((ulong) pie->width * pie->bits_per_pixel + 7) >> 3) *
1288 pie->num_planes * pie->rows_left;
1289
1290 in_line &= (nbytes < pdev->MaxInlineImageSize);
1291 }
1292 pie->initial_colorspace = pdev->pcm_color_info_index;
1293
1294 if (pmat == 0)
1295 pmat = &ctm_only(pgs);
1296 {
1297 gs_matrix mat;
1298 gs_matrix bmat;
1299 int code;
1300
1301 pdf_make_bitmap_matrix(&bmat, -rect.p.x, -rect.p.y,
1302 pim->Width, pim->Height, height);
1303 if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
1304 (code = gs_matrix_multiply(&bmat, &mat, &mat)) < 0 ||
1305 (code = gs_matrix_multiply(&mat, pmat, &pie->mat)) < 0
1306 ) {
1307 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1308 "pdf_begin_typed_image(image)");
1309 gs_free_object(mem, pie, "pdf_begin_image");
1310 return code;
1311 }
1312 /* AR3,AR4 show no image when CTM is singular; AR5 reports an error */
1313 if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx)
1314 goto fail_and_fallback;
1315 }
1316
1317 code = pdf_put_clip_path(pdev, pcpath);
1318 if (code < 0) {
1319 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1320 "pdf_begin_typed_image(image)");
1321 gs_free_object(mem, pie, "pdf_begin_image");
1322 return code;
1323 }
1324 pdf_image_writer_init(&pie->writer);
1325 /* Note : Possible values for alt_writer_count are 1,2,3,4.
1326 1 means no alternative streams.
1327 2 means the main image stream and a mask stream while converting
1328 an Image Type 4.
1329 3 means the main image stream, alternative image compression stream,
1330 and the compression chooser.
1331 4 meams 3 and a mask stream while convertingh an Image Type 4.
1332 */
1333 pie->writer.alt_writer_count = (in_line ||
1334 (pim->Width <= 64 && pim->Height <= 64)
1335 ? 1 : 2);
1336 if ((image[0].pixel.ColorSpace != NULL &&
1337 image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed
1338 && pdev->params.ColorImage.DownsampleType != ds_Subsample) ||
1339 pdev->transfer_not_identity)
1340 force_lossless = true;
1341
1342 if ((image[0].pixel.ColorSpace != NULL && image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed)
1343 || force_lossless)
1344 pie->writer.alt_writer_count = 1;
1345
1346 names = (in_line ? &pdf_color_space_names_short : &pdf_color_space_names);
1347
1348 /* We don't want to change the colour space of a mask, or an SMask (both of which are Gray) */
1349 if (!is_mask) {
1350 if (image[0].pixel.ColorSpace != NULL && !(context == PDF_IMAGE_TYPE3_MASK))
1351 convert_to_process_colors = setup_image_colorspace(pdev, &image[0], pcs, &pcs_orig, names, &cs_value);
1352
1353 if (pim->BitsPerComponent > 8 && convert_to_process_colors)
1354 goto fail_and_fallback;
1355 if (convert_to_process_colors == 4) {
1356 code = convert_DeviceN_alternate(pdev, pgs, pcs, NULL, NULL, NULL, NULL, &cs_value, in_line);
1357 if (code < 0)
1358 goto fail_and_fallback;
1359 }
1360 if (convert_to_process_colors == 3) {
1361 code = convert_separation_alternate(pdev, pgs, pcs, NULL, NULL, NULL, NULL, &cs_value, in_line);
1362 if (code < 0)
1363 goto fail_and_fallback;
1364 }
1365 if (convert_to_process_colors == 1) {
1366 code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1367 if (code < 0)
1368 goto fail_and_fallback;
1369 image[0].pixel.ColorSpace = pcs_device;
1370 image[0].pixel.BitsPerComponent = 8;
1371 code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs_device, names,
1372 in_line, NULL, 0, false);
1373 if (code < 0)
1374 goto fail_and_fallback;
1375 } else {
1376 if (convert_to_process_colors == 2) {
1377 convert_to_process_colors = 0;
1378 code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs, names,
1379 in_line, NULL, 0, true);
1380 if (code < 0)
1381 goto fail_and_fallback;
1382 } else {
1383 convert_to_process_colors = 0;
1384 code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs, names,
1385 in_line, NULL, 0, false);
1386 if (code < 0)
1387 goto fail_and_fallback;
1388 }
1389 }
1390 }
1391
1392 image[1] = image[0];
1393
1394 pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
1395
1396 code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1397 height, pnamed, in_line);
1398 if (code < 0)
1399 goto fail_and_fallback;
1400
1401 if (pdev->params.TransferFunctionInfo == tfi_Apply && pdev->transfer_not_identity && !is_mask)
1402 pdev->JPEG_PassThrough = 0;
1403
1404 /* if (pdev->JPEG_PassThrough)
1405 uncompressed = pie->writer.binary[0].strm;*/
1406
1407 /* Code below here deals with setting up the multiple data stream writing.
1408 * We can have up to 4 stream writers, which we keep in an array. We must
1409 * always have at least one which writes the uncompressed stream. If we
1410 * are writing compressed streams, we have one for the compressed stream
1411 * and one for the compression chooser.
1412 * For type 4 images being converted (for old versions of PDF or for ps2write)
1413 * we need an additional stream to write a mask, which masks the real
1414 * image.
1415 * For colour conversion we will place an additional filter in front of all
1416 * the streams which does the conversion.
1417 */
1418 if (in_line) {
1419 pdev->JPEG_PassThrough = 0;
1420 code = new_setup_lossless_filters((gx_device_psdf *) pdev,
1421 &pie->writer.binary[0],
1422 &image[0].pixel, in_line, convert_to_process_colors, (gs_matrix *)pmat, (gs_gstate *)pgs);
1423 } else {
1424 if (force_lossless) {
1425 /*
1426 * Some regrettable PostScript code (such as LanguageLevel 1 output
1427 * from Microsoft's PSCRIPT.DLL driver) misuses the transfer
1428 * function to accomplish the equivalent of indexed color.
1429 * Downsampling (well, only averaging) or JPEG compression are not
1430 * compatible with this. Play it safe by using only lossless
1431 * filters if the transfer function(s) is/are other than the
1432 * identity and by setting the downsample type to Subsample..
1433 */
1434 int saved_downsample = pdev->params.ColorImage.DownsampleType;
1435
1436 pdev->params.ColorImage.DownsampleType = ds_Subsample;
1437 code = new_setup_image_filters((gx_device_psdf *) pdev,
1438 &pie->writer.binary[0], &image[0].pixel,
1439 pmat, pgs, true, in_line, convert_to_process_colors);
1440 pdev->params.ColorImage.DownsampleType = saved_downsample;
1441 } else {
1442 code = new_setup_image_filters((gx_device_psdf *) pdev,
1443 &pie->writer.binary[0], &image[0].pixel,
1444 pmat, pgs, true, in_line, convert_to_process_colors);
1445 }
1446 }
1447
1448 if (code < 0)
1449 goto fail_and_fallback;
1450
1451 if (!convert_to_process_colors)
1452 {
1453 gs_color_space_index csi;
1454
1455 if (pdev->params.TransferFunctionInfo == tfi_Apply && pdev->transfer_not_identity && !is_mask) {
1456 pdev->JPEG_PassThrough = 0;
1457 csi = gs_color_space_get_index(image[0].pixel.ColorSpace);
1458 if (csi == gs_color_space_index_Indexed) {
1459 csi = gs_color_space_get_index(image[0].pixel.ColorSpace->base_space);
1460 if (csi == gs_color_space_index_ICC) {
1461 csi = gsicc_get_default_type(image[0].pixel.ColorSpace->base_space->cmm_icc_profile_data);
1462 }
1463 } else {
1464 if (csi == gs_color_space_index_ICC) {
1465 csi = gsicc_get_default_type(image[0].pixel.ColorSpace->cmm_icc_profile_data);
1466 }
1467 }
1468 switch(csi) {
1469 case gs_color_space_index_DevicePixel:
1470 case gs_color_space_index_CIEA:
1471 convert_to_process_colors = 1;
1472 pdf_set_process_color_model(pdev, 0);
1473 break;
1474 case gs_color_space_index_CIEDEF:
1475 case gs_color_space_index_CIEABC:
1476 case gs_color_space_index_DeviceGray:
1477 convert_to_process_colors = 1;
1478 pdf_set_process_color_model(pdev, 0);
1479 break;
1480 case gs_color_space_index_DeviceRGB:
1481 convert_to_process_colors = 1;
1482 pdf_set_process_color_model(pdev, 1);
1483 break;
1484 case gs_color_space_index_CIEDEFG:
1485 case gs_color_space_index_DeviceCMYK:
1486 convert_to_process_colors = 1;
1487 pdf_set_process_color_model(pdev, 2);
1488 break;
1489 default:
1490 break;
1491 }
1492 if (convert_to_process_colors == 1) {
1493 pcs_orig = image->pixel.ColorSpace;
1494 code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1495 if (code < 0)
1496 goto fail_and_fallback;
1497 image[0].pixel.ColorSpace = pcs_device;
1498 code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs_device, names,
1499 in_line, NULL, 0, false);
1500 if (code < 0)
1501 goto fail_and_fallback;
1502 }
1503 }
1504 }
1505 /* If we are not preserving the colour space unchanged, thenwe can't pass through JPEG */
1506 else
1507 pdev->JPEG_PassThrough = 0;
1508
1509
1510 if (convert_to_process_colors) {
1511 image[0].pixel.ColorSpace = pcs_orig;
1512 image[0].pixel.BitsPerComponent = pim->BitsPerComponent;
1513 code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
1514 (gx_device_psdf *)pdev, pim, &image[0].pixel, pgs);
1515 if (code < 0)
1516 goto fail_and_fallback;
1517 image[0].pixel.ColorSpace = pcs_device;
1518 }
1519
1520 if (pdev->JPEG_PassThrough) {
1521 /* if (pie->writer.alt_writer_count > 1) {
1522 s_close_filters(&pie->writer.binary[0].strm, uncompressed);
1523 memset(pie->writer.binary + 1, 0, sizeof(pie->writer.binary[1]));
1524 memset(pie->writer.binary + 2, 0, sizeof(pie->writer.binary[1]));
1525 }*/
1526 pdev->PassThroughWriter = pie->writer.binary[0].strm;
1527 pie->writer.alt_writer_count = 1;
1528 }
1529 pie->JPEG_PassThrough = pdev->JPEG_PassThrough;
1530
1531 if (pie->writer.alt_writer_count > 1) {
1532 code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]);
1533 if (code) {
1534 goto fail_and_fallback;
1535 }
1536 code = new_setup_image_filters((gx_device_psdf *) pdev,
1537 &pie->writer.binary[1], &image[1].pixel,
1538 pmat, pgs, force_lossless, in_line, convert_to_process_colors);
1539 if (code == gs_error_rangecheck) {
1540
1541 for (i=1;i < pie->writer.alt_writer_count; i++) {
1542 stream *s = pie->writer.binary[i].strm;
1543 cos_stream_t *pcos = cos_stream_from_pipeline(pie->writer.binary[i].strm);
1544 s_close_filters(&s, NULL);
1545 gs_free_object(pdev->pdf_memory, s, "compressed image stream");
1546 if (pcos == 0L)
1547 return gs_note_error(gs_error_ioerror);
1548 pcos->cos_procs->release((cos_object_t *)pcos, "pdf_begin_typed_image_impl");
1549 gs_free_object(pdev->pdf_memory, pcos, "compressed image cos_stream");
1550 }
1551 /* setup_image_compression rejected the alternative compression. */
1552 pie->writer.alt_writer_count = 1;
1553 memset(pie->writer.binary + 1, 0, sizeof(pie->writer.binary[1]));
1554 memset(pie->writer.binary + 2, 0, sizeof(pie->writer.binary[1]));
1555 } else if (code) {
1556 goto fail_and_fallback;
1557 } else if (convert_to_process_colors) {
1558 image[1].pixel.ColorSpace = pcs_orig;
1559 image[1].pixel.BitsPerComponent = pim->BitsPerComponent;
1560 code = psdf_setup_image_colors_filter(&pie->writer.binary[1],
1561 (gx_device_psdf *)pdev, pim, &image[1].pixel, pgs);
1562 if (code < 0) {
1563 goto fail_and_fallback;
1564 }
1565 image[1].pixel.ColorSpace = pcs_device;
1566 }
1567 }
1568
1569 for (i = 0; i < pie->writer.alt_writer_count; i++) {
1570 code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1571 &image[i].pixel, &cs_value, pie);
1572 if (code < 0)
1573 goto fail_and_fallback;
1574 }
1575 if (pie->writer.alt_writer_count == 2) {
1576 psdf_setup_compression_chooser(&pie->writer.binary[2],
1577 (gx_device_psdf *)pdev, pim->Width, pim->Height,
1578 num_components, pim->BitsPerComponent);
1579 pie->writer.alt_writer_count = 3;
1580 }
1581 if (pic->type->index == 4 && pdev->CompatibilityLevel < 1.3) {
1582 int i;
1583
1584 /* Create a stream for writing the mask. */
1585 i = pie->writer.alt_writer_count;
1586 gs_image_t_init_mask_adjust((gs_image_t *)&image[i].type1, true, false);
1587 image[i].type1.Width = image[0].pixel.Width;
1588 image[i].type1.Height = image[0].pixel.Height;
1589 /* Won't use image[2]. */
1590 code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1591 height, NULL, false);
1592 if (code)
1593 goto fail_and_fallback;
1594 code = psdf_setup_image_filters((gx_device_psdf *) pdev,
1595 &pie->writer.binary[i], &image[i].pixel,
1596 pmat, pgs, force_lossless, in_line);
1597 if (code < 0)
1598 goto fail_and_fallback;
1599 /* Bug701972 -- added input_width arg here. For this case, just passing in the same
1600 * width as before, so nothing changes. This is an obscure case that isn't tested
1601 * on the cluster (note that it requires CompatibilityLevel < 1.3).
1602 */
1603 psdf_setup_image_to_mask_filter(&pie->writer.binary[i],
1604 (gx_device_psdf *)pdev, pim->Width, pim->Height, pim->Width,
1605 num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
1606 code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1607 &image[i].pixel, &cs_value, pie);
1608 if (code < 0)
1609 goto fail_and_fallback;
1610 ++pie->writer.alt_writer_count;
1611 }
1612
1613 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1614 "pdf_begin_typed_image(image)");
1615 return 0;
1616
1617 fail_and_fallback:
1618 pdev->JPEG_PassThrough = 0;
1619 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1620 "pdf_begin_typed_image(image)");
1621 gs_free_object(mem, pie, "pdf_begin_image");
1622 return gx_default_begin_typed_image
1623 ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
1624 pinfo);
1625 }
1626
1627 int
gdev_pdf_begin_typed_image(gx_device * dev,const gs_gstate * pgs,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)1628 gdev_pdf_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
1629 const gs_matrix *pmat, const gs_image_common_t *pic,
1630 const gs_int_rect * prect,
1631 const gx_drawing_color * pdcolor,
1632 const gx_clip_path * pcpath, gs_memory_t * mem,
1633 gx_image_enum_common_t ** pinfo)
1634 {
1635 return pdf_begin_typed_image((gx_device_pdf *)dev, pgs, pmat, pic, prect,
1636 pdcolor, pcpath, mem, pinfo,
1637 PDF_IMAGE_DEFAULT);
1638 }
1639
1640 /* ---------------- All images ---------------- */
1641
1642 /* Process the next piece of an image. */
1643 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)1644 pdf_image_plane_data_alt(gx_image_enum_common_t * info,
1645 const gx_image_plane_t * planes, int height,
1646 int *rows_used, int alt_writer_index)
1647 {
1648 pdf_image_enum *pie = (pdf_image_enum *) info;
1649 int h = height;
1650 int y;
1651 /****** DOESN'T HANDLE IMAGES WITH VARYING WIDTH PER PLANE ******/
1652 uint width_bits = pie->width * pie->plane_depths[0];
1653 /****** DOESN'T HANDLE NON-ZERO data_x CORRECTLY ******/
1654 uint ignore;
1655 int nplanes = pie->num_planes;
1656 int status = 0;
1657 uint bcount = (width_bits + 7) >> 3;
1658
1659 if (h > pie->rows_left)
1660 h = pie->rows_left;
1661 for (y = 0; y < h; ++y) {
1662 if (nplanes > 1) {
1663 /*
1664 * We flip images in blocks, and each block except the last one
1665 * must contain an integral number of pixels. The easiest way
1666 * to meet this condition is for all blocks except the last to
1667 * be a multiple of 3 source bytes (guaranteeing an integral
1668 * number of 1/2/4/8/12-bit samples), i.e., 3*nplanes flipped
1669 * bytes. This requires a buffer of at least
1670 * 3*GS_IMAGE_MAX_COMPONENTS bytes.
1671 */
1672 int pi;
1673 uint count = bcount;
1674 uint offset = 0;
1675 #define ROW_BYTES max(200 /*arbitrary*/, 3 * GS_IMAGE_MAX_COMPONENTS)
1676 const byte *bit_planes[GS_IMAGE_MAX_COMPONENTS];
1677 int block_bytes = ROW_BYTES / (3 * nplanes) * 3;
1678 byte row[ROW_BYTES];
1679
1680 for (pi = 0; pi < nplanes; ++pi)
1681 bit_planes[pi] = planes[pi].data + planes[pi].raster * y;
1682 while (count) {
1683 uint flip_count;
1684 uint flipped_count;
1685
1686 if (count > block_bytes) {
1687 flip_count = block_bytes;
1688 flipped_count = block_bytes * nplanes;
1689 } else {
1690 flip_count = count;
1691 flipped_count =
1692 (width_bits % (block_bytes * 8) * nplanes + 7) >> 3;
1693 /* In case the width of the image is a precise multiple of our block size */
1694 if (flipped_count == 0)
1695 flipped_count = block_bytes * nplanes;
1696 }
1697 image_flip_planes(row, bit_planes, offset, flip_count,
1698 nplanes, pie->plane_depths[0]);
1699 status = sputs(pie->writer.binary[alt_writer_index].strm, row,
1700 flipped_count, &ignore);
1701 if (status < 0)
1702 break;
1703 offset += flip_count;
1704 count -= flip_count;
1705 }
1706 } else {
1707 status = sputs(pie->writer.binary[alt_writer_index].strm,
1708 planes[0].data + planes[0].raster * y, bcount,
1709 &ignore);
1710 }
1711 if (status < 0)
1712 break;
1713 }
1714 *rows_used = h;
1715 if (status < 0)
1716 return_error(gs_error_ioerror);
1717 return !pie->rows_left;
1718 #undef ROW_BYTES
1719 }
1720
1721 static int
pdf_image_plane_data(gx_image_enum_common_t * info,const gx_image_plane_t * planes,int height,int * rows_used)1722 pdf_image_plane_data(gx_image_enum_common_t * info,
1723 const gx_image_plane_t * planes, int height,
1724 int *rows_used)
1725 {
1726 pdf_image_enum *pie = (pdf_image_enum *) info;
1727 int i;
1728
1729 if (pie->JPEG_PassThrough) {
1730 pie->rows_left -= height;
1731 *rows_used = height;
1732 return 0;
1733 }
1734
1735 for (i = 0; i < pie->writer.alt_writer_count; i++) {
1736 int code = pdf_image_plane_data_alt(info, planes, height, rows_used, i);
1737 if (code)
1738 return code;
1739 }
1740 pie->rows_left -= *rows_used;
1741 if (pie->writer.alt_writer_count > 2)
1742 pdf_choose_compression(&pie->writer, false);
1743
1744 return !pie->rows_left;
1745 }
1746
1747 static int
use_image_as_pattern(gx_device_pdf * pdev,pdf_resource_t * pres1,const gs_matrix * pmat,gs_id id)1748 use_image_as_pattern(gx_device_pdf *pdev, pdf_resource_t *pres1,
1749 const gs_matrix *pmat, gs_id id)
1750 { /* See also dump_image in gdevpdfd.c . */
1751 gs_gstate s;
1752 gs_pattern1_instance_t inst;
1753 cos_value_t v;
1754 const pdf_resource_t *pres;
1755 int code;
1756
1757 memset(&s, 0, sizeof(s));
1758 s.ctm.xx = pmat->xx;
1759 s.ctm.xy = pmat->xy;
1760 s.ctm.yx = pmat->yx;
1761 s.ctm.yy = pmat->yy;
1762 s.ctm.tx = pmat->tx;
1763 s.ctm.ty = pmat->ty;
1764 memset(&inst, 0, sizeof(inst));
1765 inst.saved = (gs_gstate *)&s; /* HACK : will use s.ctm only. */
1766 inst.templat.PaintType = 1;
1767 inst.templat.TilingType = 1;
1768 inst.templat.BBox.p.x = inst.templat.BBox.p.y = 0;
1769 inst.templat.BBox.q.x = 1;
1770 inst.templat.BBox.q.y = 1;
1771 inst.templat.XStep = 2; /* Set 2 times bigger step against artifacts. */
1772 inst.templat.YStep = 2;
1773
1774 {
1775 pattern_accum_param_s param;
1776 param.pinst = (void *)&inst;
1777 param.graphics_state = (void *)&s;
1778 param.pinst_id = inst.id;
1779
1780 code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1781 gxdso_pattern_start_accum, ¶m, sizeof(pattern_accum_param_s));
1782 }
1783
1784 if (code >= 0)
1785 pprintld1(pdev->strm, "/R%ld Do\n", pdf_resource_id(pres1));
1786 pres = pdev->accumulating_substream_resource;
1787 if (code >= 0)
1788 code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres1);
1789 if (code >= 0) {
1790 pattern_accum_param_s param;
1791 param.pinst = (void *)&inst;
1792 param.graphics_state = (void *)&s;
1793 param.pinst_id = inst.id;
1794
1795 code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1796 gxdso_pattern_finish_accum, ¶m, id);
1797 }
1798 if (code >= 0)
1799 code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1800 gxdso_pattern_load, &inst, id);
1801 if (code >= 0) {
1802 stream_puts(pdev->strm, "q ");
1803 code = pdf_cs_Pattern_colored(pdev, &v);
1804 }
1805 if (code >= 0) {
1806 cos_value_write(&v, pdev);
1807 pprintld1(pdev->strm, " cs /R%ld scn ", pdf_resource_id(pres));
1808 }
1809 if (code >= 0) {
1810 /* The image offset weas broken in gx_begin_image3_generic,
1811 (see 'origin' in there).
1812 As a temporary hack use the offset of the image.
1813 fixme : This isn't generally correct,
1814 because the mask may be "transpozed" against the image. */
1815 gs_matrix m = pdev->converting_image_matrix;
1816
1817 m.tx = pmat->tx;
1818 m.ty = pmat->ty;
1819 code = pdf_do_image_by_id(pdev, pdev->image_mask_scale,
1820 &m, true, pdev->image_mask_id);
1821 stream_puts(pdev->strm, "Q\n");
1822 }
1823 return code;
1824 }
1825
1826 typedef enum {
1827 USE_AS_MASK,
1828 USE_AS_IMAGE,
1829 USE_AS_PATTERN
1830 } pdf_image_usage_t;
1831
1832 /* Close PDF image and do it. */
1833 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)1834 pdf_end_and_do_image(gx_device_pdf *pdev, pdf_image_writer *piw,
1835 const gs_matrix *mat, gs_id ps_bitmap_id, pdf_image_usage_t do_image)
1836 {
1837 int code = pdf_end_write_image(pdev, piw);
1838 pdf_resource_t *pres = piw->pres;
1839
1840 switch (code) {
1841 default:
1842 return code; /* error */
1843 case 1:
1844 code = 0;
1845 break;
1846 case 0:
1847 if (do_image == USE_AS_IMAGE) {
1848 if (pdev->image_mask_id != gs_no_id) {
1849 char buf[20];
1850
1851 gs_sprintf(buf, "%ld 0 R", pdev->image_mask_id);
1852 code = cos_dict_put_string_copy((cos_dict_t *)pres->object,
1853 pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf);
1854 (*(pres->object)).md5_valid = 0;
1855 if (code < 0)
1856 return code;
1857 }
1858 if (pdev->image_mask_skip)
1859 code = 0;
1860 else
1861 code = pdf_do_image(pdev, pres, mat, true);
1862 } else if (do_image == USE_AS_MASK) {
1863 /* Provide data for pdf_do_image_by_id, which will be called through
1864 use_image_as_pattern during the next call to this function.
1865 See pdf_do_image about the meaning of 'scale'. */
1866 const pdf_x_object_t *const pxo = (const pdf_x_object_t *)pres;
1867
1868 pdev->image_mask_scale = (double)pxo->data_height / pxo->height;
1869 pdev->image_mask_id = pdf_resource_id(pres);
1870 pdev->converting_image_matrix = *mat;
1871 } else if (do_image == USE_AS_PATTERN)
1872 code = use_image_as_pattern(pdev, pres, mat, ps_bitmap_id);
1873 }
1874 return code;
1875 }
1876
1877 /* Clean up by releasing the buffers. */
1878 static int
pdf_image_end_image_data(gx_image_enum_common_t * info,bool draw_last,pdf_image_usage_t do_image)1879 pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
1880 pdf_image_usage_t do_image)
1881 {
1882 gx_device_pdf *pdev = (gx_device_pdf *)info->dev;
1883 pdf_image_enum *pie = (pdf_image_enum *)info;
1884 int height = pie->writer.height;
1885 int data_height = height - pie->rows_left;
1886 int code = 0, ecode;
1887
1888 if (pie->writer.pres)
1889 ((pdf_x_object_t *)pie->writer.pres)->data_height = data_height;
1890 else if (data_height > 0)
1891 pdf_put_image_matrix(pdev, &pie->mat, (double)data_height / height);
1892 if (data_height > 0) {
1893 if (pie->writer.pres) {
1894 code = pdf_complete_image_data(pdev, &pie->writer, data_height,
1895 pie->width, pie->bits_per_pixel);
1896 if (code < 0)
1897 return code;
1898 }
1899 code = pdf_end_image_binary(pdev, &pie->writer, data_height);
1900 /* The call above possibly decreases pie->writer.alt_writer_count in 2. */
1901 if (code < 0)
1902 return code;
1903 if (pie->writer.alt_writer_count == 2) {
1904 /* We're converting a type 4 image into an imagemask with a pattern color. */
1905 /* Since the type 3 image writes the mask first, do so here. */
1906 pdf_image_writer writer = pie->writer;
1907
1908 writer.binary[0] = pie->writer.binary[1];
1909 writer.pres = pie->writer.pres_mask;
1910 writer.alt_writer_count = 1;
1911 memset(&pie->writer.binary[1], 0, sizeof(pie->writer.binary[1]));
1912 pie->writer.alt_writer_count--; /* For GC. */
1913 pie->writer.pres_mask = 0; /* For GC. */
1914 code = pdf_end_image_binary(pdev, &writer, data_height);
1915 if (code < 0)
1916 return code;
1917 code = pdf_end_and_do_image(pdev, &writer, &pie->mat, info->id, USE_AS_MASK);
1918 if (code < 0)
1919 return code;
1920 code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, USE_AS_PATTERN);
1921 } else
1922 code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, do_image);
1923 pie->writer.alt_writer_count--; /* For GC. */
1924 }
1925 if (pie->initial_colorspace != pdev->pcm_color_info_index)
1926 pdf_set_process_color_model(pdev, pie->initial_colorspace);
1927
1928 /* Clean up any outstanding streams before freeing the enumerator */
1929 while (pie->writer.alt_writer_count-- > 0) {
1930 ecode = psdf_end_binary(&(pie->writer.binary[pie->writer.alt_writer_count]));
1931 if (ecode < 0 && code >= 0) code = ecode;
1932 }
1933
1934 gx_image_free_enum(&info);
1935 return code;
1936 }
1937
1938 /* End a normal image, drawing it. */
1939 static int
pdf_image_end_image(gx_image_enum_common_t * info,bool draw_last)1940 pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last)
1941 {
1942 return pdf_image_end_image_data(info, draw_last, USE_AS_IMAGE);
1943 }
1944
1945 /* End an image converted with pdf_lcvd_t. */
1946 static int
pdf_image_end_image_cvd(gx_image_enum_common_t * info,bool draw_last)1947 pdf_image_end_image_cvd(gx_image_enum_common_t * info, bool draw_last)
1948 { pdf_lcvd_t *cvd = (pdf_lcvd_t *)info->dev;
1949 int code = pdf_dump_converted_image(cvd->pdev, cvd);
1950 int code1 = gx_image1_end_image(info, draw_last);
1951 int code2 = gs_closedevice((gx_device *)cvd->mask);
1952 int code3 = gs_closedevice((gx_device *)cvd);
1953
1954 gs_free_object(cvd->mask->memory, (gx_device *)cvd->mask, "pdf_image_end_image_cvd");
1955 gs_free_object(cvd->mdev.memory, (gx_device *)cvd, "pdf_image_end_image_cvd");
1956 return code < 0 ? code : code1 < 0 ? code1 : code2 < 0 ? code2 : code3;
1957 }
1958 /* ---------------- Type 3/3x images ---------------- */
1959
1960 /*
1961 * For both types of masked images, we create temporary dummy (null) devices
1962 * that forward the begin_typed_image call to the implementation above.
1963 */
1964 static int
pdf_make_mxd(gx_device ** pmxdev,gx_device * tdev,gs_memory_t * mem)1965 pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem)
1966 {
1967 gx_device *fdev;
1968 int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem);
1969
1970 if (code < 0)
1971 return code;
1972 gx_device_set_target((gx_device_forward *)fdev, tdev);
1973 *pmxdev = fdev;
1974 return 0;
1975 }
1976
1977 /* End the mask of an ImageType 3 image, not drawing it. */
1978 static int
pdf_image_end_image_object(gx_image_enum_common_t * info,bool draw_last)1979 pdf_image_end_image_object(gx_image_enum_common_t * info, bool draw_last)
1980 {
1981 return pdf_image_end_image_data(info, draw_last, USE_AS_MASK);
1982 }
1983 /* End the data of an ImageType 3 image, converting it into pattern. */
1984 static int
pdf_image_end_image_object2(gx_image_enum_common_t * info,bool draw_last)1985 pdf_image_end_image_object2(gx_image_enum_common_t * info, bool draw_last)
1986 {
1987 return pdf_image_end_image_data(info, draw_last, USE_AS_PATTERN);
1988 }
1989
1990 /* ---------------- Type 3 images ---------------- */
1991
1992 /* Implement the mask image device. */
1993 static dev_proc_begin_typed_image(pdf_mid_begin_typed_image);
1994 static int
pdf_image3_make_mid(gx_device ** pmidev,gx_device * dev,int width,int height,gs_memory_t * mem)1995 pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
1996 gs_memory_t *mem)
1997 {
1998 gx_device_pdf *pdev = (gx_device_pdf *)dev;
1999
2000 if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2001 gs_matrix m;
2002 pdf_lcvd_t *cvd = NULL;
2003 int code;
2004
2005 gs_make_identity(&m);
2006 code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
2007 true, 0, 0, width, height, true);
2008 if (code < 0)
2009 return code;
2010 cvd->mask->target = (gx_device *)cvd; /* Temporary, just to communicate with
2011 pdf_image3_make_mcde. The latter will reset it. */
2012 cvd->mask_is_empty = false;
2013 *pmidev = (gx_device *)cvd->mask;
2014 return 0;
2015 } else {
2016 int code = pdf_make_mxd(pmidev, dev, mem);
2017
2018 if (code < 0)
2019 return code;
2020 set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2021 return 0;
2022 }
2023 }
2024 static int
pdf_mid_begin_typed_image(gx_device * dev,const gs_gstate * pgs,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)2025 pdf_mid_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
2026 const gs_matrix *pmat, const gs_image_common_t *pic,
2027 const gs_int_rect * prect,
2028 const gx_drawing_color * pdcolor,
2029 const gx_clip_path * pcpath, gs_memory_t * mem,
2030 gx_image_enum_common_t ** pinfo)
2031 {
2032 /* The target of the null device is the pdfwrite device. */
2033 gx_device_pdf *const pdev = (gx_device_pdf *)
2034 ((gx_device_null *)dev)->target;
2035 return pdf_begin_typed_image
2036 (pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo,
2037 PDF_IMAGE_TYPE3_MASK);
2038 }
2039
2040 /* Implement the mask clip device. */
2041 static int
pdf_image3_make_mcde(gx_device * dev,const gs_gstate * pgs,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)2042 pdf_image3_make_mcde(gx_device *dev, const gs_gstate *pgs,
2043 const gs_matrix *pmat, const gs_image_common_t *pic,
2044 const gs_int_rect *prect, const gx_drawing_color *pdcolor,
2045 const gx_clip_path *pcpath, gs_memory_t *mem,
2046 gx_image_enum_common_t **pinfo,
2047 gx_device **pmcdev, gx_device *midev,
2048 gx_image_enum_common_t *pminfo,
2049 const gs_int_point *origin)
2050 {
2051 int code;
2052 gx_device_pdf *pdev = (gx_device_pdf *)dev;
2053
2054 if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2055 /* pdf_image3_make_mid must set midev with a pdf_lcvd_t instance.*/
2056 pdf_lcvd_t *cvd = (pdf_lcvd_t *)((gx_device_memory *)midev)->target;
2057
2058 ((gx_device_memory *)midev)->target = NULL;
2059 cvd->m = pdev->converting_image_matrix;
2060 cvd->mdev.mapped_x = origin->x;
2061 cvd->mdev.mapped_y = origin->y;
2062 *pmcdev = (gx_device *)&cvd->mdev;
2063 code = gx_default_begin_typed_image
2064 ((gx_device *)&cvd->mdev, pgs, pmat, pic, prect, pdcolor, NULL, mem,
2065 pinfo);
2066 if (code < 0)
2067 return code;
2068 } else {
2069 code = pdf_make_mxd(pmcdev, midev, mem);
2070 if (code < 0)
2071 return code;
2072 code = pdf_begin_typed_image
2073 ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2074 pinfo, PDF_IMAGE_TYPE3_DATA);
2075 if (code < 0)
2076 return code;
2077 }
2078 /* Due to equal image merging, we delay the adding of the "Mask" entry into
2079 a type 3 image dictionary until the mask is completed.
2080 Will do in pdf_end_and_do_image.*/
2081 return 0;
2082 }
2083
2084 /* ---------------- Type 3x images ---------------- */
2085
2086 /* Implement the mask image device. */
2087 static int
pdf_image3x_make_mid(gx_device ** pmidev,gx_device * dev,int width,int height,int depth,gs_memory_t * mem)2088 pdf_image3x_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
2089 int depth, gs_memory_t *mem)
2090 {
2091 int code = pdf_make_mxd(pmidev, dev, mem);
2092
2093 if (code < 0)
2094 return code;
2095 set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2096 return 0;
2097 }
2098
2099 /* Implement the mask clip device. */
2100 static int
pdf_image3x_make_mcde(gx_device * dev,const gs_gstate * pgs,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)2101 pdf_image3x_make_mcde(gx_device *dev, const gs_gstate *pgs,
2102 const gs_matrix *pmat, const gs_image_common_t *pic,
2103 const gs_int_rect *prect,
2104 const gx_drawing_color *pdcolor,
2105 const gx_clip_path *pcpath, gs_memory_t *mem,
2106 gx_image_enum_common_t **pinfo,
2107 gx_device **pmcdev, gx_device *midev[2],
2108 gx_image_enum_common_t *pminfo[2],
2109 const gs_int_point origin[2],
2110 const gs_image3x_t *pim)
2111 {
2112 int code;
2113 pdf_image_enum *pmie;
2114 int i;
2115 const gs_image3x_mask_t *pixm;
2116
2117 if (midev[0]) {
2118 if (midev[1])
2119 return_error(gs_error_rangecheck);
2120 i = 0, pixm = &pim->Opacity;
2121 } else if (midev[1])
2122 i = 1, pixm = &pim->Shape;
2123 else
2124 return_error(gs_error_rangecheck);
2125 code = pdf_make_mxd(pmcdev, midev[i], mem);
2126 if (code < 0)
2127 return code;
2128 code = pdf_begin_typed_image
2129 ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2130 pinfo, PDF_IMAGE_TYPE3_DATA);
2131 if (code < 0)
2132 return code;
2133 if ((*pinfo)->procs != &pdf_image_enum_procs) {
2134 /* We couldn't handle the image. Bail out. */
2135 gx_image_end(*pinfo, false);
2136 gs_free_object(mem, *pmcdev, "pdf_image3x_make_mcde");
2137 return_error(gs_error_rangecheck);
2138 }
2139 pmie = (pdf_image_enum *)pminfo[i];
2140 /*
2141 * Add the SMask entry to the image dictionary, and, if needed,
2142 * the Matte entry to the mask dictionary.
2143 */
2144 if (pixm->has_Matte) {
2145 gx_device_pdf *pdev = (gx_device_pdf *)dev;
2146 int DoMatte = 0, num_components =
2147 gs_color_space_num_components(pim->ColorSpace);
2148
2149 switch (pdev->params.ColorConversionStrategy) {
2150 case ccs_LeaveColorUnchanged:
2151 DoMatte = 1;
2152 break;
2153 case ccs_RGB:
2154 case ccs_sRGB:
2155 if (num_components == 3)
2156 DoMatte = 1;
2157 else
2158 DoMatte = 0;
2159 break;
2160 case ccs_CMYK:
2161 if (num_components == 4)
2162 DoMatte = 1;
2163 else
2164 DoMatte = 0;
2165 break;
2166 case ccs_Gray:
2167 if (num_components == 1)
2168 DoMatte = 1;
2169 else
2170 DoMatte = 0;
2171 break;
2172 case ccs_UseDeviceIndependentColor:
2173 case ccs_UseDeviceIndependentColorForImages:
2174 case ccs_ByObjectType:
2175 default:
2176 DoMatte = 0;
2177 break;
2178 }
2179
2180 if (DoMatte) {
2181 code = cos_dict_put_c_key_floats((gx_device_pdf *)dev,
2182 (cos_dict_t *)pmie->writer.pres->object,
2183 "/Matte", pixm->Matte,
2184 num_components);
2185 if (code < 0)
2186 return code;
2187 }
2188 }
2189 /* Don't put SMask here because pmie->writer.pres->object may be substituted
2190 * after the image stream is accummulated. pdf_end_and_do_image will set
2191 * SMask with the right value. Bug 690345.
2192 */
2193 return 0;
2194 }
2195
pdf_substitute_pattern(pdf_resource_t * pres)2196 pdf_resource_t *pdf_substitute_pattern(pdf_resource_t *pres)
2197 {
2198 pdf_pattern_t *ppat = (pdf_pattern_t *)pres;
2199
2200 return (pdf_resource_t *)(ppat->substitute != 0 ? ppat->substitute : ppat);
2201 }
2202
2203 static int
check_unsubstituted2(gx_device_pdf * pdev,pdf_resource_t * pres0,pdf_resource_t * pres1)2204 check_unsubstituted2(gx_device_pdf * pdev, pdf_resource_t *pres0, pdf_resource_t *pres1)
2205 {
2206 pdf_pattern_t *ppat0 = (pdf_pattern_t *)pres0;
2207 pdf_pattern_t *ppat1 = (pdf_pattern_t *)pres1;
2208
2209 return (ppat0->substitute == NULL && ppat1->substitute == NULL);
2210 }
2211
2212 static int
check_unsubstituted1(gx_device_pdf * pdev,pdf_resource_t * pres0)2213 check_unsubstituted1(gx_device_pdf * pdev, pdf_resource_t *pres0)
2214 {
2215 pdf_pattern_t *ppat = (pdf_pattern_t *)pres0;
2216
2217 return ppat->substitute != NULL;
2218 }
2219
2220 /*
2221 The device specific operations - just pattern management.
2222 See gxdevcli.h about return codes.
2223 */
2224 int
gdev_pdf_dev_spec_op(gx_device * pdev1,int dev_spec_op,void * data,int size)2225 gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
2226 {
2227 gx_device_pdf *pdev = (gx_device_pdf *)pdev1;
2228 int code=0, force_CTM_change=0;
2229 pdf_resource_t *pres, *pres1;
2230 gx_bitmap_id id = (gx_bitmap_id)size;
2231
2232 switch (dev_spec_op) {
2233 case gxdso_pattern_can_accum:
2234 return 1;
2235 case gxdso_pdf_form_name:
2236 if (pdev->PDFFormName) {
2237 gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2238 }
2239 pdev->PDFFormName = (char *)gs_alloc_bytes(pdev->memory->non_gc_memory, size + 1, "Name of Form for pdfmark");
2240 memset(pdev->PDFFormName, 0x00, size + 1);
2241 memcpy(pdev->PDFFormName, data, size);
2242 return 0;
2243 case gxdso_pdf_last_form_ID:
2244 {
2245 int *i = (int *)data;
2246 *i = pdev->LastFormID;
2247 }
2248 return 0;
2249 case gxdso_form_begin:
2250 if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 0) && pdev->PatternDepth == 0) {
2251 gs_form_template_t *tmplate = (gs_form_template_t *)data;
2252 float arry[6];
2253 cos_dict_t *pcd = NULL, *pcd_Resources = NULL;
2254
2255 /* Make sure the document and page stream are open */
2256 code = pdfwrite_pdf_open_document(pdev);
2257 if (code < 0)
2258 return code;
2259 code = pdf_open_contents(pdev, PDF_IN_STREAM);
2260 if (code < 0)
2261 return code;
2262 if (!pdev->PDFFormName) {
2263 /* Put any extant clip out before we start the form */
2264 code = pdf_put_clip_path(pdev, tmplate->pcpath);
2265 if (code < 0)
2266 return code;
2267 /* Set the CTM to be the one passed in from the interpreter,
2268 * this allows us to spot forms even when translation/rotation takes place
2269 * as we remove the CTN from the form stream before capture
2270 */
2271 pprintg6(pdev->strm, "q %g %g %g %g %g %g cm\n", tmplate->CTM.xx, tmplate->CTM.xy,
2272 tmplate->CTM.yx, tmplate->CTM.yy, tmplate->CTM.tx, tmplate->CTM.ty);
2273 }
2274
2275 /* start capturing the form stream */
2276 code = pdf_enter_substream(pdev, resourceXObject, id, &pres, false,
2277 pdev->CompressStreams);
2278 if (code < 0)
2279 return code;
2280 pcd = cos_stream_dict((cos_stream_t *)pres->object);
2281 pcd_Resources = cos_dict_alloc(pdev, "pdf_pattern(Resources)");
2282 if (pcd == NULL || pcd_Resources == NULL)
2283 return_error(gs_error_VMerror);
2284 code = cos_dict_put_c_strings(pcd, "/Type", "/XObject");
2285 if (code >= 0)
2286 code = cos_dict_put_c_strings(pcd, "/Subtype", "/Form");
2287 if (code >= 0)
2288 code = cos_dict_put_c_strings(pcd, "/FormType", "1");
2289 if (code >= 0)
2290 code = cos_dict_put_c_key_object(pcd, "/Resources", COS_OBJECT(pcd_Resources));
2291
2292 if (pdev->PDFFormName) {
2293 /* This is not (I think) required when executing PS forms, because the
2294 * CTM is written out before we execute the Form. It *is* required for
2295 * PDF Appearance Forms, because the Form is written directly from the
2296 * outer context, not from the page, so we don't emit the CTM first.
2297 * We want to alter the Form BBox to take any required rotation and scaling
2298 * (from FitPage and /Rotate) into account so that the form appearance is
2299 * properly scaled and rotated.
2300 */
2301 gs_rect bbox_out;
2302 gs_matrix cmat, new_mat = tmplate->CTM;
2303
2304 /* We don't want anything left over from the page content stream, or other
2305 * annotation appearances, to affect whether or not we emit any graphics
2306 * state, so reset the state here to the defaults.
2307 */
2308 pdf_viewer_state_from_gs_gstate(pdev, tmplate->pgs, NULL);
2309 /* For PDF Appearance streams at least, the Form BBox is modified by the
2310 * Form Matrix.
2311 */
2312 code = gs_matrix_multiply(&tmplate->form_matrix, &tmplate->CTM, &cmat);
2313 if (code < 0)
2314 return code;
2315 code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2316 if (code < 0)
2317 return code;
2318
2319 /* Check the BBox is on the page. Modify it if it is not (this can happen
2320 * if the MediaBox does not have bottom left at 0,0)
2321 */
2322 cmat.xx = cmat.yy = 1.0f;
2323 cmat.xy = cmat.yx = cmat.tx = cmat.ty = 0.0f;
2324 if(bbox_out.q.x - bbox_out.p.x > pdev->width) {
2325 cmat.xx = pdev->width / (bbox_out.q.x - bbox_out.p.x);
2326 bbox_out.q.x = bbox_out.p.x + ((bbox_out.q.x - bbox_out.p.x) * cmat.xx);
2327 force_CTM_change = 1;
2328 }
2329 if(bbox_out.q.y - bbox_out.p.y > pdev->height) {
2330 cmat.yy = pdev->height / (bbox_out.q.y - bbox_out.p.y);
2331 bbox_out.q.y = bbox_out.p.y + ((bbox_out.q.y - bbox_out.p.y) * cmat.yy);
2332 force_CTM_change = 1;
2333 }
2334
2335 if (bbox_out.p.x < 0) {
2336 cmat.tx = bbox_out.p.x * -1;
2337 bbox_out.q.x += cmat.tx;
2338 force_CTM_change = 1;
2339 }
2340 if (floor(bbox_out.q.x) > pdev->width) {
2341 cmat.tx -= bbox_out.p.x;
2342 bbox_out.q.x -= bbox_out.p.x;
2343 bbox_out.p.x = 0;
2344 force_CTM_change = 1;
2345 }
2346 if (bbox_out.p.y < 0) {
2347 cmat.ty = bbox_out.p.y * -1;
2348 bbox_out.q.y += cmat.ty;
2349 force_CTM_change = 1;
2350 }
2351 if (floor(bbox_out.q.y) > pdev->height) {
2352 cmat.ty += pdev->height - bbox_out.q.y;
2353 force_CTM_change = 1;
2354 }
2355
2356 if (force_CTM_change) {
2357 code = gs_matrix_multiply(&tmplate->CTM, &cmat, &new_mat);
2358 if (code < 0)
2359 return code;
2360 code = gs_matrix_multiply(&tmplate->form_matrix, &new_mat, &cmat);
2361 if (code < 0)
2362 return code;
2363 code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2364 if (code < 0)
2365 return code;
2366 tmplate->CTM = cmat;
2367 }
2368 arry[0] = bbox_out.p.x;
2369 arry[1] = bbox_out.p.y;
2370 arry[2] = bbox_out.q.x;
2371 arry[3] = bbox_out.q.y;
2372 if (code >= 0)
2373 code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2374 if (code < 0)
2375 return code;
2376
2377 /* Note that we will apply the CTM to the form, and the Form Matrix. To prevcent
2378 * us applying the Matrix twice, we need to set it to the identity in the Form
2379 * dictionary. I'm not sure why we don't need to do that for PostScript Forms.
2380 */
2381 arry[0] = arry[3] = 1.0f;
2382 arry[1] = arry[2] = arry[4] = arry[5] = 0.0f;
2383 } else {
2384 arry[0] = tmplate->BBox.p.x;
2385 arry[1] = tmplate->BBox.p.y;
2386 arry[2] = tmplate->BBox.q.x;
2387 arry[3] = tmplate->BBox.q.y;
2388 if (code >= 0)
2389 code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2390 if (code < 0)
2391 return code;
2392
2393 arry[0] = tmplate->form_matrix.xx;
2394 arry[1] = tmplate->form_matrix.xy;
2395 arry[2] = tmplate->form_matrix.yx;
2396 arry[3] = tmplate->form_matrix.yy;
2397 arry[4] = tmplate->form_matrix.tx;
2398 arry[5] = tmplate->form_matrix.ty;
2399
2400 pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2401 72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2402 }
2403
2404 code = cos_dict_put_c_key_floats(pdev, pcd, "/Matrix", arry, 6);
2405 if (code < 0)
2406 return code;
2407
2408 /* We'll return this to the interpreter and have it set
2409 * as the CTM, so that we remove the prior CTM before capturing the form.
2410 * This is safe because forms are always run inside a gsave/grestore, so
2411 * CTM will be put back for us.
2412 */
2413 if (!pdev->PDFFormName) {
2414 tmplate->CTM.xx = pdev->HWResolution[0] / 72;
2415 tmplate->CTM.xy = 0.0;
2416 tmplate->CTM.yx = 0.0;
2417 tmplate->CTM.yy = pdev->HWResolution[0] / 72;
2418 tmplate->CTM.tx = 0.0;
2419 tmplate->CTM.ty = 0.0;
2420
2421 pdev->substream_Resources = pcd_Resources;
2422 pres->rid = id;
2423 if (code >= 0)
2424 pdev->HighLevelForm++;
2425 return 1;
2426 } else {
2427 /* For PDF Appearance streams (Forms) we *must* apply the
2428 * CTM. This is because if the PDF has a non-zero Rotate key
2429 * we bake that rotation into the CTM. If we didn't apply that
2430 * then the annotation wouldn't get rotated :-(
2431 */
2432 pdev->substream_Resources = pcd_Resources;
2433 pres->rid = id;
2434 if (code >= 0)
2435 pdev->HighLevelForm++;
2436 return force_CTM_change;
2437 }
2438 }
2439 return code;
2440 case gxdso_form_end:
2441 /* This test must be the same as the one in gxdso_form_begin, above */
2442 if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 1) && pdev->PatternDepth == 0) {
2443 if (pdev->CompatibilityLevel <= 1.7) {
2444 code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2445 if (code < 0)
2446 return code;
2447 }
2448 pres = pres1 = pdev->accumulating_substream_resource;
2449 code = pdf_exit_substream(pdev);
2450 if (code < 0)
2451 return code;
2452 code = pdf_find_same_resource(pdev, resourceXObject, &pres, check_unsubstituted2);
2453 if (code < 0)
2454 return code;
2455 if (code > 0) {
2456 code = pdf_cancel_resource(pdev, pres1, resourceXObject);
2457 if (code < 0)
2458 return code;
2459 pres->where_used |= pdev->used_mask;
2460 } else if (pres->object->id < 0)
2461 pdf_reserve_object_id(pdev, pres, 0);
2462 if (pdev->PDFFormName) {
2463 cos_value_t value;
2464
2465 code = cos_dict_put(pdev->local_named_objects, (const byte *)pdev->PDFFormName,
2466 strlen(pdev->PDFFormName), cos_object_value(&value, pres->object));
2467
2468 if (code < 0)
2469 return code;
2470 pdf_drop_resource_from_chain(pdev, pres, resourceXObject);
2471
2472 gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name oof Form for pdfmark");
2473 pdev->PDFFormName = 0x00;
2474 } else {
2475 pprintld1(pdev->strm, "/R%ld Do Q\n", pdf_resource_id(pres));
2476 }
2477 pdev->HighLevelForm--;
2478 if (pdev->accumulating_substream_resource) {
2479 code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
2480 if (code < 0)
2481 return code;
2482 }
2483 pdev->LastFormID = pdf_resource_id(pres);
2484 }
2485 return 0;
2486 case gxdso_get_form_ID:
2487 {
2488 int *ID = data;
2489 *ID = pdev->LastFormID;
2490 }
2491 return 0;
2492 case gxdso_repeat_form:
2493 {
2494 gs_form_template_t *tmplate = (gs_form_template_t *)data;
2495
2496 /* Make sure the document and page stream are open */
2497 code = pdfwrite_pdf_open_document(pdev);
2498 if (code < 0)
2499 return code;
2500 code = pdf_open_contents(pdev, PDF_IN_STREAM);
2501 if (code < 0)
2502 return code;
2503 /* Put any extant clip out before we start the form */
2504 code = pdf_put_clip_path(pdev, tmplate->pcpath);
2505 if (code < 0)
2506 return code;
2507 /* Set the CTM to be the one passed in from the interpreter,
2508 * this allows us to spot forms even when translation/rotation takes place
2509 * as we remove the CTN from the form stream before capture
2510 */
2511 pprintg6(pdev->strm, "q %g %g %g %g %g %g cm\n", tmplate->CTM.xx, tmplate->CTM.xy,
2512 tmplate->CTM.yx, tmplate->CTM.yy, tmplate->CTM.tx, tmplate->CTM.ty);
2513 pprintld1(pdev->strm, "/R%ld Do Q\n", tmplate->FormID);
2514 pres = pdf_find_resource_by_resource_id(pdev, resourceXObject, tmplate->FormID);
2515 if (pres == NULL)
2516 return_error(gs_error_undefined);
2517 pres->where_used |= pdev->used_mask;
2518 if (pdev->accumulating_substream_resource) {
2519 code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
2520 if (code < 0)
2521 return code;
2522 }
2523 }
2524 return 0;
2525 case gxdso_pattern_start_accum:
2526 {
2527 pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2528 gs_pattern1_instance_t *pinst = param->pinst;
2529 gs_gstate *pgs = param->graphics_state;
2530
2531 id = param->pinst_id;
2532 code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
2533 if (code < 0)
2534 return code;
2535 code = pdf_enter_substream(pdev, resourcePattern, id, &pres, false,
2536 pdev->CompressStreams);
2537 if (code < 0)
2538 return code;
2539 /* We have started a new substream, to avoid confusing the 'saved viewer state'
2540 * (the stack of pdfwrite's saved copies of graophics states) we need to reset the
2541 * soft_mask_id, which is the ID of the SMask we have already created in the pdfwrite
2542 * output. The gsave/grestore round the spec_op to start and finish the pattern
2543 * accumulator (see pattern_paint_prepare and pattern_paint_finish) will ensure that
2544 * the ID is restored when we finish capturing the pattern.
2545 */
2546 pdev->state.soft_mask_id = pgs->soft_mask_id;
2547 pres->rid = id;
2548 code = pdf_store_pattern1_params(pdev, pres, pinst);
2549 if (code < 0)
2550 return code;
2551 /* Scale the coordinate system, because object handlers assume so. See none_to_stream. */
2552 pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2553 72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2554 pdev->PatternDepth++;
2555 pdev->PatternsSinceForm++;
2556 }
2557 return 1;
2558 case gxdso_pattern_finish_accum:
2559 if (pdev->CompatibilityLevel <= 1.7) {
2560 if (pdev->substream_Resources == NULL) {
2561 pdev->substream_Resources = cos_dict_alloc(pdev, "pdf_pattern(Resources)");
2562 if (pdev->substream_Resources == NULL)
2563 return_error(gs_error_VMerror);
2564 }
2565 code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2566 if (code < 0)
2567 return code;
2568 }
2569 pres = pres1 = pdev->accumulating_substream_resource;
2570 code = pdf_exit_substream(pdev);
2571 if (code < 0)
2572 return code;
2573 if (pdev->substituted_pattern_count > 300 &&
2574 pdev->substituted_pattern_drop_page != pdev->next_page) { /* arbitrary */
2575 pdf_drop_resources(pdev, resourcePattern, check_unsubstituted1);
2576 pdev->substituted_pattern_count = 0;
2577 pdev->substituted_pattern_drop_page = pdev->next_page;
2578 }
2579 code = pdf_find_same_resource(pdev, resourcePattern, &pres, check_unsubstituted2);
2580 if (code < 0)
2581 return code;
2582 if (code > 0) {
2583 pdf_pattern_t *ppat = (pdf_pattern_t *)pres1;
2584
2585 code = pdf_cancel_resource(pdev, pres1, resourcePattern);
2586 if (code < 0)
2587 return code;
2588 /* Do not remove pres1, because it keeps the substitution. */
2589 ppat->substitute = (pdf_pattern_t *)pres;
2590 pres->where_used |= pdev->used_mask;
2591 pdev->substituted_pattern_count++;
2592 } else if (pres->object->id < 0)
2593 pdf_reserve_object_id(pdev, pres, 0);
2594 pdev->PatternDepth--;
2595 pdev->PatternsSinceForm--;
2596 return 1;
2597 case gxdso_pattern_load:
2598 pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, id);
2599 if (pres == 0)
2600 return 0;
2601 pres = pdf_substitute_pattern(pres);
2602 pres->where_used |= pdev->used_mask;
2603 code = pdf_add_resource(pdev, pdev->substream_Resources, "/Pattern", pres);
2604 if (code < 0)
2605 return code;
2606 return 1;
2607 case gxdso_pattern_shading_area:
2608 return 0;
2609 case gxdso_pattern_is_cpath_accum:
2610 return 0;
2611 case gxdso_pattern_shfill_doesnt_need_path:
2612 return 0; /* gdev_pdf_fill_path still does need a path. */
2613 case gxdso_pattern_handles_clip_path:
2614 /* This is important when the default implementation of
2615 of fill_path is called due to a failure in setcolor
2616 or so, for example when a shading is incorrect.
2617 The test case is the unfixed (buggy) Genoa test 446-01.ps .
2618 In this case pdfwrite converts the object into rectangles,
2619 and the clipping device has to be set up. */
2620 return 0;
2621 case gxdso_supports_hlcolor:
2622 /* This is used due to some aliasing between the rect_hl color
2623 filling used by pdfwrite vs. that used by the planar device
2624 which is actually a devn vs. the pattern type for pdfwrite.
2625 We use this to distingush between the two */
2626 return 1;
2627 case gxdso_needs_invariant_palette:
2628 /* Indicates that it is not permissible to change /Indexed colour space
2629 * palette entries after the colour space has been set.
2630 */
2631 return 1;
2632 case gxdso_JPEG_passthrough_query:
2633 pdev->JPEG_PassThrough = pdev->params.PassThroughJPEGImages;
2634 return 1;
2635 break;
2636 case gxdso_JPEG_passthrough_begin:
2637 return 0;
2638 break;
2639 case gxdso_JPEG_passthrough_data:
2640 if (pdev->JPEG_PassThrough && pdev->PassThroughWriter)
2641 {
2642 uint ignore;
2643 if (sputs(pdev->PassThroughWriter,
2644 data, size,
2645 &ignore) < 0)
2646 return_error(gs_error_ioerror);
2647 }
2648 return 0;
2649 break;
2650 case gxdso_JPEG_passthrough_end:
2651 pdev->JPEG_PassThrough = 0;
2652 pdev->PassThroughWriter = 0;
2653 return 0;
2654 break;
2655 case gxdso_event_info:
2656 {
2657 dev_param_req_t *request = (dev_param_req_t *)data;
2658 if (memcmp(request->Param, "SubstitutedFont", 15) == 0 && pdev->PDFA) {
2659 switch (pdev->PDFACompatibilityPolicy) {
2660 case 0:
2661 case 1:
2662 emprintf(pdev->memory,
2663 "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, reverting to normal PDF output!\n");
2664 pdev->AbortPDFAX = true;
2665 pdev->PDFX = 0;
2666 break;
2667 case 2:
2668 emprintf(pdev->memory,
2669 "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, aborting conversion!\n");
2670 pdev->AbortPDFAX = true;
2671 pdev->PDFX = 0;
2672 return gs_note_error(gs_error_unknownerror);
2673 break;
2674 default:
2675 emprintf(pdev->memory,
2676 "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, unknown PDFACompatibilityPolicy, reverting to normal PDF output!\n");
2677 pdev->AbortPDFAX = true;
2678 pdev->PDFX = 0;
2679 break;
2680 }
2681 }
2682 return 0;
2683 }
2684 break;
2685 case gxdso_get_dev_param:
2686 {
2687 int code;
2688 dev_param_req_t *request = (dev_param_req_t *)data;
2689 code = gdev_pdf_get_param(pdev1, request->Param, request->list);
2690 if (code != gs_error_undefined)
2691 return code;
2692 }
2693 /* Fall through */
2694 }
2695 return gx_default_dev_spec_op(pdev1, dev_spec_op, data, size);
2696 }
2697