File mgp-alpha-channel.diff of Package mgp

---
 draw.c        |   35 +++++++++++++++++++++++++-
 image/image.h |    1 
 image/new.c   |    4 ++
 image/zoom.c  |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
 4 files changed, 109 insertions(+), 9 deletions(-)

--- a/draw.c
+++ b/draw.c
@@ -1966,6 +1966,13 @@ obj_image_color(image, bimage, d, inithi
 	return i;
 }
 
+static Pixel impose_pixel(Pixel fore, Pixel back, byte a)
+{
+	return RGB_TO_TRUE(TRUE_RED(fore) * a + TRUE_RED(back) * (255 - a),
+			   TRUE_GREEN(fore) * a + TRUE_GREEN(back) * (255 - a),
+			   TRUE_BLUE(fore) * a + TRUE_BLUE(back) * (255 - a));
+}
+
 static Image *
 obj_image_trans(image, x, y)
 	Image *image;
@@ -1980,6 +1987,7 @@ obj_image_trans(image, x, y)
 	int trans;
 	u_int bw, bh, bx, by;
 	int inithist;
+	byte *alpha = NULL;
 
 	if (!COMPLEX_BGIMAGE) {
 		if (back_color[caching] != xcol.pixel) {
@@ -1999,6 +2007,19 @@ obj_image_trans(image, x, y)
 			n = RGB_TO_TRUE(xcol.red, xcol.green, xcol.blue);
 			pl = image->pixlen;
 			p = image->data;
+			if (image->alpha) {
+				alpha = image->alpha;
+				for (j = 0; j < image->height; j++) {
+					for (i = 0; i < image->width; i++, p += pl) {
+						byte a = *alpha++;
+						if (a == 255)
+							continue;
+						d = impose_pixel(memToVal(p, pl), n, a);
+						valToMem(d, p, pl);
+					}
+				}
+				break;
+			}
 			for (j = 0; j < image->height; j++) {
 				for (i = 0; i < image->width; i++, p += pl) {
 					if (memToVal(p, pl) == d)
@@ -2024,6 +2045,8 @@ obj_image_trans(image, x, y)
 	}
 	pl = image->pixlen;
 	p = image->data + image->width * j * pl;
+	if (image->type == ITRUE && image->alpha)
+		alpha = image->alpha + image->width * j;
 	bpl = bgpixmap[bgindex].image->pixlen;
 	pd = -1;
 	n = 0;	/* for lint */
@@ -2040,6 +2063,16 @@ obj_image_trans(image, x, y)
 				b = bgpixmap[bgindex].image->data + 
 					bgpixmap[bgindex].image->width * by * bpl;
 			}
+			if (alpha) {
+				byte a = *alpha++;
+				if (a == 255)
+					continue;
+				d = impose_pixel(memToVal(p, pl),
+						 memToVal(b, bpl), a);
+				valToMem(d, p, pl);
+				continue;
+			}
+
 			if (memToVal(p, pl) != trans)
 				continue;
 			d = memToVal(b, bpl);
@@ -2099,7 +2132,7 @@ obj_draw_image(target, x, y, obj, page)
 		}
 		freeImage(timage);
 	}
-	if (image->trans >= 0)
+	if (image->trans >= 0 || image->alpha)
 		image = obj_image_trans(image, x, y);
 	obj->data.image.image = image;	/* to free later */
 	ximageinfo= imageToXImage(display, screen, visual, depth, image,
--- a/image/image.h
+++ b/image/image.h
@@ -90,6 +90,7 @@ typedef struct {
   unsigned int  depth;  /* depth of image in bits if IRGB type */
   unsigned int  pixlen; /* length of pixel if IRGB type */
   byte         *data;   /* data rounded to full byte for each row */
+  byte         *alpha;  /* optional alpha channel */
   int		trans;	/* transparent index in rgb */
 } Image;
 
--- a/image/new.c
+++ b/image/new.c
@@ -119,6 +119,7 @@ Image *newBitImage(width, height)
   linelen= (width / 8) + (width % 8 ? 1 : 0); /* thanx johnh@amcc.com */
   image->data= (unsigned char *)lcalloc(linelen * height);
   image->trans = -1;
+  image->alpha = NULL;
   return(image);
 }
 
