summaryrefslogtreecommitdiff
path: root/met/metimage.c
diff options
context:
space:
mode:
Diffstat (limited to 'met/metimage.c')
-rw-r--r--met/metimage.c536
1 files changed, 0 insertions, 536 deletions
diff --git a/met/metimage.c b/met/metimage.c
deleted file mode 100644
index 3b529dde0..000000000
--- a/met/metimage.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/* Portions Copyright (C) 2001 artofcode LLC.
- Portions Copyright (C) 1996, 2001, 2005 Artifex Software Inc.
- Portions Copyright (C) 1988, 2000 Aladdin Enterprises.
- This software is based in part on the work of the Independent JPEG Group.
- All Rights Reserved.
-
- 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., 101 Lucas Valley Road #110,
- San Rafael, CA 94903, (415)492-9861, for further information. */
-
-/*$Id$*/
-
-/* image related elements */
-
-/* element constructor */
-
-#include "memory_.h"
-#include "gsmemory.h"
-#include "gsmatrix.h"
-#include "gp.h"
-#include "metcomplex.h"
-#include "metelement.h"
-#include "metutil.h"
-#include "math_.h"
-#include "metimage.h"
-#include "metgstate.h"
-#include "ctype_.h"
-#include "gsimage.h"
-#include "gscspace.h"
-#include "gsptype1.h"
-#include "gscoord.h"
-#include "gscolor2.h"
-#include <stdlib.h> /* nb for atof */
-#include "strimpl.h"
-#include "scommon.h"
-#include "jpeglib_.h" /* for jpeg filter */
-#include "sdct.h"
-#include "sjpeg.h"
-#include "zipparse.h"
-#include "gxstate.h" /* for gs_state_memory() */
-#include "gdebug.h"
-#include "gsutil.h"
-
-private int
-ImageBrush_cook(void **ppdata, met_state_t *ms, const char *el, const char **attr)
-{
- CT_ImageBrush *aImageBrush =
- (CT_ImageBrush *)gs_alloc_bytes(ms->memory,
- sizeof(CT_ImageBrush),
- "ImageBrush_cook");
- int i;
-
- memset(aImageBrush, 0, sizeof(CT_ImageBrush));
-
-#define MYSET(field, value) \
- met_cmp_and_set((field), attr[i], attr[i+1], (value))
-
- /* parse attributes, filling in the zeroed out C struct */
- for(i = 0; attr[i]; i += 2) {
- if (!MYSET(&aImageBrush->Key, "Key"))
- ;
- else if (!MYSET(&aImageBrush->Transform, "Transform"))
- ;
- else if (!MYSET(&aImageBrush->Viewbox, "Viewbox"))
- ;
- else if (!MYSET(&aImageBrush->Viewport, "Viewport"))
- ;
- else if (!MYSET(&aImageBrush->Fill, "Fill"))
- ;
- else if (!MYSET(&aImageBrush->TileMode, "TileMode"))
- ;
- else if (!MYSET(&aImageBrush->ViewboxUnits, "ViewboxUnits"))
- ;
- else if (!MYSET(&aImageBrush->ViewportUnits, "ViewportUnits"))
- ;
- else if (!MYSET(&aImageBrush->ImageSource, "ImageSource"))
- ;
- else {
- gs_warn2("unsupported attribute %s=%s",
- attr[i], attr[i+1]);
- }
- }
-
- /* copy back the data for the parser. */
- *ppdata = aImageBrush;
- return 0;
-}
-
-/* temporary code to read raster format. reads the whole works. NB
- */
-private int
-readdata(gs_memory_t *mem, zip_state_t *pzip, ST_Name ImageSource, byte **bufp, int *lenp)
-{
- byte *buf;
- ulong len = 0;
- zip_part_t *part = find_zip_part_by_name(pzip, ImageSource);
-
- if (part == NULL)
- return gs_throw1(-1,"Image part not found %s", ImageSource);
-
- len = zip_part_length(part);
-
- buf = gs_alloc_bytes(mem, len, "xps_readdata buffer");
- if ( buf == 0 ) {
- return -1;
- }
-
- zip_part_seek(part, 0, 0);
- if ( len != zip_part_read(buf, len, part) ) {
- return gs_throw(-1, "zip_part_read len wrong");
- }
-
- *bufp = buf;
- *lenp = len;
-#define NO_PNG_TO_JPEG_HACK 1
-#ifndef NO_PNG_TO_JPEG_HACK
- /* NB: this converts PNG to JPEGS on the fly using /tmp/foo.png and /tmp/foo.jpg
- * NB: also converts TIFF to jpg
- * NB: file name extension detection is weak,
- * file data inspection would be much better.
- */
-
- {
- const char *ctif_convert = "/usr/bin/convert /tmp/foo.tif /tmp/foo.jpg";
- const char *ctif = "/tmp/foo.tif";
- const char *cpng_convert = "/usr/bin/convert /tmp/foo.png /tmp/foo.jpg";
- const char *cpng = "/tmp/foo.png";
- char *imgStr;
- char *convertStr;
- bool doit = false;
-
- if (0 == strncasecmp(&ImageSource[strlen(ImageSource) -5], "tiff", 4 )) {
- imgStr = ctif;
- convertStr = ctif_convert;
- doit = true;
- }
-
- else if (0 == strncasecmp(&ImageSource[strlen(ImageSource) -4], "png", 3 )); {
- imgStr = cpng;
- convertStr = cpng_convert;
- doit = true;
- }
-
- if (doit) {
- FILE *in = fopen(imgStr, "w");
- fwrite(buf, 1, len, in);
- fclose(in);
-
- system( convertStr );
-
- in = fopen("/tmp/foo.jpg", "r");
- if (in == NULL)
- return gs_throw(-1, "/tmp/foo.jpg file open failed");
- len = (fseek(in, 0L, SEEK_END), ftell(in));
- rewind(in);
- gs_free_object(mem, buf, "readdata");
- buf = gs_alloc_bytes(mem, len, "readdata");
- if (!buf)
- return -1;
- fread(buf, 1, len, in);
- fclose(in);
- *bufp = buf;
- *lenp = len;
- }
- }
-#endif
- /* NB no deletion of images,
- * NB should process once and use many not read many
- */
-
- return 0;
-}
-
-int
-met_PaintPattern(const gs_client_color *pcc, gs_state *pgs)
-{
- gs_memory_t *mem = gs_state_memory(pgs);
- const gs_client_pattern *ppat = gs_getpattern(pcc);
- const met_pattern_t *pmpat = ppat->client_data;
- int code;
-
- /* if it's a gradient brush */
- if (!pmpat->raster_image)
- {
- gs_gsave(pgs);
- if (pmpat->linear)
- code = LinearGradientBrush_paint(pmpat->linear, pgs);
- if (pmpat->radial)
- code = RadialGradientBrush_paint(pmpat->radial, pgs);
- if (pmpat->visual)
- code = VisualBrush_paint(pmpat->visual, pgs);
- gs_grestore(pgs);
- if (code < 0)
- return gs_rethrow(code, "could not paint gradient pattern");
- return gs_okay;
- }
-
- const xps_image_t *pmim = pmpat->raster_image;
- const byte *pdata = pmim->samples;
- gs_image_enum *penum;
- gs_color_space color_space;
- gs_image_t image;
- uint imbytes = pmim->stride * pmim->height;
- uint used;
-
-
- if (gs_debug_c('b'))
- dprintf5("paint_image cs=%d n=%d bpc=%d w=%d h=%d\n",
- pmim->colorspace, pmim->comps, pmim->bits, pmim->width, pmim->height);
-
- /* should be just save the ctm */
- gs_gsave(pgs);
- gs_scale(pgs, 96.0/pmim->xres, 96.0/pmim->yres);
-
- switch (pmim->colorspace)
- {
- case XPS_GRAY:
- gs_cspace_init_DeviceGray(mem, &color_space);
- break;
- case XPS_RGB:
- gs_cspace_init_DeviceRGB(mem, &color_space);
- break;
- case XPS_CMYK:
- gs_cspace_init_DeviceCMYK(mem, &color_space);
- break;
- default:
- return gs_throw(-1, "cannot handle images with alpha channels");
- }
-
- gs_image_t_init(&image, &color_space);
- image.ColorSpace = &color_space;
- image.BitsPerComponent = pmim->bits;
- image.Width = pmim->width;
- image.Height = pmim->height;
-
- penum = gs_image_enum_alloc(mem, "met_PaintPattern");
- if (!penum)
- return gs_throw(-1, "gs_enum_allocate failed");
-
- if ((code = gs_image_init(penum, &image, false, pgs)) < 0)
- return gs_throw(code, "gs_image_init failed");
-
- if ((code = gs_image_next(penum, pdata, imbytes, &used)) < 0)
- return gs_throw(code, "gs_image_next failed");
-
- if (imbytes < used)
- return gs_throw2(-1, "not enough image data (image=%d used=%d)", imbytes, used);
- if (imbytes > used)
- return gs_throw2(0, "too much image data (image=%d used=%d)", imbytes, used);
-
- gs_image_cleanup(penum, pgs);
- gs_free_object(mem, penum, "px_paint_pattern");
- gs_grestore(pgs);
-
- return gs_okay;
-}
-
-
-
-/*
- * Strip alpha channel from an image
- */
-private void
-xps_strip_alpha(xps_image_t *image)
-{
- int cs = image->colorspace;
- int n = image->comps;
- int y, x, k;
- byte *sp, *dp;
-
- if (image->bits != 8)
- {
- gs_warn1("cannot strip alpha from %dbpc images", image->bits);
- return;
- }
-
- if ((cs != XPS_GRAY_A) && (cs != XPS_RGB_A) && (cs != XPS_CMYK_A))
- return;
-
- for (y = 0; y < image->height; y++)
- {
- sp = image->samples + image->width * n * y;
- dp = image->samples + image->width * (n - 1) * y;
- for (x = 0; x < image->width; x++)
- {
- for (k = 0; k < n - 1; k++)
- *dp++ = *sp++;
- sp++;
- }
- }
-
- image->colorspace --;
- image->comps --;
- image->stride = (n - 1) * image->width;
-}
-
-/*
- * Switch on file magic to decode an image.
- */
-
-private int
-xps_decode_image(gs_memory_t *mem, byte *rbuf, int rlen, xps_image_t *image)
-{
- int error;
-
- if (rbuf[0] == 0xff && rbuf[1] == 0xd8)
- error = xps_decode_jpeg(mem, rbuf, rlen, image);
- else if (memcmp(rbuf, "\211PNG\r\n\032\n", 8) == 0)
- error = xps_decode_png(mem, rbuf, rlen, image);
- else if (memcmp(rbuf, "MM", 2) == 0)
- error = xps_decode_tiff(mem, rbuf, rlen, image);
- else if (memcmp(rbuf, "II", 2) == 0)
- error = xps_decode_tiff(mem, rbuf, rlen, image);
- else
- error = gs_throw(-1, "unknown image file format");
-
- if (error)
- return gs_rethrow(error, "could not decode image");
-
- /* NB: strip out alpha until we can handle it */
- xps_strip_alpha(image);
- return gs_okay;
-}
-
-
-/* NB for the demo we render and set the pattern in the graphics
- state */
-private int
-make_pattern(ST_Name ImageSource, met_pattern_t *metpat, met_state_t *ms)
-{
- byte *rbuf; /* raster buffer */
- int rlen;
- int code;
- gs_client_pattern gspat;
- gs_client_color gscolor;
- gs_memory_t *mem = ms->memory;
-
- code = readdata(mem, ms->pzip, ImageSource, &rbuf, &rlen);
- if (code < 0)
- return gs_rethrow(code, "read image data failed");
-
- code = xps_decode_image(mem, rbuf, rlen, metpat->raster_image);
- if (code < 0)
- {
- gs_free_object(mem, rbuf, "readdata");
- return gs_rethrow(code, "decode image data failed");
- }
-
- gs_free_object(mem, rbuf, "readdata");
-
- gs_pattern1_init(&gspat);
- uid_set_UniqueID(&gspat.uid, gs_next_ids(mem, 1));
- gspat.PaintType = 1;
- gspat.TilingType = 1;
-
- /* NB: Viewbox(0,0,0,0) appears to be legal, adjust to sane value */
- metpat->Viewbox.q.x = max( metpat->Viewbox.q.x, 1 );
- metpat->Viewbox.q.y = max( metpat->Viewbox.q.y, 1 );
-
- gspat.BBox.p.x = 0;
- gspat.BBox.p.y = 0;
- gspat.BBox.q.x = metpat->Viewbox.q.x - metpat->Viewbox.p.x;
- gspat.BBox.q.y = metpat->Viewbox.q.y - metpat->Viewbox.p.y;
-
- gspat.XStep = metpat->Viewbox.q.x - metpat->Viewbox.p.x;
- gspat.YStep = metpat->Viewbox.q.y - metpat->Viewbox.p.y;
- gspat.PaintProc = met_PaintPattern;
- gspat.client_data = (void *)metpat;
- {
- gs_matrix mat;
- gs_color_space cs;
- gs_state *pgs = ms->pgs;
- gs_rect vbox = metpat->Viewbox;
- gs_rect vport = metpat->Viewport;
- gs_gsave(pgs);
- /* resolution scaling is done when the pattern is painted */
- /* translate the viewbox to the origin, scale the viewbox to
- the viewport and translate the viewbox back. */
- gs_make_translation(vport.p.x, vport.p.y, &mat);
- {
- /* NB: don't scale smaller than a pixel */
- double scalex = max((1.00/( metpat->raster_image->xres)),
- ((vport.q.x - vport.p.x) / (vbox.q.x - vbox.p.x)));
- double scaley = max((1.00/( metpat->raster_image->yres)),
- ((vport.q.y - vport.p.y) / (vbox.q.y - vbox.p.y)));
- gs_matrix_scale(&mat, scalex, scaley, &mat);
- }
- gs_matrix_translate(&mat, -vbox.p.x, vbox.p.y, &mat);
-
- /* nb defaults to RGB */
- gs_cspace_init_DeviceRGB(mem, &cs);
- gs_setcolorspace(pgs, &cs);
- gs_makepattern(&gscolor, &gspat, &mat, pgs, NULL);
- gs_grestore(pgs);
- gs_setpattern(pgs, &gscolor);
- {
- met_path_child_t parent = met_currentpathchild(pgs);
- if (parent == met_fill)
- met_setpatternfill(pgs);
- else if (parent == met_stroke)
- met_setpatternstroke(pgs);
- else {
- gs_throw(-1, "pattern has no context");
- return -1;
- }
- }
- }
- return 0;
-}
-
-
-
-private bool is_Data_delimeter(char b)
-{
- return (b == ',') || (isspace(b));
-}
-
-/* action associated with this element */
-private int
-ImageBrush_action(void *data, met_state_t *ms)
-{
- /* create the pattern dictionary entry */
- CT_ImageBrush *aImageBrush = data;
- met_pattern_t *pat = (met_pattern_t *)gs_alloc_bytes(ms->memory,
- sizeof(met_pattern_t), "ImageBrush_action");
- xps_image_t *pim = (xps_image_t *)gs_alloc_bytes(ms->memory,
- sizeof(xps_image_t), "ImageBrush_action");
-
-
- if (!pat || !pim)
- return -1;
-
- pat->raster_image = pim;
- /* nb gcc'isms ahead */
- if (aImageBrush->Transform) {
- char transstring[strlen(aImageBrush->Transform)];
- strcpy(transstring, aImageBrush->Transform);
- /* nb wasteful */
- char *args[strlen(aImageBrush->Transform)];
- char **pargs = args;
- met_split(transstring, args, is_Data_delimeter);
- /* nb checking */
- pat->Transform.xx = atof(pargs[0]);
- pat->Transform.xy = atof(pargs[1]);
- pat->Transform.yx = atof(pargs[2]);
- pat->Transform.yy = atof(pargs[3]);
- pat->Transform.tx = atof(pargs[4]);
- pat->Transform.ty = atof(pargs[5]);
- }
-
- if (aImageBrush->Viewbox) {
- char viewbox[strlen(aImageBrush->Viewbox)];
- strcpy(viewbox, aImageBrush->Viewbox);
- /* nb wasteful */
- char *args[strlen(aImageBrush->Viewbox)];
- char **pargs = args;
- met_split(viewbox, args, is_Data_delimeter);
- pat->Viewbox.p.x = atof(pargs[0]);
- pat->Viewbox.p.y = atof(pargs[1]);
- pat->Viewbox.q.x = pat->Viewbox.p.x + atof(pargs[2]);
- pat->Viewbox.q.y = pat->Viewbox.p.y + atof(pargs[3]);
- /* the spec says if the viewbox extant is zero in both
- directions take a point sample. We are not exactly sure
- what this means. Here is one interpretation. */
- if ((pat->Viewbox.p.x == pat->Viewbox.q.x) &&
- (pat->Viewbox.p.y == pat->Viewbox.q.y)) {
- pat->Viewbox.q.x = pat->Viewbox.p.x + 1.0;
- pat->Viewbox.q.y = pat->Viewbox.q.y + 1.0;
- }
-
- }
- if (aImageBrush->Viewport) {
- /* do ever feel like your doing the same thing over and over
- again... */
- char viewport[strlen(aImageBrush->Viewport)];
- strcpy(viewport, aImageBrush->Viewport);
- /* nb wasteful */
- char *args[strlen(aImageBrush->Viewbox)];
- char **pargs = args;
- met_split(viewport, args, is_Data_delimeter);
- pat->Viewport.p.x = atof(pargs[0]);
- pat->Viewport.p.y = atof(pargs[1]);
- pat->Viewport.q.x = pat->Viewport.p.x + atof(pargs[2]);
- pat->Viewport.q.y = pat->Viewport.p.y + atof(pargs[3]);
- }
-
- if (aImageBrush->Transform) {
- char transform[strlen(aImageBrush->Transform)];
- char *args[strlen(aImageBrush->Transform)];
- strcpy(transform, aImageBrush->Transform);
- char **pargs = args;
- met_split(transform, args, is_Data_delimeter);
- pat->Transform.xx = atof(pargs[0]);
- pat->Transform.xy = atof(pargs[1]);
- pat->Transform.yx = atof(pargs[2]);
- pat->Transform.yy = atof(pargs[3]);
- pat->Transform.tx = atof(pargs[4]);
- pat->Transform.ty = atof(pargs[5]);
- }
- make_pattern(aImageBrush->ImageSource, pat, ms);
-
- return 0;
-}
-
-private int
-ImageBrush_done(void *data, met_state_t *ms)
-{
- CT_ImageBrush *aImageBrush = (CT_ImageBrush *)data;
-
- gs_free_object(ms->memory, aImageBrush->Key, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush->Transform, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush->Viewbox, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush->Viewport, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush->Fill, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush->TileMode, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush->ViewboxUnits, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush->ViewportUnits, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush->ImageSource, "ImageBrush_done");
- gs_free_object(ms->memory, aImageBrush, "ImageBrush_done");
-
- return 0; /* incomplete */
-}
-
-
-const met_element_t met_element_procs_ImageBrush = {
- "ImageBrush",
- {
- ImageBrush_cook,
- ImageBrush_action,
- ImageBrush_done
- }
-};
-
-