summaryrefslogtreecommitdiff
path: root/Build/source/libs/gd/libgd-src/src/gd.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/gd/libgd-src/src/gd.c')
-rw-r--r--Build/source/libs/gd/libgd-src/src/gd.c539
1 files changed, 426 insertions, 113 deletions
diff --git a/Build/source/libs/gd/libgd-src/src/gd.c b/Build/source/libs/gd/libgd-src/src/gd.c
index 053873b4d97..f0fc40ede11 100644
--- a/Build/source/libs/gd/libgd-src/src/gd.c
+++ b/Build/source/libs/gd/libgd-src/src/gd.c
@@ -96,12 +96,19 @@ void gd_stderr_error(int priority, const char *format, va_list args)
static gdErrorMethod gd_error_method = gd_stderr_error;
+static void _gd_error_ex(int priority, const char *format, va_list args)
+{
+ if (gd_error_method) {
+ gd_error_method(priority, format, args);
+ }
+}
+
void gd_error(const char *format, ...)
{
va_list args;
va_start(args, format);
- gd_error_ex(GD_WARNING, format, args);
+ _gd_error_ex(GD_WARNING, format, args);
va_end(args);
}
void gd_error_ex(int priority, const char *format, ...)
@@ -109,17 +116,21 @@ void gd_error_ex(int priority, const char *format, ...)
va_list args;
va_start(args, format);
- if (gd_error_method) {
- gd_error_method(priority, format, args);
- }
+ _gd_error_ex(priority, format, args);
va_end(args);
}
+/*
+ Function: gdSetErrorMethod
+*/
BGD_DECLARE(void) gdSetErrorMethod(gdErrorMethod error_method)
{
gd_error_method = error_method;
}
+/*
+ Function: gdClearErrorMethod
+*/
BGD_DECLARE(void) gdClearErrorMethod(void)
{
gd_error_method = gd_stderr_error;
@@ -127,6 +138,10 @@ BGD_DECLARE(void) gdClearErrorMethod(void)
static void gdImageBrushApply (gdImagePtr im, int x, int y);
static void gdImageTileApply (gdImagePtr im, int x, int y);
+
+/*
+ Function: gdImageGetTrueColorPixel
+*/
BGD_DECLARE(int) gdImageGetTrueColorPixel (gdImagePtr im, int x, int y);
@@ -272,7 +287,7 @@ BGD_DECLARE(gdImagePtr) gdImageCreateTrueColor (int sx, int sy)
return 0;
}
- if (overflow2(sizeof(int), sx)) {
+ if (overflow2(sizeof(int *), sx)) {
return NULL;
}
@@ -380,11 +395,17 @@ BGD_DECLARE(void) gdImageDestroy (gdImagePtr im)
gdFree (im);
}
+/*
+ Function: gdImageColorClosest
+*/
BGD_DECLARE(int) gdImageColorClosest (gdImagePtr im, int r, int g, int b)
{
return gdImageColorClosestAlpha (im, r, g, b, gdAlphaOpaque);
}
+/*
+ Function: gdImageColorClosestAlpha
+*/
BGD_DECLARE(int) gdImageColorClosestAlpha (gdImagePtr im, int r, int g, int b, int a)
{
int i;
@@ -552,6 +573,9 @@ HWB_to_RGB (HWBType HWB, RGBType * RGB)
}
#endif
+/*
+ Function: gdImageColorClosestHWB
+*/
BGD_DECLARE(int) gdImageColorClosestHWB (gdImagePtr im, int r, int g, int b)
{
int i;
@@ -577,11 +601,17 @@ BGD_DECLARE(int) gdImageColorClosestHWB (gdImagePtr im, int r, int g, int b)
return ct;
}
+/*
+ Function: gdImageColorExact
+*/
BGD_DECLARE(int) gdImageColorExact (gdImagePtr im, int r, int g, int b)
{
return gdImageColorExactAlpha (im, r, g, b, gdAlphaOpaque);
}
+/*
+ Function: gdImageColorExactAlpha
+*/
BGD_DECLARE(int) gdImageColorExactAlpha (gdImagePtr im, int r, int g, int b, int a)
{
int i;
@@ -600,11 +630,17 @@ BGD_DECLARE(int) gdImageColorExactAlpha (gdImagePtr im, int r, int g, int b, int
return -1;
}
+/*
+ Function: gdImageColorAllocate
+*/
BGD_DECLARE(int) gdImageColorAllocate (gdImagePtr im, int r, int g, int b)
{
return gdImageColorAllocateAlpha (im, r, g, b, gdAlphaOpaque);
}
+/*
+ Function: gdImageColorAllocateAlpha
+*/
BGD_DECLARE(int) gdImageColorAllocateAlpha (gdImagePtr im, int r, int g, int b, int a)
{
int i;
@@ -634,21 +670,24 @@ BGD_DECLARE(int) gdImageColorAllocateAlpha (gdImagePtr im, int r, int g, int b,
}
/*
- * gdImageColorResolve is an alternative for the code fragment:
- *
- * if ((color=gdImageColorExact(im,R,G,B)) < 0)
- * if ((color=gdImageColorAllocate(im,R,G,B)) < 0)
- * color=gdImageColorClosest(im,R,G,B);
- *
- * in a single function. Its advantage is that it is guaranteed to
- * return a color index in one search over the color table.
- */
+ Function: gdImageColorResolve
+
+ gdImageColorResolve is an alternative for the code fragment
+ | if ((color=gdImageColorExact(im,R,G,B)) < 0)
+ | if ((color=gdImageColorAllocate(im,R,G,B)) < 0)
+ | color=gdImageColorClosest(im,R,G,B);
+ in a single function. Its advantage is that it is guaranteed to
+ return a color index in one search over the color table.
+*/
BGD_DECLARE(int) gdImageColorResolve (gdImagePtr im, int r, int g, int b)
{
return gdImageColorResolveAlpha (im, r, g, b, gdAlphaOpaque);
}
+/*
+ Function: gdImageColorResolveAlpha
+*/
BGD_DECLARE(int) gdImageColorResolveAlpha (gdImagePtr im, int r, int g, int b, int a)
{
int c;
@@ -700,6 +739,9 @@ BGD_DECLARE(int) gdImageColorResolveAlpha (gdImagePtr im, int r, int g, int b, i
return op; /* Return newly allocated color */
}
+/*
+ Function: gdImageColorDeallocate
+*/
BGD_DECLARE(void) gdImageColorDeallocate (gdImagePtr im, int color)
{
if (im->trueColor || (color >= gdMaxColors) || (color < 0)) {
@@ -709,8 +751,15 @@ BGD_DECLARE(void) gdImageColorDeallocate (gdImagePtr im, int color)
im->open[color] = 1;
}
+/*
+ Function: gdImageColorTransparent
+*/
BGD_DECLARE(void) gdImageColorTransparent (gdImagePtr im, int color)
{
+ if (color < 0) {
+ return;
+ }
+
if (!im->trueColor) {
if((color < -1) || (color >= gdMaxColors)) {
return;
@@ -725,6 +774,9 @@ BGD_DECLARE(void) gdImageColorTransparent (gdImagePtr im, int color)
im->transparent = color;
}
+/*
+ Function: gdImagePaletteCopy
+*/
BGD_DECLARE(void) gdImagePaletteCopy (gdImagePtr to, gdImagePtr from)
{
int i;
@@ -777,6 +829,9 @@ BGD_DECLARE(void) gdImagePaletteCopy (gdImagePtr to, gdImagePtr from)
}
+/*
+ Function: gdImageColorReplace
+*/
BGD_DECLARE(int) gdImageColorReplace (gdImagePtr im, int src, int dst)
{
register int x, y;
@@ -808,6 +863,9 @@ BGD_DECLARE(int) gdImageColorReplace (gdImagePtr im, int src, int dst)
return n;
}
+/*
+ Function: gdImageColorReplaceThreshold
+*/
BGD_DECLARE(int) gdImageColorReplaceThreshold (gdImagePtr im, int src, int dst, float threshold)
{
register int x, y;
@@ -846,6 +904,9 @@ static int colorCmp (const void *x, const void *y)
return (a > b) - (a < b);
}
+/*
+ Function: gdImageColorReplaceArray
+*/
BGD_DECLARE(int) gdImageColorReplaceArray (gdImagePtr im, int len, int *src, int *dst)
{
register int x, y;
@@ -895,6 +956,9 @@ BGD_DECLARE(int) gdImageColorReplaceArray (gdImagePtr im, int len, int *src, int
return n;
}
+/*
+ Function: gdImageColorReplaceCallback
+*/
BGD_DECLARE(int) gdImageColorReplaceCallback (gdImagePtr im, gdCallbackImageColor callback)
{
int c, d, n = 0;
@@ -1020,6 +1084,9 @@ clip_1d (int *x0, int *y0, int *x1, int *y1, int mindim, int maxdim)
/* end of line clipping code */
+/*
+ Function: gdImageSetPixel
+*/
BGD_DECLARE(void) gdImageSetPixel (gdImagePtr im, int x, int y, int color)
{
int p;
@@ -1211,6 +1278,9 @@ gdImageTileApply (gdImagePtr im, int x, int y)
}
}
+/*
+ Function: gdImageGetPixel
+*/
BGD_DECLARE(int) gdImageGetPixel (gdImagePtr im, int x, int y)
{
if (gdImageBoundsSafeMacro (im, x, y)) {
@@ -1224,6 +1294,9 @@ BGD_DECLARE(int) gdImageGetPixel (gdImagePtr im, int x, int y)
}
}
+/*
+ Function: gdImageGetTrueColorPixel
+*/
BGD_DECLARE(int) gdImageGetTrueColorPixel (gdImagePtr im, int x, int y)
{
int p = gdImageGetPixel (im, x, y);
@@ -1236,19 +1309,26 @@ BGD_DECLARE(int) gdImageGetTrueColorPixel (gdImagePtr im, int x, int y)
}
}
+/*
+ Function: gdImageAABlend
+
+ NO-OP, kept for library compatibility.
+*/
BGD_DECLARE(void) gdImageAABlend (gdImagePtr im)
{
- /* NO-OP, kept for library compatibility. */
(void)im;
}
static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col);
+static void _gdImageFilledHRectangle (gdImagePtr im, int x1, int y1, int x2, int y2,
+ int color);
+
static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col)
{
if (im->thick > 1) {
int thickhalf = im->thick >> 1;
- gdImageFilledRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col);
+ _gdImageFilledHRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col);
} else {
if (x2 < x1) {
int t = x2;
@@ -1282,7 +1362,11 @@ static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col)
return;
}
-/* Bresenham as presented in Foley & Van Dam */
+/*
+ Function: gdImageLine
+
+ Bresenham as presented in Foley & Van Dam.
+*/
BGD_DECLARE(void) gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
{
int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
@@ -1325,20 +1409,17 @@ BGD_DECLARE(void) gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, in
if (dy <= dx) {
/* More-or-less horizontal. use wid for vertical stroke */
/* Doug Claar: watch out for NaN in atan2 (2.0.5) */
- if ((dx == 0) && (dy == 0)) {
- wid = 1;
+
+ /* 2.0.12: Michael Schwartz: divide rather than multiply;
+ TBB: but watch out for /0! */
+ double ac = cos (atan2 (dy, dx));
+ if (ac != 0) {
+ wid = thick / ac;
} else {
- /* 2.0.12: Michael Schwartz: divide rather than multiply;
- TBB: but watch out for /0! */
- double ac = cos (atan2 (dy, dx));
- if (ac != 0) {
- wid = thick / ac;
- } else {
- wid = 1;
- }
- if (wid == 0) {
- wid = 1;
- }
+ wid = 1;
+ }
+ if (wid == 0) {
+ wid = 1;
}
d = 2 * dy - dx;
incr1 = 2 * dy;
@@ -1453,6 +1534,9 @@ BGD_DECLARE(void) gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, in
static void dashedSet (gdImagePtr im, int x, int y, int color,
int *onP, int *dashStepP, int wid, int vert);
+/*
+ Function: gdImageDashedLine
+*/
BGD_DECLARE(void) gdImageDashedLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
{
int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
@@ -1594,11 +1678,17 @@ dashedSet (gdImagePtr im, int x, int y, int color,
*onP = on;
}
+/*
+ Function: gdImageBoundsSafe
+*/
BGD_DECLARE(int) gdImageBoundsSafe (gdImagePtr im, int x, int y)
{
return gdImageBoundsSafeMacro (im, x, y);
}
+/*
+ Function: gdImageChar
+*/
BGD_DECLARE(void) gdImageChar (gdImagePtr im, gdFontPtr f, int x, int y, int c, int color)
{
int cx, cy;
@@ -1625,6 +1715,9 @@ BGD_DECLARE(void) gdImageChar (gdImagePtr im, gdFontPtr f, int x, int y, int c,
}
}
+/*
+ Function: gdImageCharUp
+*/
BGD_DECLARE(void) gdImageCharUp (gdImagePtr im, gdFontPtr f, int x, int y, int c, int color)
{
int cx, cy;
@@ -1651,6 +1744,9 @@ BGD_DECLARE(void) gdImageCharUp (gdImagePtr im, gdFontPtr f, int x, int y, int c
}
}
+/*
+ Function: gdImageString
+*/
BGD_DECLARE(void) gdImageString (gdImagePtr im, gdFontPtr f,
int x, int y, unsigned char *s, int color)
{
@@ -1663,6 +1759,9 @@ BGD_DECLARE(void) gdImageString (gdImagePtr im, gdFontPtr f,
}
}
+/*
+ Function: gdImageStringUp
+*/
BGD_DECLARE(void) gdImageStringUp (gdImagePtr im, gdFontPtr f,
int x, int y, unsigned char *s, int color)
{
@@ -1677,6 +1776,9 @@ BGD_DECLARE(void) gdImageStringUp (gdImagePtr im, gdFontPtr f,
static int strlen16 (unsigned short *s);
+/*
+ Function: gdImageString16
+*/
BGD_DECLARE(void) gdImageString16 (gdImagePtr im, gdFontPtr f,
int x, int y, unsigned short *s, int color)
{
@@ -1689,6 +1791,9 @@ BGD_DECLARE(void) gdImageString16 (gdImagePtr im, gdFontPtr f,
}
}
+/*
+ Function: gdImageStringUp16
+*/
BGD_DECLARE(void) gdImageStringUp16 (gdImagePtr im, gdFontPtr f,
int x, int y, unsigned short *s, int color)
{
@@ -1727,21 +1832,25 @@ lsqrt (long n)
/* s and e are integers modulo 360 (degrees), with 0 degrees
being the rightmost extreme and degrees changing clockwise.
cx and cy are the center in pixels; w and h are the horizontal
- and vertical diameter in pixels. Nice interface, but slow.
- See gd_arc_f_buggy.c for a better version that doesn't
- seem to be bug-free yet. */
+ and vertical diameter in pixels. */
+/*
+ Function: gdImageArc
+*/
BGD_DECLARE(void) gdImageArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e,
int color)
{
gdImageFilledArc (im, cx, cy, w, h, s, e, color, gdNoFill);
}
+/*
+ Function: gdImageFilledArc
+*/
BGD_DECLARE(void) gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e,
int color, int style)
{
- gdPoint pts[3];
- int i;
+ gdPoint pts[363];
+ int i, pti;
int lx = 0, ly = 0;
int fx = 0, fy = 0;
@@ -1771,7 +1880,7 @@ BGD_DECLARE(void) gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h,
}
}
- for (i = s; (i <= e); i++) {
+ for (i = s, pti = 1; (i <= e); i++, pti++) {
int x, y;
x = ((long) gdCosT[i % 360] * (long) w / (2 * 1024)) + cx;
y = ((long) gdSinT[i % 360] * (long) h / (2 * 1024)) + cy;
@@ -1780,19 +1889,29 @@ BGD_DECLARE(void) gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h,
if (style & gdNoFill) {
gdImageLine (im, lx, ly, x, y, color);
} else {
- /* This is expensive! */
- pts[0].x = lx;
- pts[0].y = ly;
- pts[1].x = x;
- pts[1].y = y;
- pts[2].x = cx;
- pts[2].y = cy;
- gdImageFilledPolygon (im, pts, 3, color);
+ if (y == ly) {
+ pti--; /* don't add this point */
+ if (((i > 270 || i < 90) && x > lx) || ((i > 90 && i < 270) && x < lx)) {
+ /* replace the old x coord, if increasing on the
+ right side or decreasing on the left side */
+ pts[pti].x = x;
+ }
+ } else {
+ pts[pti].x = x;
+ pts[pti].y = y;
+ }
}
}
} else {
fx = x;
fy = y;
+
+ if (!(style & (gdChord | gdNoFill))) {
+ pts[0].x = cx;
+ pts[0].y = cy;
+ pts[pti].x = x;
+ pts[pti].y = y;
+ }
}
lx = x;
ly = y;
@@ -1819,10 +1938,17 @@ BGD_DECLARE(void) gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h,
gdImageLine (im, cx, cy, lx, ly, color);
gdImageLine (im, cx, cy, fx, fy, color);
}
+ } else {
+ pts[pti].x = cx;
+ pts[pti].y = cy;
+ gdImageFilledPolygon(im, pts, pti+1, color);
}
}
}
+/*
+ Function: gdImageEllipse
+*/
BGD_DECLARE(void) gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c)
{
int x=0,mx1=0,mx2=0,my1=0,my2=0;
@@ -1867,6 +1993,9 @@ BGD_DECLARE(void) gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, in
}
+/*
+ Function: gdImageFilledEllipse
+*/
BGD_DECLARE(void) gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c)
{
int x=0,mx1=0,mx2=0,my1=0,my2=0;
@@ -1909,20 +2038,20 @@ BGD_DECLARE(void) gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, in
rx -=dy;
r +=rx;
}
- if(old_y2!=my2) {
- for(i=mx1; i<=mx2; i++) {
- gdImageSetPixel(im,i,my1,c);
- }
- }
+
if(old_y2!=my2) {
for(i=mx1; i<=mx2; i++) {
gdImageSetPixel(im,i,my2,c);
+ gdImageSetPixel(im,i,my1,c);
}
}
old_y2 = my2;
}
}
+/*
+ Function: gdImageFillToBorder
+*/
BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
{
int lastBorder;
@@ -1931,16 +2060,33 @@ BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border,
int i;
int restoreAlphaBleding;
- if (border < 0) {
+ if (border < 0 || color < 0) {
/* Refuse to fill to a non-solid border */
return;
}
+ if (!im->trueColor) {
+ if ((color > (im->colorsTotal - 1)) || (border > (im->colorsTotal - 1)) || (color < 0)) {
+ return;
+ }
+ }
+
leftLimit = (-1);
restoreAlphaBleding = im->alphaBlendingFlag;
im->alphaBlendingFlag = 0;
+ if (x >= im->sx) {
+ x = im->sx - 1;
+ } else if (x < 0) {
+ x = 0;
+ }
+ if (y >= im->sy) {
+ y = im->sy - 1;
+ } else if (y < 0) {
+ y = 0;
+ }
+
for (i = x; (i >= 0); i--) {
if (gdImageGetPixel (im, i, y) == border) {
break;
@@ -2051,6 +2197,10 @@ struct seg {
{sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);
+
+/*
+ Function: gdImageFill
+*/
BGD_DECLARE(void) gdImageFill(gdImagePtr im, int x, int y, int nc)
{
int l, x1, x2, dy;
@@ -2204,9 +2354,9 @@ static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
FILL_PUSH(y+1, x, x, -1);
while (sp>stack) {
FILL_POP(y, x1, x2, dy);
- for (x=x1; x>=0 && (!pts[y + x*wx2] && gdImageGetPixel(im,x,y)==oc); x--) {
+ for (x=x1; x>=0 && (!pts[y + x*wy2] && gdImageGetPixel(im,x,y)==oc); x--) {
nc = gdImageTileGet(im,x,y);
- pts[y + x*wx2]=1;
+ pts[y + x*wy2]=1;
gdImageSetPixel(im,x, y, nc);
}
if (x>=x1) {
@@ -2220,13 +2370,13 @@ static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
}
x = x1+1;
do {
- for (; x<wx2 && (!pts[y + x*wx2] && gdImageGetPixel(im,x, y)==oc) ; x++) {
- if (pts[y + x*wx2]) {
+ for (; x<wx2 && (!pts[y + x*wy2] && gdImageGetPixel(im,x, y)==oc) ; x++) {
+ if (pts[y + x*wy2]) {
/* we should never be here */
break;
}
nc = gdImageTileGet(im,x,y);
- pts[y + x*wx2]=1;
+ pts[y + x*wy2]=1;
gdImageSetPixel(im, x, y, nc);
}
FILL_PUSH(y, l, x-1, dy);
@@ -2235,7 +2385,7 @@ static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
FILL_PUSH(y, x2+1, x-1, -dy);
}
skip:
- for (x++; x<=x2 && (pts[y + x*wx2] || gdImageGetPixel(im,x, y)!=oc); x++);
+ for (x++; x<=x2 && (pts[y + x*wy2] || gdImageGetPixel(im,x, y)!=oc); x++);
l = x;
} while (x<=x2);
}
@@ -2244,6 +2394,9 @@ skip:
gdFree(stack);
}
+/*
+ Function: gdImageRectangle
+*/
BGD_DECLARE(void) gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
{
int thick = im->thick;
@@ -2253,6 +2406,16 @@ BGD_DECLARE(void) gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y
return;
}
+ if (x1 == x2 && y1 == y2) {
+ gdImageSetPixel(im, x1, y1, color);
+ return;
+ }
+
+ if (x1 == x2 || y1 == y2) {
+ gdImageLine(im, x1, y1, x2, y2, color);
+ return;
+ }
+
if (y2 < y1) {
int t;
t = y1;
@@ -2314,7 +2477,52 @@ BGD_DECLARE(void) gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y
}
}
-BGD_DECLARE(void) gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2,
+static void _gdImageFilledHRectangle (gdImagePtr im, int x1, int y1, int x2, int y2,
+ int color)
+{
+ int x, y;
+
+ if (x1 == x2 && y1 == y2) {
+ gdImageSetPixel(im, x1, y1, color);
+ return;
+ }
+
+ if (x1 > x2) {
+ x = x1;
+ x1 = x2;
+ x2 = x;
+ }
+
+ if (y1 > y2) {
+ y = y1;
+ y1 = y2;
+ y2 = y;
+ }
+
+ if (x1 < 0) {
+ x1 = 0;
+ }
+
+ if (x2 >= gdImageSX(im)) {
+ x2 = gdImageSX(im) - 1;
+ }
+
+ if (y1 < 0) {
+ y1 = 0;
+ }
+
+ if (y2 >= gdImageSY(im)) {
+ y2 = gdImageSY(im) - 1;
+ }
+
+ for (x = x1; (x <= x2); x++) {
+ for (y = y1; (y <= y2); y++) {
+ gdImageSetPixel (im, x, y, color);
+ }
+ }
+}
+
+static void _gdImageFilledVRectangle (gdImagePtr im, int x1, int y1, int x2, int y2,
int color)
{
int x, y;
@@ -2359,6 +2567,18 @@ BGD_DECLARE(void) gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2,
}
}
+/*
+ Function: gdImageFilledRectangle
+*/
+BGD_DECLARE(void) gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2,
+ int color)
+{
+ _gdImageFilledVRectangle(im, x1, y1, x2, y2, color);
+}
+
+/*
+ Function: gdImageClone
+*/
BGD_DECLARE(gdImagePtr) gdImageClone (gdImagePtr src) {
gdImagePtr dst;
register int i, x;
@@ -2384,7 +2604,7 @@ BGD_DECLARE(gdImagePtr) gdImageClone (gdImagePtr src) {
}
for (i = 0; i < src->sy; i++) {
for (x = 0; x < src->sx; x++) {
- dst->pixels[i][x] = dst->pixels[i][x];
+ dst->pixels[i][x] = src->pixels[i][x];
}
}
} else {
@@ -2454,6 +2674,9 @@ BGD_DECLARE(gdImagePtr) gdImageClone (gdImagePtr src) {
return dst;
}
+/*
+ Function: gdImageCopy
+*/
BGD_DECLARE(void) gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX,
int srcY, int w, int h)
{
@@ -2541,8 +2764,12 @@ BGD_DECLARE(void) gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dst
}
}
-/* This function is a substitute for real alpha channel operations,
- so it doesn't pay attention to the alpha channel. */
+/*
+ Function: gdImageCopyMerge
+
+ This function is a substitute for real alpha channel operations,
+ so it doesn't pay attention to the alpha channel.
+*/
BGD_DECLARE(void) gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY,
int srcX, int srcY, int w, int h, int pct)
{
@@ -2585,8 +2812,12 @@ BGD_DECLARE(void) gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, in
}
}
-/* This function is a substitute for real alpha channel operations,
- so it doesn't pay attention to the alpha channel. */
+/*
+ Function: gdImageCopyMergeGray
+
+ This function is a substitute for real alpha channel operations,
+ so it doesn't pay attention to the alpha channel.
+*/
BGD_DECLARE(void) gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY,
int srcX, int srcY, int w, int h, int pct)
{
@@ -2645,6 +2876,9 @@ BGD_DECLARE(void) gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX
}
}
+/*
+ Function: gdImageCopyResized
+*/
BGD_DECLARE(void) gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY,
int srcX, int srcY, int dstW, int dstH, int srcW,
int srcH)
@@ -2781,6 +3015,9 @@ BGD_DECLARE(void) gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX,
coordinates allow accurate rotation of
objects of odd-numbered width or height. */
+/*
+ Function: gdImageCopyRotated
+*/
BGD_DECLARE(void) gdImageCopyRotated (gdImagePtr dst,
gdImagePtr src,
double dstX, double dstY,
@@ -2864,6 +3101,9 @@ BGD_DECLARE(void) gdImageCopyRotated (gdImagePtr dst,
#define floor2(exp) ((long) exp)
/*#define floor2(exp) floor(exp)*/
+/*
+ Function: gdImageCopyResampled
+*/
BGD_DECLARE(void) gdImageCopyResampled (gdImagePtr dst,
gdImagePtr src,
int dstX, int dstY,
@@ -2871,78 +3111,77 @@ BGD_DECLARE(void) gdImageCopyResampled (gdImagePtr dst,
int dstW, int dstH, int srcW, int srcH)
{
int x, y;
- double sy1, sy2, sx1, sx2;
if (!dst->trueColor) {
- gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH,
- srcW, srcH);
+ gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
return;
}
for (y = dstY; (y < dstY + dstH); y++) {
- sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH;
- sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH /
- (double) dstH;
for (x = dstX; (x < dstX + dstW); x++) {
- double sx, sy;
- double spixels = 0;
- double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0;
- double alpha_sum = 0.0, contrib_sum = 0.0;
-
- sx1 = ((double) x - (double) dstX) * (double) srcW / dstW;
- sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW / dstW;
+ float sy1, sy2, sx1, sx2;
+ float sx, sy;
+ float spixels = 0.0;
+ float red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0;
+ float alpha_factor, alpha_sum = 0.0, contrib_sum = 0.0;
+ sy1 = ((float)(y - dstY)) * (float)srcH / (float)dstH;
+ sy2 = ((float)(y + 1 - dstY)) * (float) srcH / (float) dstH;
sy = sy1;
do {
- double yportion;
- if (floor2 (sy) == floor2 (sy1)) {
- yportion = 1.0 - (sy - floor2 (sy));
+ float yportion;
+ if (floorf(sy) == floorf(sy1)) {
+ yportion = 1.0 - (sy - floorf(sy));
if (yportion > sy2 - sy1) {
yportion = sy2 - sy1;
}
- sy = floor2 (sy);
- } else if (sy == floor2 (sy2)) {
- yportion = sy2 - floor2 (sy2);
+ sy = floorf(sy);
+ } else if (sy == floorf(sy2)) {
+ yportion = sy2 - floorf(sy2);
} else {
yportion = 1.0;
}
+ sx1 = ((float)(x - dstX)) * (float) srcW / dstW;
+ sx2 = ((float)(x + 1 - dstX)) * (float) srcW / dstW;
sx = sx1;
do {
- double xportion;
- double pcontribution;
+ float xportion;
+ float pcontribution;
int p;
- if (floor2 (sx) == floor2 (sx1)) {
- xportion = 1.0 - (sx - floor2 (sx));
+ if (floorf(sx) == floorf(sx1)) {
+ xportion = 1.0 - (sx - floorf(sx));
if (xportion > sx2 - sx1) {
xportion = sx2 - sx1;
}
- sx = floor2 (sx);
- } else if (sx == floor2 (sx2)) {
- xportion = sx2 - floor2 (sx2);
+ sx = floorf(sx);
+ } else if (sx == floorf(sx2)) {
+ xportion = sx2 - floorf(sx2);
} else {
xportion = 1.0;
}
pcontribution = xportion * yportion;
- /* 2.08: previously srcX and srcY were ignored.
- Andrew Pattison */
- p = gdImageGetTrueColorPixel (src,
- (int) sx + srcX,
- (int) sy + srcY);
- red += gdTrueColorGetRed (p) * pcontribution;
- green += gdTrueColorGetGreen (p) * pcontribution;
- blue += gdTrueColorGetBlue (p) * pcontribution;
+ p = gdImageGetTrueColorPixel(src, (int) sx + srcX, (int) sy + srcY);
+
+ alpha_factor = ((gdAlphaMax - gdTrueColorGetAlpha(p))) * pcontribution;
+ red += gdTrueColorGetRed (p) * alpha_factor;
+ green += gdTrueColorGetGreen (p) * alpha_factor;
+ blue += gdTrueColorGetBlue (p) * alpha_factor;
alpha += gdTrueColorGetAlpha (p) * pcontribution;
+ alpha_sum += alpha_factor;
+ contrib_sum += pcontribution;
spixels += xportion * yportion;
sx += 1.0;
- } while (sx < sx2);
- sy += 1.0;
- } while (sy < sy2);
+ }
+ while (sx < sx2);
+ sy += 1.0f;
+ }
+ while (sy < sy2);
+
if (spixels != 0.0) {
red /= spixels;
green /= spixels;
blue /= spixels;
alpha /= spixels;
- alpha += 0.5;
}
- if ( alpha_sum != 0.0f) {
- if( contrib_sum != 0.0f) {
+ if ( alpha_sum != 0.0) {
+ if( contrib_sum != 0.0) {
alpha_sum /= contrib_sum;
}
red /= alpha_sum;
@@ -2956,21 +3195,20 @@ BGD_DECLARE(void) gdImageCopyResampled (gdImagePtr dst,
if (green > 255.0) {
green = 255.0;
}
- if (blue > 255.0) {
+ if (blue > 255.0f) {
blue = 255.0;
}
if (alpha > gdAlphaMax) {
alpha = gdAlphaMax;
}
- gdImageSetPixel (dst,
- x, y,
- gdTrueColorAlpha ((int) red,
- (int) green,
- (int) blue, (int) alpha));
+ gdImageSetPixel(dst, x, y, gdTrueColorAlpha ((int) red, (int) green, (int) blue, (int) alpha));
}
}
}
+/*
+ Function: gdImagePolygon
+*/
BGD_DECLARE(void) gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c)
{
if (n <= 0) {
@@ -2982,6 +3220,9 @@ BGD_DECLARE(void) gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c)
gdImageOpenPolygon (im, p, n, c);
}
+/*
+ Function: gdImageOpenPolygon
+*/
BGD_DECLARE(void) gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c)
{
int i;
@@ -3009,6 +3250,9 @@ BGD_DECLARE(void) gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c)
/* That could help to adjust intersections to produce a nice */
/* interior_extrema. */
+/*
+ Function: gdImageFilledPolygon
+*/
BGD_DECLARE(void) gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c)
{
int i;
@@ -3063,6 +3307,19 @@ BGD_DECLARE(void) gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int
maxy = p[i].y;
}
}
+ /* necessary special case: horizontal line */
+ if (n > 1 && miny == maxy) {
+ x1 = x2 = p[0].x;
+ for (i = 1; (i < n); i++) {
+ if (p[i].x < x1) {
+ x1 = p[i].x;
+ } else if (p[i].x > x2) {
+ x2 = p[i].x;
+ }
+ }
+ gdImageLine(im, x1, miny, x2, miny, c);
+ return;
+ }
pmaxy = maxy;
/* 2.0.16: Optimization by Ilia Chipitsine -- don't waste time offscreen */
/* 2.0.26: clipping rectangle is even better */
@@ -3139,6 +3396,9 @@ BGD_DECLARE(void) gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int
static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t);
+/*
+ Function: gdImageSetStyle
+*/
BGD_DECLARE(void) gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels)
{
if (im->style) {
@@ -3156,11 +3416,17 @@ BGD_DECLARE(void) gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels)
im->stylePos = 0;
}
+/*
+ Function: gdImageSetThickness
+*/
BGD_DECLARE(void) gdImageSetThickness (gdImagePtr im, int thickness)
{
im->thick = thickness;
}
+/*
+ Function: gdImageSetBrush
+*/
BGD_DECLARE(void) gdImageSetBrush (gdImagePtr im, gdImagePtr brush)
{
int i;
@@ -3178,6 +3444,9 @@ BGD_DECLARE(void) gdImageSetBrush (gdImagePtr im, gdImagePtr brush)
}
}
+/*
+ Function: gdImageSetTile
+*/
BGD_DECLARE(void) gdImageSetTile (gdImagePtr im, gdImagePtr tile)
{
int i;
@@ -3195,6 +3464,9 @@ BGD_DECLARE(void) gdImageSetTile (gdImagePtr im, gdImagePtr tile)
}
}
+/*
+ Function: gdImageSetAntiAliased
+*/
BGD_DECLARE(void) gdImageSetAntiAliased (gdImagePtr im, int c)
{
im->AA = 1;
@@ -3202,6 +3474,9 @@ BGD_DECLARE(void) gdImageSetAntiAliased (gdImagePtr im, int c)
im->AA_dont_blend = -1;
}
+/*
+ Function: gdImageSetAntiAliasedDontBlend
+*/
BGD_DECLARE(void) gdImageSetAntiAliasedDontBlend (gdImagePtr im, int c, int dont_blend)
{
im->AA = 1;
@@ -3209,11 +3484,17 @@ BGD_DECLARE(void) gdImageSetAntiAliasedDontBlend (gdImagePtr im, int c, int dont
im->AA_dont_blend = dont_blend;
}
+/*
+ Function: gdImageInterlace
+*/
BGD_DECLARE(void) gdImageInterlace (gdImagePtr im, int interlaceArg)
{
im->interlace = interlaceArg;
}
+/*
+ Function: gdImageCompare
+*/
BGD_DECLARE(int) gdImageCompare (gdImagePtr im1, gdImagePtr im2)
{
int x, y;
@@ -3296,6 +3577,9 @@ BGD_DECLARE(int) gdImageCompare (gdImagePtr im1, gdImagePtr im2)
of gdAlphaBlend(), which merges alpha in the
destination color much better. */
+/*
+ Function: gdAlphaBlend
+*/
BGD_DECLARE(int) gdAlphaBlend (int dst, int src)
{
int src_alpha = gdTrueColorGetAlpha(src);
@@ -3342,6 +3626,10 @@ BGD_DECLARE(int) gdAlphaBlend (int dst, int src)
}
static int gdAlphaOverlayColor (int src, int dst, int max );
+
+/*
+ Function: gdLayerOverlay
+*/
BGD_DECLARE(int) gdLayerOverlay (int dst, int src)
{
int a1, a2;
@@ -3367,7 +3655,11 @@ static int gdAlphaOverlayColor (int src, int dst, int max )
}
}
-/* Apply 'multiply' effect */
+/*
+ Function: gdLayerMultiply
+
+ Apply 'multiply' effect.
+*/
BGD_DECLARE(int) gdLayerMultiply (int dst, int src)
{
int a1, a2, r1, r2, g1, g2, b1, b2;
@@ -3390,16 +3682,25 @@ BGD_DECLARE(int) gdLayerMultiply (int dst, int src)
);
}
+/*
+ Function: gdImageAlphaBlending
+*/
BGD_DECLARE(void) gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg)
{
im->alphaBlendingFlag = alphaBlendingArg;
}
+/*
+ Function: gdImageSaveAlpha
+*/
BGD_DECLARE(void) gdImageSaveAlpha (gdImagePtr im, int saveAlphaArg)
{
im->saveAlphaFlag = saveAlphaArg;
}
+/*
+ Function: gdImageSetClip
+*/
BGD_DECLARE(void) gdImageSetClip (gdImagePtr im, int x1, int y1, int x2, int y2)
{
if (x1 < 0) {
@@ -3432,6 +3733,9 @@ BGD_DECLARE(void) gdImageSetClip (gdImagePtr im, int x1, int y1, int x2, int y2)
im->cy2 = y2;
}
+/*
+ Function: gdImageGetClip
+*/
BGD_DECLARE(void) gdImageGetClip (gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P)
{
*x1P = im->cx1;
@@ -3440,6 +3744,9 @@ BGD_DECLARE(void) gdImageGetClip (gdImagePtr im, int *x1P, int *y1P, int *x2P, i
*y2P = im->cy2;
}
+/*
+ Function: gdImageSetResolution
+*/
BGD_DECLARE(void) gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y)
{
if (res_x > 0) im->res_x = res_x;
@@ -3511,9 +3818,11 @@ static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int co
return;
} else {
double ag;
- ag = (abs(dy) < abs(dx)) ? cos(atan2(dy, dx)) : sin(atan2(dy, dx));
+ /* Cast the long to an int to avoid compiler warnings about truncation.
+ * This isn't a problem as computed dy/dx values came from ints above. */
+ ag = fabs(abs((int)dy) < abs((int)dx) ? cos(atan2(dy, dx)) : sin(atan2(dy, dx)));
if (ag != 0) {
- wid = abs(thick / ag);
+ wid = thick / ag;
} else {
wid = 1;
}
@@ -3531,7 +3840,7 @@ static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int co
return;
}
- if (abs(dx) > abs(dy)) {
+ if (abs((int)dx) > abs((int)dy)) {
if (dx < 0) {
tmp = x1;
x1 = x2;
@@ -3595,7 +3904,11 @@ static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int co
}
-/* convert a palette image to true color */
+/*
+ Function: gdImagePaletteToTrueColor
+
+ Convert a palette image to true color.
+*/
BGD_DECLARE(int) gdImagePaletteToTrueColor(gdImagePtr src)
{
unsigned int y;