summaryrefslogtreecommitdiff
path: root/xps
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-01-26 16:22:29 +0000
committerRobin Watts <robin.watts@artifex.com>2012-01-26 19:24:12 +0000
commit4a61e49b6eda6c9f74c8010548f529385a5ade5e (patch)
tree9d9fd82495c8d3b1a00ff3ef0dcd01f0f7147b21 /xps
parent50dbc1a356577f3df15a876f6adb716dea29bdc5 (diff)
downloadmupdf-4a61e49b6eda6c9f74c8010548f529385a5ade5e.tar.xz
Pull in XPS commits from GhostXPS to MuXPS
This brings MuXPS up to date with GhostXPS as of today. The commits pulled in are: 856ecdc Whitespace fixes for parsing dashed line attributes 91dc749 Whitespace fixes while parsing points. This commit is tweaked from the original, and the changes will be pushed back into GhostXPS shortly. a298a05 Tiff premultiplied/non-premultiped alpha differences. No changes required for this, as we hold images premultiplied already (and already cope with premultiplying where required). Some changes to comments and cleanup code to avoid leaks though.
Diffstat (limited to 'xps')
-rw-r--r--xps/muxps.h6
-rw-r--r--xps/xps_gradient.c8
-rw-r--r--xps/xps_path.c53
-rw-r--r--xps/xps_tiff.c92
4 files changed, 104 insertions, 55 deletions
diff --git a/xps/muxps.h b/xps/muxps.h
index 96a8a1eb..c708ac60 100644
--- a/xps/muxps.h
+++ b/xps/muxps.h
@@ -255,4 +255,10 @@ xps_document *xps_open_file(fz_context *ctx, char *filename);
xps_document *xps_open_stream(fz_stream *file);
void xps_free_context(xps_document *doc);
+/*
+ * Parsing helper functions
+ */
+char *xps_get_real_params(char *s, int num, float *x);
+char *xps_get_point(char *s_in, float *x, float *y);
+
#endif
diff --git a/xps/xps_gradient.c b/xps/xps_gradient.c
index 7533c4d3..f0ad0104 100644
--- a/xps/xps_gradient.c
+++ b/xps/xps_gradient.c
@@ -318,9 +318,9 @@ xps_draw_radial_gradient(xps_document *doc, fz_matrix ctm,
yrad = 1.0;
if (origin_att)
- sscanf(origin_att, "%g,%g", &x0, &y0);
+ xps_get_point(origin_att, &x0, &y0);
if (center_att)
- sscanf(center_att, "%g,%g", &x1, &y1);
+ xps_get_point(center_att, &x1, &y1);
if (radius_x_att)
xrad = fz_atof(radius_x_att);
if (radius_y_att)
@@ -362,9 +362,9 @@ xps_draw_linear_gradient(xps_document *doc, fz_matrix ctm,
x1 = y1 = 1;
if (start_point_att)
- sscanf(start_point_att, "%g,%g", &x0, &y0);
+ xps_get_point(start_point_att, &x0, &y0);
if (end_point_att)
- sscanf(end_point_att, "%g,%g", &x1, &y1);
+ xps_get_point(end_point_att, &x1, &y1);
xps_draw_one_linear_gradient(doc, ctm, stops, count, 1, x0, y0, x1, y1);
}
diff --git a/xps/xps_path.c b/xps/xps_path.c
index 8b66e1ff..e3dff868 100644
--- a/xps/xps_path.c
+++ b/xps/xps_path.c
@@ -1,6 +1,41 @@
#include "fitz.h"
#include "muxps.h"
+char *
+xps_get_real_params(char *s, int num, float *x)
+{
+ int k = 0;
+
+ if (s == NULL || *s == 0)
+ return NULL;
+
+ while (*s)
+ {
+ while (*s == 0x0d || *s == '\t' || *s == ' ' || *s == 0x0a)
+ s++;
+ x[k] = (float)strtod(s, &s);
+ while (*s == 0x0d || *s == '\t' || *s == ' ' || *s == 0x0a)
+ s++;
+ if (*s == ',')
+ s++;
+ if (++k == num)
+ break;
+ }
+ return s;
+}
+
+char *
+xps_get_point(char *s_in, float *x, float *y)
+{
+ char *s_out = s_in;
+ float xy[2];
+
+ s_out = xps_get_real_params(s_out, 2, &xy[0]);
+ *x = xy[0];
+ *y = xy[1];
+ return s_out;
+}
+
static fz_point
fz_currentpoint(fz_path *path)
{
@@ -475,8 +510,8 @@ xps_parse_arc_segment(fz_context *doc, fz_path *path, xml_element *root, int str
if (!is_stroked)
*skipped_stroke = 1;
- sscanf(point_att, "%g,%g", &point_x, &point_y);
- sscanf(size_att, "%g,%g", &size_x, &size_y);
+ xps_get_point(point_att, &point_x, &point_y);
+ xps_get_point(size_att, &size_x, &size_y);
rotation_angle = fz_atof(rotation_angle_att);
is_large_arc = !strcmp(is_large_arc_att, "true");
is_clockwise = !strcmp(sweep_direction_att, "Clockwise");
@@ -518,8 +553,7 @@ xps_parse_poly_quadratic_bezier_segment(fz_context *doc, fz_path *path, xml_elem
while (*s != 0)
{
while (*s == ' ') s++;
- sscanf(s, "%g,%g", &x[n], &y[n]);
- while (*s != ' ' && *s != 0) s++;
+ s = xps_get_point(s, &x[n], &y[n]);
n ++;
if (n == 2)
{
@@ -567,8 +601,7 @@ xps_parse_poly_bezier_segment(fz_context *doc, fz_path *path, xml_element *root,
while (*s != 0)
{
while (*s == ' ') s++;
- sscanf(s, "%g,%g", &x[n], &y[n]);
- while (*s != ' ' && *s != 0) s++;
+ s = xps_get_point(s, &x[n], &y[n]);
n ++;
if (n == 3)
{
@@ -606,12 +639,11 @@ xps_parse_poly_line_segment(fz_context *doc, fz_path *path, xml_element *root, i
while (*s != 0)
{
while (*s == ' ') s++;
- sscanf(s, "%g,%g", &x, &y);
+ s = xps_get_point(s, &x, &y);
if (stroking && !is_stroked)
fz_moveto(doc, path, x, y);
else
fz_lineto(doc, path, x, y);
- while (*s != ' ' && *s != 0) s++;
}
}
@@ -640,7 +672,7 @@ xps_parse_path_figure(fz_context *doc, fz_path *path, xml_element *root, int str
if (is_filled_att)
is_filled = !strcmp(is_filled_att, "true");
if (start_point_att)
- sscanf(start_point_att, "%g,%g", &start_x, &start_y);
+ xps_get_point(start_point_att, &start_x, &start_y);
if (!stroking && !is_filled) /* not filled, when filling */
return;
@@ -910,7 +942,8 @@ xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *d
{
while (*s == ' ')
s++;
- stroke.dash_list[stroke.dash_len++] = fz_atof(s) * stroke.linewidth;
+ if (*s) /* needed in case of a space before the last quote */
+ stroke.dash_list[stroke.dash_len++] = fz_atof(s) * stroke.linewidth;
while (*s && *s != ' ')
s++;
}
diff --git a/xps/xps_tiff.c b/xps/xps_tiff.c
index b7d8ee04..9fae5e2d 100644
--- a/xps/xps_tiff.c
+++ b/xps/xps_tiff.c
@@ -503,6 +503,20 @@ xps_decode_tiff_strips(struct tiff *tiff)
p += tiff->stride;
}
}
+
+ /* Premultiplied transparency */
+ if (tiff->extrasamples == 1)
+ {
+ /* In GhostXPS we undo the premultiplication here; muxps holds
+ * all our images premultiplied by default, so nothing to do.
+ */
+ }
+
+ /* Non-premultiplied transparency */
+ if (tiff->extrasamples == 2)
+ {
+ /* Premultiplied files are corrected for elsewhere */
+ }
}
static inline int readbyte(struct tiff *tiff)
@@ -765,62 +779,58 @@ xps_decode_tiff(fz_context *ctx, byte *buf, int len)
fz_pixmap *image;
struct tiff tiff;
- xps_decode_tiff_header(ctx, &tiff, buf, len);
-
- /* Decode the image strips */
+ fz_try(ctx)
+ {
+ xps_decode_tiff_header(ctx, &tiff, buf, len);
- if (tiff.rowsperstrip > tiff.imagelength)
- tiff.rowsperstrip = tiff.imagelength;
+ /* Decode the image strips */
- xps_decode_tiff_strips(&tiff);
+ if (tiff.rowsperstrip > tiff.imagelength)
+ tiff.rowsperstrip = tiff.imagelength;
- /* Byte swap 16-bit images to big endian if necessary */
- if (tiff.bitspersample == 16)
- if (tiff.order == TII)
- xps_swap_byte_order(tiff.samples, tiff.imagewidth * tiff.imagelength * tiff.samplesperpixel);
+ xps_decode_tiff_strips(&tiff);
- /* Expand into fz_pixmap struct */
+ /* Byte swap 16-bit images to big endian if necessary */
+ if (tiff.bitspersample == 16)
+ if (tiff.order == TII)
+ xps_swap_byte_order(tiff.samples, tiff.imagewidth * tiff.imagelength * tiff.samplesperpixel);
- fz_try(ctx)
- {
+ /* Expand into fz_pixmap struct */
image = fz_new_pixmap(tiff.ctx, tiff.colorspace, tiff.imagewidth, tiff.imagelength);
+ image->xres = tiff.xresolution;
+ image->yres = tiff.yresolution;
+
+ fz_unpack_tile(image, tiff.samples, tiff.samplesperpixel, tiff.bitspersample, tiff.stride, 0);
+
+ /* We should only do this on non-pre-multiplied images, but files in the wild are bad */
+ if (tiff.extrasamples /* == 2 */)
+ {
+ /* CMYK is a subtractive colorspace, we want additive for premul alpha */
+ if (image->n == 5)
+ {
+ fz_pixmap *rgb = fz_new_pixmap(tiff.ctx, fz_device_rgb, image->w, image->h);
+ fz_convert_pixmap(tiff.ctx, image, rgb);
+ rgb->xres = image->xres;
+ rgb->yres = image->yres;
+ fz_drop_pixmap(ctx, image);
+ image = rgb;
+ }
+ fz_premultiply_pixmap(image);
+ }
}
- fz_catch(ctx)
+ fz_always(ctx)
{
+ /* Clean up scratch memory */
if (tiff.colormap) fz_free(ctx, tiff.colormap);
if (tiff.stripoffsets) fz_free(ctx, tiff.stripoffsets);
if (tiff.stripbytecounts) fz_free(ctx, tiff.stripbytecounts);
if (tiff.samples) fz_free(ctx, tiff.samples);
- fz_throw(ctx, "out of memory");
+ if (tiff.profile) fz_free(ctx, tiff.profile);
}
-
- image->xres = tiff.xresolution;
- image->yres = tiff.yresolution;
-
- fz_unpack_tile(image, tiff.samples, tiff.samplesperpixel, tiff.bitspersample, tiff.stride, 0);
-
- /* We should only do this on non-pre-multiplied images, but files in the wild are bad */
- if (tiff.extrasamples /* == 2 */)
+ fz_catch(ctx)
{
- /* CMYK is a subtractive colorspace, we want additive for premul alpha */
- if (image->n == 5)
- {
- fz_pixmap *rgb = fz_new_pixmap(tiff.ctx, fz_device_rgb, image->w, image->h);
- fz_convert_pixmap(tiff.ctx, image, rgb);
- rgb->xres = image->xres;
- rgb->yres = image->yres;
- fz_drop_pixmap(ctx, image);
- image = rgb;
- }
- fz_premultiply_pixmap(image);
+ fz_throw(ctx, "out of memory");
}
- /* Clean up scratch memory */
-
- if (tiff.colormap) fz_free(ctx, tiff.colormap);
- if (tiff.stripoffsets) fz_free(ctx, tiff.stripoffsets);
- if (tiff.stripbytecounts) fz_free(ctx, tiff.stripbytecounts);
- if (tiff.samples) fz_free(ctx, tiff.samples);
-
return image;
}