@@ -141,6 +142,7 @@ Image *newRGBImage(width, height, depth)
   image->pixlen= pixlen;
   image->data= (unsigned char *)lmalloc(width * height * pixlen);
   image->trans = -1;
+  image->alpha = NULL;
   return(image);
 }
 
@@ -157,6 +159,7 @@ Image *newTrueImage(width, height)
   image->depth= 24;
   image->pixlen= 3;
   image->data= (unsigned char *)lmalloc(width * height * 3);
+  image->alpha = NULL;
   image->trans = -1;
   return(image);
 }
@@ -171,6 +174,7 @@ void freeImageData(image)
   if (!TRUEP(image))
     freeRGBMapData(&(image->rgb));
   lfree(image->data);
+  lfree(image->alpha);
 }
 
 void freeImage(image)
--- a/image/zoom.c
+++ b/image/zoom.c
@@ -58,6 +58,7 @@ static void resize_image(oimage, image)
   int i, j;
   byte *line1, *line2;
   byte *destptr;
+  byte *adest = NULL;
   unsigned int srclinelen;
   unsigned int pixlen;
   Pixel v[4];
@@ -68,6 +69,12 @@ static void resize_image(oimage, image)
   pixlen= oimage->pixlen;
   srclinelen= oimage->width * pixlen;
   destptr = image->data;
+  if (oimage->trans != -1 || oimage->alpha) {
+    image->trans = -1;
+    lfree(image->alpha);
+    image->alpha = lmalloc(image->width * image->height);
+    adest = image->alpha;
+  }
   cy = 0;
   xstep = (double)oimage->width / (double)image->width;
   ystep = (double)oimage->height / (double)image->height;
