Hi,I continued to work on the anti-aliasing, specifically the lack of aliasing when the line hits the edge of the image.
Attached is a patch that is applied AFTER the last one I posted. It cleans up the lines, so tiled images now look awesome.
Also attached is the build-script and the last diff, plus the little segfault test file, for completeness.
Please let me know what you are going to do with these patches. I intend to get them applied upstream, I'm hoping you could be the one to do it since you are the maintainer of its package and are therefore a good guy.
cheers, Paul
--- libgd2-2.0.33/gd.c 2006-04-21 11:31:18.000000000 +0800 +++ libgd2-2.0.33/gd.c 2006-04-21 11:31:15.000000000 +0800 @@ -3095,7 +3095,8 @@ /* TBB: set the last pixel for consistency (<=) */ while ((x >> 16) <= x2) { gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (y >> 8) & 0xFF); - gdImageSetAAPixelColor(im, x >> 16, (y >> 16) + 1,col, (~y >> 8) & 0xFF); + if ((y >> 16) + 1 <= im->cy2) + gdImageSetAAPixelColor(im, x >> 16, (y >> 16) + 1,col, (~y >> 8) & 0xFF); x += (1 << 16); y += inc; } @@ -3116,7 +3117,8 @@ /* TBB: set the last pixel for consistency (<=) */ while ((y>>16) <= y2) { gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (x >> 8) & 0xFF); - gdImageSetAAPixelColor(im, (x >> 16) + 1, (y >> 16),col, (~x >> 8) & 0xFF); + if ((x >> 16) + 1 <= im->cx2) + gdImageSetAAPixelColor(im, (x >> 16) + 1, (y >> 16),col, (~x >> 8) & 0xFF); x += inc; y += (1<<16); }
--- libgd2-2.0.33/gd.c 2006-04-21 16:37:55.000000000 +0800 +++ libgd2-2.0.33/gd.c 2006-04-21 16:39:07.000000000 +0800 @@ -3055,6 +3055,9 @@ im->tpixels[y][x]=gdTrueColorAlpha(dr, dg, db, gdAlphaOpaque); } +/* simple helper */ +inline int min_int(int a, int b) { return (a < b ? a : b); } + static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col) { /* keep them as 32bits */ @@ -3065,11 +3068,15 @@ gdImageLine(im, x1, y1, x2, y2, col); return; } - /* TBB: use the clipping rectangle */ - if (clip_1d (&x1, &y1, &x2, &y2, im->cx1, im->cx2) == 0) - return; - if (clip_1d (&y1, &x1, &y2, &x2, im->cy1, im->cy2) == 0) - return; + + /* TBB: use the clipping rectangle */ + /* use expanded image bounds to ensure we get all the AA pixels drawn on the edges */ + /* Note the +1 and -1 */ + if (clip_1d (&x1, &y1, &x2, &y2, im->cx1-1, im->cx2+1) == 0) + return; + if (clip_1d (&y1, &x1, &y2, &x2, im->cy1-1, im->cy2+1) == 0) + return; + dx = x2 - x1; dy = y2 - y1; @@ -3089,15 +3096,25 @@ dx = x2 - x1; dy = y2 - y1; } - x = x1 << 16; + x = x1; y = y1 << 16; inc = (dy * 65536) / dx; + /* TBB: set the last pixel for consistency (<=) */ - while ((x >> 16) <= x2) { - gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (y >> 8) & 0xFF); - if ((y >> 16) + 1 <= im->cy2) - gdImageSetAAPixelColor(im, x >> 16, (y >> 16) + 1,col, (~y >> 8) & 0xFF); - x += (1 << 16); + /* Constrain the loop to the image bounds */ + if (x < 0) + { + y -= inc * x; + x = 0; + } + x2 = min_int(x2,im->cx2); + while (x <= x2) { + int py = y >> 16; + if (py >= im->cy1 && py <= im->cy2) + gdImageSetAAPixelColor(im, x, py, col, (y >> 8) & 0xFF); + if (py + 1 <= im->cy2) + gdImageSetAAPixelColor(im, x, py + 1,col, (~y >> 8) & 0xFF); + x += 1; y += inc; } } else { @@ -3112,15 +3129,26 @@ dy = y2 - y1; } x = x1 << 16; - y = y1 << 16; + // y = y1 << 16; + y = y1; inc = (dx * 65536) / dy; + /* TBB: set the last pixel for consistency (<=) */ - while ((y>>16) <= y2) { - gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (x >> 8) & 0xFF); - if ((x >> 16) + 1 <= im->cx2) - gdImageSetAAPixelColor(im, (x >> 16) + 1, (y >> 16),col, (~x >> 8) & 0xFF); + /* Constrain the loop to the image bounds */ + if (y < 0) + { + x -= inc * y; + y = 0; + } + y2 = min_int(y2,im->cy2); + while (y <= y2) { + int px = x >> 16; + if (px >= im->cx1 && px <= im->cx2) + gdImageSetAAPixelColor(im, px, y, col, (x >> 8) & 0xFF); + if (px + 1 <= im->cx2) + gdImageSetAAPixelColor(im, px + 1, y,col, (~x >> 8) & 0xFF); x += inc; - y += (1<<16); + y += 1; } } }
make_libgd2.sh
Description: Bourne shell script
#include <gd.h> int main() { gdImagePtr im = gdImageCreateTrueColor(100,100); int colour = gdTrueColorAlpha(100,100,100,100); gdImageSetAntiAliased(im,colour); gdImageLine(im, 95, 100, 100, 98, gdAntiAliased); return 0; }