From b8efb1cf3ce4c57fd4a0396c2a9102630d3d6e36 Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor.andersson@artifex.com>
Date: Tue, 22 Mar 2011 18:26:07 +0100
Subject: xps: import ghostxps source

---
 xps/xpsjpeg.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 143 insertions(+)
 create mode 100644 xps/xpsjpeg.c

(limited to 'xps/xpsjpeg.c')

diff --git a/xps/xpsjpeg.c b/xps/xpsjpeg.c
new file mode 100644
index 00000000..878fd85a
--- /dev/null
+++ b/xps/xpsjpeg.c
@@ -0,0 +1,143 @@
+/* Copyright (C) 2006-2010 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 that
+   license.  Refer to licensing information at http://www.artifex.com/
+   or contact Artifex Software, Inc.,  7 Mt. Lassen  Drive - Suite A-134,
+   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* XPS interpreter - JPEG image support */
+
+#include "ghostxps.h"
+
+#include "stream.h"
+#include "strimpl.h"
+#include "gsstate.h"
+#include "jpeglib_.h"
+#include "sdct.h"
+#include "sjpeg.h"
+
+static int
+xps_report_error(stream_state * st, const char *str)
+{
+	(void) gs_throw1(-1, "%s", str);
+	return 0;
+}
+
+int
+xps_decode_jpeg(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
+{
+	jpeg_decompress_data jddp;
+	stream_DCT_state state;
+	stream_cursor_read rp;
+	stream_cursor_write wp;
+	int code;
+	int wlen;
+	byte *wbuf;
+	jpeg_saved_marker_ptr curr_marker;
+
+	s_init_state((stream_state*)&state, &s_DCTD_template, ctx->memory);
+	state.report_error = xps_report_error;
+
+	s_DCTD_template.set_defaults((stream_state*)&state);
+
+	state.jpeg_memory = ctx->memory;
+	state.data.decompress = &jddp;
+
+	jddp.template = s_DCTD_template;
+	jddp.memory = ctx->memory;
+	jddp.scanline_buffer = NULL;
+
+	if ((code = gs_jpeg_create_decompress(&state)) < 0)
+		return gs_throw(-1, "cannot gs_jpeg_create_decompress");
+
+	s_DCTD_template.init((stream_state*)&state);
+
+	rp.ptr = rbuf - 1;
+	rp.limit = rbuf + rlen - 1;
+
+	/* read the header only by not having a write buffer */
+	wp.ptr = 0;
+	wp.limit = 0;
+
+	/* Set up to save the ICC marker APP2.
+	 * According to the spec we should be getting APP1 APP2 and APP13.
+	 * Library gets APP0 and APP14. */
+	jpeg_save_markers(&(jddp.dinfo), 0xe2, 0xFFFF);
+
+	code = s_DCTD_template.process((stream_state*)&state, &rp, &wp, true);
+	if (code != 1)
+		return gs_throw(-1, "premature EOF or error in jpeg");
+
+	/* Check if we had an ICC profile */
+	curr_marker = jddp.dinfo.marker_list;
+	while (curr_marker != NULL)
+	{
+		if (curr_marker->marker == 0xe2)
+		{
+			/* Found ICC profile. Create a buffer and copy over now.
+			 * Strip JPEG APP2 14 byte header */
+			image->profilesize = curr_marker->data_length - 14;
+			image->profile = xps_alloc(ctx, image->profilesize);
+			if (image->profile)
+			{
+				/* If we can't create it, just ignore */
+				memcpy(image->profile, &(curr_marker->data[14]), image->profilesize);
+			}
+			break;
+		}
+		curr_marker = curr_marker->next;
+	}
+
+	image->width = jddp.dinfo.output_width;
+	image->height = jddp.dinfo.output_height;
+	image->comps = jddp.dinfo.output_components;
+	image->bits = 8;
+	image->stride = image->width * image->comps;
+
+	if (image->comps == 1)
+		image->colorspace = ctx->gray;
+	if (image->comps == 3)
+		image->colorspace = ctx->srgb;
+	if (image->comps == 4)
+		image->colorspace = ctx->cmyk;
+
+	if (jddp.dinfo.density_unit == 1)
+	{
+		image->xres = jddp.dinfo.X_density;
+		image->yres = jddp.dinfo.Y_density;
+	}
+	else if (jddp.dinfo.density_unit == 2)
+	{
+		image->xres = jddp.dinfo.X_density * 2.54;
+		image->yres = jddp.dinfo.Y_density * 2.54;
+	}
+	else
+	{
+		image->xres = 96;
+		image->yres = 96;
+	}
+
+	wlen = image->stride * image->height;
+	wbuf = xps_alloc(ctx, wlen);
+	if (!wbuf)
+		return gs_throw1(-1, "out of memory allocating samples: %d", wlen);
+
+	image->samples = wbuf;
+
+	wp.ptr = wbuf - 1;
+	wp.limit = wbuf + wlen - 1;
+
+	code = s_DCTD_template.process((stream_state*)&state, &rp, &wp, true);
+	if (code != EOFC)
+		return gs_throw1(-1, "error in jpeg (code = %d)", code);
+
+	gs_jpeg_destroy(&state);
+
+	return gs_okay;
+}
-- 
cgit v1.2.3