@@ -84,6 +91,8 @@ static void resize_image(oimage, image)
     line2 = oimage->data + srclinelen * y2;
     cx = 0;
     for (i = image->width; i > 0; i--) {
+      byte a[4];
+      memset(a, 0xff, 4);
       x1 = cx;
       if (x1 >= maxx) {
 	x1 = x2 = maxx;
@@ -93,9 +102,25 @@ static void resize_image(oimage, image)
 	xoff = cx - x1;
       }
       v[0] = memToVal(line1 + pixlen * x1, pixlen);
+      if (v[0] == oimage->trans) {
+	v[0] = 0;
+	a[0] = 0;
+      }
       v[1] = memToVal(line1 + pixlen * x2, pixlen);
+      if (v[1] == oimage->trans) {
+	v[1] = 0;
+	a[1] = 0;
+      }
       v[2] = memToVal(line2 + pixlen * x1, pixlen);
+      if (v[2] == oimage->trans) {
+	v[2] = 0;
+	a[2] = 0;
+      }
       v[3] = memToVal(line2 + pixlen * x2, pixlen);
+      if (v[3] == oimage->trans) {
+	v[3] = 0;
+	a[3] = 0;
+      }
       r = (TRUE_RED(v[0]) * (1 - xoff) +
 	   TRUE_RED(v[1]) * xoff) * (1 - yoff) +
 	(TRUE_RED(v[2]) * (1 - xoff) +
@@ -111,6 +136,21 @@ static void resize_image(oimage, image)
       v[0] = rgb8_to_true(r, g, b);
       valToMem(v[0], destptr, pixlen);
       destptr += pixlen;
+
+      if (adest) {
+	if (oimage->alpha) {
+	  byte *alpha1 = oimage->alpha + oimage->width * y1;
+	  byte *alpha2 = oimage->alpha + oimage->width * y2;
+	  a[0] = alpha1[x1];
+	  a[1] = alpha1[x2];
+	  a[2] = alpha2[x1];
+	  a[3] = alpha2[x2];
+	}
+
+	*adest++ = (byte)((a[0] * (1 - xoff) + a[1] * xoff) * (1 - yoff) +
+			  (a[2] * (1 - xoff) + a[3] * xoff) * yoff);
+      }
+
       cx += xstep;
     }
     cy += ystep;
@@ -125,6 +165,7 @@ static Image *reduced_image(oimage, widt
 {
   Image *dest;
   byte *destptr;
+  byte *adest = NULL;
   unsigned int srclinelen;
   unsigned int i, j;
   unsigned int factorx = oimage->width / width;
@@ -145,23 +186,41 @@ static Image *reduced_image(oimage, widt
 
   dest = newTrueImage(width, height);
   destptr = dest->data;
+  if (oimage->trans) {
+    dest->alpha = (unsigned char *)lmalloc(width * height);
+    adest = dest->alpha;
+  }
 
   srclinelen = oimage->width * oimage->pixlen;
 
   for (j = 0; j < oimage->height; j += factory) {
     for (i = 0; i < oimage->width; i += factorx) {
-      unsigned int r, g, b, div, x, y;
+      unsigned int r, g, b, a, div, x, y;
       Pixel v;
 
-      r = g = b= 0;
+      r = g = b = a = 0;
       div = 0;
       for (y = 0; y < factory && j + y < oimage->height; y++) {
 	byte *src = oimage->data + srclinelen * (j + y);
+	byte *asrc = NULL;
+	if (oimage->alpha)
+	  asrc = oimage->alpha + oimage->width * (j + y);
 	for (x = 0; x < factorx && i + x < oimage->width; x++) {
 	  v = memToVal(src + pixlen * (i + x), pixlen);
-	  r += TRUE_RED(v);
-	  g += TRUE_GREEN(v);
-	  b += TRUE_BLUE(v);
+	  if (asrc) {
+	    if (*asrc) {
+	      r += TRUE_RED(v);
+	      g += TRUE_GREEN(v);
+	      g += TRUE_BLUE(v);
+	    }
+	    a += *asrc;
+	    asrc++;
+	  } else if (v != oimage->trans) {
+	    r += TRUE_RED(v);
+	    g += TRUE_GREEN(v);
+	    b += TRUE_BLUE(v);
+	    a += 0xff;
+	  }
 	  div++;
 	}
       }
@@ -171,6 +230,8 @@ static Image *reduced_image(oimage, widt
       v = rgb8_to_true(r, g, b);
       valToMem(v, destptr, pixlen);
       destptr += pixlen;
+      if (adest)
+	*adest++ = a / div;
     }
   }
   return dest;
@@ -287,7 +348,7 @@ Image *zoom(oimage, xzoom, yzoom, verbos
   case ITRUE:
     if (!RGBP(oimage)) {
       Image *tmpimage = NULL;
-      if (smooth_scaling && oimage->transparent == -1 &&
+      if (smooth_scaling &&
 	  (oimage->width / xwidth > 1 || oimage->height / ywidth > 1)) {
 	tmpimage = reduced_image(oimage, xwidth, ywidth);
 	if (tmpimage->width == xwidth && tmpimage->height == ywidth) {
@@ -296,7 +357,7 @@ Image *zoom(oimage, xzoom, yzoom, verbos
 	}
       }
       image= newTrueImage(xwidth, ywidth);
-      if (smooth_scaling && oimage->transparent == -1) {
+      if (smooth_scaling) {
 	resize_image(tmpimage ? tmpimage : oimage, image);
 	if (tmpimage)
 	  freeImage(tmpimage);
@@ -333,7 +394,8 @@ Image *zoom(oimage, xzoom, yzoom, verbos
 
   if (image) {
       image->title= dupString(buf);
-      image->trans = oimage->trans;
+      if (!image->alpha)
+	image->trans = oimage->trans;
   }
   lfree((byte *)xindex);
   lfree((byte *)yindex);
openSUSE Build Service is sponsored by