diff options
Diffstat (limited to 'fitz/res_pixmap.c')
-rw-r--r-- | fitz/res_pixmap.c | 86 |
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 |