summaryrefslogtreecommitdiff
path: root/gs/src/gdevpdfi.c
diff options
context:
space:
mode:
authorL Peter Deutsch <lpd@ghostscript.com>2000-09-11 02:14:09 +0000
committerL Peter Deutsch <lpd@ghostscript.com>2000-09-11 02:14:09 +0000
commit34e6ce71c14fa3cc24dd84daf41f06e57a718437 (patch)
tree066da6a98184347c7460b6bdb49a8fd0f7e5aa8d /gs/src/gdevpdfi.c
parent39207d100fca4d9759ed65ca70aa0c3742cfcb09 (diff)
downloadghostpdl-34e6ce71c14fa3cc24dd84daf41f06e57a718437.tar.gz
Adds the ability to write some PDF 1.4 constructs: graphics state parameters
AIS, BM, ca/CA, and TK, and images with soft masks (except for Matte). git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@703 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs/src/gdevpdfi.c')
-rw-r--r--gs/src/gdevpdfi.c291
1 files changed, 196 insertions, 95 deletions
diff --git a/gs/src/gdevpdfi.c b/gs/src/gdevpdfi.c
index ddd08f2a3..92d4e0f02 100644
--- a/gs/src/gdevpdfi.c
+++ b/gs/src/gdevpdfi.c
@@ -27,6 +27,7 @@
#include "gdevpdfo.h" /* for data stream */
#include "gxcspace.h"
#include "gximage3.h"
+#include "gximag3x.h"
#include "gsiparm4.h"
/* Forward references */
@@ -35,6 +36,8 @@ private image_enum_proc_end_image(pdf_image_end_image);
private image_enum_proc_end_image(pdf_image_end_image_object);
private IMAGE3_MAKE_MID_PROC(pdf_image3_make_mid);
private IMAGE3_MAKE_MCDE_PROC(pdf_image3_make_mcde);
+private IMAGE3X_MAKE_MID_PROC(pdf_image3x_make_mid);
+private IMAGE3X_MAKE_MCDE_PROC(pdf_image3x_make_mcde);
private const gx_image_enum_procs_t pdf_image_enum_procs = {
pdf_image_plane_data,
@@ -135,6 +138,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis,
pdf_image_enum *pie;
gs_image_format_t format;
const gs_color_space *pcs;
+ gs_color_space cs_gray_temp;
cos_value_t cs_value;
int num_components;
bool is_mask = false, in_line = false;
@@ -148,6 +152,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis,
gs_pixel_image_t pixel; /* we may change some components */
gs_image1_t type1;
gs_image3_t type3;
+ gs_image3x_t type3x;
gs_image4_t type4;
} image;
ulong nbytes;
@@ -184,6 +189,21 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis,
pdf_image3_make_mid,
pdf_image3_make_mcde, pinfo);
}
+ case IMAGE3X_IMAGETYPE: {
+ /* See ImageType3 above for more information. */
+ const gs_image3x_t *pim3x = (const gs_image3x_t *)pic;
+
+ if (pdev->CompatibilityLevel < 1.4)
+ goto nyi;
+ if (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
+ prect->q.x == pim3x->Width &&
+ prect->q.y == pim3x->Height))
+ goto nyi;
+ return gx_begin_image3x_generic((gx_device *)pdev, pis, pmat, pic,
+ prect, pdcolor, pcpath, mem,
+ pdf_image3x_make_mid,
+ pdf_image3x_make_mcde, pinfo);
+ }
case 4:
if (pdev->CompatibilityLevel < 1.3)
goto nyi;
@@ -207,12 +227,20 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis,
code = pdf_open_page(pdev, PDF_IN_STREAM);
if (code < 0)
return code;
- if (is_mask && context != PDF_IMAGE_TYPE3_MASK) {
- code = pdf_set_drawing_color(pdev, pdcolor, &pdev->fill_color,
- &psdf_set_fill_color_commands);
- if (code < 0)
- goto nyi;
- }
+ if (context == PDF_IMAGE_TYPE3_MASK) {
+ /*
+ * The soft mask for an ImageType 3x image uses a DevicePixel
+ * color space, which pdf_color_space() can't handle. Patch it
+ * to DeviceGray here.
+ */
+ gs_cspace_init_DeviceGray(&cs_gray_temp);
+ pcs = &cs_gray_temp;
+ } else if (is_mask)
+ code = pdf_prepare_imagemask(pdev, pis, pdcolor);
+ else
+ code = pdf_prepare_image(pdev, pis);
+ if (code < 0)
+ goto nyi;
if (prect)
rect = *prect;
else {
@@ -297,95 +325,7 @@ gdev_pdf_begin_typed_image(gx_device * dev, const gs_imager_state * pis,
PDF_IMAGE_DEFAULT);
}
-/*
- * For ImageType 3 images, we create temporary dummy (null) devices that
- * forward the begin_typed_image call to the implementation above.
- */
-private int
-pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem)
-{
- gx_device *fdev;
- int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem);
-
- if (code < 0)
- return code;
- gx_device_set_target((gx_device_forward *)fdev, tdev);
- *pmxdev = fdev;
- return 0;
-}
-/* Implement the mask image device. */
-private dev_proc_begin_typed_image(pdf_mid_begin_typed_image);
-private int
-pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
- gs_memory_t *mem)
-{
- int code = pdf_make_mxd(pmidev, dev, mem);
-
- if (code < 0)
- return code;
- set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
- return 0;
-}
-private int
-pdf_mid_begin_typed_image(gx_device * dev, const gs_imager_state * pis,
- const gs_matrix *pmat, const gs_image_common_t *pic,
- const gs_int_rect * prect,
- const gx_drawing_color * pdcolor,
- const gx_clip_path * pcpath, gs_memory_t * mem,
- gx_image_enum_common_t ** pinfo)
-{
- /* The target of the null device is the pdfwrite device. */
- gx_device_pdf *const pdev = (gx_device_pdf *)
- ((gx_device_null *)dev)->target;
- int code = pdf_begin_typed_image
- (pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, pinfo,
- PDF_IMAGE_TYPE3_MASK);
-
- if (code < 0)
- return code;
- if ((*pinfo)->procs != &pdf_image_object_enum_procs) {
- /* We couldn't handle the mask image. Bail out. */
- /* (This is never supposed to happen.) */
- return_error(gs_error_rangecheck);
- }
- return code;
-}
-/* Implement the mask clip device. */
-private int
-pdf_image3_make_mcde(gx_device *dev, const gs_imager_state *pis,
- const gs_matrix *pmat, const gs_image_common_t *pic,
- const gs_int_rect *prect, const gx_drawing_color *pdcolor,
- const gx_clip_path *pcpath, gs_memory_t *mem,
- gx_image_enum_common_t **pinfo,
- gx_device **pmcdev, gx_device *midev,
- gx_image_enum_common_t *pminfo,
- const gs_int_point *origin)
-{
- int code = pdf_make_mxd(pmcdev, midev, mem);
- pdf_image_enum *pmie;
- pdf_image_enum *pmce;
- cos_stream_t *pmcs;
-
- if (code < 0)
- return code;
- code = pdf_begin_typed_image
- ((gx_device_pdf *)dev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
- pinfo, PDF_IMAGE_TYPE3_DATA);
- if (code < 0)
- return code;
- /* Add the /Mask entry to the image dictionary. */
- if ((*pinfo)->procs != &pdf_image_enum_procs) {
- /* We couldn't handle the image. Bail out. */
- gx_image_end(*pinfo, false);
- gs_free_object(mem, *pmcdev, "pdf_image3_make_mcde");
- return_error(gs_error_rangecheck);
- }
- pmie = (pdf_image_enum *)pminfo;
- pmce = (pdf_image_enum *)(*pinfo);
- pmcs = (cos_stream_t *)pmce->writer.pres->object;
- return cos_dict_put_c_key_object(cos_stream_dict(pmcs), "/Mask",
- pmie->writer.pres->object);
-}
+/* ---------------- All images ---------------- */
/* Process the next piece of an image. */
private int
@@ -503,15 +443,176 @@ pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
gs_free_object(pie->memory, pie, "pdf_end_image");
return code;
}
+
/* End a normal image, drawing it. */
private int
pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last)
{
return pdf_image_end_image_data(info, draw_last, true);
}
+
+/* ---------------- Type 3/3x images ---------------- */
+
+/*
+ * For both types of masked images, we create temporary dummy (null) devices
+ * that forward the begin_typed_image call to the implementation above.
+ */
+private int
+pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem)
+{
+ gx_device *fdev;
+ int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem);
+
+ if (code < 0)
+ return code;
+ gx_device_set_target((gx_device_forward *)fdev, tdev);
+ *pmxdev = fdev;
+ return 0;
+}
+
/* End the mask of an ImageType 3 image, not drawing it. */
private int
pdf_image_end_image_object(gx_image_enum_common_t * info, bool draw_last)
{
return pdf_image_end_image_data(info, draw_last, false);
}
+
+/* ---------------- Type 3 images ---------------- */
+
+/* Implement the mask image device. */
+private dev_proc_begin_typed_image(pdf_mid_begin_typed_image);
+private int
+pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
+ gs_memory_t *mem)
+{
+ int code = pdf_make_mxd(pmidev, dev, mem);
+
+ if (code < 0)
+ return code;
+ set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
+ return 0;
+}
+private int
+pdf_mid_begin_typed_image(gx_device * dev, const gs_imager_state * pis,
+ const gs_matrix *pmat, const gs_image_common_t *pic,
+ const gs_int_rect * prect,
+ const gx_drawing_color * pdcolor,
+ const gx_clip_path * pcpath, gs_memory_t * mem,
+ gx_image_enum_common_t ** pinfo)
+{
+ /* The target of the null device is the pdfwrite device. */
+ gx_device_pdf *const pdev = (gx_device_pdf *)
+ ((gx_device_null *)dev)->target;
+ int code = pdf_begin_typed_image
+ (pdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, pinfo,
+ PDF_IMAGE_TYPE3_MASK);
+
+ if (code < 0)
+ return code;
+ if ((*pinfo)->procs != &pdf_image_object_enum_procs) {
+ /* We couldn't handle the mask image. Bail out. */
+ /* (This is never supposed to happen.) */
+ return_error(gs_error_rangecheck);
+ }
+ return code;
+}
+
+/* Implement the mask clip device. */
+private int
+pdf_image3_make_mcde(gx_device *dev, const gs_imager_state *pis,
+ const gs_matrix *pmat, const gs_image_common_t *pic,
+ const gs_int_rect *prect, const gx_drawing_color *pdcolor,
+ const gx_clip_path *pcpath, gs_memory_t *mem,
+ gx_image_enum_common_t **pinfo,
+ gx_device **pmcdev, gx_device *midev,
+ gx_image_enum_common_t *pminfo,
+ const gs_int_point *origin)
+{
+ int code = pdf_make_mxd(pmcdev, midev, mem);
+ pdf_image_enum *pmie;
+ pdf_image_enum *pmce;
+ cos_stream_t *pmcs;
+
+ if (code < 0)
+ return code;
+ code = pdf_begin_typed_image
+ ((gx_device_pdf *)dev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
+ pinfo, PDF_IMAGE_TYPE3_DATA);
+ if (code < 0)
+ return code;
+ /* Add the /Mask entry to the image dictionary. */
+ if ((*pinfo)->procs != &pdf_image_enum_procs) {
+ /* We couldn't handle the image. Bail out. */
+ gx_image_end(*pinfo, false);
+ gs_free_object(mem, *pmcdev, "pdf_image3_make_mcde");
+ return_error(gs_error_rangecheck);
+ }
+ pmie = (pdf_image_enum *)pminfo;
+ pmce = (pdf_image_enum *)(*pinfo);
+ pmcs = (cos_stream_t *)pmce->writer.pres->object;
+ return cos_dict_put_c_key_object(cos_stream_dict(pmcs), "/Mask",
+ pmie->writer.pres->object);
+}
+
+/* ---------------- Type 3x images ---------------- */
+
+/* Implement the mask image device. */
+private int
+pdf_image3x_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
+ int depth, gs_memory_t *mem)
+{
+ int code = pdf_make_mxd(pmidev, dev, mem);
+
+ if (code < 0)
+ return code;
+ set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
+ return 0;
+}
+
+/* Implement the mask clip device. */
+private int
+pdf_image3x_make_mcde(gx_device *dev, const gs_imager_state *pis,
+ const gs_matrix *pmat, const gs_image_common_t *pic,
+ const gs_int_rect *prect,
+ const gx_drawing_color *pdcolor,
+ const gx_clip_path *pcpath, gs_memory_t *mem,
+ gx_image_enum_common_t **pinfo,
+ gx_device **pmcdev, gx_device *midev[2],
+ gx_image_enum_common_t *pminfo[2],
+ const gs_int_point origin[2])
+{
+ int code;
+ pdf_image_enum *pmie;
+ pdf_image_enum *pmce;
+ cos_stream_t *pmcs;
+ int i;
+
+ if (midev[0]) {
+ if (midev[1])
+ return_error(gs_error_rangecheck);
+ i = 0;
+ } else if (midev[1])
+ i = 1;
+ else
+ return_error(gs_error_rangecheck);
+ code = pdf_make_mxd(pmcdev, midev[i], mem);
+ if (code < 0)
+ return code;
+ code = pdf_begin_typed_image
+ ((gx_device_pdf *)dev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
+ pinfo, PDF_IMAGE_TYPE3_DATA);
+ if (code < 0)
+ return code;
+ /* Add the /SMask entry to the image dictionary. */
+ if ((*pinfo)->procs != &pdf_image_enum_procs) {
+ /* We couldn't handle the image. Bail out. */
+ gx_image_end(*pinfo, false);
+ gs_free_object(mem, *pmcdev, "pdf_image3_make_mcde");
+ return_error(gs_error_rangecheck);
+ }
+ pmie = (pdf_image_enum *)pminfo[i];
+ pmce = (pdf_image_enum *)(*pinfo);
+ pmcs = (cos_stream_t *)pmce->writer.pres->object;
+ return cos_dict_put_c_key_object(cos_stream_dict(pmcs), "/SMask",
+ pmie->writer.pres->object);
+}