summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gs/base/gdevpdfb.h11
-rw-r--r--gs/base/gdevpdfg.c500
-rw-r--r--gs/base/gdevpdfi.c982
-rw-r--r--gs/base/gdevpdfk.c5
-rw-r--r--gs/base/gdevpdfp.c125
-rw-r--r--gs/base/gdevpdfx.h5
-rw-r--r--gs/base/gdevpsdf.h18
-rw-r--r--gs/base/gdevpsdi.c154
-rw-r--r--gs/base/gdevpsds.c43
-rw-r--r--gs/base/gdevpsds.h11
10 files changed, 1801 insertions, 53 deletions
diff --git a/gs/base/gdevpdfb.h b/gs/base/gdevpdfb.h
index 48b85ab28..13babb957 100644
--- a/gs/base/gdevpdfb.h
+++ b/gs/base/gdevpdfb.h
@@ -272,8 +272,11 @@ const gx_device_pdf PDF_DEVICE_IDENT =
272 true, /* IsDistiller (true even for ps2write!) */ 272 true, /* IsDistiller (true even for ps2write!) */
273 !PDF_FOR_OPDFREAD, /* PreserveSMask */ 273 !PDF_FOR_OPDFREAD, /* PreserveSMask */
274 !PDF_FOR_OPDFREAD, /* PreserveTrMode */ 274 !PDF_FOR_OPDFREAD, /* PreserveTrMode */
275 false, /* NoT3CCITT */ 275 false, /* NoT3CCITT */
276 false, /* Linearise */ 276 true, /* UseOldColor */
277 0, /* FirstPage */ 277 false, /* Linearise */
278 0 /* LastPage */ 278 0, /* FirstPage (from the command line) */
279 0, /* LastPage (from the command line) */
280 0, /* pointer to resourceusage */
281 0 /* Size of resourceusage */
279}; 282};
diff --git a/gs/base/gdevpdfg.c b/gs/base/gdevpdfg.c
index f71f94554..d5f84cb1e 100644
--- a/gs/base/gdevpdfg.c
+++ b/gs/base/gdevpdfg.c
@@ -36,6 +36,7 @@
36#include "gdevpdfg.h" 36#include "gdevpdfg.h"
37#include "gdevpdfo.h" 37#include "gdevpdfo.h"
38#include "gsicc_manage.h" 38#include "gsicc_manage.h"
39#include "gsicc_cache.h"
39 40
40/* ---------------- Miscellaneous ---------------- */ 41/* ---------------- Miscellaneous ---------------- */
41 42
@@ -292,6 +293,502 @@ is_pattern2_allowed_in_strategy(gx_device_pdf * pdev, const gx_drawing_color *pd
292 return is_cspace_allowed_in_strategy(pdev, csi); 293 return is_cspace_allowed_in_strategy(pdev, csi);
293} 294}
294 295
296
297static int write_color_as_process(gx_device_pdf * pdev, const gs_imager_state * pis, const gs_color_space *pcs,
298 const gx_drawing_color *pdc, bool *used_process_color,
299 const psdf_set_color_commands_t *ppscc, gs_client_color *pcc)
300{
301 int code, i;
302 gsicc_link_t *icc_link;
303 gsicc_rendering_param_t rendering_params;
304 frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
305 unsigned short Converted[GS_CLIENT_COLOR_MAX_COMPONENTS];
306 unsigned short Source[GS_CLIENT_COLOR_MAX_COMPONENTS];
307 gs_color_space_index csi, csi2;
308
309 csi = csi2 = gs_color_space_get_index(pcs);
310
311 if (csi == gs_color_space_index_Indexed) {
312 gs_color_space *pcs2 = pcs->base_space;
313 csi2 = gs_color_space_get_index(pcs2);
314 }
315 if (csi2 == gs_color_space_index_DeviceN ||
316 csi2 == gs_color_space_index_Separation) {
317
318 const char *command = NULL;
319
320 memset (&conc, 0x00, sizeof(frac) * GS_CLIENT_COLOR_MAX_COMPONENTS);
321 pcs->type->concretize_color(pcc, pcs, conc, pis, (gx_device *)pdev);
322 csi = gs_color_space_get_index(pcs->base_space);
323 if (csi != gs_color_space_index_ICC) {
324 *used_process_color = true;
325 switch (pdev->color_info.num_components) {
326 case 1:
327 command = ppscc->setgray;
328 break;
329 case 3:
330 command = ppscc->setrgbcolor;
331 break;
332 case 4:
333 command = ppscc->setcmykcolor;
334 break;
335 }
336 pprintg1(pdev->strm, "%g", psdf_round((conc[0] / (double)65535), 255, 8));
337 for (i = 1; i < pdev->color_info.num_components; i++) {
338 pprintg1(pdev->strm, " %g", psdf_round((conc[i] / (double)65535), 255, 8));
339 }
340 pprints1(pdev->strm, " %s\n", command);
341 return 0;
342 } else {
343 pcs = pcs->base_space;
344 for (i=0;i<pdev->color_info.num_components;i++)
345 Source[i] = (unsigned short)(conc[i]);
346 }
347 }
348 if (csi == gs_color_space_index_Indexed) {
349 memset (&conc, 0x00, sizeof(frac) * GS_CLIENT_COLOR_MAX_COMPONENTS);
350 pcs->type->concretize_color(pcc, pcs, conc, pis, (gx_device *)pdev);
351 pcs = pcs->base_space;
352 for (i=0;i<pcs->cmm_icc_profile_data->num_comps;i++)
353 Source[i] = (unsigned short)(conc[i]);
354 } else {
355 if (csi2 >= gs_color_space_index_CIEDEFG &&
356 csi2 <= gs_color_space_index_CIEA) {
357 int j = 0;
358
359 switch (csi2) {
360 case gs_color_space_index_CIEDEFG:
361 j += 1;
362 case gs_color_space_index_CIEDEF:
363 case gs_color_space_index_CIEABC:
364 j += 2;
365 case gs_color_space_index_CIEA:
366 j += 1;
367 break;
368 default: /* can't happen, simply silences compiler warnings */
369 break;
370 }
371 for (i=0;i<j;i++)
372 Source[i] = (unsigned short)(pcc->paint.values[i] * 65535);
373 } else {
374 if (csi2 != gs_color_space_index_DeviceN &&
375 csi2 != gs_color_space_index_Separation) {
376 for (i=0;i<pcs->cmm_icc_profile_data->num_comps;i++)
377 Source[i] = (unsigned short)(pcc->paint.values[i] * 65535);
378 }
379 }
380 }
381 rendering_params.black_point_comp = pis->blackptcomp;
382 rendering_params.graphics_type_tag = pdev->graphics_type_tag;
383 rendering_params.override_icc = false;
384 rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
385 rendering_params.rendering_intent = pis->renderingintent;
386 rendering_params.cmm = gsCMM_DEFAULT;
387 icc_link = gsicc_get_link(pis, (gx_device *)pdev, pcs,
388 NULL, &rendering_params,
389 pis->memory);
390 (icc_link->procs.map_color)((gx_device *)pdev, icc_link, Source, Converted, 2);
391 gsicc_release_link(icc_link);
392 for (i = 0;i < pdev->color_info.num_components;i++)
393 pcc->paint.values[i] = Source[i] / 65535.0f;
394 code = psdf_set_color((gx_device_vector *)pdev, pdc, ppscc);
395 if (code < 0)
396 return code;
397 *used_process_color = true;
398 return 0;
399}
400
401static int write_color_unchanged(gx_device_pdf * pdev, const gs_imager_state * pis,
402 gs_client_color *pcc, gx_hl_saved_color *current,
403 gx_hl_saved_color * psc, const psdf_set_color_commands_t *ppscc,
404 bool *used_process_color, const gs_color_space *pcs,
405 const gx_drawing_color *pdc)
406{
407 gs_color_space_index csi, csi2;
408 int code;
409 const char *command = NULL;
410
411 csi = csi2 = gs_color_space_get_index(pcs);
412 if (csi == gs_color_space_index_ICC) {
413 csi2 = gsicc_get_default_type(pcs->cmm_icc_profile_data);
414 }
415
416 switch (csi2) {
417 case gs_color_space_index_DeviceGray:
418 command = ppscc->setgray;
419 code = pdf_write_ccolor(pdev, pis, pcc);
420 if (code < 0)
421 return code;
422 pprints1(pdev->strm, " %s\n", command);
423 break;
424 case gs_color_space_index_DeviceRGB:
425 command = ppscc->setrgbcolor;
426 code = pdf_write_ccolor(pdev, pis, pcc);
427 if (code < 0)
428 return code;
429 pprints1(pdev->strm, " %s\n", command);
430 break;
431 case gs_color_space_index_DeviceCMYK:
432 command = ppscc->setcmykcolor;
433 code = pdf_write_ccolor(pdev, pis, pcc);
434 if (code < 0)
435 return code;
436 pprints1(pdev->strm, " %s\n", command);
437 break;
438 default:
439 if (!gx_hld_saved_color_same_cspace(current, psc)) {
440 cos_value_t cs_value;
441
442 code = pdf_color_space_named(pdev, &cs_value, NULL, pcs,
443 &pdf_color_space_names, true, NULL, 0);
444 /* fixme : creates redundant PDF objects. */
445 if (code == gs_error_rangecheck) {
446 /* The color space can't write to PDF. This should never happen */
447 return write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
448 }
449 if (code < 0)
450 return code;
451 code = cos_value_write(&cs_value, pdev);
452 if (code < 0)
453 return code;
454 pprints1(pdev->strm, " %s\n", ppscc->setcolorspace);
455 *used_process_color = false;
456 code = pdf_write_ccolor(pdev, pis, pcc);
457 if (code < 0)
458 return code;
459 pprints1(pdev->strm, " %s\n", ppscc->setcolorn);
460 } else if (*used_process_color)
461 return write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
462 else {
463 code = pdf_write_ccolor(pdev, pis, pcc);
464 if (code < 0)
465 return code;
466 pprints1(pdev->strm, " %s\n", ppscc->setcolorn);
467 }
468 break;
469 }
470 *used_process_color = false;
471
472 return 0;
473}
474
475static int write_color_as_process_ICC(gx_device_pdf * pdev, const gs_imager_state * pis, const gs_color_space *pcs,
476 const gx_drawing_color *pdc, gx_hl_saved_color * psc, bool *used_process_color,
477 const psdf_set_color_commands_t *ppscc, gs_client_color *pcc,
478 gx_hl_saved_color *current)
479{
480 int i, code;
481 cos_value_t cs_value;
482
483 if (!gx_hld_saved_color_same_cspace(current, psc)) {
484 code = pdf_color_space_named(pdev, &cs_value, NULL, pcs,
485 &pdf_color_space_names, true, NULL, 0);
486 /* fixme : creates redundant PDF objects. */
487 if (code == gs_error_rangecheck) {
488 /* The color space can't write to PDF. This should never happen */
489 return write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
490 }
491 if (code < 0)
492 return code;
493 code = cos_value_write(&cs_value, pdev);
494 if (code < 0)
495 return code;
496 pprints1(pdev->strm, " %s\n", ppscc->setcolorspace);
497 *used_process_color = false;
498 pprintg1(pdev->strm, "%g", psdf_round(pcc->paint.values[0], 255, 8));
499 for (i = 1; i < pcs->type->num_components(pcs); i++) {
500 pprintg1(pdev->strm, " %g", psdf_round(pcc->paint.values[i], 255, 8));
501 }
502 if (code < 0)
503 return code;
504 pprints1(pdev->strm, " %s\n", ppscc->setcolorn);
505 } else if (*used_process_color)
506 return write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
507 return 0;
508}
509
510static int new_pdf_reset_color(gx_device_pdf * pdev, const gs_imager_state * pis,
511 const gx_drawing_color *pdc, gx_hl_saved_color * psc,
512 bool *used_process_color,
513 const psdf_set_color_commands_t *ppscc)
514{
515 int code=0, code1=0;
516 gx_hl_saved_color temp;
517 gs_client_color *pcc; /* fixme: not needed due to gx_hld_get_color_component. */
518 cos_value_t cs_value;
519 gs_color_space_index csi;
520 gs_color_space_index csi2;
521 const gs_color_space *pcs, *pcs2;
522
523 if (pdev->skip_colors)
524 return 0;
525
526 /* Get a copy of the current colour so we can examine it. */
527 gx_hld_save_color(pis, pdc, &temp);
528
529 /* Since pdfwrite never applies halftones and patterns, but monitors
530 * halftone/pattern IDs separately, we don't need to compare
531 * halftone/pattern bodies here.
532 */
533 if (gx_hld_saved_color_equal(&temp, psc))
534 /* New colour (and space) same as old colour, no need to do anything */
535 return 0;
536
537 /* Do we have a Pattern colour space ? */
538 switch (gx_hld_get_color_space_and_ccolor(pis, pdc, &pcs, (const gs_client_color **)&pcc)) {
539 case pattern_color_space:
540 {
541 pdf_resource_t *pres;
542
543 if (pdc->type == gx_dc_type_pattern) {
544 /* Can't handle tiling patterns in levels 1.0 and 1.1, and
545 * unlike shading patterns we have no fallback.
546 */
547 if (pdev->CompatibilityLevel < 1.2) {
548 return gs_error_undefined;
549 }
550 code = pdf_put_colored_pattern(pdev, pdc, pcs,
551 ppscc, pis->have_pattern_streams, &pres);
552 }
553 else if (pdc->type == &gx_dc_pure_masked) {
554 code = pdf_put_uncolored_pattern(pdev, pdc, pcs,
555 ppscc, pis->have_pattern_streams, &pres);
556 if (code < 0 || pres == 0) {
557 /* replaced a pattern with a flat fill, but we still
558 * need to change the 'saved' colour or we will
559 * get out of step with the PDF content.
560 */
561 *psc = temp;
562 return code;
563 }
564 if (pis->have_pattern_streams)
565 code = pdf_write_ccolor(pdev, pis, pcc);
566 } else if (pdc->type == &gx_dc_pattern2) {
567 if (pdev->CompatibilityLevel <= 1.2)
568 return_error(gs_error_rangecheck);
569 if (!is_pattern2_allowed_in_strategy(pdev, pdc))
570 return_error(gs_error_rangecheck);
571 code1 = pdf_put_pattern2(pdev, pdc, ppscc, &pres);
572 if (code1 < 0)
573 return code1;
574 } else
575 return_error(gs_error_rangecheck);
576 if (code < 0)
577 return code;
578 code = pdf_add_resource(pdev, pdev->substream_Resources, "/Pattern", pres);
579 if (code1 != gs_error_rangecheck) {
580 cos_value_write(cos_resource_value(&cs_value, pres->object), pdev);
581 pprints1(pdev->strm, " %s\n", ppscc->setcolorn);
582 }
583 else
584 pres->where_used = 0;
585 if (code < 0)
586 return code;
587 *used_process_color = false;
588 }
589 break;
590 case non_pattern_color_space:
591 csi = csi2 = gs_color_space_get_index(pcs);
592 if (csi == gs_color_space_index_ICC) {
593 csi2 = gsicc_get_default_type(pcs->cmm_icc_profile_data);
594 }
595 /* Figure out what to do if we are outputting to really ancient versions of PDF */
596 /* NB ps2write sets CompatibilityLevel to 1.2 so we cater for it here */
597 if (pdev->CompatibilityLevel <= 1.2) {
598
599 /* If we have an /Indexed space, we need to look at the base space */
600 if (csi2 == gs_color_space_index_Indexed) {
601 pcs2 = pcs->base_space;
602 csi2 = gs_color_space_get_index(pcs2);
603 }
604
605 switch (csi2) {
606 case gs_color_space_index_DeviceGray:
607 if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
608 pdev->params.ColorConversionStrategy == ccs_Gray)
609 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
610 else
611 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
612 break;
613 case gs_color_space_index_DeviceRGB:
614 if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
615 pdev->params.ColorConversionStrategy == ccs_RGB)
616 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
617 else
618 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
619 break;
620 case gs_color_space_index_DeviceCMYK:
621 if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
622 pdev->params.ColorConversionStrategy == ccs_CMYK)
623 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
624 else
625 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
626 break;
627 case gs_color_space_index_CIEA:
628 case gs_color_space_index_CIEABC:
629 case gs_color_space_index_CIEDEF:
630 case gs_color_space_index_CIEDEFG:
631 case gs_color_space_index_Separation:
632 if (pdev->ForOPDFRead) {
633 switch (pdev->params.ColorConversionStrategy) {
634 case ccs_ByObjectType:
635 /* Object type not implemented yet */
636 case ccs_UseDeviceDependentColor:
637 /* DeviceDependentColor deprecated */
638 case ccs_UseDeviceIndependentColorForImages:
639 /* If only correcting images, then leave unchanged */
640 case ccs_LeaveColorUnchanged:
641 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
642 break;
643 default:
644 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
645 break;
646 }
647 }
648 else
649 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
650 break;
651 case gs_color_space_index_DeviceN:
652 case gs_color_space_index_DevicePixel:
653 case gs_color_space_index_Indexed:
654 case gs_color_space_index_ICC:
655 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
656 break;
657 default:
658 return (gs_note_error(gs_error_rangecheck));
659 break;
660 }
661 } else {
662 switch(pdev->params.ColorConversionStrategy) {
663 case ccs_ByObjectType:
664 /* Object type not implemented yet */
665 case ccs_UseDeviceDependentColor:
666 /* DeviceDependentCOlor deprecated */
667 case ccs_UseDeviceIndependentColorForImages:
668 /* If only correcting images, then leave unchanged */
669 case ccs_LeaveColorUnchanged:
670 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
671 break;
672 case ccs_sRGB:
673 case ccs_UseDeviceIndependentColor:
674 code = write_color_as_process_ICC(pdev, pis, pcs, pdc, psc, used_process_color, ppscc, pcc, &temp);
675 break;
676 case ccs_CMYK:
677 switch(csi2) {
678 case gs_color_space_index_DeviceGray:
679 case gs_color_space_index_DeviceCMYK:
680 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
681 break;
682 case gs_color_space_index_Separation:
683 case gs_color_space_index_DeviceN:
684 code = write_color_as_process_ICC(pdev, pis, pcs, pdc, psc, used_process_color, ppscc, pcc, &temp);
685 break;
686 case gs_color_space_index_Indexed:
687 pcs2 = pcs->base_space;
688 csi = gs_color_space_get_index(pcs2);
689 if (csi == gs_color_space_index_ICC)
690 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
691 switch(csi) {
692 case gs_color_space_index_DeviceGray:
693 case gs_color_space_index_DeviceCMYK:
694 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
695 break;
696 case gs_color_space_index_Separation:
697 case gs_color_space_index_DeviceN:
698 code = write_color_as_process_ICC(pdev, pis, pcs, pdc, psc, used_process_color, ppscc, pcc, &temp);
699 break;
700 default:
701 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
702 break;
703 }
704 break;
705 default:
706 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
707 break;
708 }
709 break;
710 case ccs_Gray:
711 switch(csi2) {
712 case gs_color_space_index_DeviceGray:
713 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
714 break;
715 case gs_color_space_index_Separation:
716 case gs_color_space_index_DeviceN:
717 code = write_color_as_process_ICC(pdev, pis, pcs, pdc, psc, used_process_color, ppscc, pcc, &temp);
718 break;
719 case gs_color_space_index_Indexed:
720 pcs2 = pcs->base_space;
721 csi = gs_color_space_get_index(pcs2);
722 if (csi == gs_color_space_index_ICC)
723 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
724 switch(csi) {
725 case gs_color_space_index_DeviceGray:
726 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
727 break;
728 case gs_color_space_index_Separation:
729 case gs_color_space_index_DeviceN:
730 code = write_color_as_process_ICC(pdev, pis, pcs, pdc, psc, used_process_color, ppscc, pcc, &temp);
731 break;
732 default:
733 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
734 break;
735 }
736 break;
737 default:
738 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
739 break;
740 }
741 break;
742 case ccs_RGB:
743 switch(csi2) {
744 case gs_color_space_index_DeviceGray:
745 case gs_color_space_index_DeviceRGB:
746 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
747 break;
748 case gs_color_space_index_Separation:
749 case gs_color_space_index_DeviceN:
750 code = write_color_as_process_ICC(pdev, pis, pcs, pdc, psc, used_process_color, ppscc, pcc, &temp);
751 break;
752 case gs_color_space_index_Indexed:
753 pcs2 = pcs->base_space;
754 csi = gs_color_space_get_index(pcs2);
755 if (csi == gs_color_space_index_ICC)
756 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
757 switch(csi) {
758 case gs_color_space_index_DeviceGray:
759 case gs_color_space_index_DeviceRGB:
760 code = write_color_unchanged(pdev, pis, pcc, &temp, psc, ppscc, used_process_color, pcs, pdc);
761 break;
762 case gs_color_space_index_Separation:
763 case gs_color_space_index_DeviceN:
764 code = write_color_as_process_ICC(pdev, pis, pcs, pdc, psc, used_process_color, ppscc, pcc, &temp);
765 break;
766 default:
767 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
768 break;
769 }
770 break;
771 default:
772 code = write_color_as_process(pdev, pis, pcs, pdc, used_process_color, ppscc, pcc);
773 break;
774 }
775 break;
776 default:
777 break;
778 }
779 }
780 break;
781 default: /* must not happen. */
782 case use_process_color:
783 code = psdf_set_color((gx_device_vector *)pdev, pdc, ppscc);
784 if (code < 0)
785 return code;
786 *used_process_color = true;
787 break;
788 }
789 *psc = temp;
790 return code;
791}
295/* Set the fill or stroke color. */ 792/* Set the fill or stroke color. */
296int 793int
297pdf_reset_color(gx_device_pdf * pdev, const gs_imager_state * pis, 794pdf_reset_color(gx_device_pdf * pdev, const gs_imager_state * pis,
@@ -309,6 +806,9 @@ pdf_reset_color(gx_device_pdf * pdev, const gs_imager_state * pis,
309 gs_color_space_index csi; 806 gs_color_space_index csi;
310 gs_color_space_index csi2; 807 gs_color_space_index csi2;
311 808
809 if (!pdev->UseOldColor)
810 return new_pdf_reset_color(pdev, pis, pdc, psc, used_process_color, ppscc);
811
312 if (pdev->skip_colors) 812 if (pdev->skip_colors)
313 return 0; 813 return 0;
314 gx_hld_save_color(pis, pdc, &temp); 814 gx_hld_save_color(pis, pdc, &temp);
diff --git a/gs/base/gdevpdfi.c b/gs/base/gdevpdfi.c
index b20109e0f..0d467c636 100644
--- a/gs/base/gdevpdfi.c
+++ b/gs/base/gdevpdfi.c
@@ -900,11 +900,11 @@ pdf_begin_typed_image_impl(gx_device_pdf *pdev, const gs_imager_state * pis,
900 nyi: 900 nyi:
901 return gx_default_begin_typed_image 901 return gx_default_begin_typed_image
902 ((gx_device *)pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, 902 ((gx_device *)pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
903 pinfo); 903 pinfo);
904} 904}
905 905
906static int 906static int
907pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, 907old_pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis,
908 const gs_matrix *pmat, const gs_image_common_t *pic, 908 const gs_matrix *pmat, const gs_image_common_t *pic,
909 const gs_int_rect * prect, 909 const gs_int_rect * prect,
910 const gx_drawing_color * pdcolor, 910 const gx_drawing_color * pdcolor,
@@ -924,6 +924,984 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis,
924 return code; 924 return code;
925} 925}
926 926
927static int setup_type1_image(gx_device_pdf *pdev, const gs_image_common_t *pic,
928 const gx_drawing_color * pdcolor, image_union_t *image,
929 pdf_typed_image_context_t context)
930{
931 const gs_image_t *pim1 = (const gs_image_t *)pic;
932
933 if (pim1->Alpha != gs_image_alpha_none)
934 return -1;
935 if (pim1->ImageMask) {
936 /* If parameters are invalid, use the fallback implementation. */
937 if (!(gx_dc_is_pattern1_color(pdcolor)))
938 if (pim1->BitsPerComponent != 1 ||
939 !((pim1->Decode[0] == 0.0 && pim1->Decode[1] == 1.0) ||
940 (pim1->Decode[0] == 1.0 && pim1->Decode[1] == 0.0))
941 )
942 return -1;
943 }
944 image[0].type1 = *pim1;
945 /* If we can write in-line then make it so */
946 return (context == PDF_IMAGE_DEFAULT &&
947 can_write_image_in_line(pdev, pim1));
948}
949
950static int setup_type3_image(gx_device_pdf *pdev, const gs_imager_state * pis,
951 const gs_matrix *pmat, const gs_image_common_t *pic,
952 const gs_int_rect * prect,
953 const gx_drawing_color * pdcolor,
954 const gx_clip_path * pcpath, gs_memory_t * mem,
955 gx_image_enum_common_t ** pinfo,
956 image_union_t *image)
957{
958 const gs_image3_t *pim3 = (const gs_image3_t *)pic;
959 gs_image3_t pim3a;
960 const gs_image_common_t *pic1 = pic;
961 gs_matrix m, mi;
962 const gs_matrix *pmat1 = pmat;
963 int code;
964
965 if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
966 if (pdf_must_put_clip_path(pdev, pcpath))
967 code = pdf_unclip(pdev);
968 else
969 code = pdf_open_page(pdev, PDF_IN_STREAM);
970 if (code < 0)
971 return code;
972 code = pdf_put_clip_path(pdev, pcpath);
973 if (code < 0)
974 return code;
975 gs_make_identity(&m);
976 pmat1 = &m;
977 m.tx = floor(pis->ctm.tx + 0.5); /* Round the origin against the image size distorsions */
978 m.ty = floor(pis->ctm.ty + 0.5);
979 pim3a = *pim3;
980 gs_matrix_invert(&pim3a.ImageMatrix, &mi);
981 gs_make_identity(&pim3a.ImageMatrix);
982 if (pim3a.Width < pim3a.MaskDict.Width && pim3a.Width > 0) {
983 int sx = (pim3a.MaskDict.Width + pim3a.Width - 1) / pim3a.Width;
984
985 gs_matrix_scale(&mi, 1.0 / sx, 1, &mi);
986 gs_matrix_scale(&pim3a.ImageMatrix, 1.0 / sx, 1, &pim3a.ImageMatrix);
987 }
988 if (pim3a.Height < pim3a.MaskDict.Height && pim3a.Height > 0) {
989 int sy = (pim3a.MaskDict.Height + pim3a.Height - 1) / pim3a.Height;
990
991 gs_matrix_scale(&mi, 1, 1.0 / sy, &mi);
992 gs_matrix_scale(&pim3a.ImageMatrix, 1, 1.0 / sy, &pim3a.ImageMatrix);
993 }
994 gs_matrix_multiply(&mi, &pim3a.MaskDict.ImageMatrix, &pim3a.MaskDict.ImageMatrix);
995 pic1 = (gs_image_common_t *)&pim3a;
996 /* Setting pdev->converting_image_matrix to communicate with pdf_image3_make_mcde. */
997 gs_matrix_multiply(&mi, &ctm_only(pis), &pdev->converting_image_matrix);
998 }
999 /*
1000 * We handle ImageType 3 images in a completely different way:
1001 * the default implementation sets up the enumerator.
1002 */
1003 return gx_begin_image3_generic((gx_device *)pdev, pis, pmat1, pic1,
1004 prect, pdcolor, pcpath, mem,
1005 pdf_image3_make_mid,
1006 pdf_image3_make_mcde, pinfo);
1007}
1008
1009static int convert_type4_image(gx_device_pdf *pdev, const gs_imager_state * pis,
1010 const gs_matrix *pmat, const gs_image_common_t *pic,
1011 const gs_int_rect * prect,
1012 const gx_drawing_color * pdcolor,
1013 const gx_clip_path * pcpath, gs_memory_t * mem,
1014 gx_image_enum_common_t ** pinfo,
1015 pdf_typed_image_context_t context, image_union_t *image,
1016 cos_dict_t *pnamed)
1017{
1018 /* Try to convert the image to a plain masked image. */
1019 gx_drawing_color icolor;
1020 int code;
1021
1022 pdev->image_mask_is_SMask = false;
1023 if (pdf_convert_image4_to_image1(pdev, pis, pdcolor,
1024 (const gs_image4_t *)pic,
1025 &image[0].type1, &icolor) >= 0) {
1026 gs_state *pgs = (gs_state *)gx_hld_get_gstate_ptr(pis);
1027
1028 if (pgs == NULL)
1029 return_error(gs_error_unregistered); /* Must not happen. */
1030
1031 /* Undo the pop of the NI stack if necessary. */
1032 if (pnamed)
1033 cos_array_add_object(pdev->NI_stack, COS_OBJECT(pnamed));
1034 /* HACK: temporary patch the color space, to allow
1035 pdf_prepare_imagemask to write the right color for the imagemask. */
1036 code = gs_gsave(pgs);
1037 if (code < 0)
1038 return code;
1039 /* {csrc}: const cast warning */
1040 code = gs_setcolorspace(pgs, ((const gs_image4_t *)pic)->ColorSpace);
1041 if (code < 0)
1042 return code;
1043 code = pdf_begin_typed_image(pdev, pis, pmat,
1044 (gs_image_common_t *)&image[0].type1,
1045 prect, &icolor, pcpath, mem,
1046 pinfo, context);
1047 if (code < 0)
1048 return code;
1049 return gs_grestore(pgs);
1050 }
1051 return 1;
1052}
1053
1054static int convert_type4_to_masked_image(gx_device_pdf *pdev, const gs_imager_state * pis,
1055 const gs_image_common_t *pic,
1056 const gs_int_rect * prect,
1057 const gx_drawing_color * pdcolor,
1058 const gx_clip_path * pcpath, gs_memory_t * mem,
1059 gx_image_enum_common_t ** pinfo)
1060{
1061 gs_matrix m, m1, mi;
1062 gs_image4_t pi4 = *(const gs_image4_t *)pic;
1063 int code;
1064 pdf_lcvd_t *cvd = NULL;
1065
1066 if (pdf_must_put_clip_path(pdev, pcpath))
1067 code = pdf_unclip(pdev);
1068 else
1069 code = pdf_open_page(pdev, PDF_IN_STREAM);
1070 if (code < 0)
1071 return code;
1072 code = pdf_put_clip_path(pdev, pcpath);
1073 if (code < 0)
1074 return code;
1075 gs_make_identity(&m1);
1076 gs_matrix_invert(&pic->ImageMatrix, &mi);
1077 gs_matrix_multiply(&mi, &ctm_only(pis), &m);
1078 code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
1079 true, 0, 0, pi4.Width, pi4.Height, false);
1080 if (code < 0)
1081 return code;
1082 cvd->mdev.is_open = true; /* fixme: same as above. */
1083 cvd->mask->is_open = true; /* fixme: same as above. */
1084 cvd->mask_is_empty = false;
1085 code = (*dev_proc(cvd->mask, fill_rectangle))((gx_device *)cvd->mask,
1086 0, 0, cvd->mask->width, cvd->mask->height, (gx_color_index)0);
1087 if (code < 0)
1088 return code;
1089 gx_device_retain((gx_device *)cvd, true);
1090 gx_device_retain((gx_device *)cvd->mask, true);
1091 gs_make_identity(&pi4.ImageMatrix);
1092 code = gx_default_begin_typed_image((gx_device *)cvd,
1093 pis, &m1, (gs_image_common_t *)&pi4, prect, pdcolor, NULL, mem, pinfo);
1094 if (code < 0)
1095 return code;
1096 (*pinfo)->procs = &pdf_image_cvd_enum_procs;
1097 return 0;
1098}
1099
1100static int setup_image_process_colorspace(gx_device_pdf *pdev, image_union_t *image, gs_color_space **pcs_orig,
1101 const char *sname, cos_value_t *cs_value)
1102{
1103 int code;
1104 gs_color_space *pcs_device = NULL;
1105
1106 cos_c_string_value(cs_value, sname);
1107 *pcs_orig = image->pixel.ColorSpace;
1108 code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1109 if (code < 0)
1110 return code;
1111 image->pixel.ColorSpace = pcs_device;
1112 return 0;
1113}
1114
1115/* 0 = write unchanged
1116 1 = convert to process
1117 2 = write as ICC
1118 */
1119static int setup_image_colorspace(gx_device_pdf *pdev, image_union_t *image, const gs_color_space *pcs, gs_color_space **pcs_orig,
1120 const pdf_color_space_names_t *names, cos_value_t *cs_value)
1121{
1122 int code=0;
1123 gs_color_space_index csi;
1124 gs_color_space_index csi2;
1125 const gs_color_space *pcs2 = pcs;
1126
1127 csi = csi2 = gs_color_space_get_index(pcs);
1128 if (csi == gs_color_space_index_ICC) {
1129 csi2 = gsicc_get_default_type(pcs->cmm_icc_profile_data);
1130 }
1131 /* Figure out what to do if we are outputting to really ancient versions of PDF */
1132 /* NB ps2write sets CompatibilityLevel to 1.2 so we cater for it here */
1133 if (pdev->CompatibilityLevel <= 1.2) {
1134
1135 /* If we have an /Indexed space, we need to look at the base space */
1136 if (csi2 == gs_color_space_index_Indexed) {
1137 pcs2 = pcs->base_space;
1138 csi2 = gs_color_space_get_index(pcs2);
1139 }
1140
1141 switch (csi2) {
1142 case gs_color_space_index_DeviceGray:
1143 if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
1144 pdev->params.ColorConversionStrategy == ccs_Gray) {
1145 return 0;
1146 }
1147 else {
1148 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
1149 if (code < 0)
1150 return code;
1151 return 1;
1152 }
1153 break;
1154 case gs_color_space_index_DeviceRGB:
1155 if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
1156 pdev->params.ColorConversionStrategy == ccs_RGB)
1157 return 0;
1158 else {
1159 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
1160 if (code < 0)
1161 return code;
1162 return 1;
1163 }
1164 break;
1165 case gs_color_space_index_DeviceCMYK:
1166 if ((pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
1167 pdev->params.ColorConversionStrategy == ccs_CMYK) && !pdev->params.ConvertCMYKImagesToRGB)
1168 return 0;
1169 else {
1170 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
1171 if (code < 0)
1172 return code;
1173 return 1;
1174 }
1175 break;
1176 case gs_color_space_index_CIEA:
1177 case gs_color_space_index_CIEABC:
1178 case gs_color_space_index_CIEDEF:
1179 case gs_color_space_index_CIEDEFG:
1180 case gs_color_space_index_Separation:
1181 if (pdev->ForOPDFRead) {
1182 switch (pdev->params.ColorConversionStrategy) {
1183 case ccs_ByObjectType:
1184 /* Object type not implemented yet */
1185 case ccs_UseDeviceDependentColor:
1186 /* DeviceDependentColor deprecated */
1187 case ccs_UseDeviceIndependentColorForImages:
1188 /* If only correcting images, then leave unchanged */
1189 case ccs_LeaveColorUnchanged:
1190 if (csi2 == gs_color_space_index_Separation)
1191 return 0;
1192 /* Fall through and convert CIE to the device space */
1193 default:
1194 switch (pdev->pcm_color_info_index) {
1195 case gs_color_space_index_DeviceGray:
1196 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
1197 break;
1198 case gs_color_space_index_DeviceRGB:
1199 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
1200 break;
1201 case gs_color_space_index_DeviceCMYK:
1202 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
1203 break;
1204 default:
1205 emprintf(pdev->memory, "Unsupported ProcessColorModel.");
1206 return_error(gs_error_undefined);
1207 }
1208 if (code < 0)
1209 return code;
1210 return 1;
1211 break;
1212 }
1213 }
1214 else
1215 return 1;
1216 break;
1217
1218 case gs_color_space_index_ICC:
1219 /* Note that if csi is ICC, check to see if this was one of
1220 the default substitutes that we introduced for DeviceGray,
1221 DeviceRGB or DeviceCMYK. If it is, then just write
1222 the default color. Depending upon the flavor of PDF,
1223 or other options, we may want to actually have all
1224 the colors defined by ICC profiles and not do the following
1225 substituion of the Device space. */
1226 csi2 = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
1227
1228 switch (csi2) {
1229 case gs_color_space_index_DeviceGray:
1230 if (pdev->params.ColorConversionStrategy == ccs_Gray ||
1231 pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
1232 return 0;
1233 break;
1234 case gs_color_space_index_DeviceRGB:
1235 if (pdev->params.ColorConversionStrategy == ccs_RGB ||
1236 pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
1237 return 0;
1238 break;
1239 case gs_color_space_index_DeviceCMYK:
1240 if (pdev->params.ColorConversionStrategy == ccs_CMYK ||
1241 pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
1242 return 0;
1243 break;
1244 default:
1245 break;
1246 }
1247 /* Fall through for non-handled cases */
1248 case gs_color_space_index_DeviceN:
1249 case gs_color_space_index_DevicePixel:
1250 case gs_color_space_index_Indexed:
1251 switch (pdev->pcm_color_info_index) {
1252 case gs_color_space_index_DeviceGray:
1253 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
1254 break;
1255 case gs_color_space_index_DeviceRGB:
1256 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
1257 break;
1258 case gs_color_space_index_DeviceCMYK:
1259 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
1260 break;
1261 default:
1262 emprintf(pdev->memory, "Unsupported ProcessColorModel.");
1263 return_error(gs_error_undefined);
1264 }
1265 if (code < 0)
1266 return code;
1267 return 1;
1268 break;
1269 default:
1270 return (gs_note_error(gs_error_rangecheck));
1271 break;
1272 }
1273 } else {
1274 switch(pdev->params.ColorConversionStrategy) {
1275 case ccs_ByObjectType:
1276 /* Object type not implemented yet */
1277 case ccs_UseDeviceDependentColor:
1278 /* DeviceDependentCOlor deprecated */
1279 case ccs_UseDeviceIndependentColorForImages:
1280 /* If only correcting images, then leave unchanged */
1281 case ccs_LeaveColorUnchanged:
1282 return 0;
1283 break;
1284 case ccs_sRGB:
1285 case ccs_UseDeviceIndependentColor:
1286 return 2;
1287 break;
1288 case ccs_CMYK:
1289 switch(csi2) {
1290 case gs_color_space_index_DeviceGray:
1291 case gs_color_space_index_DeviceCMYK:
1292 return 0;
1293 break;
1294 case gs_color_space_index_Separation:
1295 case gs_color_space_index_DeviceN:
1296 return 0;
1297 break;
1298 case gs_color_space_index_Indexed:
1299 pcs2 = pcs->base_space;
1300 csi = gs_color_space_get_index(pcs2);
1301 if (csi == gs_color_space_index_ICC)
1302 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
1303 switch(csi) {
1304 case gs_color_space_index_DeviceGray:
1305 case gs_color_space_index_DeviceCMYK:
1306 return 0;
1307 break;
1308 case gs_color_space_index_Separation:
1309 case gs_color_space_index_DeviceN:
1310 return 2;
1311 break;
1312 default:
1313 switch (pdev->pcm_color_info_index) {
1314 case gs_color_space_index_DeviceGray:
1315 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
1316 break;
1317 case gs_color_space_index_DeviceRGB:
1318 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
1319 break;
1320 case gs_color_space_index_DeviceCMYK:
1321 code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
1322 break;
1323 default:
1324 emprintf(pdev->memory, "Unsupported ProcessColorModel.");
1325 return_error(gs_error_undefined);
1326 }
1327 if (code < 0)
1328 return code;
1329 return 1;
1330 break;
1331 }
1332 break;
1333 default:
1334 return 0;
1335 break;
1336 }
1337 break;
1338 case ccs_Gray:
1339 switch(csi2) {
1340 case gs_color_space_index_DeviceGray:
1341 return 0;
1342 break;
1343 case gs_color_space_index_Separation:
1344 case gs_color_space_index_DeviceN:
1345 return 2;
1346 break;
1347 case gs_color_space_index_Indexed:
1348 pcs2 = pcs->base_space;
1349 csi = gs_color_space_get_index(pcs2);
1350 if (csi == gs_color_space_index_ICC)
1351 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
1352 switch(csi) {
1353 case gs_color_space_index_DeviceGray:
1354 return 0;
1355 break;
1356 case gs_color_space_index_Separation:
1357 case gs_color_space_index_DeviceN:
1358 return 2;
1359 break;
1360 default:
1361 return 0;
1362 break;
1363 }
1364 break;
1365 default:
1366 return 0;
1367 break;
1368 }
1369 break;
1370 case ccs_RGB:
1371 switch(csi2) {
1372 case gs_color_space_index_DeviceGray:
1373 case gs_color_space_index_DeviceRGB:
1374 return 0;
1375 break;
1376 case gs_color_space_index_Separation:
1377 case gs_color_space_index_DeviceN:
1378 return 2;
1379 break;
1380 case gs_color_space_index_Indexed:
1381 pcs2 = pcs->base_space;
1382 csi = gs_color_space_get_index(pcs2);
1383 if (csi == gs_color_space_index_ICC)
1384 csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
1385 switch(csi) {
1386 case gs_color_space_index_DeviceGray:
1387 case gs_color_space_index_DeviceRGB:
1388 return 0;
1389 break;
1390 case gs_color_space_index_Separation:
1391 case gs_color_space_index_DeviceN:
1392 return 2;
1393 break;
1394 default:
1395 return 0;
1396 break;
1397 }
1398 break;
1399 default:
1400 return 0;
1401 break;
1402 }
1403 break;
1404 default:
1405 break;
1406 }
1407 }
1408 return 0;
1409}
1410
1411static int
1412new_pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis,
1413 const gs_matrix *pmat, const gs_image_common_t *pic,
1414 const gs_int_rect * prect,
1415 const gx_drawing_color * pdcolor,
1416 const gx_clip_path * pcpath, gs_memory_t * mem,
1417 gx_image_enum_common_t ** pinfo,
1418 pdf_typed_image_context_t context)
1419{
1420 int code, i;
1421 unsigned int use_fallback = 0, in_line = 0, is_mask = 0,
1422 force_lossless = 0, convert_to_process_colors = 0, reduce_bits = 0;
1423 int width, height;
1424 cos_dict_t *pnamed = 0;
1425 image_union_t *image;
1426 const gs_pixel_image_t *pim;
1427 gs_int_rect rect;
1428 gs_image_format_t format;
1429 const gs_color_space *pcs;
1430 int num_components;
1431 pdf_image_enum *pie;
1432 const pdf_color_space_names_t *names;
1433 gs_color_space *pcs_orig = NULL;
1434 gs_color_space *pcs_device = NULL;
1435 cos_value_t cs_value;
1436 const gs_range_t *pranges = 0;
1437
1438 image = (image_union_t *)gs_malloc(mem->non_gc_memory, 4,
1439 sizeof(image_union_t), "pdf_begin_typed_image(image)");
1440 if (image == 0)
1441 return_error(gs_error_VMerror);
1442
1443 /*
1444 * Pop the image name from the NI stack. We must do this, to keep the
1445 * stack in sync, even if it turns out we can't handle the image.
1446 */
1447 {
1448 cos_value_t ni_value;
1449
1450 if (cos_array_unadd(pdev->NI_stack, &ni_value) >= 0)
1451 pnamed = (cos_dict_t *)ni_value.contents.object;
1452 }
1453
1454 /* An initialization for pdf_end_and_do_image :
1455 We need to delay adding the "Mask" entry into a type 3 image dictionary
1456 until the mask is completed due to equal image merging. */
1457 pdev->image_mask_id = gs_no_id;
1458
1459 /* Check for the image types we can handle. */
1460 switch (pic->type->index) {
1461 case 1:
1462 is_mask = ((const gs_image_t *)pic)->ImageMask;
1463 code = setup_type1_image(pdev, pic, pdcolor, image, context);
1464 if (code < 0) {
1465 use_fallback = 1;
1466 }
1467 else
1468 in_line = code;
1469 break;
1470
1471 case 3:
1472 pdev->image_mask_is_SMask = false;
1473 if (pdev->CompatibilityLevel < 1.2 ||
1474 (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
1475 prect->q.x == ((const gs_image3_t *)pic)->Width &&
1476 prect->q.y == ((const gs_image3_t *)pic)->Height))) {
1477 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1478 "pdf_begin_typed_image(image)");
1479 return (gx_default_begin_typed_image((gx_device *)pdev, pis, pmat, pic, prect, pdcolor,
1480 pcpath, mem, pinfo));
1481 }
1482 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1483 "pdf_begin_typed_image(image)");
1484 return (setup_type3_image(pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, image));
1485 break;
1486
1487 case IMAGE3X_IMAGETYPE:
1488 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1489 "pdf_begin_typed_image(image)");
1490 if (pdev->CompatibilityLevel < 1.4 ||
1491 (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
1492 prect->q.x == ((const gs_image3x_t *)pic)->Width &&
1493 prect->q.y == ((const gs_image3x_t *)pic)->Height))) {
1494 return (gx_default_begin_typed_image((gx_device *)pdev, pis, pmat, pic, prect, pdcolor,
1495 pcpath, mem, pinfo));
1496 }
1497 pdev->image_mask_is_SMask = true;
1498 return gx_begin_image3x_generic((gx_device *)pdev, pis, pmat, pic,
1499 prect, pdcolor, pcpath, mem,
1500 pdf_image3x_make_mid,
1501 pdf_image3x_make_mcde, pinfo);
1502 break;
1503
1504 case 4:
1505 code = convert_type4_image(pdev, pis, pmat, pic, prect, pdcolor,
1506 pcpath, mem, pinfo, context, image, pnamed);
1507 if (code < 0) {
1508 use_fallback = 1;
1509 }
1510 if (code == 0) {
1511 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1512 "pdf_begin_typed_image(image)");
1513 return code;
1514 }
1515 /* No luck. Masked images require PDF 1.3 or higher. */
1516 if (pdev->CompatibilityLevel < 1.2) {
1517 use_fallback = 1;
1518 }
1519 if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
1520 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1521 "pdf_begin_typed_image(image)");
1522 return (convert_type4_to_masked_image(pdev, pis, pic, prect, pdcolor,
1523 pcpath, mem,pinfo));
1524 }
1525 image[0].type4 = *(const gs_image4_t *)pic;
1526 break;
1527
1528 default:
1529 use_fallback = 1;
1530 break;
1531 }
1532
1533 pim = (const gs_pixel_image_t *)pic;
1534 format = pim->format;
1535 switch (format) {
1536 case gs_image_format_chunky:
1537 case gs_image_format_component_planar:
1538 break;
1539 default:
1540 use_fallback = 1;
1541 }
1542 /* AR5 on Windows doesn't support 0-size images. Skipping. */
1543 if (pim->Width == 0 || pim->Height == 0)
1544 use_fallback = 1;
1545 /* PDF doesn't support images with more than 8 bits per component. */
1546 switch (pim->BitsPerComponent) {
1547 case 1:
1548 case 2:
1549 case 4:
1550 case 8:
1551 break;
1552 case 12:
1553 case 16:
1554 use_fallback = 1;
1555// reduce_bits = pim->BitsPerComponent;
1556 break;
1557 default:
1558 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1559 "pdf_begin_typed_image(image)");
1560 return_error(gs_error_rangecheck);
1561 }
1562 if (prect)
1563 rect = *prect;
1564 else {
1565 rect.p.x = rect.p.y = 0;
1566 rect.q.x = pim->Width, rect.q.y = pim->Height;
1567 }
1568 if (rect.p.x != 0 || rect.p.y != 0 ||
1569 rect.q.x != pim->Width || rect.q.y != pim->Height ||
1570 (is_mask && pim->CombineWithColor))
1571 use_fallback = 1;
1572
1573 if (use_fallback) {
1574 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1575 "pdf_begin_typed_image(image)");
1576 return gx_default_begin_typed_image
1577 ((gx_device *)pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
1578 pinfo);
1579 }
1580
1581 pcs = pim->ColorSpace;
1582 num_components = (is_mask ? 1 : gs_color_space_num_components(pcs));
1583
1584 if (pdf_must_put_clip_path(pdev, pcpath))
1585 code = pdf_unclip(pdev);
1586 else
1587 code = pdf_open_page(pdev, PDF_IN_STREAM);
1588 if (code < 0) {
1589 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1590 "pdf_begin_typed_image(image)");
1591 return gx_default_begin_typed_image
1592 ((gx_device *)pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
1593 pinfo);
1594 }
1595
1596 if (context == PDF_IMAGE_TYPE3_MASK) {
1597 /*
1598 * The soft mask for an ImageType 3x image uses a DevicePixel
1599 * color space, which pdf_color_space() can't handle. Patch it
1600 * to DeviceGray here.
1601 */
1602 /* {csrc} make sure this gets freed */
1603 pcs = gs_cspace_new_DeviceGray(pdev->memory);
1604 } else if (is_mask)
1605 code = pdf_prepare_imagemask(pdev, pis, pdcolor);
1606 else
1607 code = pdf_prepare_image(pdev, pis);
1608 if (code < 0) {
1609 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1610 "pdf_begin_typed_image(image)");
1611 return gx_default_begin_typed_image
1612 ((gx_device *)pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
1613 pinfo);
1614 }
1615
1616 pie = gs_alloc_struct(mem, pdf_image_enum, &st_pdf_image_enum,
1617 "pdf_begin_image");
1618 if (pie == 0) {
1619 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1620 "pdf_begin_typed_image(image)");
1621 return_error(gs_error_VMerror);
1622 }
1623 memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
1624 *pinfo = (gx_image_enum_common_t *) pie;
1625 gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim,
1626 ((pdev->CompatibilityLevel >= 1.3) ?
1627 (context == PDF_IMAGE_TYPE3_MASK ?
1628 &pdf_image_object_enum_procs :
1629 &pdf_image_enum_procs) :
1630 context == PDF_IMAGE_TYPE3_MASK ?
1631 &pdf_image_object_enum_procs :
1632 context == PDF_IMAGE_TYPE3_DATA ?
1633 &pdf_image_object_enum_procs2 :
1634 &pdf_image_enum_procs),
1635 (gx_device *)pdev, num_components, format);
1636 pie->memory = mem;
1637 width = rect.q.x - rect.p.x;
1638 pie->width = width;
1639 height = rect.q.y - rect.p.y;
1640 pie->bits_per_pixel =
1641 (reduce_bits ? reduce_bits : pim->BitsPerComponent) * num_components / pie->num_planes;
1642 pie->rows_left = height;
1643 if (pnamed != 0) /* Don't in-line the image if it is named. */
1644 in_line = false;
1645 else {
1646 double nbytes = (double)(((ulong) pie->width * pie->bits_per_pixel + 7) >> 3) *
1647 pie->num_planes * pie->rows_left;
1648
1649 in_line &= (nbytes < pdev->MaxInlineImageSize);
1650 }
1651
1652 if (pmat == 0)
1653 pmat = &ctm_only(pis);
1654 {
1655 gs_matrix mat;
1656 gs_matrix bmat;
1657 int code;
1658
1659 pdf_make_bitmap_matrix(&bmat, -rect.p.x, -rect.p.y,
1660 pim->Width, pim->Height, height);
1661 if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
1662 (code = gs_matrix_multiply(&bmat, &mat, &mat)) < 0 ||
1663 (code = gs_matrix_multiply(&mat, pmat, &pie->mat)) < 0
1664 ) {
1665 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1666 "pdf_begin_typed_image(image)");
1667 gs_free_object(mem, pie, "pdf_begin_image");
1668 return code;
1669 }
1670 /* AR3,AR4 show no image when CTM is singular; AR5 reports an error */
1671 if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx)
1672 goto fail_and_fallback;
1673 }
1674
1675 code = pdf_put_clip_path(pdev, pcpath);
1676 if (code < 0) {
1677 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1678 "pdf_begin_typed_image(image)");
1679 gs_free_object(mem, pie, "pdf_begin_image");
1680 return code;
1681 }
1682 pdf_image_writer_init(&pie->writer);
1683 /* Note : Possible values for alt_writer_count are 1,2,3,4.
1684 1 means no alternative streams.
1685 2 means the main image stream and a mask stream while converting
1686 an Image Type 4.
1687 3 means the main image stream, alternative image compression stream,
1688 and the compression chooser.
1689 4 meams 3 and a mask stream while convertingh an Image Type 4.
1690 */
1691 pie->writer.alt_writer_count = (in_line ||
1692 (pim->Width <= 64 && pim->Height <= 64)
1693 ? 1 : 2);
1694 if ((image[0].pixel.ColorSpace != NULL &&
1695 image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed
1696 && pdev->params.ColorImage.DownsampleType != ds_Subsample) ||
1697 pdev->transfer_not_identity)
1698 force_lossless = true;
1699
1700 names = (in_line ? &pdf_color_space_names_short : &pdf_color_space_names);
1701
1702 /* We don't want to change the colour space of a mask, or an SMask (both of which are Gray) */
1703 if (!is_mask) {
1704 if (image[0].pixel.ColorSpace != NULL && !(context == PDF_IMAGE_TYPE3_MASK))
1705 convert_to_process_colors = setup_image_colorspace(pdev, &image[0], pcs, &pcs_orig, names, &cs_value);
1706 if (convert_to_process_colors == 1) {
1707 code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1708 if (code < 0)
1709 goto fail_and_fallback;
1710 image[0].pixel.ColorSpace = pcs_device;
1711 code = pdf_color_space_named(pdev, &cs_value, &pranges, pcs_device, names,
1712 in_line, NULL, 0);
1713 if (code < 0)
1714 goto fail_and_fallback;
1715 } else {
1716 if (pcs->cmm_icc_profile_data != NULL &&
1717 pcs->cmm_icc_profile_data->islab) {
1718 gscms_set_icc_range((cmm_profile_t **)&(pcs->cmm_icc_profile_data));
1719 }
1720 code = pdf_color_space_named(pdev, &cs_value, &pranges, pcs, names,
1721 in_line, NULL, 0);
1722 if (code < 0)
1723 goto fail_and_fallback;
1724 }
1725 }
1726
1727 image[1] = image[0];
1728
1729 pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
1730
1731 code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1732 height, pnamed, in_line);
1733 if (code < 0)
1734 goto fail_and_fallback;
1735
1736 /* Code below here deals with setting up the multiple data stream writing.
1737 * We can have up to 4 stream writers, which we keep in an array. We must
1738 * always have at least one which writes the uncompressed stream. If we
1739 * are writing compressed streams, we have one for the compressed stream
1740 * and one for the compression chooser.
1741 * For type 4 images being converted (for old versions of PDF or for ps2write)
1742 * we need an additional stream to write a mask, which masks the real
1743 * image.
1744 * For colour conversion we will place an additional filter in front of all
1745 * the streams which does the conversion.
1746 */
1747 if (in_line) {
1748 code = new_setup_lossless_filters((gx_device_psdf *) pdev,
1749 &pie->writer.binary[0],
1750 &image[0].pixel, in_line, convert_to_process_colors);
1751 } else {
1752 if (force_lossless) {
1753 /*
1754 * Some regrettable PostScript code (such as LanguageLevel 1 output
1755 * from Microsoft's PSCRIPT.DLL driver) misuses the transfer
1756 * function to accomplish the equivalent of indexed color.
1757 * Downsampling (well, only averaging) or JPEG compression are not
1758 * compatible with this. Play it safe by using only lossless
1759 * filters if the transfer function(s) is/are other than the
1760 * identity and by setting the downsample type to Subsample..
1761 */
1762 int saved_downsample = pdev->params.ColorImage.DownsampleType;
1763
1764 pdev->params.ColorImage.DownsampleType = ds_Subsample;
1765 code = new_setup_image_filters((gx_device_psdf *) pdev,
1766 &pie->writer.binary[0], &image[0].pixel,
1767 pmat, pis, true, in_line, convert_to_process_colors);
1768 pdev->params.ColorImage.DownsampleType = saved_downsample;
1769 } else {
1770 code = new_setup_image_filters((gx_device_psdf *) pdev,
1771 &pie->writer.binary[0], &image[0].pixel,
1772 pmat, pis, true, in_line, convert_to_process_colors);
1773 }
1774 }
1775
1776 if (code < 0)
1777 goto fail_and_fallback;
1778
1779 if (convert_to_process_colors) {
1780 image[0].pixel.ColorSpace = pcs_orig;
1781 code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
1782 (gx_device_psdf *)pdev, &image[0].pixel, pis);
1783 if (code < 0)
1784 goto fail_and_fallback;
1785 image[0].pixel.ColorSpace = pcs_device;
1786 }
1787
1788 if (reduce_bits) {
1789 code = new_resize_input(&pie->writer.binary[0], pim->Width, gs_color_space_num_components(pim->ColorSpace), reduce_bits, 8);
1790 if (code < 0)
1791 goto fail_and_fallback;
1792 }
1793
1794 if (pie->writer.alt_writer_count > 1) {
1795 code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]);
1796 if (code) {
1797 goto fail_and_fallback;
1798 }
1799 code = new_setup_image_filters((gx_device_psdf *) pdev,
1800 &pie->writer.binary[1], &image[1].pixel,
1801 pmat, pis, force_lossless, in_line, convert_to_process_colors);
1802 if (code == gs_error_rangecheck) {
1803
1804 for (i=1;i < pie->writer.alt_writer_count; i++) {
1805 stream *s = pie->writer.binary[i].strm;
1806 cos_stream_t *pcos = cos_stream_from_pipeline(pie->writer.binary[i].strm);
1807 s_close_filters(&s, NULL);
1808 gs_free_object(pdev->pdf_memory, s, "compressed image stream");
1809 pcos->cos_procs->release((cos_object_t *)pcos, "pdf_begin_typed_image_impl");
1810 gs_free_object(pdev->pdf_memory, pcos, "compressed image cos_stream");
1811 }
1812 /* setup_image_compression rejected the alternative compression. */
1813 pie->writer.alt_writer_count = 1;
1814 memset(pie->writer.binary + 1, 0, sizeof(pie->writer.binary[1]));
1815 memset(pie->writer.binary + 2, 0, sizeof(pie->writer.binary[1]));
1816 } else if (code) {
1817 goto fail_and_fallback;
1818 } else if (convert_to_process_colors) {
1819 image[1].pixel.ColorSpace = pcs_orig;
1820 code = psdf_setup_image_colors_filter(&pie->writer.binary[1],
1821 (gx_device_psdf *)pdev, &image[1].pixel, pis);
1822 if (code < 0) {
1823 goto fail_and_fallback;
1824 }
1825 image[1].pixel.ColorSpace = pcs_device;
1826 }
1827 if (reduce_bits) {
1828 code = new_resize_input(&pie->writer.binary[0], pim->Width, gs_color_space_num_components(pim->ColorSpace), reduce_bits, 8);
1829 if (code < 0)
1830 goto fail_and_fallback;
1831 }
1832 }
1833
1834 for (i = 0; i < pie->writer.alt_writer_count; i++) {
1835 code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1836 &image[i].pixel, &cs_value, pie);
1837 if (code < 0)
1838 goto fail_and_fallback;
1839 }
1840 if (pie->writer.alt_writer_count == 2) {
1841 psdf_setup_compression_chooser(&pie->writer.binary[2],
1842 (gx_device_psdf *)pdev, pim->Width, pim->Height,
1843 num_components, pim->BitsPerComponent);
1844 pie->writer.alt_writer_count = 3;
1845 }
1846 if (pic->type->index == 4 && pdev->CompatibilityLevel < 1.3) {
1847 int i;
1848
1849 /* Create a stream for writing the mask. */
1850 i = pie->writer.alt_writer_count;
1851 gs_image_t_init_mask_adjust((gs_image_t *)&image[i].type1, true, false);
1852 image[i].type1.Width = image[0].pixel.Width;
1853 image[i].type1.Height = image[0].pixel.Height;
1854 /* Won't use image[2]. */
1855 code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1856 height, NULL, false);
1857 if (code)
1858 goto fail_and_fallback;
1859 code = psdf_setup_image_filters((gx_device_psdf *) pdev,
1860 &pie->writer.binary[i], &image[i].pixel,
1861 pmat, pis, force_lossless, in_line);
1862 if (code < 0)
1863 goto fail_and_fallback;
1864 psdf_setup_image_to_mask_filter(&pie->writer.binary[i],
1865 (gx_device_psdf *)pdev, pim->Width, pim->Height,
1866 num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
1867 code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1868 &image[i].pixel, &cs_value, pie);
1869 if (code < 0)
1870 goto fail_and_fallback;
1871 ++pie->writer.alt_writer_count;
1872 }
1873
1874 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1875 "pdf_begin_typed_image(image)");
1876 return 0;
1877
1878fail_and_fallback:
1879 gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1880 "pdf_begin_typed_image(image)");
1881 gs_free_object(mem, pie, "pdf_begin_image");
1882 return gx_default_begin_typed_image
1883 ((gx_device *)pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
1884 pinfo);
1885}
1886
1887static int pdf_begin_typed_image(gx_device_pdf *pdev,
1888 const gs_imager_state * pis, const gs_matrix *pmat,
1889 const gs_image_common_t *pic, const gs_int_rect * prect,
1890 const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
1891 gs_memory_t * mem, gx_image_enum_common_t ** pinfo,
1892 pdf_typed_image_context_t context)
1893{
1894 if (!pdev->UseOldColor) {
1895 return new_pdf_begin_typed_image(pdev, pis, pmat, pic, prect,
1896 pdcolor, pcpath, mem, pinfo,
1897 context);
1898 } else {
1899 return old_pdf_begin_typed_image(pdev, pis, pmat, pic, prect,
1900 pdcolor, pcpath, mem, pinfo,
1901 context);
1902 }
1903}
1904
927int 1905int
928gdev_pdf_begin_typed_image(gx_device * dev, const gs_imager_state * pis, 1906gdev_pdf_begin_typed_image(gx_device * dev, const gs_imager_state * pis,
929 const gs_matrix *pmat, const gs_image_common_t *pic, 1907 const gs_matrix *pmat, const gs_image_common_t *pic,
diff --git a/gs/base/gdevpdfk.c b/gs/base/gdevpdfk.c
index 3e5092d5d..b54a0d7a3 100644
--- a/gs/base/gdevpdfk.c
+++ b/gs/base/gdevpdfk.c
@@ -271,6 +271,10 @@ pdf_make_iccbased(gx_device_pdf *pdev, cos_array_t *pca, int ncomps,
271 bool scale_inputs = false; 271 bool scale_inputs = false;
272 int i; 272 int i;
273 273
274 /* This code makes no sense to me, and if I remove it we get better
275 * results. So we'll chop it out for the new colour work.
276 */
277 if (pdev->UseOldColor) {
274 /* Check the ranges. */ 278 /* Check the ranges. */
275 if (pprange) 279 if (pprange)
276 *pprange = 0; 280 *pprange = 0;
@@ -287,6 +291,7 @@ pdf_make_iccbased(gx_device_pdf *pdev, cos_array_t *pca, int ncomps,
287 else if (rmin > 0.0 || rmax < 1.0) 291 else if (rmin > 0.0 || rmax < 1.0)
288 std_ranges = false; 292 std_ranges = false;
289 } 293 }
294 }
290 295
291 /* Range values are a bit tricky to check. 296 /* Range values are a bit tricky to check.
292 For example, CIELAB ICC profiles have 297 For example, CIELAB ICC profiles have
diff --git a/gs/base/gdevpdfp.c b/gs/base/gdevpdfp.c
index 7e12fe111..e86424c40 100644
--- a/gs/base/gdevpdfp.c
+++ b/gs/base/gdevpdfp.c
@@ -22,6 +22,7 @@
22#include "gdevpdfo.h" 22#include "gdevpdfo.h"
23#include "gdevpdfg.h" 23#include "gdevpdfg.h"
24#include "gsparamx.h" 24#include "gsparamx.h"
25#include "gsicc_manage.h"
25 26
26/* 27/*
27 * The pdfwrite device supports the following "real" parameters: 28 * The pdfwrite device supports the following "real" parameters:
@@ -125,6 +126,7 @@ static const gs_param_item_t pdf_param_items[] = {
125 pi("PreserveSMask", gs_param_type_bool, PreserveSMask), 126 pi("PreserveSMask", gs_param_type_bool, PreserveSMask),
126 pi("PreserveTrMode", gs_param_type_bool, PreserveTrMode), 127 pi("PreserveTrMode", gs_param_type_bool, PreserveTrMode),
127 pi("NoT3CCITT", gs_param_type_bool, NoT3CCITT), 128 pi("NoT3CCITT", gs_param_type_bool, NoT3CCITT),
129 pi("PDFUseOldCMS", gs_param_type_bool, UseOldColor),
128 pi("FastWebView", gs_param_type_bool, Linearise), 130 pi("FastWebView", gs_param_type_bool, Linearise),
129 pi("FirstPage", gs_param_type_int, FirstPage), 131 pi("FirstPage", gs_param_type_int, FirstPage),
130 pi("LastPage", gs_param_type_int, LastPage), 132 pi("LastPage", gs_param_type_int, LastPage),
@@ -508,30 +510,70 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
508 ecode = gdev_psdf_put_params(dev, plist); 510 ecode = gdev_psdf_put_params(dev, plist);
509 if (ecode < 0) 511 if (ecode < 0)
510 goto fail; 512 goto fail;
511 if ((pdev->params.ColorConversionStrategy == ccs_CMYK && 513 if (!pdev->UseOldColor) {
512 strcmp(pdev->color_info.cm_name, "DeviceCMYK")) || 514 if (pdev->params.ConvertCMYKImagesToRGB) {
513 (pdev->params.ColorConversionStrategy == ccs_sRGB && 515 if (pdev->params.ColorConversionStrategy == ccs_CMYK) {
514 strcmp(pdev->color_info.cm_name, "DeviceRGB")) || 516 emprintf(pdev->memory, "ConvertCMYKImagesToRGB is not compatible with ColorConversionStrategy of CMYK\n");
515 (pdev->params.ColorConversionStrategy == ccs_Gray && 517 } else {
516 strcmp(pdev->color_info.cm_name, "DeviceGray"))) { 518 if (pdev->params.ColorConversionStrategy == ccs_Gray) {
517 emprintf(pdev->memory, 519 emprintf(pdev->memory, "ConvertCMYKImagesToRGB is not compatible with ColorConversionStrategy of Gray\n");
518 "ColorConversionStrategy is incompatible to ProcessColorModel.\n"); 520 } else {
519 ecode = gs_note_error(gs_error_rangecheck); 521 if (pdev->icc_struct)
520 pdev->params.ColorConversionStrategy = save_ccs; 522 rc_decrement(pdev->icc_struct,
521 } 523 "reset default profile\n");
522 if (pdev->params.ColorConversionStrategy == ccs_UseDeviceIndependentColor) { 524 pdf_set_process_color_model(pdev,1);
523 if (!pdev->UseCIEColor) { 525 code = gsicc_init_device_profile_struct((gx_device *)pdev, NULL, 0);
526 }
527 }
528 }
529 switch (pdev->params.ColorConversionStrategy) {
530 case ccs_LeaveColorUnchanged:
531 case ccs_UseDeviceDependentColor:
532 case ccs_UseDeviceIndependentColor:
533 case ccs_UseDeviceIndependentColorForImages:
534 case ccs_ByObjectType:
535 case ccs_sRGB:
536 break;
537 case ccs_CMYK:
538 if (pdev->icc_struct)
539 rc_decrement(pdev->icc_struct,
540 "reset default profile\n");
541 pdf_set_process_color_model(pdev, 2);
542 code = gsicc_init_device_profile_struct((gx_device *)pdev, NULL, 0);
543 break;
544 case ccs_Gray:
545 if (pdev->icc_struct)
546 rc_decrement(pdev->icc_struct,
547 "reset default profile\n");
548 pdf_set_process_color_model(pdev,0);
549 code = gsicc_init_device_profile_struct((gx_device *)pdev, NULL, 0);
550 break;
551 case ccs_RGB:
552 /* Only bother to do this if we didn't handle it above */
553 if (!pdev->params.ConvertCMYKImagesToRGB) {
554 if (pdev->icc_struct)
555 rc_decrement(pdev->icc_struct,
556 "reset default profile\n");
557 pdf_set_process_color_model(pdev,1);
558 code = gsicc_init_device_profile_struct((gx_device *)pdev, NULL, 0);
559 }
560 break;
561 default:
562 break;
563 }
564 } else {
565 if ((pdev->params.ColorConversionStrategy == ccs_CMYK &&
566 strcmp(pdev->color_info.cm_name, "DeviceCMYK")) ||
567 (pdev->params.ColorConversionStrategy == ccs_sRGB &&
568 strcmp(pdev->color_info.cm_name, "DeviceRGB")) ||
569 (pdev->params.ColorConversionStrategy == ccs_Gray &&
570 strcmp(pdev->color_info.cm_name, "DeviceGray"))) {
524 emprintf(pdev->memory, 571 emprintf(pdev->memory,
525 "Set UseCIEColor for UseDeviceIndependentColor to work properly.\n"); 572 "ColorConversionStrategy is incompatible to ProcessColorModel.\n");
526 ecode = gs_note_error(gs_error_rangecheck); 573 ecode = gs_note_error(gs_error_rangecheck);
527 pdev->UseCIEColor = true; 574 pdev->params.ColorConversionStrategy = save_ccs;
528 } 575 }
529 } 576 if (pdev->params.ColorConversionStrategy == ccs_UseDeviceIndependentColor) {
530 if (pdev->params.ColorConversionStrategy == ccs_UseDeviceIndependentColorForImages) {
531 if (!pdev->UseCIEColor) {
532 emprintf(pdev->memory,
533 "UseDeviceDependentColorForImages is not supported. Use UseDeviceIndependentColor.\n");
534 pdev->params.ColorConversionStrategy = ccs_UseDeviceIndependentColor;
535 if (!pdev->UseCIEColor) { 577 if (!pdev->UseCIEColor) {
536 emprintf(pdev->memory, 578 emprintf(pdev->memory,
537 "Set UseCIEColor for UseDeviceIndependentColor to work properly.\n"); 579 "Set UseCIEColor for UseDeviceIndependentColor to work properly.\n");
@@ -539,20 +581,33 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
539 pdev->UseCIEColor = true; 581 pdev->UseCIEColor = true;
540 } 582 }
541 } 583 }
542 } 584 if (pdev->params.ColorConversionStrategy == ccs_UseDeviceIndependentColorForImages) {
543 if (pdev->params.ColorConversionStrategy == ccs_UseDeviceDependentColor) { 585 if (!pdev->UseCIEColor) {
544 if (!strcmp(pdev->color_info.cm_name, "DeviceCMYK")) { 586 emprintf(pdev->memory,
545 emprintf(pdev->memory, 587 "UseDeviceDependentColorForImages is not supported. Use UseDeviceIndependentColor.\n");
546 "Replacing the deprecated device parameter value UseDeviceDependentColor with CMYK.\n"); 588 pdev->params.ColorConversionStrategy = ccs_UseDeviceIndependentColor;
547 pdev->params.ColorConversionStrategy = ccs_CMYK; 589 if (!pdev->UseCIEColor) {
548 } else if (!strcmp(pdev->color_info.cm_name, "DeviceRGB")) { 590 emprintf(pdev->memory,
549 emprintf(pdev->memory, 591 "Set UseCIEColor for UseDeviceIndependentColor to work properly.\n");
550 "Replacing the deprecated device parameter value UseDeviceDependentColor with sRGB.\n"); 592 ecode = gs_note_error(gs_error_rangecheck);
551 pdev->params.ColorConversionStrategy = ccs_sRGB; 593 pdev->UseCIEColor = true;
552 } else { 594 }
553 emprintf(pdev->memory, 595 }
554 "Replacing the deprecated device parameter value UseDeviceDependentColor with Gray.\n"); 596 }
555 pdev->params.ColorConversionStrategy = ccs_Gray; 597 if (pdev->params.ColorConversionStrategy == ccs_UseDeviceDependentColor) {
598 if (!strcmp(pdev->color_info.cm_name, "DeviceCMYK")) {
599 emprintf(pdev->memory,
600 "Replacing the deprecated device parameter value UseDeviceDependentColor with CMYK.\n");
601 pdev->params.ColorConversionStrategy = ccs_CMYK;
602 } else if (!strcmp(pdev->color_info.cm_name, "DeviceRGB")) {
603 emprintf(pdev->memory,
604 "Replacing the deprecated device parameter value UseDeviceDependentColor with sRGB.\n");
605 pdev->params.ColorConversionStrategy = ccs_sRGB;
606 } else {
607 emprintf(pdev->memory,
608 "Replacing the deprecated device parameter value UseDeviceDependentColor with Gray.\n");
609 pdev->params.ColorConversionStrategy = ccs_Gray;
610 }
556 } 611 }
557 } 612 }
558 if (cl < 1.5 && pdev->params.ColorImage.Filter != NULL && 613 if (cl < 1.5 && pdev->params.ColorImage.Filter != NULL &&
diff --git a/gs/base/gdevpdfx.h b/gs/base/gdevpdfx.h
index bc0545d9e..7a444433a 100644
--- a/gs/base/gdevpdfx.h
+++ b/gs/base/gdevpdfx.h
@@ -842,6 +842,9 @@ struct gx_device_pdf_s {
842 * This parameter is present only to allow 842 * This parameter is present only to allow
843 * ps2write output to work on those pritners. 843 * ps2write output to work on those pritners.
844 */ 844 */
845 bool UseOldColor; /* Use the old pdfwrite colour conversions instead of the CMS
846 * temporary variable
847 */
845 bool Linearise; /* Whether to Linearizse the file, the next 2 parameter 848 bool Linearise; /* Whether to Linearizse the file, the next 2 parameter
846 * are only used if this is true. 849 * are only used if this is true.
847 */ 850 */
@@ -859,8 +862,6 @@ struct gx_device_pdf_s {
859 862
860#define is_in_page(pdev)\ 863#define is_in_page(pdev)\
861 ((pdev)->contents_id != 0) 864 ((pdev)->contents_id != 0)
862#define is_in_document(pdev)\
863 (is_in_page(pdev) || (pdev)->last_resource != 0)
864 865
865/* Enumerate the individual pointers in a gx_device_pdf. */ 866/* Enumerate the individual pointers in a gx_device_pdf. */
866#define gx_device_pdf_do_ptrs(m)\ 867#define gx_device_pdf_do_ptrs(m)\
diff --git a/gs/base/gdevpsdf.h b/gs/base/gdevpsdf.h
index 8fefe6237..a71ff70ea 100644
--- a/gs/base/gdevpsdf.h
+++ b/gs/base/gdevpsdf.h
@@ -116,12 +116,15 @@ typedef struct psdf_distiller_params_s {
116 ccs_UseDeviceIndependentColorForImages, 116 ccs_UseDeviceIndependentColorForImages,
117 ccs_sRGB, 117 ccs_sRGB,
118 ccs_CMYK, 118 ccs_CMYK,
119 ccs_Gray 119 ccs_Gray,
120 ccs_RGB,
121 ccs_ByObjectType
120 } ColorConversionStrategy; 122 } ColorConversionStrategy;
121#define psdf_ccs_names\ 123#define psdf_ccs_names\
122 "LeaveColorUnchanged", "UseDeviceDependentColor",\ 124 "LeaveColorUnchanged", "UseDeviceDependentColor",\
123 "UseDeviceIndependentColor", "UseDeviceIndependentColorForImages",\ 125 "UseDeviceIndependentColor", "UseDeviceIndependentColorForImages",\
124 "sRGB", "CMYK", "Gray" 126 "sRGB", "CMYK", "Gray", "RGB", "ByObjectType"
127
125 bool PreserveHalftoneInfo; 128 bool PreserveHalftoneInfo;
126 bool PreserveOverprintSettings; 129 bool PreserveOverprintSettings;
127 enum psdf_transfer_function_info { 130 enum psdf_transfer_function_info {
@@ -407,12 +410,23 @@ int psdf_setup_image_filters(gx_device_psdf *pdev, psdf_binary_writer *pbw,
407 const gs_imager_state * pis, bool lossless, 410 const gs_imager_state * pis, bool lossless,
408 bool in_line); 411 bool in_line);
409 412
413int new_setup_image_filters(gx_device_psdf *pdev, psdf_binary_writer *pbw,
414 gs_pixel_image_t *pim, const gs_matrix *pctm,
415 const gs_imager_state * pis, bool lossless,
416 bool in_line, bool colour_conversion);
417
410/* Set up compression filters for a lossless image, with no downsampling, */ 418/* Set up compression filters for a lossless image, with no downsampling, */
411/* no color space conversion, and only lossless filters. */ 419/* no color space conversion, and only lossless filters. */
412/* Note that this may modify the image parameters. */ 420/* Note that this may modify the image parameters. */
413int psdf_setup_lossless_filters(gx_device_psdf *pdev, psdf_binary_writer *pbw, 421int psdf_setup_lossless_filters(gx_device_psdf *pdev, psdf_binary_writer *pbw,
414 gs_pixel_image_t *pim, bool in_line); 422 gs_pixel_image_t *pim, bool in_line);
415 423
424int new_setup_lossless_filters(gx_device_psdf *pdev, psdf_binary_writer *pbw,
425 gs_pixel_image_t *pim, bool in_line, bool colour_conversion);
426
427
428int new_resize_input(psdf_binary_writer *pbw, int width, int num_comps, int bpc_in, int bpc_out);
429
416/* Finish writing binary data. */ 430/* Finish writing binary data. */
417int psdf_end_binary(psdf_binary_writer * pbw); 431int psdf_end_binary(psdf_binary_writer * pbw);
418 432
diff --git a/gs/base/gdevpsdi.c b/gs/base/gdevpsdi.c
index 31304e423..ca33cc0b4 100644
--- a/gs/base/gdevpsdi.c
+++ b/gs/base/gdevpsdi.c
@@ -48,7 +48,7 @@ extern stream_state_proc_put_params(s_CF_put_params, stream_CF_state);
48/* 48/*
49 * Add a filter to expand or reduce the pixel width if needed. 49 * Add a filter to expand or reduce the pixel width if needed.
50 * At least one of bpc_in and bpc_out is 8; the other is 1, 2, 4, or 8, 50 * At least one of bpc_in and bpc_out is 8; the other is 1, 2, 4, or 8,
51 * except if bpc_out is 8, bpc_in may be 12. 51 * except if bpc_out is 8, bpc_in may be 12 (or 16).
52 */ 52 */
53static int 53static int
54pixel_resize(psdf_binary_writer * pbw, int width, int num_components, 54pixel_resize(psdf_binary_writer * pbw, int width, int num_components,
@@ -62,9 +62,9 @@ pixel_resize(psdf_binary_writer * pbw, int width, int num_components,
62 if (bpc_out == bpc_in) 62 if (bpc_out == bpc_in)
63 return 0; 63 return 0;
64 if (bpc_in != 8) { 64 if (bpc_in != 8) {
65 static const stream_template *const exts[13] = { 65 static const stream_template *const exts[17] = {
66 0, &s_1_8_template, &s_2_8_template, 0, &s_4_8_template, 66 0, &s_1_8_template, &s_2_8_template, 0, &s_4_8_template,
67 0, 0, 0, 0, 0, 0, 0, &s_12_8_template 67 0, 0, 0, 0, 0, 0, 0, &s_12_8_template, 0, 0, 0, &s_16_8_template
68 }; 68 };
69 69
70 templat = exts[bpc_in]; 70 templat = exts[bpc_in];
@@ -105,7 +105,7 @@ convert_color(gx_device *pdev, const gs_color_space *pcs, const gs_imager_state
105 return 0; 105 return 0;
106} 106}
107 107
108/* A hewristic choice of DCT compression parameters - see bug 687174. */ 108/* A heuristic choice of DCT compression parameters - see bug 687174. */
109static int 109static int
110choose_DCT_params(gx_device *pdev, const gs_color_space *pcs, 110choose_DCT_params(gx_device *pdev, const gs_color_space *pcs,
111 const gs_imager_state * pis, 111 const gs_imager_state * pis,
@@ -743,3 +743,149 @@ psdf_setup_image_colors_filter(psdf_binary_writer *pbw,
743 } 743 }
744 return 0; 744 return 0;
745} 745}
746
747/* Set up compression and downsampling filters for an image. */
748/* Note that this may modify the image parameters. */
749int
750new_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw,
751 gs_pixel_image_t * pim, const gs_matrix * pctm,
752 const gs_imager_state * pis, bool lossless, bool in_line,
753 bool colour_conversion)
754{
755 /*
756 * The following algorithms are per Adobe Tech Note # 5151,
757 * "Acrobat Distiller Parameters", revised 16 September 1996
758 * for Acrobat(TM) Distiller(TM) 3.0.
759 *
760 * The control structure is a little tricky, because filter
761 * pipelines must be constructed back-to-front.
762 */
763 int code = 0;
764 psdf_image_params params;
765 int bpc = pim->BitsPerComponent;
766 int bpc_out = pim->BitsPerComponent = min(bpc, 8);
767 int ncomp;
768 double resolution;
769
770 /*
771 * The Adobe documentation doesn't say this, but mask images are
772 * compressed on the same basis as 1-bit-deep monochrome images,
773 * except that anti-aliasing (resolution/depth tradeoff) is not
774 * allowed.
775 */
776 if (pim->ColorSpace == NULL) { /* mask image */
777 params = pdev->params.MonoImage;
778 params.Depth = 1;
779 ncomp = 1;
780 } else {
781 ncomp = gs_color_space_num_components(pim->ColorSpace);
782 if (pim->ColorSpace->type->index == gs_color_space_index_Indexed) {
783 params = pdev->params.ColorImage;
784 /* Ensure we don't use JPEG on a /Indexed colour space */
785 params.AutoFilter = false;
786 params.Filter = "FlateEncode";
787 } else {
788 if (ncomp == 1) {
789 if (bpc == 1)
790 params = pdev->params.MonoImage;
791 else
792 params = pdev->params.GrayImage;
793 if (params.Depth == -1)
794 params.Depth = bpc;
795 } else {
796 params = pdev->params.ColorImage;
797 /* params.Depth is reset below */
798 }
799 }
800 }
801
802 /*
803 * We can compute the image resolution by:
804 * W / (W * ImageMatrix^-1 * CTM / HWResolution).
805 * We can replace W by 1 to simplify the computation.
806 */
807 if (pctm == 0)
808 resolution = -1;
809 else {
810 gs_point pt;
811
812 /* We could do both X and Y, but why bother? */
813 code = gs_distance_transform_inverse(1.0, 0.0, &pim->ImageMatrix, &pt);
814 if (code < 0)
815 return code;
816 gs_distance_transform(pt.x, pt.y, pctm, &pt);
817 resolution = 1.0 / hypot(pt.x / pdev->HWResolution[0],
818 pt.y / pdev->HWResolution[1]);
819 }
820 if (ncomp == 1 && pim->ColorSpace && pim->ColorSpace->type->index != gs_color_space_index_Indexed) {
821 /* Monochrome, gray, or mask */
822 /* Check for downsampling. */
823 if (do_downsample(&params, pim, resolution)) {
824 /* Use the downsampled depth, not the original data depth. */
825 if (params.Depth == 1) {
826 params.Filter = pdev->params.MonoImage.Filter;
827 params.filter_template = pdev->params.MonoImage.filter_template;
828 params.Dict = pdev->params.MonoImage.Dict;
829 adjust_auto_filter_strategy_mono(pdev, &params, pdev->params.MonoImage.Dict, pim, in_line);
830 } else {
831 params.Filter = pdev->params.GrayImage.Filter;
832 params.filter_template = pdev->params.GrayImage.filter_template;
833 params.Dict = pdev->params.GrayImage.Dict;
834 adjust_auto_filter_strategy(pdev, &params, pdev->params.GrayImage.Dict, pim, in_line);
835 }
836 code = setup_downsampling(pbw, &params, pim, pis, resolution, lossless);
837 } else {
838 adjust_auto_filter_strategy(pdev, &params, pdev->params.GrayImage.Dict, pim, in_line);
839 code = setup_image_compression(pbw, &params, pim, pis, lossless);
840 }
841 if (code < 0)
842 return code;
843 code = pixel_resize(pbw, pim->Width, ncomp, bpc, bpc_out);
844 } else {
845 /* Color */
846 if (params.Depth == -1)
847 params.Depth = (colour_conversion ? 8 : bpc_out);
848 if (do_downsample(&params, pim, resolution)) {
849 adjust_auto_filter_strategy(pdev, &params, pdev->params.ColorImage.Dict, pim, in_line);
850 code = setup_downsampling(pbw, &params, pim, pis, resolution, lossless);
851 } else {
852 adjust_auto_filter_strategy(pdev, &params, pdev->params.ColorImage.Dict, pim, in_line);
853 code = setup_image_compression(pbw, &params, pim, pis, lossless);
854 }
855 if (code < 0)
856 return code;
857 code = pixel_resize(pbw, pim->Width, ncomp, bpc, bpc_out);
858 if (code < 0)
859 return code;
860 }
861 return code;
862}
863
864int
865new_setup_lossless_filters(gx_device_psdf *pdev, psdf_binary_writer *pbw,
866 gs_pixel_image_t *pim, bool in_line,
867 bool colour_conversion)
868{
869 /*
870 * Set up a device with modified parameters for computing the image
871 * compression filters. Don't allow downsampling or lossy compression.
872 */
873 gx_device_psdf ipdev;
874
875 ipdev = *pdev;
876 ipdev.params.ColorImage.AutoFilter = false;
877 ipdev.params.ColorImage.Downsample = false;
878 ipdev.params.ColorImage.Filter = "FlateEncode";
879 ipdev.params.ColorImage.filter_template = &s_zlibE_template;
880 ipdev.params.ConvertCMYKImagesToRGB = false;
881 ipdev.params.GrayImage.AutoFilter = false;
882 ipdev.params.GrayImage.Downsample = false;
883 ipdev.params.GrayImage.Filter = "FlateEncode";
884 ipdev.params.GrayImage.filter_template = &s_zlibE_template;
885 return new_setup_image_filters(&ipdev, pbw, pim, NULL, NULL, true, in_line, colour_conversion);
886}
887
888int new_resize_input(psdf_binary_writer *pbw, int width, int num_comps, int bpc_in, int bpc_out)
889{
890 return pixel_resize(pbw, width, num_comps, bpc_in, bpc_out);
891}
diff --git a/gs/base/gdevpsds.c b/gs/base/gdevpsds.c
index 94065bf3a..8c662b5ab 100644
--- a/gs/base/gdevpsds.c
+++ b/gs/base/gdevpsds.c
@@ -76,6 +76,15 @@ s_12_init(stream_state * st)
76 ss->bits_per_sample = 12; /* not needed */ 76 ss->bits_per_sample = 12; /* not needed */
77 return 0; 77 return 0;
78} 78}
79static int
80s_16_init(stream_state * st)
81{
82 stream_1248_state *const ss = (stream_1248_state *) st;
83
84 ss->left = ss->samples_per_row;
85 ss->bits_per_sample = 16; /* not needed */
86 return 0;
87}
79 88
80/* Process one buffer. */ 89/* Process one buffer. */
81#define BEGIN_1248\ 90#define BEGIN_1248\
@@ -207,6 +216,22 @@ s_12_8_process(stream_state * st, stream_cursor_read * pr,
207 END_1248; 216 END_1248;
208} 217}
209 218
219/* 16-to-8 "expansion" */
220static int
221s_16_8_process(stream_state * st, stream_cursor_read * pr,
222 stream_cursor_write * pw, bool last)
223{
224 BEGIN_1248;
225
226 n = ss->samples_per_row; /* misuse n to avoid a compiler warning */
227 status = 0;
228 for (; rlimit - p >= 2; ++q) {
229 q[1] = (byte)p[1]; /* Set output to the high byte of the input */
230 p+=2; /* Discard the low byte */
231 }
232 END_1248;
233}
234
210/* 8-to-N reduction */ 235/* 8-to-N reduction */
211#define FOREACH_8_N(out, nin)\ 236#define FOREACH_8_N(out, nin)\
212 byte out;\ 237 byte out;\
@@ -297,6 +322,9 @@ const stream_template s_4_8_template = {
297const stream_template s_12_8_template = { 322const stream_template s_12_8_template = {
298 &st_1248_state, s_12_init, s_12_8_process, 1, 2 323 &st_1248_state, s_12_init, s_12_8_process, 1, 2
299}; 324};
325const stream_template s_16_8_template = {
326 &st_1248_state, s_16_init, s_16_8_process, 1, 2
327};
300 328
301const stream_template s_8_1_template = { 329const stream_template s_8_1_template = {
302 &st_1248_state, s_1_init, s_8_N_process, 8, 1 330 &st_1248_state, s_1_init, s_8_N_process, 8, 1
@@ -1108,6 +1136,21 @@ s_image_colors_set_color_space(stream_image_colors_state * ss, gx_device *pdev,
1108 memcpy(ss->Decode, Decode, ss->depth * sizeof(Decode[0]) * 2); 1136 memcpy(ss->Decode, Decode, ss->depth * sizeof(Decode[0]) * 2);
1109} 1137}
1110 1138
1139void
1140s_new_image_colors_set_color_space(stream_image_colors_state * ss, gx_device *pdev,
1141 const gs_color_space *pcs, const gs_imager_state *pis,
1142 float *Decode)
1143{
1144 ss->output_depth = pdev->color_info.num_components;
1145 ss->output_component_index = ss->output_depth;
1146 ss->output_bits_per_sample = pdev->color_info.comp_bits[0]; /* Same precision for all components. */
1147 ss->convert_color = s_image_colors_convert_to_device_color;
1148 ss->pdev = pdev;
1149 ss->pcs = pcs;
1150 ss->pis = pis;
1151 memcpy(ss->Decode, Decode, ss->depth * sizeof(Decode[0]) * 2);
1152}
1153
1111/* Process a buffer. */ 1154/* Process a buffer. */
1112static int 1155static int
1113s_image_colors_process(stream_state * st, stream_cursor_read * pr, 1156s_image_colors_process(stream_state * st, stream_cursor_read * pr,
diff --git a/gs/base/gdevpsds.h b/gs/base/gdevpsds.h
index 6d54c4e57..5917863b4 100644
--- a/gs/base/gdevpsds.h
+++ b/gs/base/gdevpsds.h
@@ -34,14 +34,15 @@ typedef struct stream_1248_state_s {
34 uint left; /* # of samples left in current row */ 34 uint left; /* # of samples left in current row */
35} stream_1248_state; 35} stream_1248_state;
36 36
37/* Convert N (1, 2, 4, 12) bits to 8. */ 37/* Convert N (1, 2, 4, 12, 16) bits to 8. */
38extern const stream_template s_1_8_template; 38extern const stream_template s_1_8_template;
39extern const stream_template s_2_8_template; 39extern const stream_template s_2_8_template;
40extern const stream_template s_4_8_template; 40extern const stream_template s_4_8_template;
41extern const stream_template s_12_8_template; 41extern const stream_template s_12_8_template;
42extern const stream_template s_16_8_template;
42 43
43/* Reduce 8 bits to N (1, 2, 4). */ 44/* Reduce 8 bits to N (1, 2, 4). */
44/* We do not currently support converting 8 bits to 12. */ 45/* We do not currently support converting 8 bits to 12 or 16. */
45extern const stream_template s_8_1_template; 46extern const stream_template s_8_1_template;
46extern const stream_template s_8_2_template; 47extern const stream_template s_8_2_template;
47extern const stream_template s_8_4_template; 48extern const stream_template s_8_4_template;
@@ -215,8 +216,6 @@ struct stream_image_colors_state_s {
215 "stream_image_colors_state", stream_image_colors_enum_ptrs,\ 216 "stream_image_colors_state", stream_image_colors_enum_ptrs,\
216 stream_image_colors_reloc_ptrs, pcs, pdev, pis) 217 stream_image_colors_reloc_ptrs, pcs, pdev, pis)
217 218
218extern const stream_template s_image_colors_template;
219
220void s_image_colors_set_dimensions(stream_image_colors_state * st, 219void s_image_colors_set_dimensions(stream_image_colors_state * st,
221 int width, int height, int depth, int bits_per_sample); 220 int width, int height, int depth, int bits_per_sample);
222 221
@@ -226,6 +225,10 @@ void s_image_colors_set_color_space(stream_image_colors_state * ss, gx_device *p
226 const gs_color_space *pcs, const gs_imager_state *pis, 225 const gs_color_space *pcs, const gs_imager_state *pis,
227 float *Decode); 226 float *Decode);
228 227
228void s_new_image_colors_set_color_space(stream_image_colors_state * ss, gx_device *pdev,
229 const gs_color_space *pcs, const gs_imager_state *pis,
230 float *Decode);
231
229extern const stream_template s__image_colors_template; 232extern const stream_template s__image_colors_template;
230 233
231#endif /* gdevpsds_INCLUDED */ 234#endif /* gdevpsds_INCLUDED */