Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Backports:SLE-15-SP4
mgp
mgp-alpha-channel.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
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);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor