+/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
{
int i;
gdImagePtr im;
+
+ if (overflow2(sizeof (unsigned char *), sy)) {
+ return NULL;
+ }
+ if (overflow2(sizeof (unsigned char *), sx)) {
+ return NULL;
+ }
+
im = (gdImage *) gdMalloc (sizeof (gdImage));
- if (!im)
- return NULL;
+ if (!im) {
+ return NULL;
+ }
+
memset (im, 0, sizeof (gdImage));
/* Row-major ever since gd 1.3 */
im->pixels = (unsigned char **) gdMalloc (sizeof (unsigned char *) * sy);
- if (!im->pixels)
- {
- free(im);
- return NULL;
- }
+ if (!im->pixels) {
+ gdFree(im);
+ return NULL;
+ }
+
im->polyInts = 0;
im->polyAllocated = 0;
im->brush = 0;
{
/* Row-major ever since gd 1.3 */
im->pixels[i] = (unsigned char *) gdCalloc (sx, sizeof (unsigned char));
- if (!im->pixels[i])
- {
- for (--i ; i >= 0; i--)
- {
- gdFree(im->pixels[i]);
- }
- gdFree(im);
- return NULL;
- }
+ if (!im->pixels[i])
+ {
+ for (--i ; i >= 0; i--)
+ {
+ gdFree(im->pixels[i]);
+ }
+ gdFree(im->pixels);
+ gdFree(im);
+ return NULL;
+ }
+
}
im->sx = sx;
im->sy = sy;
{
int i;
gdImagePtr im;
+
+ if (overflow2(sx, sy)) {
+ return NULL;
+ }
+
+ if (overflow2(sizeof (int *), sy)) {
+ return 0;
+ }
+
+ if (overflow2(sizeof(int), sx)) {
+ return NULL;
+ }
+
im = (gdImage *) gdMalloc (sizeof (gdImage));
+ if (!im) {
+ return 0;
+ }
memset (im, 0, sizeof (gdImage));
+
im->tpixels = (int **) gdMalloc (sizeof (int *) * sy);
+ if (!im->tpixels) {
+ gdFree(im);
+ return 0;
+ }
im->polyInts = 0;
im->polyAllocated = 0;
im->brush = 0;
for (i = 0; (i < sy); i++)
{
im->tpixels[i] = (int *) gdCalloc (sx, sizeof (int));
+ if (!im->tpixels[i]) {
+ /* 2.0.34 */
+ i--;
+ while (i >= 0) {
+ gdFree(im->tpixels[i]);
+ i--;
+ }
+ gdFree(im->tpixels);
+ gdFree(im);
+ return 0;
+ }
}
im->sx = sx;
im->sy = sy;
}
else
{
- diff = abs (HWB1.H - HWB2.H);
+ diff = fabs (HWB1.H - HWB2.H);
if (diff > 3)
{
diff = 6 - diff; /* Remember, it's a colour circle */
if (im->trueColor)
{
p = gdImageGetTrueColorPixel (im->tile, srcx, srcy);
- gdImageSetPixel (im, x, y, p);
+ if (p != gdImageGetTransparent (im->tile)) {
+ gdImageSetPixel (im, x, y, p);
+ }
}
else
{
{
return gdTrueColorAlpha (im->red[p], im->green[p], im->blue[p],
(im->transparent == p) ? gdAlphaTransparent :
- gdAlphaOpaque);
+ im->alpha[p]);
}
else
{
static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col);
+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);
+ } else {
+ if (x2 < x1) {
+ int t = x2;
+ x2 = x1;
+ x1 = t;
+ }
+
+ for (;x1 <= x2; x1++) {
+ gdImageSetPixel(im, x1, y, col);
+ }
+ }
+ return;
+}
+
+static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col)
+{
+ if (im->thick > 1) {
+ int thickhalf = im->thick >> 1;
+ gdImageFilledRectangle(im, x - thickhalf, y1, x + im->thick - thickhalf - 1, y2, col);
+ } else {
+ if (y2 < y1) {
+ int t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+
+ for (;y1 <= y2; y1++) {
+ gdImageSetPixel(im, x, y1, col);
+ }
+ }
+ return;
+}
+
/* Bresenham as presented in Foley & Van Dam */
BGD_DECLARE(void) gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
{
int wid;
int w, wstart;
int thick;
+
if (color == gdAntiAliased)
{
/*
dx = abs (x2 - x1);
dy = abs (y2 - y1);
+
+ if (dx == 0) {
+ gdImageVLine(im, x1, y1, y2, color);
+ return;
+ } else if (dy == 0) {
+ gdImageHLine(im, y1, x1, x2, color);
+ return;
+ }
+
if (dy <= dx)
{
/* More-or-less horizontal. use wid for vertical stroke */
int i;
int lx = 0, ly = 0;
int fx = 0, fy = 0;
- while (e < s)
- {
- e += 360;
- }
+
+ if ((s % 360) == (e % 360)) {
+ s = 0; e = 360;
+ } else {
+ if (s > 360) {
+ s = s % 360;
+ }
+
+ if (e > 360) {
+ e = e % 360;
+ }
+
+ while (s < 0) {
+ s += 360;
+ }
+
+ while (e < s) {
+ e += 360;
+ }
+
+ if (s == e) {
+ s = 0; e = 360;
+ }
+ }
+
for (i = s; (i <= e); i++)
{
int x, y;
{
if (!(style & gdChord))
{
- if (style & gdNoFill)
+ if (style & gdNoFill)
{
gdImageLine (im, lx, ly, x, y, color);
}
}
}
-BGD_DECLARE(void) gdImageFilledEllipse (gdImagePtr im, int cx, int cy, int w, int h, int color)
+BGD_DECLARE(void) gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c)
{
- gdImageFilledArc (im, cx, cy, w, h, 0, 360, color, gdPie);
+ int x=0,mx1=0,mx2=0,my1=0,my2=0;
+ long aq,bq,dx,dy,r,rx,ry,a,b;
+ int i;
+ int old_y1,old_y2;
+
+ a=w>>1;
+ b=h>>1;
+
+ gdImageLine(im, mx-a, my, mx+a, my, c);
+
+ mx1 = mx-a;my1 = my;
+ mx2 = mx+a;my2 = my;
+
+ aq = a * a;
+ bq = b * b;
+ dx = aq << 1;
+ dy = bq << 1;
+ r = a * bq;
+ rx = r << 1;
+ ry = 0;
+ x = a;
+ old_y2=-2;
+ old_y1=-2;
+ while (x > 0){
+ if (r > 0) {
+ my1++;my2--;
+ ry +=dx;
+ r -=ry;
+ }
+ if (r <= 0){
+ x--;
+ mx1++;mx2--;
+ 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);
+ }
+ }
+ old_y2 = my2;
+ old_y1 = my1;
+ }
}
BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
/* Seek left */
int leftLimit, rightLimit;
int i;
- leftLimit = (-1);
+ int restoreAlphaBleding;
+
if (border < 0)
{
/* Refuse to fill to a non-solid border */
return;
}
+
+ leftLimit = (-1);
+
+ restoreAlphaBleding = im->alphaBlendingFlag;
+ im->alphaBlendingFlag = 0;
+
for (i = x; (i >= 0); i--)
{
if (gdImageGetPixel (im, i, y) == border)
}
if (leftLimit == (-1))
{
+ im->alphaBlendingFlag = restoreAlphaBleding;
return;
}
/* Seek right */
lastBorder = 1;
for (i = leftLimit; (i <= rightLimit); i++)
{
- int c;
- c = gdImageGetPixel (im, i, y + 1);
+ int c = gdImageGetPixel (im, i, y + 1);
if (lastBorder)
{
if ((c != border) && (c != color))
}
}
}
+ im->alphaBlendingFlag = restoreAlphaBleding;
+}
+
+/*
+ * set the pixel at (x,y) and its 4-connected neighbors
+ * with the same pixel value to the new pixel value nc (new color).
+ * A 4-connected neighbor: pixel above, below, left, or right of a pixel.
+ * ideas from comp.graphics discussions.
+ * For tiled fill, the use of a flag buffer is mandatory. As the tile image can
+ * contain the same color as the color to fill. To do not bloat normal filling
+ * code I added a 2nd private function.
+ */
+
+static int gdImageTileGet (gdImagePtr im, int x, int y)
+{
+ int srcx, srcy;
+ int tileColor,p;
+ if (!im->tile) {
+ return -1;
+ }
+ srcx = x % gdImageSX(im->tile);
+ srcy = y % gdImageSY(im->tile);
+ p = gdImageGetPixel(im->tile, srcx, srcy);
+ if (p == im->tile->transparent) {
+ tileColor = im->transparent;
+ } else if (im->trueColor) {
+ if (im->tile->trueColor) {
+ tileColor = p;
+ } else {
+ tileColor = gdTrueColorAlpha( gdImageRed(im->tile,p), gdImageGreen(im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p));
+ }
+ } else {
+ if (im->tile->trueColor) {
+ tileColor = gdImageColorResolveAlpha(im, gdTrueColorGetRed (p), gdTrueColorGetGreen (p), gdTrueColorGetBlue (p), gdTrueColorGetAlpha (p));
+ } else {
+ tileColor = p;
+ tileColor = gdImageColorResolveAlpha(im, gdImageRed (im->tile,p), gdImageGreen (im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p));
+ }
+ }
+ return tileColor;
}
-BGD_DECLARE(void) gdImageFill (gdImagePtr im, int x, int y, int color)
+
+
+/* horizontal segment of scan line y */
+struct seg {int y, xl, xr, dy;};
+
+/* max depth of stack */
+#define FILL_MAX 1200000
+#define FILL_PUSH(Y, XL, XR, DY) \
+ if (sp<stack+FILL_MAX*10 && Y+(DY)>=0 && Y+(DY)<wy2) \
+ {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;}
+
+#define FILL_POP(Y, XL, XR, DY) \
+ {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
+
+void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);
+BGD_DECLARE(void) gdImageFill(gdImagePtr im, int x, int y, int nc)
{
- int lastBorder;
- int old;
- int leftLimit, rightLimit;
- int i;
- old = gdImageGetPixel (im, x, y);
- if (color == gdTiled)
- {
- /* Tile fill -- got to watch out! */
- int p, tileColor;
- int srcx, srcy;
- if (!im->tile)
- {
- return;
+ int l, x1, x2, dy;
+ int oc; /* old pixel value */
+ int wx2,wy2;
+
+ int alphablending_bak;
+
+ /* stack of filled segments */
+ /* struct seg stack[FILL_MAX],*sp = stack;; */
+ struct seg *stack;
+ struct seg *sp;
+
+ if (!im->trueColor && nc > (im->colorsTotal - 1)) {
+ return;
}
- /* Refuse to flood-fill with a transparent pattern --
- I can't do it without allocating another image */
- if (gdImageGetTransparent (im->tile) != (-1))
- {
- return;
+
+ alphablending_bak = im->alphaBlendingFlag;
+ im->alphaBlendingFlag = 0;
+
+ if (nc==gdTiled) {
+ _gdImageFillTiled(im,x,y,nc);
+ im->alphaBlendingFlag = alphablending_bak;
+ return;
}
- srcx = x % gdImageSX (im->tile);
- srcy = y % gdImageSY (im->tile);
- p = gdImageGetPixel (im->tile, srcx, srcy);
- if (im->trueColor)
- {
- tileColor = p;
+
+ wx2=im->sx;wy2=im->sy;
+ oc = gdImageGetPixel(im, x, y);
+ if (oc==nc || x<0 || x>wx2 || y<0 || y>wy2) {
+ im->alphaBlendingFlag = alphablending_bak;
+ return;
}
- else
- {
- if (im->tile->trueColor)
- {
- tileColor = gdImageColorResolveAlpha (im,
- gdTrueColorGetRed (p),
- gdTrueColorGetGreen (p),
- gdTrueColorGetBlue (p),
- gdTrueColorGetAlpha (p));
- }
- else
- {
- tileColor = im->tileColorMap[p];
- }
+
+ /* Do not use the 4 neighbors implementation with
+ * small images
+ */
+ if (im->sx < 4) {
+ int ix = x, iy = y, c;
+ do {
+ c = gdImageGetPixel(im, ix, iy);
+ if (c != oc) {
+ goto done;
+ }
+ gdImageSetPixel(im, ix, iy, nc);
+ } while(ix++ < (im->sx -1));
+ ix = x; iy = y + 1;
+ do {
+ c = gdImageGetPixel(im, ix, iy);
+ if (c != oc) {
+ goto done;
+ }
+ gdImageSetPixel(im, ix, iy, nc);
+ } while(ix++ < (im->sx -1));
+ goto done;
}
- if (old == tileColor)
- {
- /* Nothing to be done */
- return;
+
+ stack = (struct seg *)gdMalloc(sizeof(struct seg) * ((int)(im->sy*im->sx)/4));
+ if (!stack) {
+ return;
}
- }
- else
- {
- if (old == color)
- {
- /* Nothing to be done */
- return;
+ sp = stack;
+
+ /* required! */
+ FILL_PUSH(y,x,x,1);
+ /* seed segment (popped 1st) */
+ FILL_PUSH(y+1, x, x, -1);
+ while (sp>stack) {
+ FILL_POP(y, x1, x2, dy);
+
+ for (x=x1; x>=0 && gdImageGetPixel(im,x, y)==oc; x--) {
+ gdImageSetPixel(im,x, y, nc);
+ }
+ if (x>=x1) {
+ goto skip;
+ }
+ l = x+1;
+
+ /* leak on left? */
+ if (l<x1) {
+ FILL_PUSH(y, l, x1-1, -dy);
+ }
+ x = x1+1;
+ do {
+ for (; x<=wx2 && gdImageGetPixel(im,x, y)==oc; x++) {
+ gdImageSetPixel(im, x, y, nc);
+ }
+ FILL_PUSH(y, l, x-1, dy);
+ /* leak on right? */
+ if (x>x2+1) {
+ FILL_PUSH(y, x2+1, x-1, -dy);
+ }
+skip: for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++);
+
+ l = x;
+ } while (x<=x2);
}
- }
- /* Seek left */
- leftLimit = (-1);
- for (i = x; (i >= 0); i--)
- {
- if (gdImageGetPixel (im, i, y) != old)
- {
- break;
+
+ gdFree(stack);
+
+done:
+ im->alphaBlendingFlag = alphablending_bak;
+}
+
+void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
+{
+ int i,l, x1, x2, dy;
+ int oc; /* old pixel value */
+ int tiled;
+ int wx2,wy2;
+ /* stack of filled segments */
+ struct seg *stack;
+ struct seg *sp;
+
+ int **pts;
+ if(!im->tile){
+ return;
}
- gdImageSetPixel (im, i, y, color);
- leftLimit = i;
- }
- if (leftLimit == (-1))
- {
- return;
- }
- /* Seek right */
- rightLimit = x;
- for (i = (x + 1); (i < im->sx); i++)
- {
- if (gdImageGetPixel (im, i, y) != old)
- {
- break;
+
+ wx2=im->sx;wy2=im->sy;
+ tiled = nc==gdTiled;
+
+ nc = gdImageTileGet(im,x,y);
+ pts = (int **) gdCalloc(sizeof(int *) * im->sy, sizeof(int));
+ if (!pts) {
+ return;
}
- gdImageSetPixel (im, i, y, color);
- rightLimit = i;
- }
- /* Look at lines above and below and start paints */
- /* Above */
- if (y > 0)
- {
- lastBorder = 1;
- for (i = leftLimit; (i <= rightLimit); i++)
- {
- int c;
- c = gdImageGetPixel (im, i, y - 1);
- if (lastBorder)
- {
- if (c == old)
- {
- gdImageFill (im, i, y - 1, color);
- lastBorder = 0;
+
+ for (i=0; i<im->sy;i++) {
+ pts[i] = (int *) gdCalloc(im->sx, sizeof(int));
+
+ if (!pts[i]) {
+ for (--i ; i >= 0; i--) {
+ gdFree(pts[i]);
+ }
+ return;
}
- }
- else if (c != old)
- {
- lastBorder = 1;
- }
}
- }
- /* Below */
- if (y < ((im->sy) - 1))
- {
- lastBorder = 1;
- for (i = leftLimit; (i <= rightLimit); i++)
- {
- int c;
- c = gdImageGetPixel (im, i, y + 1);
- if (lastBorder)
- {
- if (c == old)
- {
- gdImageFill (im, i, y + 1, color);
- lastBorder = 0;
+
+ stack = (struct seg *)gdMalloc(sizeof(struct seg) * ((int)(im->sy*im->sx)/4));
+ if (!stack) {
+ return;
+ }
+ sp = stack;
+
+ oc = gdImageGetPixel(im, x, y);
+
+ /* required! */
+ FILL_PUSH(y,x,x,1);
+ /* seed segment (popped 1st) */
+ FILL_PUSH(y+1, x, x, -1);
+ while (sp>stack) {
+ FILL_POP(y, x1, x2, dy);
+ for (x=x1; x>=0 && (!pts[y][x] && gdImageGetPixel(im,x,y)==oc); x--) {
+ if (pts[y][x]){
+ /* we should never be here */
+ break;
+ }
+ nc = gdImageTileGet(im,x,y);
+ pts[y][x]=1;
+ gdImageSetPixel(im,x, y, nc);
}
- }
- else if (c != old)
- {
- lastBorder = 1;
- }
+ if (x>=x1) {
+ goto skip;
+ }
+ l = x+1;
+
+ /* leak on left? */
+ if (l<x1) {
+ FILL_PUSH(y, l, x1-1, -dy);
+ }
+ x = x1+1;
+ do {
+ for (; x<wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) {
+ if (pts[y][x]){
+ /* we should never be here */
+ break;
+ }
+ nc = gdImageTileGet(im,x,y);
+ pts[y][x]=1;
+ gdImageSetPixel(im, x, y, nc);
+ }
+ FILL_PUSH(y, l, x-1, dy);
+ /* leak on right? */
+ if (x>x2+1) {
+ FILL_PUSH(y, x2+1, x-1, -dy);
+ }
+skip: for (x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++);
+ l = x;
+ } while (x<=x2);
}
- }
+ for (i=0; i<im->sy;i++) {
+ gdFree(pts[i]);
+ }
+ gdFree(pts);
+ gdFree(stack);
}
BGD_DECLARE(void) gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
{
- int x1h = x1, x1v = x1, y1h = y1, y1v = y1, x2h = x2, x2v = x2, y2h = y2,
- y2v = y2;
- int thick = im->thick;
- if (thick > 1)
- {
- int half = thick / 2;
- int half1 = thick - half;
+ int x1h = x1, x1v = x1, y1h = y1, y1v = y1, x2h = x2, x2v = x2, y2h = y2, y2v = y2;
+ int thick = im->thick;
+ int half1 = 1;
+ int t;
+
+ if (y2 < y1) {
+ t=y1;
+ y1 = y2;
+ y2 = t;
+
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+
+ x1h = x1; x1v = x1; y1h = y1; y1v = y1; x2h = x2; x2v = x2; y2h = y2; y2v = y2;
+ if (thick > 1) {
+ int cx, cy, x1ul, y1ul, x2lr, y2lr;
+ int half = thick >> 1;
+ half1 = thick - half;
+ x1ul = x1 - half;
+ y1ul = y1 - half;
+
+ x2lr = x2 + half;
+ y2lr = y2 + half;
+
+ cy = y1ul + thick;
+ while (cy-- > y1ul) {
+ cx = x1ul - 1;
+ while (cx++ < x2lr) {
+ gdImageSetPixel(im, cx, cy, color);
+ }
+ }
- if (y1 < y2)
- {
- y1v = y1h - half;
- y2v = y2h + half1 - 1;
- }
- else
- {
- y1v = y1h + half1 - 1;
- y2v = y2h - half;
- }
- }
+ cy = y2lr - thick;
+ while (cy++ < y2lr) {
+ cx = x1ul - 1;
+ while (cx++ < x2lr) {
+ gdImageSetPixel(im, cx, cy, color);
+ }
+ }
- gdImageLine (im, x1h, y1h, x2h, y1h, color);
- gdImageLine (im, x1h, y2h, x2h, y2h, color);
- gdImageLine (im, x1v, y1v, x1v, y2v, color);
- gdImageLine (im, x2v, y1v, x2v, y2v, color);
+ cy = y1ul + thick - 1;
+ while (cy++ < y2lr -thick) {
+ cx = x1ul - 1;
+ while (cx++ < x1ul + thick) {
+ gdImageSetPixel(im, cx, cy, color);
+ }
+ }
+
+ cy = y1ul + thick - 1;
+ while (cy++ < y2lr -thick) {
+ cx = x2lr - thick - 1;
+ while (cx++ < x2lr) {
+ gdImageSetPixel(im, cx, cy, color);
+ }
+ }
+
+ return;
+ } else {
+ y1v = y1h + 1;
+ y2v = y2h - 1;
+ gdImageLine(im, x1h, y1h, x2h, y1h, color);
+ gdImageLine(im, x1h, y2h, x2h, y2h, color);
+ gdImageLine(im, x1v, y1v, x1v, y2v, color);
+ gdImageLine(im, x2v, y1v, x2v, y2v, color);
+ }
}
BGD_DECLARE(void) gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2,
nicely kills any plotting for rectangles completely outside the
window as it makes the tests in the for loops fail */
if (x1 < 0)
- x1 = 0;
+ x1 = 0;
if (x1 > gdImageSX (im))
- x1 = gdImageSX (im);
+ x1 = gdImageSX (im);
if (y1 < 0)
- y1 = 0;
+ y1 = 0;
if (y1 > gdImageSY (im))
- y1 = gdImageSY (im);
+ y1 = gdImageSY (im);
+
+ if (x1 > x2) {
+ x = x1;
+ x1 = x2;
+ x2 = x;
+ }
+ if (y1 > y2) {
+ y = y1;
+ y1 = y2;
+ y2 = y;
+ }
for (y = y1; (y <= y2); y++)
{
int tox, toy;
int i;
int colorMap[gdMaxColors];
- if (dst->trueColor)
- {
- /* 2.0: much easier when the destination is truecolor. */
- /* 2.0.10: needs a transparent-index check that is still valid if
- the source is not truecolor. Thanks to Frank Warmerdam. */
- for (y = 0; (y < h); y++)
- {
- for (x = 0; (x < w); x++)
- {
- int p = gdImageGetPixel (src, srcX + x, srcY + y);
- if (p != src->transparent)
- {
- int c = gdImageGetTrueColorPixel (src, srcX + x,
- srcY + y);
- gdImageSetPixel (dst, dstX + x, dstY + y, c);
- }
- }
- }
- return;
- }
+
+ if (dst->trueColor) {
+ /* 2.0: much easier when the destination is truecolor. */
+ /* 2.0.10: needs a transparent-index check that is still valid if
+ * * the source is not truecolor. Thanks to Frank Warmerdam.
+ */
+
+ if (src->trueColor) {
+ for (y = 0; (y < h); y++) {
+ for (x = 0; (x < w); x++) {
+ int c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y);
+ gdImageSetPixel (dst, dstX + x, dstY + y, c);
+ }
+ }
+ } else {
+ /* source is palette based */
+ for (y = 0; (y < h); y++) {
+ for (x = 0; (x < w); x++) {
+ int c = gdImageGetPixel (src, srcX + x, srcY + y);
+ if (c != src->transparent) {
+ gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]));
+ }
+ }
+ }
+ }
+ return;
+ }
+
for (i = 0; (i < gdMaxColors); i++)
- {
- colorMap[i] = (-1);
- }
+ {
+ colorMap[i] = (-1);
+ }
toy = dstY;
for (y = srcY; (y < (srcY + h)); y++)
- {
- tox = dstX;
- for (x = srcX; (x < (srcX + w)); x++)
- {
- int nc;
- int mapTo;
- c = gdImageGetPixel (src, x, y);
- /* Added 7/24/95: support transparent copies */
- if (gdImageGetTransparent (src) == c)
- {
- tox++;
- continue;
- }
- /* Have we established a mapping for this color? */
- if (src->trueColor)
- {
- /* 2.05: remap to the palette available in the
- destination image. This is slow and
- works badly, but it beats crashing! Thanks
- to Padhrig McCarthy. */
+ {
+ tox = dstX;
+ for (x = srcX; (x < (srcX + w)); x++)
+ {
+ int nc;
+ int mapTo;
+ c = gdImageGetPixel (src, x, y);
+ /* Added 7/24/95: support transparent copies */
+ if (gdImageGetTransparent (src) == c)
+ {
+ tox++;
+ continue;
+ }
+ /* Have we established a mapping for this color? */
+ if (src->trueColor)
+ {
+ /* 2.05: remap to the palette available in the
+ destination image. This is slow and
+ works badly, but it beats crashing! Thanks
+ to Padhrig McCarthy. */
mapTo = gdImageColorResolveAlpha (dst,
gdTrueColorGetRed (c),
gdTrueColorGetGreen (c),
else
{
dc = gdImageGetPixel (dst, tox, toy);
- g = 0.29900 * dst->red[dc]
- + 0.58700 * dst->green[dc] + 0.11400 * dst->blue[dc];
+ g = 0.29900 * gdImageRed(dst, dc)
+ + 0.58700 * gdImageGreen(dst, dc) + 0.11400 * gdImageBlue(dst, dc);
ncR = gdImageRed (src, c) * (pct / 100.0)
+ g * ((100 - pct) / 100.0);
return;
}
stx = (int *) gdMalloc (sizeof (int) * srcW);
+ if (!stx) {
+ return;
+ }
+
sty = (int *) gdMalloc (sizeof (int) * srcH);
+ if (!sty) {
+ return;
+ }
+
/* Fixed by Mao Morimoto 2.0.16 */
for (i = 0; (i < srcW); i++)
{
double scY = srcY + ((double) srcHeight) / 2;
int cmap[gdMaxColors];
int i;
+
+ /*
+ 2.0.34: transparency preservation. The transparentness of
+ the transparent color is more important than its hue.
+ */
+ if (src->transparent != -1) {
+ if (dst->transparent == -1) {
+ dst->transparent = src->transparent;
+ }
+ }
+
for (i = 0; (i < gdMaxColors); i++)
{
cmap[i] = (-1);
if ((sx >= srcX) && (sx < srcX + srcWidth) &&
(sy >= srcY) && (sy < srcY + srcHeight))
{
- int c = gdImageGetPixel (src, sx, sy);
- if (!src->trueColor)
- {
+ int c = gdImageGetPixel (src, sx, sy);
+ /* 2.0.34: transparency wins */
+ if (c == src->transparent)
+ {
+ gdImageSetPixel (dst, dx, dy, dst->transparent);
+ }
+ else if (!src->trueColor)
+ {
/* Use a table to avoid an expensive
lookup on every single pixel */
if (cmap[c] == -1)
}
bytes = (w * h / 8) + 1;
im = gdImageCreate (w, h);
+ if (!im) {
+ return 0;
+ }
+
gdImageColorAllocate (im, 255, 255, 255);
gdImageColorAllocate (im, 0, 0, 0);
x = 0;
return;
}
im->polyInts = (int *) gdMalloc (sizeof (int) * n);
+ if (!im->polyInts) {
+ return;
+ }
im->polyAllocated = n;
}
if (im->polyAllocated < n)
{
im->polyAllocated *= 2;
}
+ if (overflow2(sizeof (int), im->polyAllocated)) {
+ return;
+ }
im->polyInts = (int *) gdRealloc (im->polyInts,
sizeof (int) * im->polyAllocated);
+ if (!im->polyInts) {
+ return;
+ }
}
miny = p[0].y;
maxy = p[0].y;
return;
}
im->style = (int *) gdMalloc (sizeof (int) * noOfPixels);
+ if (!im->style) {
+ return;
+ }
memcpy (im->style, style, sizeof (int) * noOfPixels);
im->styleLength = noOfPixels;
im->stylePos = 0;
static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t)
{
int dr,dg,db,p,r,g,b;
+
+ /* 2.0.34: watch out for out of range calls */
+ if (!gdImageBoundsSafeMacro(im, x, y)) {
+ return;
+ }
p = gdImageGetPixel(im,x,y);
/* TBB: we have to implement the dont_blend stuff to provide
the full feature set of the old implementation */
BLEND_COLOR(t, dr, r, dr);
BLEND_COLOR(t, dg, g, dg);
BLEND_COLOR(t, db, b, db);
- im->tpixels[y][x]=gdTrueColorAlpha(dr, dg, db, gdAlphaOpaque);
+ im->tpixels[y][x] = gdTrueColorAlpha(dr, dg, db, gdAlphaOpaque);
}
static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
/* keep them as 32bits */
long x, y, inc;
long dx, dy,tmp;
+
if (!im->trueColor) {
/* TBB: don't crash when the image is of the wrong type */
gdImageLine(im, x1, y1, x2, y2, col);
dx = x2 - x1;
dy = y2 - y1;
+ /* Axis aligned lines */
+ if (dx == 0) {
+ gdImageVLine(im, x1, y1, y2, col);
+ return;
+ } else if (dy == 0) {
+ gdImageHLine(im, y1, x1, x2, col);
+ return;
+ }
+
if (dx == 0 && dy == 0) {
/* TBB: allow setting points */
gdImageSetAAPixelColor(im, x1, y1, col, 0xFF);
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdio.h>
#include <math.h>
#include <string.h>
#define LOCALCOLORMAP 0x80
#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
-#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0)
+#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0)
#define LM_to_uint(a,b) (((b)<<8)|(a))
} Gif89 = { -1, -1, -1, 0 };
#endif
+#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
+
+typedef struct {
+ unsigned char buf[280];
+ int curbit, lastbit, done, last_byte;
+} CODE_STATIC_DATA;
+
+typedef struct {
+ int fresh;
+ int code_size, set_code_size;
+ int max_code, max_code_size;
+ int firstcode, oldcode;
+ int clear_code, end_code;
+ int table[2][(1<< MAX_LWZ_BITS)];
+ int stack[STACK_SIZE], *sp;
+ CODE_STATIC_DATA scd;
+} LZW_STATIC_DATA;
+
static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);
static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP);
static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP);
-static int GetCode (gdIOCtx *fd, int code_size, int flag, int *ZeroDataBlockP);
-static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size, int *ZeroDataBlockP);
+static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP);
+static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP);
static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */
unsigned char c;
unsigned char ColorMap[3][MAXCOLORMAPSIZE];
unsigned char localColorMap[3][MAXCOLORMAPSIZE];
- int imw, imh;
- int useGlobalColormap;
+ int imw, imh, screen_width, screen_height;
+ int gif87a, useGlobalColormap;
int bitPixel;
int i;
/*1.4//int imageCount = 0; */
- char version[4];
/* 2.0.28: threadsafe storage */
int ZeroDataBlock = FALSE;
- int maxcount = 1024;
+ int haveGlobalColormap;
gdImagePtr im = 0;
if (! ReadOK(fd,buf,6)) {
if (strncmp((char *)buf,"GIF",3) != 0) {
return 0;
}
- strncpy(version, (char *)buf + 3, 3);
- version[3] = '\0';
+ if (memcmp((char *)buf+3, "87a", 3) == 0) {
+ gif87a = 1;
+ } else if (memcmp((char *)buf+3, "89a", 3) == 0) {
+ gif87a = 0;
+ } else {
+ return 0;
+ }
+
+ if (! ReadOK(fd,buf,7)) {
+ return 0;
+ }
- if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
- return 0;
- }
- if (! ReadOK(fd,buf,7)) {
- return 0;
- }
BitPixel = 2<<(buf[4]&0x07);
#if 0
ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
Background = buf[5];
AspectRatio = buf[6];
#endif
-
- if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
- if (ReadColorMap(fd, BitPixel, ColorMap)) {
- return 0;
- }
- }
+ screen_width = imw = LM_to_uint(buf[0],buf[1]);
+ screen_height = imh = LM_to_uint(buf[2],buf[3]);
+
+ haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */
+ if (haveGlobalColormap) {
+ if (ReadColorMap(fd, BitPixel, ColorMap)) {
+ return 0;
+ }
+ }
for (;;) {
+ int top, left;
+ int width, height;
+
if (! ReadOK(fd,&c,1)) {
return 0;
}
if (c == ';') { /* GIF terminator */
- goto terminated;
- }
+ goto terminated;
+ }
if (c == '!') { /* Extension */
if (! ReadOK(fd,&c,1)) {
}
if (c != ',') { /* Not a valid start character */
- if (--maxcount < 0)
- goto terminated; /* Looping */
continue;
}
useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
- bitPixel = 1<<((buf[8]&0x07)+1);
-
- imw = LM_to_uint(buf[4],buf[5]);
- imh = LM_to_uint(buf[6],buf[7]);
- if (!(im = gdImageCreate(imw, imh))) {
- return 0;
- }
- im->interlace = BitSet(buf[8], INTERLACE);
- if (! useGlobalColormap) {
+ bitPixel = 1<<((buf[8]&0x07)+1);
+ left = LM_to_uint(buf[0], buf[1]);
+ top = LM_to_uint(buf[2], buf[3]);
+ width = LM_to_uint(buf[4], buf[5]);
+ height = LM_to_uint(buf[6], buf[7]);
+
+ if (left + width > screen_width || top + height > screen_height) {
+ if (VERBOSE) {
+ printf("Frame is not confined to screen dimension.\n");
+ }
+ return 0;
+ }
+
+ if (!(im = gdImageCreate(width, height))) {
+ return 0;
+ }
+ im->interlace = BitSet(buf[8], INTERLACE);
+ if (!useGlobalColormap) {
if (ReadColorMap(fd, bitPixel, localColorMap)) {
- return 0;
+ gdImageDestroy(im);
+ return 0;
}
- ReadImage(im, fd, imw, imh, localColorMap,
+ ReadImage(im, fd, width, height, localColorMap,
BitSet(buf[8], INTERLACE), &ZeroDataBlock);
} else {
- ReadImage(im, fd, imw, imh,
+ if (!haveGlobalColormap) {
+ gdImageDestroy(im);
+ return 0;
+ }
+ ReadImage(im, fd, width, height,
ColorMap,
BitSet(buf[8], INTERLACE), &ZeroDataBlock);
}
if (!im) {
return 0;
}
+ if (!im->colorsTotal) {
+ gdImageDestroy(im);
+ return 0;
+ }
/* Check for open colors at the end, so
we can reduce colorsTotal and ultimately
BitsPerPixel */
static int
DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP)
{
- static unsigned char buf[256];
- int maxcount = 1024;
+ unsigned char buf[256];
switch (label) {
case 0xf9: /* Graphic Control Extension */
+ memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */
(void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP);
#if 0
Gif89.disposal = (buf[0] >> 2) & 0x7;
if ((buf[0] & 0x1) != 0)
*Transparent = buf[3];
- while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) != 0 && --maxcount >= 0)
- ;
+ while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0);
return FALSE;
default:
break;
}
- while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) != 0 && --maxcount >= 0)
+ while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0)
;
return FALSE;
}
static int
-GetCode_(gdIOCtx *fd, int code_size, int flag, int *ZeroDataBlockP)
+GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
- static unsigned char buf[280];
- static int curbit, lastbit, done, last_byte;
- int i, j, ret;
- unsigned char count;
+ int i, j, ret;
+ unsigned char count;
if (flag) {
- curbit = 0;
- lastbit = 0;
- done = FALSE;
+ scd->curbit = 0;
+ scd->lastbit = 0;
+ scd->last_byte = 0;
+ scd->done = FALSE;
return 0;
}
- if ( (curbit+code_size) >= lastbit) {
- if (done) {
- if (curbit >= lastbit) {
+ if ( (scd->curbit + code_size) >= scd->lastbit) {
+ if (scd->done) {
+ if (scd->curbit >= scd->lastbit) {
/* Oh well */
}
return -1;
}
- buf[0] = buf[last_byte-2];
- buf[1] = buf[last_byte-1];
+ scd->buf[0] = scd->buf[scd->last_byte-2];
+ scd->buf[1] = scd->buf[scd->last_byte-1];
- if ((count = GetDataBlock(fd, &buf[2], ZeroDataBlockP)) == 0)
- done = TRUE;
+ if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0)
+ scd->done = TRUE;
- last_byte = 2 + count;
- curbit = (curbit - lastbit) + 16;
- lastbit = (2+count)*8 ;
+ scd->last_byte = 2 + count;
+ scd->curbit = (scd->curbit - scd->lastbit) + 16;
+ scd->lastbit = (2+count)*8 ;
}
ret = 0;
- for (i = curbit, j = 0; j < code_size; ++i, ++j)
- ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
+ for (i = scd->curbit, j = 0; j < code_size; ++i, ++j)
+ ret |= ((scd->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
- curbit += code_size;
+ scd->curbit += code_size;
return ret;
}
static int
-GetCode(gdIOCtx *fd, int code_size, int flag, int *ZeroDataBlockP)
+GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
int rv;
- rv = GetCode_(fd,code_size,flag, ZeroDataBlockP);
+ rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP);
if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
return(rv);
}
-#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
static int
-LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size, int *ZeroDataBlockP)
+LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
{
- static int fresh = FALSE;
- int code, incode;
- static int code_size, set_code_size;
- static int max_code, max_code_size;
- static int firstcode, oldcode;
- static int clear_code, end_code;
- static int table[2][(1<< MAX_LWZ_BITS)];
- static int stack[STACK_SIZE], *sp;
- register int i;
+ int code, incode, i;
if (flag) {
- set_code_size = input_code_size;
- code_size = set_code_size+1;
- clear_code = 1 << set_code_size ;
- end_code = clear_code + 1;
- max_code_size = 2*clear_code;
- max_code = clear_code+2;
-
- GetCode(fd, 0, TRUE, ZeroDataBlockP);
+ sd->set_code_size = input_code_size;
+ sd->code_size = sd->set_code_size+1;
+ sd->clear_code = 1 << sd->set_code_size ;
+ sd->end_code = sd->clear_code + 1;
+ sd->max_code_size = 2*sd->clear_code;
+ sd->max_code = sd->clear_code+2;
+
+ GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP);
- fresh = TRUE;
+ sd->fresh = TRUE;
- for (i = 0; i < clear_code; ++i) {
- table[0][i] = 0;
- table[1][i] = i;
+ for (i = 0; i < sd->clear_code; ++i) {
+ sd->table[0][i] = 0;
+ sd->table[1][i] = i;
}
for (; i < (1<<MAX_LWZ_BITS); ++i)
- table[0][i] = table[1][0] = 0;
+ sd->table[0][i] = sd->table[1][0] = 0;
- sp = stack;
+ sd->sp = sd->stack;
return 0;
- } else if (fresh) {
- fresh = FALSE;
+ } else if (sd->fresh) {
+ sd->fresh = FALSE;
do {
- firstcode = oldcode =
- GetCode(fd, code_size, FALSE, ZeroDataBlockP);
- } while (firstcode == clear_code);
- return firstcode;
+ sd->firstcode = sd->oldcode =
+ GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
+ } while (sd->firstcode == sd->clear_code);
+ return sd->firstcode;
}
- if (sp > stack)
- return *--sp;
+ if (sd->sp > sd->stack)
+ return *--sd->sp;
- while ((code = GetCode(fd, code_size, FALSE, ZeroDataBlockP)) >= 0) {
- if (code == clear_code) {
- for (i = 0; i < clear_code; ++i) {
- table[0][i] = 0;
- table[1][i] = i;
+ while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) {
+ if (code == sd->clear_code) {
+ for (i = 0; i < sd->clear_code; ++i) {
+ sd->table[0][i] = 0;
+ sd->table[1][i] = i;
}
for (; i < (1<<MAX_LWZ_BITS); ++i)
- table[0][i] = table[1][i] = 0;
- code_size = set_code_size+1;
- max_code_size = 2*clear_code;
- max_code = clear_code+2;
- sp = stack;
- firstcode = oldcode =
- GetCode(fd, code_size, FALSE, ZeroDataBlockP);
- return firstcode;
- } else if (code == end_code) {
+ sd->table[0][i] = sd->table[1][i] = 0;
+ sd->code_size = sd->set_code_size+1;
+ sd->max_code_size = 2*sd->clear_code;
+ sd->max_code = sd->clear_code+2;
+ sd->sp = sd->stack;
+ sd->firstcode = sd->oldcode =
+ GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
+ return sd->firstcode;
+ } else if (code == sd->end_code) {
int count;
unsigned char buf[260];
- int maxcount = 1024;
if (*ZeroDataBlockP)
return -2;
- while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0 && --maxcount >= 0)
+ while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0)
;
- if (count != 0 || maxcount < 0)
+ if (count != 0)
return -2;
}
incode = code;
- if (sp == (stack + STACK_SIZE)) {
+ if (sd->sp == (sd->stack + STACK_SIZE)) {
/* Bad compressed data stream */
return -1;
}
- if (code >= max_code) {
- *sp++ = firstcode;
- code = oldcode;
+ if (code >= sd->max_code) {
+ *sd->sp++ = sd->firstcode;
+ code = sd->oldcode;
}
- while (code >= clear_code) {
- if (sp == (stack + STACK_SIZE)) {
+ while (code >= sd->clear_code) {
+ if (sd->sp == (sd->stack + STACK_SIZE)) {
/* Bad compressed data stream */
return -1;
}
- *sp++ = table[1][code];
- if (code == table[0][code]) {
+ *sd->sp++ = sd->table[1][code];
+ if (code == sd->table[0][code]) {
/* Oh well */
}
- code = table[0][code];
+ code = sd->table[0][code];
}
- *sp++ = firstcode = table[1][code];
+ *sd->sp++ = sd->firstcode = sd->table[1][code];
- if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
- table[0][code] = oldcode;
- table[1][code] = firstcode;
- ++max_code;
- if ((max_code >= max_code_size) &&
- (max_code_size < (1<<MAX_LWZ_BITS))) {
- max_code_size *= 2;
- ++code_size;
+ if ((code = sd->max_code) <(1<<MAX_LWZ_BITS)) {
+ sd->table[0][code] = sd->oldcode;
+ sd->table[1][code] = sd->firstcode;
+ ++sd->max_code;
+ if ((sd->max_code >= sd->max_code_size) &&
+ (sd->max_code_size < (1<<MAX_LWZ_BITS))) {
+ sd->max_code_size *= 2;
+ ++sd->code_size;
}
}
- oldcode = incode;
+ sd->oldcode = incode;
- if (sp > stack)
- return *--sp;
+ if (sd->sp > sd->stack)
+ return *--sd->sp;
}
return code;
}
static int
-LWZReadByte(gdIOCtx *fd, int flag, int input_code_size, int *ZeroDataBlockP)
+LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
{
int rv;
- rv = LWZReadByte_(fd,flag,input_code_size, ZeroDataBlockP);
+ rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP);
if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
return(rv);
}
int v;
int xpos = 0, ypos = 0, pass = 0;
int i;
+ LZW_STATIC_DATA sd;
+
+ /*
+ ** Initialize the Compression routines
+ */
+ if (! ReadOK(fd,&c,1)) {
+ return;
+ }
+
+ if (c > MAX_LWZ_BITS) {
+ return;
+ }
+
/* Stash the color map into the image */
for (i=0; (i<gdMaxColors); i++) {
im->red[i] = cmap[CM_RED][i];
}
/* Many (perhaps most) of these colors will remain marked open. */
im->colorsTotal = gdMaxColors;
- /*
- ** Initialize the Compression routines
- */
- if (! ReadOK(fd,&c,1)) {
- return;
- }
- if (LWZReadByte(fd, TRUE, c, ZeroDataBlockP) < 0) {
+ if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) {
return;
}
** REMOVED For 1.4
*/
/*if (ignore) { */
- /* while (LWZReadByte(fd, FALSE, c) >= 0) */
+ /* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */
/* ; */
/* return; */
/*} */
- while ((v = LWZReadByte(fd,FALSE,c, ZeroDataBlockP)) >= 0 ) {
+ while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0 ) {
+ if (v >= gdMaxColors) {
+ v = 0;
+ }
+
/* This how we recognize which colors are actually used. */
if (im->open[v]) {
im->open[v] = 0;
}
fini:
- if (LWZReadByte(fd,FALSE,c, ZeroDataBlockP)>=0) {
+ if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) {
/* Ignore extra */
}
}