summaryrefslogtreecommitdiff
path: root/fitz/res_pixmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fitz/res_pixmap.c')
-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