diff options
author | Rasmus Lerdorf <rasmus@php.net> | 2002-10-29 23:08:01 +0000 |
---|---|---|
committer | Rasmus Lerdorf <rasmus@php.net> | 2002-10-29 23:08:01 +0000 |
commit | a24534a1ed1a38024fba0c5fe5374effb7432d0b (patch) | |
tree | d60c061c3cec25d29c4d99026eee958b75aa4a34 /ext/gd | |
parent | 8c95cefac6db0ec18002e9c46b55895c584c8c07 (diff) | |
download | php-git-a24534a1ed1a38024fba0c5fe5374effb7432d0b.tar.gz |
Update bundled gd library with relevant changes from gd-2.0.4
I still need to add a configure check for the gdIOCtx struct
changes so building against older external gd libs will work again.
Diffstat (limited to 'ext/gd')
-rw-r--r-- | ext/gd/gd.c | 6 | ||||
-rw-r--r-- | ext/gd/gd_ctx.c | 4 | ||||
-rw-r--r-- | ext/gd/libgd/gd.c | 24 | ||||
-rw-r--r-- | ext/gd/libgd/gd.h | 7 | ||||
-rw-r--r-- | ext/gd/libgd/gd2topng.c | 4 | ||||
-rw-r--r-- | ext/gd/libgd/gd_gd.c | 8 | ||||
-rw-r--r-- | ext/gd/libgd/gd_gd2.c | 35 | ||||
-rw-r--r-- | ext/gd/libgd/gd_gif_in.c | 4 | ||||
-rw-r--r-- | ext/gd/libgd/gd_io.h | 2 | ||||
-rw-r--r-- | ext/gd/libgd/gd_io_dp.c | 3 | ||||
-rw-r--r-- | ext/gd/libgd/gd_io_file.c | 2 | ||||
-rw-r--r-- | ext/gd/libgd/gd_io_ss.c | 2 | ||||
-rw-r--r-- | ext/gd/libgd/gd_jpeg.c | 20 | ||||
-rw-r--r-- | ext/gd/libgd/gd_png.c | 17 | ||||
-rw-r--r-- | ext/gd/libgd/gd_ss.c | 19 | ||||
-rw-r--r-- | ext/gd/libgd/gd_wbmp.c | 6 | ||||
-rw-r--r-- | ext/gd/libgd/gdcache.h | 5 | ||||
-rw-r--r-- | ext/gd/libgd/gdft.c | 313 | ||||
-rw-r--r-- | ext/gd/libgd/gdhelpers.h | 2 | ||||
-rw-r--r-- | ext/gd/libgd/gdkanji.c | 2 | ||||
-rw-r--r-- | ext/gd/libgd/gdparttopng.c | 4 | ||||
-rw-r--r-- | ext/gd/libgd/gdtest.c | 6 |
22 files changed, 327 insertions, 168 deletions
diff --git a/ext/gd/gd.c b/ext/gd/gd.c index f56aa1c17f..0f560b0c01 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -1073,10 +1073,10 @@ static int _php_image_type (char data[8]) io_ctx = gdNewDynamicCtx (8, data); if (io_ctx) { if (getmbi((int(*)(void*))gdGetC, io_ctx) == 0 && skipheader((int(*)(void*))gdGetC, io_ctx) == 0 ) { - io_ctx->free(io_ctx); + io_ctx->gd_free(io_ctx); return PHP_GDIMG_TYPE_WBM; } else - io_ctx->free(io_ctx); + io_ctx->gd_free(io_ctx); } } #endif @@ -1253,7 +1253,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, } else { im = (*ioctx_func_p)(io_ctx); } - io_ctx->free(io_ctx); + io_ctx->gd_free(io_ctx); #endif } else { diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index 3e6b17dead..e836757f07 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -67,7 +67,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, ctx = emalloc(sizeof(gdIOCtx)); ctx->putC = _php_image_output_putc; ctx->putBuf = _php_image_output_putbuf; - ctx->free = _php_image_output_ctxfree; + ctx->gd_free = _php_image_output_ctxfree; #if APACHE && defined(CHARSET_EBCDIC) /* XXX this is unlikely to work any more thies@thieso.net */ @@ -95,7 +95,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, break; } - ctx->free(ctx); + ctx->gd_free(ctx); if(fp) { fflush(fp); diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 2d712a6db3..f946b15f71 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -90,6 +90,7 @@ static int gdFullAlphaBlend(int dst, int src); static int gdLayerOverlay(int dst, int src); static int gdAlphaBlendColor(int b1, int b2, int a1, int a2); static int gdAlphaOverlayColor(int src, int dst, int max); +static int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y); gdImagePtr gdImageCreate (int sx, int sy) @@ -152,8 +153,13 @@ gdImageCreateTrueColor (int sx, int sy) im->transparent = (-1); im->interlace = 0; im->trueColor = 1; - im->saveAlphaFlag = 1; - im->alphaBlendingFlag = 0; + /* 2.0.2: alpha blending is now on by default, and saving of alpha is + off by default. This allows font antialiasing to work as expected + on the first try in JPEGs -- quite important -- and also allows + for smaller PNGs when saving of alpha channel is not really + desired, which it usually isn't! */ + im->saveAlphaFlag = 0; + im->alphaBlendingFlag = 1; im->thick = 1; return im; } @@ -217,7 +223,8 @@ gdImageColorClosestAlpha (gdImagePtr im, int r, int g, int b, int a) rd = (im->red[i] - r); gd = (im->green[i] - g); bd = (im->blue[i] - b); - ad = (im->blue[i] - b); + /* gd 2.02: whoops, was - b (thanks to David Marwood) */ + ad = (im->blue[i] - a); dist = rd * rd + gd * gd + bd * bd + ad * ad; if (first || (dist < mindist)) { @@ -509,6 +516,12 @@ gdImageColorResolveAlpha (gdImagePtr im, int r, int g, int b, int a) op = c; /* Save open slot */ continue; /* Color not in use */ } + if (c == im->transparent) + { + /* don't ever resolve to the color that has + * been designated as the transparent color */ + continue; + } rd = (long) (im->red[c] - r); gd = (long) (im->green[c] - g); bd = (long) (im->blue[c] - b); @@ -1336,7 +1349,7 @@ gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int gdPoint pts[3]; int i; int lx = 0, ly = 0; - int fx, fy; + int fx = 0, fy = 0; int w2, h2; w2 = w / 2; h2 = h / 2; @@ -1975,7 +1988,7 @@ gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX tox = dstX; for (x = srcX; (x < (srcX + srcW)); x++) { - int nc; + int nc = 0; int mapTo; if (!stx[x - srcX]) { @@ -2073,7 +2086,6 @@ gdImageCopyResampled (gdImagePtr dst, { for (x = dstX; (x < dstX + dstW); x++) { - /*int pd = gdImageGetPixel (dst, x, y);*/ float sy1, sy2, sx1, sx2; float sx, sy; float spixels = 0.0f; diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index ab38a577c9..21c3c5515b 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -7,7 +7,7 @@ extern "C" { #ifndef WIN32 /* default fontpath for unix systems */ -#define DEFAULT_FONTPATH "/usr/share/fonts/truetype" +#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1" #define PATHSEPARATOR ":" #else /* default fontpath for windows systems */ @@ -254,6 +254,9 @@ void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); +/* clean up after using fonts in gdImageStringFT() */ +void gdFreeFontCache(); + /* Calls gdImageStringFT. Provided for backwards compatibility only. */ char *gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string); @@ -370,6 +373,8 @@ void gdFree(void *m); /* Best to free this memory with gdFree(), not free() */ void *gdImageWBMPPtr(gdImagePtr im, int *size, int fg); +/* 100 is highest quality (there is always a little loss with JPEG). + 0 is lowest. 10 is about the lowest useful setting. */ void gdImageJpeg(gdImagePtr im, FILE *out, int quality); void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality); diff --git a/ext/gd/libgd/gd2topng.c b/ext/gd/libgd/gd2topng.c index c898f25e18..6db5eb3003 100644 --- a/ext/gd/libgd/gd2topng.c +++ b/ext/gd/libgd/gd2topng.c @@ -37,7 +37,11 @@ main (int argc, char **argv) gdImageDestroy (im); exit (1); } +#ifdef HAVE_LIBPNG gdImagePng (im, out); +#else + fprintf(stderr, "No PNG library support available.\n"); +#endif fclose (out); gdImageDestroy (im); diff --git a/ext/gd/libgd/gd_gd.c b/ext/gd/libgd/gd_gd.c index 60037395c3..53b1c71f99 100644 --- a/ext/gd/libgd/gd_gd.c +++ b/ext/gd/libgd/gd_gd.c @@ -147,7 +147,7 @@ gdImageCreateFromGd (FILE * inFile) in = gdNewFileCtx (inFile); im = gdImageCreateFromGdCtx (in); - in->free (in); + in->gd_free (in); return im; } @@ -196,7 +196,7 @@ _gdPutColors (gdImagePtr im, gdIOCtx * out) { int i; - gdPutC ((unsigned char)im->trueColor, out); + gdPutC (im->trueColor, out); if (!im->trueColor) { gdPutWord (im->colorsTotal, out); @@ -256,7 +256,7 @@ gdImageGd (gdImagePtr im, FILE * outFile) { gdIOCtx *out = gdNewFileCtx (outFile); _gdImageGd (im, out); - out->free (out); + out->gd_free (out); } void * @@ -266,6 +266,6 @@ gdImageGdPtr (gdImagePtr im, int *size) gdIOCtx *out = gdNewDynamicCtx (2048, NULL); _gdImageGd (im, out); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c index 98e619b19a..66d98f0915 100644 --- a/ext/gd/libgd/gd_gd2.c +++ b/ext/gd/libgd/gd_gd2.c @@ -15,10 +15,11 @@ #include <math.h> #include <string.h> #include <stdlib.h> -#include <zlib.h> #include "gd.h" #include "gdhelpers.h" +#include <zlib.h> + #define TRUE 1 #define FALSE 0 @@ -250,7 +251,7 @@ gdImageCreateFromGd2 (FILE * inFile) im = gdImageCreateFromGd2Ctx (in); - in->free (in); + in->gd_free (in); return im; } @@ -266,10 +267,10 @@ gdImageCreateFromGd2Ctx (gdIOCtxPtr in) t_chunk_info *chunkIdx = NULL; /* So we can gdFree it with impunity. */ unsigned char *chunkBuf = NULL; /* So we can gdFree it with impunity. */ int chunkNum = 0; - int chunkMax; + int chunkMax = 0; uLongf chunkLen; - int chunkPos; - int compMax; + int chunkPos = 0; + int compMax = 0; int bytesPerPixel; char *compBuf = NULL; /* So we can gdFree it with impunity. */ @@ -433,7 +434,7 @@ gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h) im = gdImageCreateFromGd2PartCtx (in, srcx, srcy, w, h); - in->free (in); + in->gd_free (in); return im; } @@ -450,9 +451,9 @@ gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, int h) t_chunk_info *chunkIdx = NULL; char *chunkBuf = NULL; int chunkNum; - int chunkMax; + int chunkMax = 0; uLongf chunkLen; - int chunkPos; + int chunkPos = 0; int compMax; char *compBuf = NULL; @@ -635,10 +636,10 @@ gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, int h) { if (im->trueColor) { - ch = (chunkBuf[chunkPos++] << 24) - + (chunkBuf[chunkPos++] << 16) - + (chunkBuf[chunkPos++] << 8) - + (chunkBuf[chunkPos++]); + ch = chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; } else { @@ -710,12 +711,12 @@ _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) char *chunkData = NULL; /* So we can gdFree it with impunity. */ char *compData = NULL; /* So we can gdFree it with impunity. */ uLongf compLen; - int idxPos; + int idxPos = 0; int idxSize; t_chunk_info *chunkIdx = NULL; int posSave; int bytesPerPixel = im->trueColor ? 4 : 1; - int compMax; + int compMax = 0; /*printf("Trying to write GD2 file\n"); */ @@ -762,7 +763,7 @@ _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) /* The zlib notes say output buffer size should be (input size) * 1.01 * 12 */ /* - we'll use 1.02 to be paranoid. */ /* */ - compMax = (int)(cs * bytesPerPixel * cs * 1.02f + 12); + compMax = cs * bytesPerPixel * cs * 1.02 + 12; /* */ /* Allocate the buffers. */ @@ -908,7 +909,7 @@ gdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt) { gdIOCtx *out = gdNewFileCtx (outFile); _gdImageGd2 (im, out, cs, fmt); - out->free (out); + out->gd_free (out); } void * @@ -918,6 +919,6 @@ gdImageGd2Ptr (gdImagePtr im, int cs, int fmt, int *size) gdIOCtx *out = gdNewDynamicCtx (2048, NULL); _gdImageGd2 (im, out, cs, fmt); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c index e600b80470..fc1b587cc8 100644 --- a/ext/gd/libgd/gd_gif_in.c +++ b/ext/gd/libgd/gd_gif_in.c @@ -83,7 +83,7 @@ gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) im = gdImageCreateFromGifCtx(in); - in->free(in); + in->gd_free(in); return im; } @@ -96,7 +96,7 @@ gdImageCreateFromGif(FILE *fdFile) im = gdImageCreateFromGifCtx(fd); - fd->free(fd); + fd->gd_free(fd); return im; } diff --git a/ext/gd/libgd/gd_io.h b/ext/gd/libgd/gd_io.h index 5c0bd24879..c28379abd8 100644 --- a/ext/gd/libgd/gd_io.h +++ b/ext/gd/libgd/gd_io.h @@ -13,7 +13,7 @@ typedef struct gdIOCtx { int (*seek)(struct gdIOCtx*, const int); long (*tell)(struct gdIOCtx*); - void (*free)(struct gdIOCtx*); + void (*gd_free)(struct gdIOCtx*); } gdIOCtx; diff --git a/ext/gd/libgd/gd_io_dp.c b/ext/gd/libgd/gd_io_dp.c index d28dfb01a4..c41743e78f 100644 --- a/ext/gd/libgd/gd_io_dp.c +++ b/ext/gd/libgd/gd_io_dp.c @@ -1,4 +1,3 @@ - /* * io_dp.c * @@ -95,7 +94,7 @@ gdNewDynamicCtx (int initialSize, void *data) ctx->ctx.seek = dynamicSeek; ctx->ctx.tell = dynamicTell; - ctx->ctx.free = gdFreeDynamicCtx; + ctx->ctx.gd_free = gdFreeDynamicCtx; return (gdIOCtx *) ctx; } diff --git a/ext/gd/libgd/gd_io_file.c b/ext/gd/libgd/gd_io_file.c index d0efd1af79..713646120e 100644 --- a/ext/gd/libgd/gd_io_file.c +++ b/ext/gd/libgd/gd_io_file.c @@ -71,7 +71,7 @@ gdNewFileCtx (FILE * f) ctx->ctx.tell = fileTell; ctx->ctx.seek = fileSeek; - ctx->ctx.free = gdFreeFileCtx; + ctx->ctx.gd_free = gdFreeFileCtx; return (gdIOCtx *) ctx; } diff --git a/ext/gd/libgd/gd_io_ss.c b/ext/gd/libgd/gd_io_ss.c index 1ea78d568b..dd96fdfa45 100644 --- a/ext/gd/libgd/gd_io_ss.c +++ b/ext/gd/libgd/gd_io_ss.c @@ -71,7 +71,7 @@ gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk) ctx->ctx.tell = NULL; ctx->ctx.seek = NULL; - ctx->ctx.free = gdFreeSsCtx; + ctx->ctx.gd_free = gdFreeSsCtx; return (gdIOCtx *) ctx; } diff --git a/ext/gd/libgd/gd_jpeg.c b/ext/gd/libgd/gd_jpeg.c index 96b895ec38..b0bfb0a065 100644 --- a/ext/gd/libgd/gd_jpeg.c +++ b/ext/gd/libgd/gd_jpeg.c @@ -1,5 +1,3 @@ - - /* * gd_jpeg.c: Read and write JPEG (JFIF) format image files using the * gd graphics library (http://www.boutell.com/gd/). @@ -20,20 +18,21 @@ * major CGI brain damage */ -/* TBB: move this up so include files are not brought in */ -#ifdef HAVE_LIBJPEG - #include <stdio.h> #include <stdlib.h> #include <setjmp.h> #include <limits.h> #include <string.h> +#include "gd.h" +/* TBB: move this up so include files are not brought in */ +/* JCE: arrange HAVE_LIBJPEG so that it can be set in gd.h */ +#ifdef HAVE_LIBJPEG +#include "gdhelpers.h" + /* 1.8.1: remove dependency on jinclude.h */ #include "jpeglib.h" #include "jerror.h" -#include "gd.h" -#include "gdhelpers.h" static const char *const GD_JPEG_VERSION = "1.0"; @@ -85,7 +84,7 @@ gdImageJpeg (gdImagePtr im, FILE * outFile, int quality) { gdIOCtx *out = gdNewFileCtx (outFile); gdImageJpegCtx (im, out, quality); - out->free (out); + out->gd_free (out); } void * @@ -95,7 +94,7 @@ gdImageJpegPtr (gdImagePtr im, int *size, int quality) gdIOCtx *out = gdNewDynamicCtx (2048, NULL); gdImageJpegCtx (im, out, quality); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } @@ -249,7 +248,6 @@ gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality) } } jpeg_finish_compress (&cinfo); -/*error:*/ jpeg_destroy_compress (&cinfo); gdFree (row); } @@ -260,7 +258,7 @@ gdImageCreateFromJpeg (FILE * inFile) gdImagePtr im; gdIOCtx *in = gdNewFileCtx (inFile); im = gdImageCreateFromJpegCtx (in); - in->free (in); + in->gd_free (in); return im; } diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c index 19f74cdef2..1c91eaa16c 100644 --- a/ext/gd/libgd/gd_png.c +++ b/ext/gd/libgd/gd_png.c @@ -1,11 +1,12 @@ - -#ifdef HAVE_LIBPNG - #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include "gd.h" + +/* JCE: Arrange HAVE_LIBPNG so that it can be set in gd.h */ +#ifdef HAVE_LIBPNG + #include "gdhelpers.h" #include "png.h" /* includes zlib.h and setjmp.h */ @@ -101,7 +102,7 @@ gdImageCreateFromPng (FILE * inFile) gdImagePtr im; gdIOCtx *in = gdNewFileCtx (inFile); im = gdImageCreateFromPngCtx (in); - in->free (in); + in->gd_free (in); return im; } @@ -125,7 +126,7 @@ gdImageCreateFromPngCtx (gdIOCtx * infile) png_bytep image_data = NULL; png_bytepp row_pointers = NULL; gdImagePtr im = NULL; - int i, j, *open; + int i, j, *open = NULL; png_uint_32 ui, uj; volatile int transparent = -1; volatile int palette_allocated = FALSE; @@ -422,7 +423,7 @@ gdImagePng (gdImagePtr im, FILE * outFile) { gdIOCtx *out = gdNewFileCtx (outFile); gdImagePngCtx (im, out); - out->free (out); + out->gd_free (out); } void * @@ -432,7 +433,7 @@ gdImagePngPtr (gdImagePtr im, int *size) gdIOCtx *out = gdNewDynamicCtx (2048, NULL); gdImagePngCtx (im, out); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } @@ -443,7 +444,7 @@ gdImagePngPtr (gdImagePtr im, int *size) void gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile) { - int i, j, bit_depth, interlace_type; + int i, j, bit_depth = 0, interlace_type; int width = im->sx; int height = im->sy; int colors = im->colorsTotal; diff --git a/ext/gd/libgd/gd_ss.c b/ext/gd/libgd/gd_ss.c index 200442ba0f..d640a2193d 100644 --- a/ext/gd/libgd/gd_ss.c +++ b/ext/gd/libgd/gd_ss.c @@ -16,12 +16,13 @@ extern gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource); /*#define GD_SS_DBG(s) (s) */ #define GD_SS_DBG(s) +#ifdef HAVE_LIBPNG void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) { gdIOCtx *out = gdNewSSCtx (NULL, outSink); gdImagePngCtx (im, out); - out->free (out); + out->gd_free (out); } gdImagePtr @@ -32,7 +33,21 @@ gdImageCreateFromPngSource (gdSourcePtr inSource) im = gdImageCreateFromPngCtx (in); - in->free (in); + in->gd_free (in); return im; } +#else /* no HAVE_LIBPNG */ +void +gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) +{ + fprintf(stderr,"PNG support is not available\n"); +} +gdImagePtr +gdImageCreateFromPngSource (gdSourcePtr inSource) +{ + fprintf(stderr,"PNG support is not available\n"); + return NULL; +} +#endif /* HAVE_LIBPNG */ + diff --git a/ext/gd/libgd/gd_wbmp.c b/ext/gd/libgd/gd_wbmp.c index c7948f9865..02abaf6a5b 100644 --- a/ext/gd/libgd/gd_wbmp.c +++ b/ext/gd/libgd/gd_wbmp.c @@ -188,7 +188,7 @@ gdImageCreateFromWBMP (FILE * inFile) gdImagePtr im; gdIOCtx *in = gdNewFileCtx (inFile); im = gdImageCreateFromWBMPCtx (in); - in->free (in); + in->gd_free (in); return (im); } @@ -200,7 +200,7 @@ gdImageWBMP (gdImagePtr im, int fg, FILE * outFile) { gdIOCtx *out = gdNewFileCtx (outFile); gdImageWBMPCtx (im, fg, out); - out->free (out); + out->gd_free (out); } /* gdImageWBMPPtr @@ -213,6 +213,6 @@ gdImageWBMPPtr (gdImagePtr im, int *size, int fg) gdIOCtx *out = gdNewDynamicCtx (2048, NULL); gdImageWBMPCtx (im, fg, out); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } diff --git a/ext/gd/libgd/gdcache.h b/ext/gd/libgd/gdcache.h index f2e8509106..2446d614bd 100644 --- a/ext/gd/libgd/gdcache.h +++ b/ext/gd/libgd/gdcache.h @@ -40,7 +40,10 @@ /* header */ /*********************************************************/ -#include <malloc.h> +#include <stdlib.h> +#ifdef HAVE_MALLOC_H + #include <malloc.h> +#endif #ifndef NULL #define NULL (void *)0 #endif diff --git a/ext/gd/libgd/gdft.c b/ext/gd/libgd/gdft.c index 520e49f351..8345c78894 100644 --- a/ext/gd/libgd/gdft.c +++ b/ext/gd/libgd/gdft.c @@ -15,7 +15,7 @@ #ifndef MSWIN32 #include <unistd.h> #else -#define R_OK 2 +#include <io.h> #endif #ifdef WIN32 extern int access(const char *pathname, int mode); @@ -352,7 +352,6 @@ fontFetch (char **error, void *key) fontsearchpath = getenv ("GDFONTPATH"); if (!fontsearchpath) fontsearchpath = DEFAULT_FONTPATH; - path = strdup (fontsearchpath); fontlist = strdup (a->fontlist); /* @@ -362,6 +361,8 @@ fontFetch (char **error, void *key) name = gd_strtok_r (0, LISTSEPARATOR, &strtok_ptr)) { + /* make a fresh copy each time - strtok corrupts it. */ + path = strdup (fontsearchpath); /* * Allocate an oversized buffer that is guaranteed to be * big enough for all paths to be tested. @@ -369,7 +370,7 @@ fontFetch (char **error, void *key) fullname = gdRealloc (fullname, strlen (fontsearchpath) + strlen (name) + 6); /* if name is an absolute filename then test directly */ - if (*name == '/') + if (*name == '/' || (name[0] != 0 && name[1] == ':' && (name[2] == '/' || name[2] == '\\'))) { sprintf (fullname, "%s", name); if (access (fullname, R_OK) == 0) @@ -387,11 +388,23 @@ fontFetch (char **error, void *key) font_found++; break; } + sprintf (fullname, "%s/%s.pfa", dir, name); + if (access (fullname, R_OK) == 0) + { + font_found++; + break; } - if (font_found) + sprintf (fullname, "%s/%s.pfb", dir, name); + if (access (fullname, R_OK) == 0) + { + font_found++; break; } + } gdFree (path); + if (font_found) + break; + } gdFree (fontlist); if (!font_found) { @@ -481,7 +494,10 @@ tweenColorTest (void *element, void *key) * Computes a color in im's color table that is part way between * the background and foreground colors proportional to the gray * pixel value in the range 0-NUMCOLORS. The fg and bg colors must already - * be in the color table. + * be in the color table for palette images. For truecolor images the + * returned value simply has an alpha component and gdImageAlphaBlend + * does the work so that text can be alpha blended across a complex + * background (TBB; and for real in 2.0.2). */ static void * tweenColorFetch (char **error, void *key) @@ -500,31 +516,34 @@ tweenColorFetch (char **error, void *key) /* if fg is specified by a negative color idx, then don't antialias */ if (fg < 0) { + if ((pixel + pixel) >= NUMCOLORS) a->tweencolor = -fg; + else + a->tweencolor = bg; } else { npixel = NUMCOLORS - pixel; if (im->trueColor) - { - /* 2.0.1: use gdImageSetPixel to do the alpha blending work, - or to just store the alpha level. All we have to do here - is incorporate our knowledge of the percentage of this - pixel that is really "lit" by pushing the alpha value - up toward transparency in edge regions. */ - a->tweencolor = gdTrueColorAlpha ( - gdTrueColorGetRed (fg), - gdTrueColorGetGreen (fg), - gdTrueColorGetBlue (fg), - gdAlphaMax - ((gdAlphaMax - gdTrueColorGetAlpha (fg)) * pixel / NUMCOLORS) ); - } + { + /* 2.0.1: use gdImageSetPixel to do the alpha blending work, + or to just store the alpha level. All we have to do here + is incorporate our knowledge of the percentage of this + pixel that is really "lit" by pushing the alpha value + up toward transparency in edge regions. */ + a->tweencolor = gdTrueColorAlpha ( + gdTrueColorGetRed (fg), + gdTrueColorGetGreen (fg), + gdTrueColorGetBlue (fg), + gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS)); + } else - { + { a->tweencolor = gdImageColorResolve (im, (pixel * im->red[fg] + npixel * im->red[bg]) / NUMCOLORS, (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS, (pixel * im->blue[fg] + npixel * im->blue[bg]) / NUMCOLORS); - } + } } return (void *) a; } @@ -537,29 +556,84 @@ tweenColorRelease (void *element) /* draw_bitmap - transfers glyph bitmap to GD image */ static char * -gdft_draw_bitmap (gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y) +gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y) { - unsigned char *pixel; + unsigned char *pixel = NULL; + int *tpixel = NULL; int x, y, row, col, pc; tweencolor_t *tc_elem; tweencolorkey_t tc_key; - /* initialize tweenColorCache on first call */ - static gdCache_head_t *tc_cache; - - if (!tc_cache) - { - tc_cache = gdCacheCreate (TWEENCOLORCACHESIZE, - tweenColorTest, tweenColorFetch, tweenColorRelease); - } - /* copy to image, mapping colors */ tc_key.fgcolor = fg; tc_key.im = im; + /* Truecolor version; does not require the cache */ + if (im->trueColor) + { + for (row = 0; row < bitmap.rows; row++) + { + pc = row * bitmap.pitch; + y = pen_y + row; + /* clip if out of bounds */ + if (y >= im->sy || y < 0) + continue; + for (col = 0; col < bitmap.width; col++, pc++) + { + int level; + if (bitmap.pixel_mode == ft_pixel_mode_grays) + { + /* + * Scale to 128 levels of alpha for gd use. + * alpha 0 is opacity, so be sure to invert at the end + */ + level = (bitmap.buffer[pc] * gdAlphaMax / + (bitmap.num_grays - 1)); + } + else if (bitmap.pixel_mode == ft_pixel_mode_mono) + { + level = ((bitmap.buffer[pc / 8] + << (pc % 8)) & 128) ? gdAlphaOpaque : + gdAlphaTransparent; + } + else + { + return "Unsupported ft_pixel_mode"; + } + if (fg >= 0) { + /* Consider alpha in the foreground color itself to be an + upper bound on how opaque things get */ + level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax; + } + level = gdAlphaMax - level; + x = pen_x + col; + /* clip if out of bounds */ + if (x >= im->sx || x < 0) + continue; + /* get pixel location in gd buffer */ + tpixel = &im->tpixels[y][x]; + if (fg < 0) { + if (level < (gdAlphaMax / 2)) { + *tpixel = -fg; + } + } else { + if (im->alphaBlendingFlag) { + *tpixel = gdAlphaBlend(*tpixel, (level << 24) + (fg & 0xFFFFFF)); + } else { + *tpixel = (level << 24) + (fg & 0xFFFFFF); + } + } + } + } + return (char *) NULL; + } + /* Non-truecolor case, restored to its more or less original form */ for (row = 0; row < bitmap.rows; row++) { pc = row * bitmap.pitch; + if(bitmap.pixel_mode==ft_pixel_mode_mono) + pc *= 8; /* pc is measured in bits for monochrome images */ + y = pen_y + row; /* clip if out of bounds */ @@ -568,53 +642,49 @@ gdft_draw_bitmap (gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y) for (col = 0; col < bitmap.width; col++, pc++) { - x = pen_x + col; - - /* clip if out of bounds */ - if (x >= im->sx || x < 0) - continue; - - switch(bitmap.pixel_mode) { - case ft_pixel_mode_grays: + if (bitmap.pixel_mode == ft_pixel_mode_grays) + { /* * Round to NUMCOLORS levels of antialiasing for * index color images since only 256 colors are * available. */ - tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS) + bitmap.num_grays / 2) / (bitmap.num_grays - 1); - break; - case ft_pixel_mode_mono: + } + else if (bitmap.pixel_mode == ft_pixel_mode_mono) + { tc_key.pixel = ((bitmap.buffer[pc / 8] << (pc % 8)) & 128) ? NUMCOLORS : 0; - break; - default: + } + else + { return "Unsupported ft_pixel_mode"; } - - if (tc_key.pixel > 0) + if (tc_key.pixel > 0) /* if not background */ + { + x = pen_x + col; + + /* clip if out of bounds */ + if (x >= im->sx || x < 0) + continue; + /* get pixel location in gd buffer */ + pixel = &im->pixels[y][x]; + if (tc_key.pixel == NUMCOLORS) { - - if (im->trueColor) { - tc_elem = (tweencolor_t *) gdCacheGet ( - tc_cache, &tc_key); - - gdImageSetPixel(im, x, y, tc_elem->tweencolor); + /* use fg color directly. gd 2.0.2: watch out for + negative indexes (thanks to David Marwood). */ + *pixel = (fg < 0) ? -fg : fg; } - else { - pixel = &im->pixels[y][x]; - if (tc_key.pixel == NUMCOLORS) - *pixel = fg; - else { - tc_key.bgcolor = *pixel; + else + { + /* find antialised color */ + + tc_key.bgcolor = *pixel; tc_elem = (tweencolor_t *) gdCacheGet ( tc_cache, &tc_key); - *pixel = tc_elem->tweencolor; - - } - + *pixel = tc_elem->tweencolor; } } } @@ -622,23 +692,38 @@ gdft_draw_bitmap (gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y) return (char *) NULL; } +static int +gdroundupdown (FT_F26Dot6 v1, int updown) +{ + return (!updown) + ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) + : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6); +} + extern int any2eucjp (char *, char *, unsigned int); +/* Persistent font cache until explicitly cleared */ +/* Fonts can be used across multiple images */ +static gdCache_head_t *fontCache; +static FT_Library library; + +void +gdFreeFontCache() +{ + if (fontCache) + { + gdCacheDelete(fontCache); + FT_Done_FreeType(library); + } +} + /********************************************************************/ /* gdImageStringFT - render a utf8 string onto a gd image */ char * gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string) + double ptsize, double angle, int x, int y, char *string) { - return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, NULL); -} - -static int -gdroundupdown (FT_F26Dot6 v1, int updown) -{ - return (!updown) - ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) - : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6); + return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, NULL); } char * @@ -665,18 +750,30 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, char *tmpstr = 0; int render = (im && (im->trueColor || (fg <= 255 && fg >= -255))); FT_BitmapGlyph bm; + int render_mode = FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT; + + /* fine tuning */ + double linespace = LINESPACE; + + /* + * make a new tweenColorCache on every call + * because caching colormappings between calls + * is not safe. If the im-pointer points to a + * brand new image, the cache gives out bogus + * colorindexes. -- 27.06.2001 <krisku@arrak.fi> + */ + gdCache_head_t *tc_cache; + + tc_cache = gdCacheCreate( TWEENCOLORCACHESIZE, + tweenColorTest, tweenColorFetch, tweenColorRelease ); - /* fine tuning */ - double linespace = LINESPACE; - /***** initialize font library and font cache on first call ******/ - static gdCache_head_t *fontCache; - static FT_Library library; if (!fontCache) { if (FT_Init_FreeType (&library)) { + gdCacheDelete( tc_cache ); return "Failure to initialize font library"; } fontCache = gdCacheCreate (FONTCACHESIZE, @@ -690,6 +787,7 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, font = (font_t *) gdCacheGet (fontCache, &fontkey); if (!font) { + gdCacheDelete( tc_cache ); return fontCache->error; } face = font->face; /* shortcut */ @@ -698,17 +796,16 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, if (FT_Set_Char_Size (face, 0, (FT_F26Dot6) (ptsize * 64), GD_RESOLUTION, GD_RESOLUTION)) { + gdCacheDelete( tc_cache ); return "Could not set character size"; } - /* pull in supplied extended settings */ - if (strex) { - if ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE) - linespace = strex->linespacing; - - } + /* pull in supplied extended settings */ + if (strex) { + if ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE) + linespace = strex->linespacing; + } - matrix.xx = (FT_Fixed) (cos_a * (1 << 16)); matrix.yx = (FT_Fixed) (sin_a * (1 << 16)); matrix.xy = -matrix.yx; @@ -720,12 +817,16 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, use_kerning = FT_HAS_KERNING (face); previous = 0; + if (fg < 0) + { + render_mode |= FT_LOAD_MONOCHROME; + } #ifndef JISX0208 if (font->have_char_map_sjis) { #endif - if ((tmpstr = (char *) gdMalloc (BUFSIZ)) != NULL) + if ((tmpstr = (char *) gdMalloc (BUFSIZ))) { any2eucjp (tmpstr, string, BUFSIZ); next = tmpstr; @@ -749,8 +850,8 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, if (ch == '\r') { penf.x = 0; - x1 = (int)(penf.x * cos_a - penf.y * sin_a + 32) / 64; - y1 = (int)(penf.x * sin_a + penf.y * cos_a + 32) / 64; + x1 = (penf.x * cos_a - penf.y * sin_a + 32) / 64; + y1 = (penf.x * sin_a + penf.y * cos_a + 32) / 64; pen.x = pen.y = 0; previous = 0; /* clear kerning flag */ next++; @@ -759,10 +860,10 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, /* newlines */ if (ch == '\n') { - penf.y -= (long)(face->size->metrics.height * linespace); + penf.y -= face->size->metrics.height * LINESPACE; penf.y = (penf.y - 32) & -64; /* round to next pixel row */ - x1 = (int)(penf.x * cos_a - penf.y * sin_a + 32) / 64; - y1 = (int)(penf.x * sin_a + penf.y * cos_a + 32) / 64; + x1 = (penf.x * cos_a - penf.y * sin_a + 32) / 64; + y1 = (penf.x * sin_a + penf.y * cos_a + 32) / 64; pen.x = pen.y = 0; previous = 0; /* clear kerning flag */ next++; @@ -826,6 +927,9 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, } } + /* set rotation transform */ + FT_Set_Transform(face, &matrix, NULL); + /* Convert character code to glyph index */ glyph_index = FT_Get_Char_Index (face, ch); @@ -838,24 +942,33 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, } /* load glyph image into the slot (erase previous one) */ - err = FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT); + err = FT_Load_Glyph (face, glyph_index, render_mode); if (err) + { + gdCacheDelete( tc_cache ); return "Problem loading glyph"; + } /* transform glyph image */ FT_Get_Glyph (slot, &image); if (brect) { /* only if need brect */ FT_Glyph_Get_CBox (image, ft_glyph_bbox_gridfit, &glyph_bbox); - if (!i) - { /* if first character, init BB corner values */ - bbox.xMin = bbox.yMin = (1 << 30) - 1; - bbox.xMax = bbox.yMax = -bbox.xMin; - } glyph_bbox.xMin += penf.x; glyph_bbox.yMin += penf.y; glyph_bbox.xMax += penf.x; glyph_bbox.yMax += penf.y; + if (ch == ' ') /* special case for trailing space */ + glyph_bbox.xMax += slot->metrics.horiAdvance; + if (!i) + { /* if first character, init BB corner values */ + bbox.xMin = glyph_bbox.xMin; + bbox.yMin = glyph_bbox.yMin; + bbox.xMax = glyph_bbox.xMax; + bbox.yMax = glyph_bbox.yMax; + } + else + { if (bbox.xMin > glyph_bbox.xMin) bbox.xMin = glyph_bbox.xMin; if (bbox.yMin > glyph_bbox.yMin) @@ -864,24 +977,25 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, bbox.xMax = glyph_bbox.xMax; if (bbox.yMax < glyph_bbox.yMax) bbox.yMax = glyph_bbox.yMax; + } i++; } - /* transform glyph image */ - FT_Glyph_Transform (image, &matrix, 0); - if (render) { if (image->format != ft_glyph_format_bitmap) { err = FT_Glyph_To_Bitmap (&image, ft_render_mode_normal, 0, 1); if (err) + { + gdCacheDelete( tc_cache ); return "Problem rendering glyph"; } + } /* now, draw to our target surface */ bm = (FT_BitmapGlyph) image; - gdft_draw_bitmap (im, fg, bm->bitmap, + gdft_draw_bitmap (tc_cache, im, fg, bm->bitmap, x + x1 + ((pen.x + 31) >> 6) + bm->left, y - y1 + ((pen.y + 31) >> 6) - bm->top); } @@ -927,6 +1041,7 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, if (tmpstr) gdFree (tmpstr); + gdCacheDelete( tc_cache ); return (char *) NULL; } diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h index aefcc18b99..fdc690a2ec 100644 --- a/ext/gd/libgd/gdhelpers.h +++ b/ext/gd/libgd/gdhelpers.h @@ -1,6 +1,8 @@ #ifndef GDHELPERS_H #define GDHELPERS_H 1 +#include <sys/types.h> + /* TBB: strtok_r is not universal; provide an implementation of it. */ extern char *gd_strtok_r(char *s, char *sep, char **state); diff --git a/ext/gd/libgd/gdkanji.c b/ext/gd/libgd/gdkanji.c index 98ed4b7c7a..21eb2d373d 100644 --- a/ext/gd/libgd/gdkanji.c +++ b/ext/gd/libgd/gdkanji.c @@ -360,7 +360,7 @@ do_convert (unsigned char *to, unsigned char *from, const char *code) from_len = strlen ((const char *) from) + 1; to_len = BUFSIZ; - if (iconv (cd, (const char **) &from, &from_len, + if (iconv (cd, (char **) &from, &from_len, (char **) &to, &to_len) == -1) { #ifdef HAVE_ERRNO_H diff --git a/ext/gd/libgd/gdparttopng.c b/ext/gd/libgd/gdparttopng.c index 03386b86be..677a0b5710 100644 --- a/ext/gd/libgd/gdparttopng.c +++ b/ext/gd/libgd/gdparttopng.c @@ -47,7 +47,11 @@ main (int argc, char **argv) gdImageDestroy (im); exit (1); } +#ifdef HAVE_LIBPNG gdImagePng (im, out); +#else + fprintf(stderr, "No PNG library support.\n"); +#endif fclose (out); gdImageDestroy (im); diff --git a/ext/gd/libgd/gdtest.c b/ext/gd/libgd/gdtest.c index 68d1d23a2b..f4300bb3fd 100644 --- a/ext/gd/libgd/gdtest.c +++ b/ext/gd/libgd/gdtest.c @@ -82,7 +82,7 @@ main (int argc, char **argv) CompareImages ("GD->PNG ptr->GD", ref, im2); gdImageDestroy (im2); - ctx->free (ctx); + ctx->gd_free (ctx); /* */ @@ -117,7 +117,7 @@ main (int argc, char **argv) CompareImages ("GD->GD2 ptr->GD", ref, im2); gdImageDestroy (im2); - ctx->free (ctx); + ctx->gd_free (ctx); /* */ @@ -152,7 +152,7 @@ main (int argc, char **argv) CompareImages ("GD->GD ptr->GD", ref, im2); gdImageDestroy (im2); - ctx->free (ctx); + ctx->gd_free (ctx); /* ** Test gdImageCreateFromPngSource' |