[gs-commits] ghostpdl branch, master, updated. jbig2dec-0.14-1875-g7fc7881
[email protected] (Robin Watts) Fri, 15 Nov 2019 19:37:33 +0000 (UTC)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
The ghostpdl branch, master has been updated
via 7fc7881b00a43fe1017e593846a0baf28e8837db (commit)
via 161adc70e0d6625618c5a6afcb5e04161acc2e2c (commit)
via b8de03bdb8696517bff0259e827ece4f5746663c (commit)
via 58bee0ad2c67888a52fa02e31de3120673525fda (commit)
via 372e4f29d3fcbfeaa83a5ee8cc530cbb948edab7 (commit)
from 194c53ed02d657159a7be894b6d4b54ce1f435d4 (commit)
----------------------------------------------------------------------
commit 7fc7881b00a43fe1017e593846a0baf28e8837db
Author: Robin Watts <[email protected]>
Date: Fri Nov 15 18:50:56 2019 +0000
Add simple PWG "interpreter" for gpdl.
diff --git a/base/spwgd.c b/base/spwgd.c
index 19ec764..cb04cb7 100644
--- a/base/spwgd.c
+++ b/base/spwgd.c
@@ -171,8 +171,17 @@ data_produced:
}
}
+static void
+s_PWGD_release(stream_state * st)
+{
+ stream_PWGD_state *const ss = (stream_PWGD_state *) st;
+
+ gs_free_object(st->memory, ss->line_buffer, "PWGD(close)");
+ ss->line_buffer = NULL;
+}
+
/* Stream template */
const stream_template s_PWGD_template = {
- &st_PWGD_state, s_PWGD_init, s_PWGD_process, 1, 1, NULL,
+ &st_PWGD_state, s_PWGD_init, s_PWGD_process, 1, 1, s_PWGD_release,
s_PWGD_set_defaults
};
diff --git a/gpdl/gpdl.mak b/gpdl/gpdl.mak
index b2f39aa..3864a92 100644
--- a/gpdl/gpdl.mak
+++ b/gpdl/gpdl.mak
@@ -19,6 +19,7 @@ GPDLSRC=$(GPDLSRCDIR)$(D)
GPDLPSISRC=$(GPDLSRCDIR)$(D)psi$(D)
GPDLURFSRC=$(URFSRCDIR)$(D)
GPDLIMGSRC=$(GPDLSRCDIR)$(D)image$(D)
+GPDLPWGSRC=$(GPDLSRCDIR)$(D)pwg$(D)
GPDLOBJ=$(GPDLOBJDIR)$(D)
GPDLGEN=$(GPDLGENDIR)$(D)
@@ -33,9 +34,12 @@ GPDL_URF_TOP_OBJ_FILE=urftop.$(OBJ)
GPDL_IMG_TOP_OBJ_FILE=imagetop.$(OBJ)
GPDL_IMG_TOP_OBJ=$(GPDLOBJ)/$(GPDL_IMG_TOP_OBJ_FILE)
-GPDL_PSI_TOP_OBJS=$(GPDL_IMG_TOP_OBJ) $(GPDL_URF_TOP_OBJ) $(GPDL_PSI_TOP_OBJ) $(GPDLOBJ)gpdlimpl.$(OBJ)
+GPDL_PWG_TOP_OBJ_FILE=pwgtop.$(OBJ)
+GPDL_PWG_TOP_OBJ=$(GPDLOBJ)/$(GPDL_PWG_TOP_OBJ_FILE)
-LANG_CFLAGS=$(D_)PCL_INCLUDED$(_D) $(D_)PSI_INCLUDED$(_D) $(D_)XPS_INCLUDED$(_D) $(ENABLE_URF) $(D_)IMG_INCLUDED$(_D)
+GPDL_PSI_TOP_OBJS=$(GPDL_PWG_TOP_OBJ) $(GPDL_IMG_TOP_OBJ) $(GPDL_URF_TOP_OBJ) $(GPDL_PSI_TOP_OBJ) $(GPDLOBJ)gpdlimpl.$(OBJ)
+
+LANG_CFLAGS=$(D_)PCL_INCLUDED$(_D) $(D_)PSI_INCLUDED$(_D) $(D_)XPS_INCLUDED$(_D) $(ENABLE_URF) $(D_)IMG_INCLUDED$(_D) $(D_)PWG_INCLUDED$(_D)
GPDLCC=$(CC_) $(LANG_CFLAGS) $(I_)$(PSSRCDIR)$(_I) $(I_)$(PLSRCDIR)$(_I) $(I_)$(GLSRCDIR)$(_I) $(I_)$(DEVSRCDIR)$(_I) $(I_)$(GLGENDIR)$(_I) $(C_)
@@ -69,5 +73,10 @@ $(GPDLOBJ)/$(GPDL_URF_TOP_OBJ_FILE): $(GPDLURFSRC)urftop.c $(AK)\
$(GPDL_IMG_TOP_OBJ): $(GPDLIMGSRC)imagetop.c $(AK)\
$(gxdevice_h) $(gserrors_h) $(gsstate_h) $(strimpl_h) $(gscoord_h)\
- $(gsstate_h) $(jpeglib_h) $(setjmp__h) $(sjpeg_h)
+ $(jpeglib_h) $(setjmp__h) $(sjpeg_h) $(pltop_h)
$(GPDLCC) $(II)$(JI_)$(_I) $(GPDLIMGSRC)imagetop.c $(GPDLO_)$(GPDL_IMG_TOP_OBJ_FILE)
+
+$(GPDL_PWG_TOP_OBJ): $(GPDLPWGSRC)pwgtop.c $(AK)\
+ $(gxdevice_h) $(gserrors_h) $(gsstate_h) $(spwgx_h) $(strimpl_h)\
+ $(gscoord_h) $(pltop_h)
+ $(GPDLCC) $(II)$(JI_)$(_I) $(GPDLPWGSRC)pwgtop.c $(GPDLO_)$(GPDL_PWG_TOP_OBJ_FILE)
diff --git a/gpdl/pwg/pwgtop.c b/gpdl/pwg/pwgtop.c
new file mode 100644
index 0000000..5e7549e
--- /dev/null
+++ b/gpdl/pwg/pwgtop.c
@@ -0,0 +1,718 @@
+/* Copyright (C) 2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* pwgtop.c */
+/* Top-level API implementation of "PWG" Language Interface */
+
+#include "pltop.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gsstate.h"
+#include "spwgx.h"
+#include "strimpl.h"
+#include "gscoord.h"
+
+/* Forward decls */
+
+/************************************************************/
+/******** Language wrapper implementation (see pltop.h) *****/
+/************************************************************/
+
+typedef enum
+{
+ ii_state_identifying = 0,
+ ii_state_pwg,
+ ii_state_pwg_header,
+ ii_state_pwg_data,
+ ii_state_flush
+} ii_state;
+
+/*
+ * PWG interpreter instance
+ */
+typedef struct pwg_interp_instance_s {
+ gs_memory_t *memory;
+ gx_device *dev;
+ gx_device *nulldev;
+
+ gs_color_space *gray;
+ gs_color_space *rgb;
+ gs_color_space *cmyk;
+
+ /* PWG parser state machine */
+ ii_state state;
+
+ int pages;
+
+ uint32_t bpc;
+ uint32_t bpp;
+ uint32_t bpl;
+ uint32_t colororder;
+ uint32_t cs;
+ uint32_t duplexMode;
+ uint32_t printQuality;
+ uint32_t mediaType;
+ uint32_t copies;
+ uint32_t width;
+ uint32_t height;
+ uint32_t xresolution;
+ uint32_t yresolution;
+
+ uint32_t num_comps;
+ uint32_t byte_width;
+ uint32_t x;
+ uint32_t y;
+
+ gs_image_t image;
+ gs_image_enum *penum;
+ gs_gstate *pgs;
+
+ stream_PWGD_state pwgd_state;
+ byte stream_buffer[2048];
+
+} pwg_interp_instance_t;
+
+static int
+pwg_detect_language(const char *s, int len)
+{
+ /* For postscript, we look for %! */
+ if (len >= 4) {
+ if (memcmp(s, "RaS2", 4) == 0)
+ return 100;
+ }
+
+ return 0;
+}
+
+static const pl_interp_characteristics_t pwg_characteristics = {
+ "PWG",
+ pwg_detect_language,
+ "Artifex",
+ "0.01",
+ "13 Nov 2019",
+ 1 /* minimum input size */
+};
+
+/* Get implementation's characteristics */
+static const pl_interp_characteristics_t * /* always returns a descriptor */
+pwg_impl_characteristics(const pl_interp_implementation_t *impl) /* implementation of interpreter to alloc */
+{
+ return &pwg_characteristics;
+}
+
+static void
+pwg_deallocate(pwg_interp_instance_t *pwg)
+{
+ if (pwg == NULL)
+ return;
+
+ rc_decrement_cs(pwg->gray, "pwg_deallocate");
+ rc_decrement_cs(pwg->rgb, "pwg_deallocate");
+ rc_decrement_cs(pwg->cmyk, "pwg_deallocate");
+
+ if (pwg->pgs != NULL)
+ gs_gstate_free_chain(pwg->pgs);
+ gs_free_object(pwg->memory, pwg, "pwg_impl_allocate_interp_instance");
+}
+
+/* Deallocate a interpreter instance */
+static int
+pwg_impl_deallocate_interp_instance(pl_interp_implementation_t *impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ pwg_deallocate(pwg);
+ impl->interp_client_data = NULL;
+
+ return 0;
+}
+
+/* Do per-instance interpreter allocation/init. */
+static int
+pwg_impl_allocate_interp_instance(pl_interp_implementation_t *impl, gs_memory_t *mem)
+{
+ int code;
+ pwg_interp_instance_t *pwg
+ = (pwg_interp_instance_t *)gs_alloc_bytes(mem,
+ sizeof(pwg_interp_instance_t),
+ "pwg_impl_allocate_interp_instance");
+ if (!pwg)
+ return_error(gs_error_VMerror);
+ memset(pwg, 0, sizeof(*pwg));
+
+ pwg->memory = mem;
+ pwg->pgs = gs_gstate_alloc(mem);
+ if (pwg->pgs == NULL)
+ goto failVM;
+
+ /* Push one save level onto the stack to assuage the memory handling */
+ code = gs_gsave(pwg->pgs);
+ if (code < 0)
+ goto fail;
+
+ code = gsicc_init_iccmanager(pwg->pgs);
+ if (code < 0)
+ goto fail;
+
+ pwg->gray = gs_cspace_new_ICC(mem, pwg->pgs, 1);
+ pwg->rgb = gs_cspace_new_ICC(mem, pwg->pgs, 3);
+ pwg->cmyk = gs_cspace_new_ICC(mem, pwg->pgs, 4);
+
+ impl->interp_client_data = pwg;
+
+ return 0;
+
+failVM:
+ code = gs_note_error(gs_error_VMerror);
+fail:
+ (void)pwg_deallocate(pwg);
+ return code;
+}
+
+/*
+ * Get the allocator with which to allocate a device
+ */
+static gs_memory_t *
+pwg_impl_get_device_memory(pl_interp_implementation_t *impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ return pwg->dev ? pwg->dev->memory : NULL;
+}
+
+#if 0 /* UNUSED */
+static int
+pwg_impl_set_param(pl_interp_implementation_t *impl,
+ pl_set_param_type type,
+ const char *param,
+ const void *val)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ /* No params set here */
+ return 0;
+}
+
+static int
+pwg_impl_add_path(pl_interp_implementation_t *impl,
+ const char *path)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ /* No paths to add */
+ return 0;
+}
+
+static int
+pwg_impl_post_args_init(pl_interp_implementation_t *impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ /* No post args processing */
+ return 0;
+}
+#endif
+
+/* Prepare interp instance for the next "job" */
+static int
+pwg_impl_init_job(pl_interp_implementation_t *impl,
+ gx_device *device)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ pwg->dev = device;
+ pwg->state = ii_state_identifying;
+
+ return 0;
+}
+
+#if 0 /* UNUSED */
+static int
+pwg_impl_run_prefix_commands(pl_interp_implementation_t *impl,
+ const char *prefix)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+
+static int
+pwg_impl_process_file(pl_interp_implementation_t *impl, const char *filename)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+#endif
+
+/* Do any setup for parser per-cursor */
+static int /* ret 0 or +ve if ok, else -ve error code */
+pwg_impl_process_begin(pl_interp_implementation_t * impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+
+/* Ensure we have 'required' bytes to read, and further ensure
+ * that we have no UEL's within those bytes. */
+static int
+ensure_bytes(pwg_interp_instance_t *pwg, stream_cursor_read *pr, int required)
+{
+ int n;
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q;
+ int avail;
+
+ /* Find out how many bytes we need to check */
+ n = pr->limit - pr->ptr;
+ if (n > required)
+ n = required;
+
+ /* Make sure there are no UELs in that block */
+ q = p + n;
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL */
+ return avail < 9 ? gs_error_NeedInput : gs_error_InterpreterExit;
+ }
+ p++;
+ }
+
+ /* If we have enough bytes, great, if not, get some more */
+ return (n < required) ? gs_error_NeedInput : 0;
+}
+
+static int
+flush_to_uel(stream_cursor_read *pr)
+{
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q = pr->limit+1;
+ int avail;
+
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL. Bin everything to
+ * the start of the match. */
+ pr->ptr = p-1;
+ if (avail == 9) /* Complete match. Exit! */
+ return gs_error_InterpreterExit;
+ /* Partial match. Get more data. */
+ return gs_error_NeedInput;
+ }
+ p++;
+ }
+
+ pr->ptr = pr->limit;
+
+ return 0;
+}
+
+static int
+bytes_until_uel(const stream_cursor_read *pr)
+{
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q = pr->limit+1;
+ int avail;
+
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL. Everything up to
+ * the start of the match is up for grabs. */
+ return p - (pr->ptr+1);
+ }
+ p++;
+ }
+
+ return pr->limit - pr->ptr;
+}
+
+static int
+get32be(stream_cursor_read *pr)
+{
+ int v = pr->ptr[1] << 24;
+ v |= pr->ptr[2] << 16;
+ v |= pr->ptr[3] << 8;
+ v |= pr->ptr[4];
+ pr->ptr += 4;
+
+ return v;
+}
+
+static int
+get8(stream_cursor_read *pr)
+{
+ return *++(pr->ptr);
+}
+
+static int
+pwg_impl_process(pl_interp_implementation_t * impl, stream_cursor_read * pr)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+ int code = 0;
+ gs_color_space *cs;
+
+ /* Loop while we have bytes to read */
+ while (pr->limit > pr->ptr)
+ {
+ switch(pwg->state)
+ {
+ case ii_state_identifying:
+ /* Try and get us 4 bytes for "RaS2" */
+ code = ensure_bytes(pwg, pr, 4);
+ if (code < 0)
+ return code;
+ if (memcmp("RaS2", (const char *)pr->ptr+1, 4) == 0)
+ {
+ pr->ptr += 4;
+ pwg->state = ii_state_pwg_header;
+ break;
+ }
+ pwg->state = ii_state_flush;
+ break;
+ case ii_state_pwg_header:
+ /* Try and get us 1796 bytes for the page header */
+ code = ensure_bytes(pwg, pr, 1796);
+ if (code < 0)
+ return code;
+ pr->ptr += 64; /* CString PwgRaster */
+ pr->ptr += 64; /* CString MediaColor */
+ pr->ptr += 64; /* CString MediaType */
+ pr->ptr += 64; /* CString PrintContentOptimize */
+ pr->ptr += 1-(256-267); /* Reserved */
+ (void)get32be(pr); /* WhenEnum CutMedia */
+ pwg->duplexMode = !!get32be(pr); /* Boolean Duplex */
+ pwg->xresolution = get32be(pr);
+ pwg->yresolution = get32be(pr);
+ pr->ptr += 1-(284-299); /* Reserved */
+ (void)!!get32be(pr); /* Boolean InsertSheet */
+ (void)get32be(pr); /* WhenEnum Jog */
+ (void)get32be(pr); /* EdgeEnum LeadingEdge FeedDirection */
+ pr->ptr += 1-(312-323); /* Reserved */
+ (void)get32be(pr); /* MediaPosition */
+ (void)get32be(pr); /* MediaWeightMetric */
+ pr->ptr += 1-(332-339); /* Reserved */
+ pwg->copies = get32be(pr); /* NumCopies */
+ if (pwg->copies == 0)
+ pwg->copies = 1;
+ (void)get32be(pr); /* OrientationEnum Orientation OrientationRequested */
+ pr->ptr += 1-(348-351); /* Reserved */
+ (void)get32be(pr); /* UnsignedInt PageSize */
+ (void)get32be(pr); /* UnsignedInt PageSize */
+ pr->ptr += 1-(360-367); /* Reserved */
+ (void)!!get32be(pr); /* Boolean Tumble */
+ pwg->width = get32be(pr); /* Width */
+ pwg->height = get32be(pr); /* Height */
+ pr->ptr += 1-(380-383); /* Reserved */
+ pwg->bpc = get32be(pr); /* Bits Per Color */
+ pwg->bpp = get32be(pr); /* Bits Per Pixel */
+ pwg->bpl = get32be(pr); /* Bytes Per Line */
+ pwg->colororder = get32be(pr); /* ColorOrderEnum ColorOrder */
+ pwg->cs = get32be(pr); /* ColorSpaceEnum ColorSpace */
+ pr->ptr += 1-(404-419); /* Reserved */
+ (void)get32be(pr); /* NumColors */
+ pr->ptr += 1-(424-451); /* Reserved */
+ (void)get32be(pr); /* TotalPageCount */
+ (void)get32be(pr); /* CrossFeedTransform */
+ (void)get32be(pr); /* FeedTransform */
+ (void)get32be(pr); /* ImageBoxLeft */
+ (void)get32be(pr); /* ImageBoxTop */
+ (void)get32be(pr); /* ImageBoxRight */
+ (void)get32be(pr); /* ImageBoxBottom */
+ (void)get32be(pr); /* SrgbColor AlternatePrimary */
+ pwg->printQuality = get32be(pr); /* PrintQuality */
+ pr->ptr += 1-(488-507); /* Reserved */
+ (void)get32be(pr); /* VendorIdentifier */
+ (void)get32be(pr); /* VendorLength */
+ pr->ptr += 1-(516-1603); /* VendorData */
+ pr->ptr += 1-(1604-1667); /* Reserved */
+ pr->ptr += 1-(1668-1731); /* RenderingIntent */
+ pr->ptr += 1-(1732-1795); /* PageSizeName */
+
+ /* Decode the header */
+ if (pwg->colororder != 0)
+ goto bad_header; /* 0 = chunky = only defined one so far */
+
+ switch(pwg->cs) {
+ case 3: /* DeviceBlack */
+ case 18: /* Sgray */
+ case 48: /* Device1 (Device color, 1 colorant) */
+ pwg->num_comps = 1;
+ cs = pwg->gray;
+ break;
+ case 1: /* DeviceRGB */
+ case 19: /* sRGB */
+ case 20: /* AdobeRGB */
+ pwg->num_comps = 3;
+ cs = pwg->rgb;
+ break;
+ case 6: /* DeviceCMYK */
+ pwg->num_comps = 4;
+ cs = pwg->cmyk;
+ break;
+ default:
+ goto bad_header;
+ }
+ if (pwg->bpc != 8)
+ goto bad_header;
+ if (pwg->bpp != 8*pwg->num_comps && pwg->bpp != 16*pwg->num_comps) {
+bad_header:
+ pwg->state = ii_state_flush;
+ break;
+ }
+ pwg->byte_width = (pwg->bpp>>3)*pwg->width;
+ if (pwg->bpl != pwg->byte_width)
+ goto bad_header;
+
+ pwg->nulldev = gs_currentdevice(pwg->pgs);
+ rc_increment(pwg->nulldev);
+ code = gs_setdevice_no_erase(pwg->pgs, pwg->dev);
+ if (code < 0)
+ goto early_flush;
+ gs_initmatrix(pwg->pgs);
+
+ code = gs_scale(pwg->pgs, 1.0, -1.0);
+ if (code >= 0)
+ code = gs_translate(pwg->pgs, 0.0, -pwg->dev->height);
+ if (code >= 0)
+ code = gs_erasepage(pwg->pgs);
+ if (code < 0)
+ goto early_flush;
+
+ memset(&pwg->image, 0, sizeof(pwg->image));
+ gs_image_t_init(&pwg->image, cs);
+ pwg->image.BitsPerComponent = pwg->bpp/pwg->num_comps;
+ pwg->image.Width = pwg->width;
+ pwg->image.Height = pwg->height;
+
+ pwg->image.ImageMatrix.xx = pwg->xresolution / 72.0;
+ pwg->image.ImageMatrix.yy = pwg->yresolution / 72.0;
+
+ pwg->penum = gs_image_enum_alloc(pwg->memory, "pwg_impl_process(penum)");
+ if (pwg->penum == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto early_flush;
+ }
+
+ code = gs_image_init(pwg->penum,
+ &pwg->image,
+ false,
+ false,
+ pwg->pgs);
+ if (code < 0)
+ goto early_flush;
+
+ s_init_state((stream_state *)&pwg->pwgd_state, &s_PWGD_template, pwg->memory);
+ if (s_PWGD_template.set_defaults)
+ s_PWGD_template.set_defaults((stream_state *)&pwg->pwgd_state);
+
+ pwg->pwgd_state.width = pwg->width;
+ pwg->pwgd_state.bpp = pwg->bpp;
+
+ code = (s_PWGD_template.init)((stream_state *)&pwg->pwgd_state);
+ if (code < 0)
+ goto early_flush;
+ pwg->x = pwg->y = 0;
+ pwg->state = ii_state_pwg_data;
+ break;
+ case ii_state_pwg_data:
+ {
+ int n = bytes_until_uel(pr);
+ stream_cursor_read local_r;
+ stream_cursor_write local_w;
+ int status;
+ unsigned int used;
+ int decoded_any = 0;
+
+ local_r.ptr = pr->ptr;
+ local_r.limit = local_r.ptr + n;
+
+ do {
+ local_w.ptr = pwg->stream_buffer-1;
+ local_w.limit = local_w.ptr + sizeof(pwg->stream_buffer);
+
+ status = (s_PWGD_template.process)((stream_state *)&pwg->pwgd_state,
+ &local_r, &local_w,
+ true);
+ /* status = 0 => need data
+ * 1 => need output space */
+ /* Copy the updated pointer back */
+ pr->ptr = local_r.ptr;
+ if (local_w.ptr + 1 == pwg->stream_buffer)
+ break; /* Failed to decode any data */
+ decoded_any = 1;
+
+ code = gs_image_next(pwg->penum, pwg->stream_buffer, local_w.ptr + 1 - pwg->stream_buffer, &used);
+ if (code < 0)
+ goto flush;
+
+ pwg->x += used;
+ while (pwg->x >= pwg->byte_width) {
+ pwg->x -= pwg->byte_width;
+ pwg->y++;
+ }
+ /* Loop while we haven't had all the lines, the decompression
+ * didn't ask for more data, and the decompression didn't give
+ * us more data. */
+ } while (pwg->y < pwg->height);
+
+ if (pwg->y == pwg->height) {
+ code = gs_image_cleanup_and_free_enum(pwg->penum, pwg->pgs);
+ pwg->penum = NULL;
+ if (code < 0)
+ goto flush;
+ code = pl_finish_page(pwg->memory->gs_lib_ctx->top_of_system,
+ pwg->pgs, pwg->copies, true);
+ if (code < 0)
+ goto flush;
+ if (pwg->pages > 0) {
+ pwg->pages--;
+ /* If we've reached the expected end, we should probably flush to UEL */
+ if (pwg->pages == 0)
+ pwg->state = ii_state_flush;
+ }
+ if (pwg->pwgd_state.templat->release)
+ pwg->pwgd_state.templat->release((stream_state *)&pwg->pwgd_state);
+ pwg->state = ii_state_pwg_header;
+ } else if (decoded_any == 0) {
+ /* Failed to make progress. Just give up to avoid livelocking. */
+ goto flush;
+ }
+ break;
+ }
+ default:
+ case ii_state_flush:
+ if (0) {
+flush:
+ if (pwg->pwgd_state.templat->release)
+ pwg->pwgd_state.templat->release((stream_state *)&pwg->pwgd_state);
+early_flush:
+ pwg->state = ii_state_flush;
+ }
+ /* We want to bin any data we get up to, but not including
+ * a UEL. */
+ return flush_to_uel(pr);
+ }
+ }
+
+ return code;
+}
+
+static int
+pwg_impl_process_end(pl_interp_implementation_t * impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+ int code = 0;
+
+ /* FIXME: */
+ if (code == gs_error_InterpreterExit || code == gs_error_NeedInput)
+ code = 0;
+
+ return code;
+}
+
+/* Not implemented */
+static int
+pwg_impl_flush_to_eoj(pl_interp_implementation_t *impl, stream_cursor_read *cursor)
+{
+ const byte *p = cursor->ptr;
+ const byte *rlimit = cursor->limit;
+
+ /* Skip to, but leave UEL in buffer for PJL to find later */
+ for (; p < rlimit; ++p)
+ if (p[1] == '\033') {
+ uint avail = rlimit - p;
+
+ if (memcmp(p + 1, "\033%-12345X", min(avail, 9)))
+ continue;
+ if (avail < 9)
+ break;
+ cursor->ptr = p;
+ return 1; /* found eoj */
+ }
+ cursor->ptr = p;
+ return 0; /* need more */
+}
+
+/* Parser action for end-of-file */
+static int
+pwg_impl_process_eof(pl_interp_implementation_t *impl)
+{
+ return 0;
+}
+
+/* Report any errors after running a job */
+static int
+pwg_impl_report_errors(pl_interp_implementation_t *impl, /* interp instance to wrap up job in */
+ int code, /* prev termination status */
+ long file_position, /* file position of error, -1 if unknown */
+ bool force_to_cout /* force errors to cout */
+)
+{
+ return 0;
+}
+
+/* Wrap up interp instance after a "job" */
+static int
+pwg_impl_dnit_job(pl_interp_implementation_t *impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ if (pwg->nulldev) {
+ int code = gs_setdevice(pwg->pgs, pwg->nulldev);
+ pwg->dev = NULL;
+ rc_decrement(pwg->nulldev, "pwg_impl_dnit_job(nulldevice)");
+ pwg->nulldev = NULL;
+ return code;
+ }
+ return 0;
+}
+
+/* Parser implementation descriptor */
+const pl_interp_implementation_t pwg_implementation = {
+ pwg_impl_characteristics,
+ pwg_impl_allocate_interp_instance,
+ pwg_impl_get_device_memory,
+ NULL, /* pwg_impl_set_param */
+ NULL, /* pwg_impl_add_path */
+ NULL, /* pwg_impl_post_args_init */
+ pwg_impl_init_job,
+ NULL, /* pwg_impl_run_prefix_commands */
+ NULL, /* pwg_impl_process_file */
+ pwg_impl_process_begin,
+ pwg_impl_process,
+ pwg_impl_process_end,
+ pwg_impl_flush_to_eoj,
+ pwg_impl_process_eof,
+ pwg_impl_report_errors,
+ pwg_impl_dnit_job,
+ pwg_impl_deallocate_interp_instance,
+ NULL
+};
diff --git a/pcl/pl/plimpl.c b/pcl/pl/plimpl.c
index ebfe3a4..dddefee 100644
--- a/pcl/pl/plimpl.c
+++ b/pcl/pl/plimpl.c
@@ -39,6 +39,8 @@ extern pl_interp_implementation_t urf_implementation;
extern pl_interp_implementation_t img_implementation;
+extern pl_interp_implementation_t pwg_implementation;
+
/* Zero-terminated list of pointers to implementations */
pl_interp_implementation_t *pdl_implementations[] = {
&pjl_implementation,
@@ -58,6 +60,9 @@ pl_interp_implementation_t *pdl_implementations[] = {
#ifdef IMG_INCLUDED
&img_implementation,
#endif
+#ifdef PWG_INCLUDED
+ &pwg_implementation,
+#endif
0
};
diff --git a/windows/ghostpdl.vcproj b/windows/ghostpdl.vcproj
index 0d35c34..c105cc3 100644
--- a/windows/ghostpdl.vcproj
+++ b/windows/ghostpdl.vcproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
@@ -326,6 +326,14 @@
>
</File>
</Filter>
+ <Filter
+ Name="pwg"
+ >
+ <File
+ RelativePath="..\gpdl\pwg\pwgtop.c"
+ >
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>
----------------------------------------------------------------------
commit 161adc70e0d6625618c5a6afcb5e04161acc2e2c
Author: Robin Watts <[email protected]>
Date: Fri Nov 15 18:49:23 2019 +0000
Squash a warning about an ininitialised variable.
diff --git a/jpegxr/cw_emit.c b/jpegxr/cw_emit.c
index cda26fe..cefa11a 100644
--- a/jpegxr/cw_emit.c
+++ b/jpegxr/cw_emit.c
@@ -133,7 +133,7 @@ int jxrc_set_separate_alpha_image_plane(jxr_container_t cp, unsigned int alpha_p
static void emit_ifd(jxr_container_t cp)
{
- unsigned long ifd_mark;
+ unsigned long ifd_mark = 0;
int idx;
struct ifd_table ifd[64];
unsigned char buf[1024];
----------------------------------------------------------------------
commit b8de03bdb8696517bff0259e827ece4f5746663c
Author: Robin Watts <[email protected]>
Date: Fri Nov 15 18:48:55 2019 +0000
Squash a float -> int warning.
diff --git a/contrib/japanese/gdevlbp3.c b/contrib/japanese/gdevlbp3.c
index 096aecf..8cbc2ce 100644
--- a/contrib/japanese/gdevlbp3.c
+++ b/contrib/japanese/gdevlbp3.c
@@ -137,8 +137,8 @@ BoundImage(gx_device_printer *pDev, struct bounding *pBox)
height*10/Yres < 98 ? a5 :\
height*10/Yres < 109 ? b5 :\
height*10/Yres < 116 ? letter : a4;
- Xsize = Xres * mm_to_inch(PaperInfo[paper].w-100) / 160;
- Ysize = Yres * mm_to_inch(PaperInfo[paper].h-100) / 10;
+ Xsize = (int)(Xres * mm_to_inch(PaperInfo[paper].w-100) / 160);
+ Ysize = (int)(Yres * mm_to_inch(PaperInfo[paper].h-100) / 10);
/* ----==== Allocate momory ====---- */
if (LineSize < Xsize*2+1) {
LineSize = Xsize*2+1;
----------------------------------------------------------------------
commit 58bee0ad2c67888a52fa02e31de3120673525fda
Author: Robin Watts <[email protected]>
Date: Fri Nov 15 18:48:26 2019 +0000
Squash a double -> float warning.
diff --git a/contrib/gdevdj9.c b/contrib/gdevdj9.c
index ef53373..af0ef5b 100644
--- a/contrib/gdevdj9.c
+++ b/contrib/gdevdj9.c
@@ -684,7 +684,7 @@ cdj970_put_params(gx_device * pdev, gs_param_list * plist)
return code;
if ((code = cdj_put_param_int(plist, "Duplex", &duplex, 0, 2, code)) < 0)
return code;
- if ((code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0, code)) < 0)
+ if ((code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1f, 9.0, code)) < 0)
return code;
if ((code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code)) < 0)
return code;
----------------------------------------------------------------------
commit 372e4f29d3fcbfeaa83a5ee8cc530cbb948edab7
Author: Robin Watts <[email protected]>
Date: Wed Nov 13 18:08:20 2019 +0000
Squash a warning in gdevcif due to dropping const.
diff --git a/devices/gdevcif.c b/devices/gdevcif.c
index 7de92e8..66f61ce 100644
--- a/devices/gdevcif.c
+++ b/devices/gdevcif.c
@@ -46,7 +46,8 @@ cif_print_page(gx_device_printer *pdev, gp_file *prn_stream)
{ int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
int lnum;
byte *in = (byte *)gs_malloc(pdev->memory, line_size, 1, "cif_print_page(in)");
- char *s, *fname;
+ char *s;
+ const char *fname;
int scanline, scanbyte;
int length, start; /* length is the number of successive 1 bits, */
/* start is the set of 1 bit start position */
@@ -58,7 +59,7 @@ cif_print_page(gx_device_printer *pdev, gp_file *prn_stream)
#ifdef CLUSTER
fname = "clusterout";
#else
- fname = (char *)(pdev->fname);
+ fname = (const char *)(pdev->fname);
#endif
if ((s = strchr(fname, '.')) == NULL)
length = strlen(fname) + 1;
Summary of changes:
base/spwgd.c | 11 +-
contrib/gdevdj9.c | 2 +-
contrib/japanese/gdevlbp3.c | 4 +-
devices/gdevcif.c | 5 +-
gpdl/gpdl.mak | 15 +-
gpdl/pwg/pwgtop.c | 718 ++++++++++++++++++++++++++++++++++++++++++++
jpegxr/cw_emit.c | 2 +-
pcl/pl/plimpl.c | 5 +
windows/ghostpdl.vcproj | 10 +-
9 files changed, 761 insertions(+), 11 deletions(-)
create mode 100644 gpdl/pwg/pwgtop.c