diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-01-26 16:22:29 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-01-26 19:24:12 +0000 |
commit | 4a61e49b6eda6c9f74c8010548f529385a5ade5e (patch) | |
tree | 9d9fd82495c8d3b1a00ff3ef0dcd01f0f7147b21 /xps | |
parent | 50dbc1a356577f3df15a876f6adb716dea29bdc5 (diff) | |
download | mupdf-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.h | 6 | ||||
-rw-r--r-- | xps/xps_gradient.c | 8 | ||||
-rw-r--r-- | xps/xps_path.c | 53 | ||||
-rw-r--r-- | xps/xps_tiff.c | 92 |
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; } |