summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-06-08 20:46:58 +0100
committerRobin Watts <robin.watts@artifex.com>2012-06-08 20:46:58 +0100
commitb42125b79edc28af6508145a24308674403a8460 (patch)
treec705cb39f6ecf7493f69a2a6dab0a8fcaa8d350b /fitz
parent65b8ae915465849babc1fa712971c701136f4ed5 (diff)
downloadmupdf-b42125b79edc28af6508145a24308674403a8460.tar.xz
Fix Bug 693097; memory overwrite when handling knockout groups.
When handling knockout groups, we have to copy the background from the previous group in so we can 'knockout' properly. If the previous group is a different colorspace, this gives us problems! The fix, implemented here, is to update the copy_pixmap_rect function to know how to copy between pixmaps of different depth. Gray <-> RGB are the ones we really care about; the generic code will probably do a horrible job, but shouldn't ever be called at present. This suffices to stop the crashing - we will probably revisit this when we revise the blending support.
Diffstat (limited to 'fitz')
-rw-r--r--fitz/res_pixmap.c86
1 files changed, 79 insertions, 7 deletions
diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c
index a160b6ca..29dd95a0 100644
--- a/fitz/res_pixmap.c
+++ b/fitz/res_pixmap.c
@@ -165,7 +165,7 @@ fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_bbox r)
{
const unsigned char *srcp;
unsigned char *destp;
- int y, w, destspan, srcspan;
+ int x, y, w, destspan, srcspan;
r = fz_intersect_bbox(r, fz_pixmap_bbox(ctx, dest));
r = fz_intersect_bbox(r, fz_pixmap_bbox(ctx, src));
@@ -174,18 +174,90 @@ fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_bbox r)
if (w <= 0 || y <= 0)
return;
- w *= src->n;
srcspan = src->w * src->n;
srcp = src->samples + srcspan * (r.y0 - src->y) + src->n * (r.x0 - src->x);
destspan = dest->w * dest->n;
destp = dest->samples + destspan * (r.y0 - dest->y) + dest->n * (r.x0 - dest->x);
- do
+
+ if (src->n == dest->n)
+ {
+ w *= src->n;
+ do
+ {
+ memcpy(destp, srcp, w);
+ srcp += srcspan;
+ destp += destspan;
+ }
+ while (--y);
+ }
+ else if (src->n == 2 && dest->n == 4)
+ {
+ /* Copy, and convert from grey+alpha to rgb+alpha */
+ srcspan -= w*2;
+ destspan -= w*4;
+ do
+ {
+ for (x = w; x > 0; x--)
+ {
+ unsigned char v = *srcp++;
+ unsigned char a = *srcp++;
+ *destp++ = v;
+ *destp++ = v;
+ *destp++ = v;
+ *destp++ = a;
+ }
+ srcp += srcspan;
+ destp += destspan;
+ }
+ while (--y);
+ }
+ else if (src->n == 4 && dest->n == 2)
{
- memcpy(destp, srcp, w);
- srcp += srcspan;
- destp += destspan;
+ /* Copy, and convert from rgb+alpha to grey+alpha */
+ srcspan -= w*4;
+ destspan -= w*2;
+ do
+ {
+ for (x = w; x > 0; x--)
+ {
+ int v;
+ v = *srcp++;
+ v += *srcp++;
+ v += *srcp++;
+ *destp++ = (unsigned char)((v+1)/3);
+ *destp++ = *srcp++;
+ }
+ srcp += srcspan;
+ destp += destspan;
+ }
+ while (--y);
+ }
+ else
+ {
+ /* FIXME: Crap conversion */
+ int z;
+ int sn = src->n-1;
+ int dn = dest->n-1;
+
+ srcspan -= w*src->n;
+ destspan -= w*dest->n;
+ do
+ {
+ for (x = w; x > 0; x--)
+ {
+ int v = 0;
+ for (z = sn; z > 0; z--)
+ v += *srcp++;
+ v = (v * dn + (sn>>1)) / sn;
+ for (z = dn; z > 0; z--)
+ *destp++ = (unsigned char)v;
+ *destp++ = *srcp++;
+ }
+ srcp += srcspan;
+ destp += destspan;
+ }
+ while (--y);
}
- while (--y);
}
void