From: Jakub Bogusz Date: Fri, 10 Jan 2003 20:49:32 +0000 (+0000) Subject: - updated to 2.0.9 X-Git-Tag: auto/ac/gd-2_0_15-3~19 X-Git-Url: http://git.pld-linux.org/gitweb.cgi?a=commitdiff_plain;h=bd13356b350d4f2c46bd913c90300174f5b81b1f;p=packages%2Fgd.git - updated to 2.0.9 - updated gif patch based on version for gd 2.0.7 - updated fontpath and fixes patches - removed obsolete ac_am,gif-acam,gdTiled-segv patches Changed files: gd-ac_am.patch -> 1.7 gd-fixes.patch -> 1.2 gd-fontpath.patch -> 1.2 gd-gdTiled-segv.patch -> 1.2 gd-gif-acam.patch -> 1.2 gd-gif.patch -> 1.1 gd.spec -> 1.75 --- diff --git a/gd-ac_am.patch b/gd-ac_am.patch deleted file mode 100644 index ebfbc77..0000000 --- a/gd-ac_am.patch +++ /dev/null @@ -1,151 +0,0 @@ -diff -Nru gd-2.0.1/Makefile.am gd-2.0.1.new/Makefile.am ---- gd-2.0.1/Makefile.am Thu Jan 1 01:00:00 1970 -+++ gd-2.0.1.new/Makefile.am Fri Feb 2 00:52:03 2001 -@@ -0,0 +1,96 @@ -+## Process this file with automake to produce Makefile.in -+ -+AUTOMAKE_OPTIONS = 1.4 -+ -+INCLUDES = -I$(includedir)/freetype2 -+ -+lib_LTLIBRARIES = libgd.la -+ -+libgd_la_SOURCES = \ -+ gd.c \ -+ gd_gd.c \ -+ gd_gd2.c \ -+ gd_io.c \ -+ gd_io_dp.c \ -+ gd_io_file.c \ -+ gd_ss.c \ -+ gd_io_ss.c \ -+ gd_png.c \ -+ gd_jpeg.c \ -+ gdxpm.c \ -+ gdfontt.c \ -+ gdfonts.c \ -+ gdfontmb.c \ -+ gdfontl.c \ -+ gdfontg.c \ -+ gdtables.c \ -+ gdft.c \ -+ gdcache.c \ -+ gdkanji.c \ -+ wbmp.c \ -+ gd_wbmp.c \ -+ gdhelpers.c \ -+ gd_topal.c \ -+ gd.h \ -+ gdfontt.h \ -+ gdfonts.h \ -+ gdfontmb.h \ -+ gdfontl.h \ -+ gdfontg.h \ -+ gdhelpers.h -+ -+include_HEADERS = \ -+ gd.h \ -+ gdcache.h \ -+ gd_io.h \ -+ gdfontg.h \ -+ gdfontl.h \ -+ gdfontmb.h \ -+ gdfonts.h \ -+ gdfontt.h -+ -+libgd_la_LDFLAGS = -version-info 2:0:0 -+ -+bin_PROGRAMS = pngtogd pngtogd2 gdtopng gd2topng gd2copypal gdparttopng webpng -+ -+noinst_PROGRAMS = gdtest gddemo gd2time gdtestft testac -+ -+gdtest_SOURCES = gdtest.c gd.h -+gdtest_LDADD = libgd.la -+ -+gdtestft_SOURCES = gdtestft.c gd.h -+gdtestft_LDADD = libgd.la -+ -+gddemo_SOURCES = gddemo.c gd.h gdfonts.h gdfontg.h -+gddemo_LDADD = libgd.la -+ -+testac_SOURCES = testac.c gd.h -+testac_LDADD = libgd.la -+ -+pngtogd_SOURCES = pngtogd.c gd.h -+pngtogd_LDADD = libgd.la -+ -+pngtogd2_SOURCES = pngtogd2.c gd.h -+pngtogd2_LDADD = libgd.la -+ -+gdtopng_SOURCES = gdtopng.c gd.h -+gdtopng_LDADD = libgd.la -+ -+gd2topng_SOURCES = gd2topng.c gd.h -+gd2topng_LDADD = libgd.la -+ -+gd2copypal_SOURCES = gd2copypal.c gd.h -+gd2copypal_LDADD = libgd.la -+ -+gdparttopng_SOURCES = gdparttopng.c gd.h -+gdparttopng_LDADD = libgd.la -+ -+gd2time_SOURCES = gd2time.c gd.h -+gd2time_LDADD = libgd.la -+ -+webpng_SOURCES = webpng.c gd.h -+webpng_LDADD = libgd.la -+ -+EXTRA_DIST = demoin.png index.html test/* -+ -+CLEANFILES = demoout.png -diff -Nru gd-2.0.1/configure.in gd-2.0.1.new/configure.in ---- gd-2.0.1/configure.in Thu Jan 1 01:00:00 1970 -+++ gd-2.0.1.new/configure.in Fri Feb 2 00:45:23 2001 -@@ -0,0 +1,47 @@ -+dnl Process this file with autoconf to produce a configure script -+ -+AC_INIT(configure.in) -+ -+AC_CANONICAL_SYSTEM -+ -+AM_INIT_AUTOMAKE(gd, 2.0.1) -+ -+AM_MAINTAINER_MODE -+ -+dnl Checks for programs. -+AC_PROG_AWK -+AC_PROG_CC -+AC_PROG_INSTALL -+AC_PROG_LN_S -+AC_PROG_MAKE_SET -+AM_PROG_LIBTOOL -+ -+dnl Checks for libraries. -+dnl Replace `main' with a function in -ljpeg: -+AC_CHECK_LIB(jpeg, main, [CFLAGS="$CFLAGS -DHAVE_LIBJPEG"; LIBS="$LIBS -ljpeg"]) -+dnl Replace `main' with a function in -ltiff: -+AC_CHECK_LIB(tiff, main, [CFLAGS="$CFLAGS -DHAVE_LIBTTF"; LIBS="$LIBS -ltiff"]) -+dnl Replace `main' with a function in -ltiff: -+AC_CHECK_LIB(fff, main) -+dnl Replace `main' with a function in -lpng: -+AC_CHECK_LIB(png, main, ,AC_MSG_ERROR(libpng not found.)) -+dnl Replace `main' with a function in -lfreetype: -+AC_CHECK_LIB(freetype, main, [CFLAGS="$CFLAGS -DHAVE_LIBFREETYPE"; LIBS="$LIBS -lfreetype"]) -+dnl Replace `main' with a function in -lm: -+AC_CHECK_LIB(m, main) -+dnl Replace `main' with a function in -lz: -+AC_CHECK_LIB(z, main, ,AC_MSG_ERROR(libz not found.)) -+ -+dnl Checks for header files. -+AC_HEADER_STDC -+AC_CHECK_HEADERS(limits.h malloc.h unistd.h) -+ -+dnl Checks for typedefs, structures, and compiler characteristics. -+AC_C_CONST -+AC_TYPE_SIZE_T -+ -+dnl Checks for library functions. -+AC_FUNC_VPRINTF -+AC_CHECK_FUNCS(strtol) -+ -+AC_OUTPUT(Makefile) diff --git a/gd-fixes.patch b/gd-fixes.patch index 9d3faf0..907fb60 100644 --- a/gd-fixes.patch +++ b/gd-fixes.patch @@ -1,55 +1,3 @@ -diff -Nur gd-2.0.1.orig/gd.c gd-2.0.1/gd.c ---- gd-2.0.1.orig/gd.c Sat Aug 10 23:19:14 2002 -+++ gd-2.0.1/gd.c Sat Aug 10 23:39:35 2002 -@@ -473,6 +473,12 @@ - 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); -@@ -1928,7 +1934,7 @@ - else - { - /* Find or create the best match */ -- mapTo = gdImageColorResolveAlpha (dst, -+ nc = gdImageColorResolveAlpha (dst, - gdTrueColorGetRed (c), - gdTrueColorGetGreen (c), - gdTrueColorGetBlue (c), -@@ -1978,7 +1984,7 @@ - { - for (x = dstX; (x < dstX + dstW); x++) - { -- int pd = gdImageGetPixel (dst, x, y); -+ /* int pd = gdImageGetPixel (dst, x, y); -- not used */ - float sy1, sy2, sx1, sx2; - float sx, sy; - float spixels = 0; -diff -Nur gd-2.0.1.orig/gd_gd2.c gd-2.0.1/gd_gd2.c ---- gd-2.0.1.orig/gd_gd2.c Tue Apr 3 22:44:41 2001 -+++ gd-2.0.1/gd_gd2.c Sat Aug 10 23:48:23 2002 -@@ -635,10 +635,10 @@ - { - if (im->trueColor) - { -- ch = chunkBuf[chunkPos++] << 24 + -- chunkBuf[chunkPos++] << 16 + -- chunkBuf[chunkPos++] << 8 + -- chunkBuf[chunkPos++]; -+ ch = chunkBuf[chunkPos++] << 24; -+ ch += chunkBuf[chunkPos++] << 16; -+ ch += chunkBuf[chunkPos++] << 8; -+ ch += chunkBuf[chunkPos++]; - } - else - { diff -Nur gd-2.0.1.orig/gd_topal.c gd-2.0.1/gd_topal.c --- gd-2.0.1.orig/gd_topal.c Tue Apr 3 22:44:42 2001 +++ gd-2.0.1/gd_topal.c Sat Aug 10 23:55:17 2002 @@ -62,304 +10,3 @@ diff -Nur gd-2.0.1.orig/gd_topal.c gd-2.0.1/gd_topal.c for (ic3 = BOX_C3_ELEMS - 1; ic3 >= 0; ic3--) { if (dist3 < *bptr) -diff -Nur gd-2.0.1.orig/gdft.c gd-2.0.1/gdft.c ---- gd-2.0.1.orig/gdft.c Tue Apr 3 22:44:42 2001 -+++ gd-2.0.1/gdft.c Sun Aug 11 00:19:56 2002 -@@ -349,7 +349,6 @@ - fontsearchpath = getenv ("GDFONTPATH"); - if (!fontsearchpath) - fontsearchpath = DEFAULT_FONTPATH; -- path = strdup (fontsearchpath); - fontlist = strdup (a->fontlist); - - /* -@@ -358,7 +357,8 @@ - for (name = gd_strtok_r (fontlist, LISTSEPARATOR, &strtok_ptr); name; - 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. -@@ -384,11 +384,23 @@ - font_found++; - break; - } -+ sprintf (fullname, "%s/%s.pfa", dir, name); -+ if (access (fullname, R_OK) == 0) -+ { -+ font_found++; -+ break; -+ } -+ sprintf (fullname, "%s/%s.pfb", dir, name); -+ if (access (fullname, R_OK) == 0) -+ { -+ font_found++; -+ break; -+ } - } - if (font_found) - break; -+ gdFree (path); - } -- gdFree (path); - gdFree (fontlist); - if (!font_found) - { -@@ -497,7 +509,10 @@ - /* if fg is specified by a negative color idx, then don't antialias */ - if (fg < 0) - { -- a->tweencolor = -fg; -+ if ((pixel + pixel) >= NUMCOLORS) -+ a->tweencolor = -fg; -+ else -+ a->tweencolor = bg; - } - else - { -@@ -534,7 +549,7 @@ - - /* 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; - int *tpixel; -@@ -543,21 +558,15 @@ - 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; - 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 */ -@@ -608,11 +617,11 @@ - /* use fg color directly */ - if (im->trueColor) - { -- *tpixel = fg; -+ *tpixel = abs( fg ); - } - else - { -- *pixel = fg; -+ *pixel = abs( fg ); - } - } - else -@@ -643,8 +652,29 @@ - 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 */ - -@@ -671,15 +701,26 @@ - 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; - --/***** initialize font library and font cache on first call ******/ -- static gdCache_head_t *fontCache; -- static FT_Library library; -+ /* -+ * 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 -+ */ -+ gdCache_head_t *tc_cache; -+ -+ tc_cache = gdCacheCreate( TWEENCOLORCACHESIZE, -+ tweenColorTest, tweenColorFetch, tweenColorRelease ); - -+/***** initialize font library and font cache on first call ******/ - if (!fontCache) - { - if (FT_Init_FreeType (&library)) - { -+ gdCacheDelete( tc_cache ); - return "Failure to initialize font library"; - } - fontCache = gdCacheCreate (FONTCACHESIZE, -@@ -693,6 +734,7 @@ - font = (font_t *) gdCacheGet (fontCache, &fontkey); - if (!font) - { -+ gdCacheDelete( tc_cache ); - return fontCache->error; - } - face = font->face; /* shortcut */ -@@ -701,6 +743,7 @@ - if (FT_Set_Char_Size (face, 0, (FT_F26Dot6) (ptsize * 64), - GD_RESOLUTION, GD_RESOLUTION)) - { -+ gdCacheDelete( tc_cache ); - return "Could not set character size"; - } - -@@ -715,6 +758,10 @@ - - use_kerning = FT_HAS_KERNING (face); - previous = 0; -+ if (fg < 0) -+ { -+ render_mode |= FT_LOAD_MONOCHROME; -+ } - - #ifndef JISX0208 - if (font->have_char_map_sjis) -@@ -821,6 +868,9 @@ - } - } - -+ /* set rotation transform */ -+ FT_Set_Transform(face, &matrix, NULL); -+ - /* Convert character code to glyph index */ - glyph_index = FT_Get_Char_Index (face, ch); - -@@ -833,50 +883,60 @@ - } - - /* 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) -- return "Problem loading glyph"; -+ { -+ 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 (bbox.xMin > glyph_bbox.xMin) -- bbox.xMin = glyph_bbox.xMin; -- if (bbox.yMin > glyph_bbox.yMin) -- bbox.yMin = glyph_bbox.yMin; -- if (bbox.xMax < glyph_bbox.xMax) -- bbox.xMax = glyph_bbox.xMax; -- if (bbox.yMax < glyph_bbox.yMax) -- bbox.yMax = glyph_bbox.yMax; -+ 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) -+ bbox.yMin = glyph_bbox.yMin; -+ if (bbox.xMax < glyph_bbox.xMax) -+ 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) -- return "Problem rendering glyph"; -+ { -+ 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); - } -@@ -922,15 +982,8 @@ - - if (tmpstr) - gdFree (tmpstr); -+ gdCacheDelete (tc_cache); - return (char *) NULL; - } - --int --gdroundupdown (FT_F26Dot6 v1, int updown) --{ -- return (!updown) -- ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) -- : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6); --} -- - #endif /* HAVE_LIBFREETYPE */ diff --git a/gd-fontpath.patch b/gd-fontpath.patch index 43b0836..54a88a9 100644 --- a/gd-fontpath.patch +++ b/gd-fontpath.patch @@ -1,10 +1,10 @@ ---- gd-2.0.1/gd.h.orig Sat Aug 10 17:22:09 2002 -+++ gd-2.0.1/gd.h Sat Aug 10 18:08:33 2002 -@@ -6,7 +6,7 @@ +--- gd-2.0.9/gd.h.orig Wed Dec 11 17:37:14 2002 ++++ gd-2.0.9/gd.h Fri Jan 10 21:03:16 2003 +@@ -7,7 +7,7 @@ #endif - /* default fontpath for unix systems */ --#define DEFAULT_FONTPATH "/usr/share/fonts/truetype" + /* default fontpath for unix systems - whatever happened to standards ! */ +-#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 DEFAULT_FONTPATH "/usr/share/fonts/TTF:/usr/share/fonts/Type1" #define PATHSEPARATOR ":" diff --git a/gd-gdTiled-segv.patch b/gd-gdTiled-segv.patch deleted file mode 100644 index 7c6626d..0000000 --- a/gd-gdTiled-segv.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- gd-2.0.1/gd.c.orig Sat Aug 10 21:52:54 2002 -+++ gd-2.0.1/gd.c Sat Aug 10 21:53:36 2002 -@@ -748,6 +748,7 @@ - } - else - { -+ p = gdImageGetPixel (im->tile, srcx, srcy); - /* Allow for transparency */ - if (p != gdImageGetTransparent (im->tile)) - { diff --git a/gd-gif-acam.patch b/gd-gif-acam.patch deleted file mode 100644 index 6875ecc..0000000 --- a/gd-gif-acam.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff -Nur gd-2.0.1.orig/Makefile.am gd-2.0.1/Makefile.am ---- gd-2.0.1.orig/Makefile.am Sat Aug 10 17:03:27 2002 -+++ gd-2.0.1/Makefile.am Sat Aug 10 17:13:28 2002 -@@ -31,6 +31,10 @@ - gd_wbmp.c \ - gdhelpers.c \ - gd_topal.c \ -+ gd_gif_in.c \ -+ gd_gif_out.c \ -+ gd_biggif_out.c \ -+ gd_lzw_out.c \ - gd.h \ - gdfontt.h \ - gdfonts.h \ -@@ -51,7 +55,7 @@ - - libgd_la_LDFLAGS = -version-info 2:0:0 - --bin_PROGRAMS = pngtogd pngtogd2 gdtopng gd2topng gd2copypal gdparttopng webpng -+bin_PROGRAMS = pngtogd pngtogd2 gdtopng gd2topng gd2copypal gdparttopng webpng gd2togif gdcmpgif giftogd2 - - noinst_PROGRAMS = gdtest gddemo gd2time gdtestft testac - -@@ -91,6 +95,15 @@ - webpng_SOURCES = webpng.c gd.h - webpng_LDADD = libgd.la - -+gd2togif_SOURCES = gd2togif.c gd.h -+gd2togif_LDADD = libgd.la -+ -+gdcmpgif_SOURCES = gdcmpgif.c gd.h -+gdcmpgif_LDADD = libgd.la -+ -+giftogd2_SOURCES = giftogd2.c gd.h -+giftogd2_LDADD = libgd.la -+ - EXTRA_DIST = demoin.png index.html test/* - - CLEANFILES = demoout.png -diff -Nur gd-2.0.1.orig/gd_gif_out.c gd-2.0.1/gd_gif_out.c ---- gd-2.0.1.orig/gd_gif_out.c Sat Aug 10 17:03:27 2002 -+++ gd-2.0.1/gd_gif_out.c Sat Aug 10 17:12:39 2002 -@@ -8,8 +8,6 @@ - ** Wrapper functions for GIF output. - */ - --#define LZW_LICENCED -- - void gdImageGifToSink(gdImagePtr im, gdSinkPtr outSink) - { - gdIOCtx *out = gdNewSSCtx(NULL,outSink); -diff -Nur gd-2.0.1.orig/gd_lzw_out.c gd-2.0.1/gd_lzw_out.c ---- gd-2.0.1.orig/gd_lzw_out.c Sat Aug 10 17:03:27 2002 -+++ gd-2.0.1/gd_lzw_out.c Sat Aug 10 17:12:39 2002 -@@ -1,3 +1,4 @@ -+#ifdef LZW_LICENCED - #include - #include - #include -@@ -794,3 +795,4 @@ - /* | notice appear in supporting documentation. This software is | */ - /* | provided "as is" without express or implied warranty. | */ - /* +-------------------------------------------------------------------+ */ -+#endif diff --git a/gd-gif.patch b/gd-gif.patch new file mode 100644 index 0000000..dd2f472 --- /dev/null +++ b/gd-gif.patch @@ -0,0 +1,3019 @@ +--- gd-2.0.9/Makefile.am.orig Tue Nov 12 20:29:13 2002 ++++ gd-2.0.9/Makefile.am Fri Jan 10 21:34:04 2003 +@@ -5,7 +5,7 @@ + + SUBDIRS = config test + +-bin_PROGRAMS = annotate gdparttopng gdtopng gd2copypal gd2topng pngtogd pngtogd2 webpng ++bin_PROGRAMS = annotate gdparttopng gdtopng gd2copypal gd2topng pngtogd pngtogd2 webpng gd2togif gdcmpgif giftogd2 + + bin_SCRIPTS = bdftogd + +@@ -17,7 +17,7 @@ + + lib_LTLIBRARIES = libgd.la + +-libgd_la_SOURCES = gd.c gd_gd.c gd_gd2.c gd_io.c gd_io_dp.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_topal.c gd_wbmp.c gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c gdft.c gdhelpers.c gdhelpers.h gdkanji.c gdtables.c gdxpm.c jisx0208.h mathmake.c wbmp.c wbmp.h ++libgd_la_SOURCES = gd.c gd_gd.c gd_gd2.c gd_io.c gd_io_dp.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_topal.c gd_wbmp.c gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c gdft.c gdhelpers.c gdhelpers.h gdkanji.c gdtables.c gdxpm.c jisx0208.h mathmake.c wbmp.c wbmp.h gd_gif_in.c gd_gif_out.c gd_biggif_out.c gd_lzw_out.c + + libgd_la_LDFLAGS = -version-info 2:0:0 + +diff -Naur gd-2.0.7orig/gd.c gd-2.0.7gif/gd.c +--- gd-2.0.7orig/gd.c 2002-11-15 02:36:11.000000000 +1100 ++++ gd-2.0.7gif/gd.c 2002-11-18 11:39:01.000000000 +1100 +@@ -1831,22 +1831,24 @@ + tox++; + continue; + } +- /* If it's the same image, mapping is trivial */ +- if (dst == src) ++ /* If it's the same image, mapping is NOT trivial since we merge with greyscale target, ++ * but if pct is 100, the grey value is not used, so it becomes trivial. */ ++ if (dst == src && pct == 100) + { + nc = 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) +- + gdImageRed (dst, dc) * g * ((100 - pct) / 100.0); ++ + g * ((100 - pct) / 100.0); + ncG = gdImageGreen (src, c) * (pct / 100.0) +- + gdImageGreen (dst, dc) * g * ((100 - pct) / 100.0); ++ + g * ((100 - pct) / 100.0); + ncB = gdImageBlue (src, c) * (pct / 100.0) +- + gdImageBlue (dst, dc) * g * ((100 - pct) / 100.0); ++ + g * ((100 - pct) / 100.0); + + /* First look for an exact match */ +@@ -2253,7 +2254,17 @@ + } + + void +-gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c) ++gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c) ++{ ++ if (!n) { ++ return; ++ } ++ gdImageLine(im, p->x, p->y, p[n-1].x, p[n-1].y, c); ++ gdImageOpenPolygon(im, p, n, c); ++} ++ ++void ++gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c) + { + int i; + int lx, ly; +@@ -2263,7 +2274,6 @@ + } + lx = p->x; + ly = p->y; +- gdImageLine (im, lx, ly, p[n - 1].x, p[n - 1].y, c); + for (i = 1; (i < n); i++) + { + p++; +@@ -2503,8 +2513,8 @@ + { + for (x = 0; (x < sx); x++) + { +- p1 = im1->pixels[y][x]; +- p2 = im2->pixels[y][x]; ++ p1 = im1->trueColor ? gdImageTrueColorPixel(im1, x, y) : gdImagePalettePixel(im1, x, y); ++ p2 = im2->trueColor ? gdImageTrueColorPixel(im2, x, y) : gdImagePalettePixel(im2, x, y); + if (gdImageRed (im1, p1) != gdImageRed (im2, p2)) + { + cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; +diff -Naur gd-2.0.7orig/gd.h gd-2.0.7gif/gd.h +--- gd-2.0.7orig/gd.h 2002-11-14 02:51:02.000000000 +1100 ++++ gd-2.0.7gif/gd.h 2002-11-18 11:39:01.000000000 +1100 +@@ -201,6 +201,10 @@ + + gdImagePtr gdImageCreateFromPngSource (gdSourcePtr in); + ++ gdImagePtr gdImageCreateFromGif (FILE * fd); ++ gdImagePtr gdImageCreateFromGifCtx (gdIOCtxPtr in); ++ gdImagePtr gdImageCreateFromGifSource (gdSourcePtr in); ++ + gdImagePtr gdImageCreateFromGd (FILE * in); + gdImagePtr gdImageCreateFromGdCtx (gdIOCtxPtr in); + +@@ -274,6 +278,7 @@ + } gdPoint, *gdPointPtr; + + void gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c); ++ void gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c); + void gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c); + + /* These functions still work with truecolor images, +@@ -368,6 +373,14 @@ + /* Best to free this memory with gdFree(), not free() */ + void *gdImageJpegPtr (gdImagePtr im, int *size, int quality); + ++void gdImageLzw(gdImagePtr im, FILE *out); ++void* gdImageLzwPtr(gdImagePtr im, int *size); ++void gdImageLzwCtx(gdImagePtr im, gdIOCtxPtr out); ++ ++void gdImageBigGif(gdImagePtr im, FILE *out); ++void* gdImageBigGifPtr(gdImagePtr im, int *size); ++void gdImageBigGifCtx(gdImagePtr im, gdIOCtxPtr out); ++ + /* A custom data sink. For backwards compatibility. Use + gdIOCtx instead. */ + /* The sink function must return -1 on error, otherwise the number +@@ -380,6 +393,11 @@ + + void gdImagePngToSink (gdImagePtr im, gdSinkPtr out); + ++ void gdImageGif (gdImagePtr im, FILE *out); ++ void* gdImageGifPtr (gdImagePtr im, int *size); ++ void gdImageGifCtx (gdImagePtr im, gdIOCtxPtr out); ++ void gdImageGifToSink (gdImagePtr im, gdSinkPtr out); ++ + void gdImageGd (gdImagePtr im, FILE * out); + void gdImageGd2 (gdImagePtr im, FILE * out, int cs, int fmt); + +diff -Naur gd-2.0.7orig/gd2togif.c gd-2.0.7gif/gd2togif.c +--- gd-2.0.7orig/gd2togif.c 1970-01-01 10:00:00.000000000 +1000 ++++ gd-2.0.7gif/gd2togif.c 2002-11-18 11:39:01.000000000 +1100 +@@ -0,0 +1,40 @@ ++#include ++#include "gd.h" ++ ++/* A short program which converts a .gif file into a .gd file, for ++ your convenience in creating images on the fly from a ++ basis image that must be loaded quickly. The .gd format ++ is not intended to be a general-purpose format. */ ++ ++int main(int argc, char **argv) ++{ ++ gdImagePtr im; ++ FILE *in, *out; ++ if (argc != 3) { ++ fprintf(stderr, "Usage: gd2togif filename.gd2 filename.gif\n"); ++ exit(1); ++ } ++ in = fopen(argv[1], "rb"); ++ if (!in) { ++ fprintf(stderr, "Input file does not exist!\n"); ++ exit(1); ++ } ++ im = gdImageCreateFromGd2(in); ++ fclose(in); ++ if (!im) { ++ fprintf(stderr, "Input is not in GIF format!\n"); ++ exit(1); ++ } ++ out = fopen(argv[2], "wb"); ++ if (!out) { ++ fprintf(stderr, "Output file cannot be written to!\n"); ++ gdImageDestroy(im); ++ exit(1); ++ } ++ gdImageGif(im, out); ++ fclose(out); ++ gdImageDestroy(im); ++ ++ return 0; ++} ++ +diff -Naur gd-2.0.7orig/gd_biggif_out.c gd-2.0.7gif/gd_biggif_out.c +--- gd-2.0.7orig/gd_biggif_out.c 1970-01-01 10:00:00.000000000 +1000 ++++ gd-2.0.7gif/gd_biggif_out.c 2002-11-18 11:39:01.000000000 +1100 +@@ -0,0 +1,823 @@ ++#include ++#include ++#include ++#include ++#include "gd.h" ++ ++/* ++** Wrapper functions for this module. ++*/ ++ ++void gdImageBigGif(gdImagePtr im, FILE *outFile) ++{ ++ gdIOCtx *out = gdNewFileCtx(outFile); ++ gdImageBigGifCtx(im, out); ++ out->gd_free(out); ++} ++ ++void* gdImageBigGifPtr(gdImagePtr im, int *size) ++{ ++ void *rv; ++ gdIOCtx *out = gdNewDynamicCtx(2048, NULL); ++ gdImageBigGifCtx(im, out); ++ rv = gdDPExtractData(out,size); ++ out->gd_free(out); ++ return rv; ++} ++ ++/* Code drawn from ppmtogif.c, from the pbmplus package ++** ++** Based on GIFENCOD by David Rowley . A ++** Lempel-Zim compression based on "compress". ++** ++** Modified by Marcel Wijkstra ++** ++** Copyright (C) 1989 by Jef Poskanzer. ++** ++** Permission to use, copy, modify, and distribute this software and its ++** documentation for any purpose and without fee is hereby granted, provided ++** that the above copyright notice appear in all copies and that both that ++** copyright notice and this permission notice appear in supporting ++** documentation. This software is provided "as is" without express or ++** implied warranty. ++** ++** The Graphics Interchange Format(c) is the Copyright property of ++** CompuServe Incorporated. GIF(sm) is a Service Mark property of ++** CompuServe Incorporated. ++* ++* Heavily modified by Mouse, 1998-02-12. ++* Remove LZW compression. ++* Added miGIF run length compression. ++* ++*/ ++ ++/* ++ * a code_int must be able to hold 2**GIFBITS values of type int, and also -1 ++ */ ++typedef int code_int; ++ ++static int colorstobpp(int colors); ++static void BumpPixel (void); ++static int GIFNextPixel (gdImagePtr im); ++static void GIFEncode (gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im); ++/*static void Putword (int w, gdIOCtx *fp); */ ++static void GIFcompress (int, gdIOCtx *, gdImagePtr, int); ++static void output (code_int code); ++ ++/* UNUSED ++* static void char_init (void); ++* static void char_out (int c); ++*/ ++ ++/* Allows for reuse */ ++static void init_statics(void); ++ ++void gdImageBigGifCtx(gdImagePtr im, gdIOCtx *out) ++{ ++ int interlace, transparent, BitsPerPixel; ++ ++ interlace = im->interlace; ++ transparent = im->transparent; ++ ++ BitsPerPixel = colorstobpp(im->colorsTotal); ++ /* Clear any old values in statics strewn through the GIF code */ ++ init_statics(); ++ /* All set, let's do it. */ ++ GIFEncode( ++ out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel, ++ im->red, im->green, im->blue, im); ++} ++ ++static int ++colorstobpp(int colors) ++{ ++ int bpp = 0; ++ ++ if ( colors <= 2 ) ++ bpp = 1; ++ else if ( colors <= 4 ) ++ bpp = 2; ++ else if ( colors <= 8 ) ++ bpp = 3; ++ else if ( colors <= 16 ) ++ bpp = 4; ++ else if ( colors <= 32 ) ++ bpp = 5; ++ else if ( colors <= 64 ) ++ bpp = 6; ++ else if ( colors <= 128 ) ++ bpp = 7; ++ else if ( colors <= 256 ) ++ bpp = 8; ++ return bpp; ++ } ++ ++/***************************************************************************** ++ * ++ * GIFENCODE.C - GIF Image compression interface ++ * ++ * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent, ++ * BitsPerPixel, Red, Green, Blue, gdImagePtr ) ++ * ++ *****************************************************************************/ ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++static int Width, Height; ++static int curx, cury; ++static long CountDown; ++static int Pass = 0; ++static int Interlace; ++ ++/* ++ * Bump the 'curx' and 'cury' to point to the next pixel ++ */ ++static void ++BumpPixel(void) ++{ ++ /* ++ * Bump the current X position ++ */ ++ ++curx; ++ ++ /* ++ * If we are at the end of a scan line, set curx back to the beginning ++ * If we are interlaced, bump the cury to the appropriate spot, ++ * otherwise, just increment it. ++ */ ++ if( curx == Width ) { ++ curx = 0; ++ ++ if( !Interlace ) ++ ++cury; ++ else { ++ switch( Pass ) { ++ ++ case 0: ++ cury += 8; ++ if( cury >= Height ) { ++ ++Pass; ++ cury = 4; ++ } ++ break; ++ ++ case 1: ++ cury += 8; ++ if( cury >= Height ) { ++ ++Pass; ++ cury = 2; ++ } ++ break; ++ ++ case 2: ++ cury += 4; ++ if( cury >= Height ) { ++ ++Pass; ++ cury = 1; ++ } ++ break; ++ ++ case 3: ++ cury += 2; ++ break; ++ } ++ } ++ } ++} ++ ++/* ++ * Return the next pixel from the image ++ */ ++static int ++GIFNextPixel(gdImagePtr im) ++{ ++ int r; ++ ++ if( CountDown == 0 ) ++ return EOF; ++ ++ --CountDown; ++ ++ r = gdImageGetPixel(im, curx, cury); ++ ++ BumpPixel(); ++ ++ return r; ++} ++ ++/* public */ ++ ++static void ++GIFEncode(gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im) ++{ ++ int B; ++ int RWidth, RHeight; ++ int LeftOfs, TopOfs; ++ int Resolution; ++ int ColorMapSize; ++ int InitCodeSize; ++ int i; ++ ++ Interlace = GInterlace; ++ ++ ColorMapSize = 1 << BitsPerPixel; ++ ++ RWidth = Width = GWidth; ++ RHeight = Height = GHeight; ++ LeftOfs = TopOfs = 0; ++ ++ Resolution = BitsPerPixel; ++ ++ /* ++ * Calculate number of bits we are expecting ++ */ ++ CountDown = (long)Width * (long)Height; ++ ++ /* ++ * Indicate which pass we are on (if interlace) ++ */ ++ Pass = 0; ++ ++ /* ++ * The initial code size ++ */ ++ if( BitsPerPixel <= 1 ) ++ InitCodeSize = 2; ++ else ++ InitCodeSize = BitsPerPixel; ++ ++ /* ++ * Set up the current x and y position ++ */ ++ curx = cury = 0; ++ ++ /* ++ * Write the Magic header ++ */ ++ gdPutBuf( Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp ); ++ ++ /* ++ * Write out the screen width and height ++ */ ++ Putword( RWidth, fp ); ++ Putword( RHeight, fp ); ++ ++ /* ++ * Indicate that there is a global colour map ++ */ ++ B = 0x80; /* Yes, there is a color map */ ++ ++ /* ++ * OR in the resolution ++ */ ++ B |= (Resolution - 1) << 4; ++ ++ /* ++ * OR in the Bits per Pixel ++ */ ++ B |= (BitsPerPixel - 1); ++ ++ /* ++ * Write it out ++ */ ++ gdPutC( B, fp ); ++ ++ /* ++ * Write out the Background colour ++ */ ++ gdPutC( Background, fp ); ++ ++ /* ++ * Byte of 0's (future expansion) ++ */ ++ gdPutC( 0, fp ); ++ ++ /* ++ * Write out the Global Colour Map ++ */ ++ for( i=0; i= 0 ) { ++ gdPutC( '!', fp ); ++ gdPutC( 0xf9, fp ); ++ gdPutC( 4, fp ); ++ gdPutC( 1, fp ); ++ gdPutC( 0, fp ); ++ gdPutC( 0, fp ); ++ gdPutC( (unsigned char) Transparent, fp ); ++ gdPutC( 0, fp ); ++ } ++ ++ /* ++ * Write an Image separator ++ */ ++ gdPutC( ',', fp ); ++ ++ /* ++ * Write the Image header ++ */ ++ ++ Putword( LeftOfs, fp ); ++ Putword( TopOfs, fp ); ++ Putword( Width, fp ); ++ Putword( Height, fp ); ++ ++ /* ++ * Write out whether or not the image is interlaced ++ */ ++ if( Interlace ) ++ gdPutC( 0x40, fp ); ++ else ++ gdPutC( 0x00, fp ); ++ ++ /* ++ * Write out the initial code size ++ */ ++ gdPutC( InitCodeSize, fp ); ++ ++ /* ++ * Go and actually compress the data ++ */ ++ GIFcompress( InitCodeSize+1, fp, im, Background ); ++ ++ /* ++ * Write out a Zero-length packet (to end the series) ++ */ ++ gdPutC( 0, fp ); ++ ++ /* ++ * Write the GIF file terminator ++ */ ++ gdPutC( ';', fp ); ++} ++ ++/* Write out a word to the GIF file */ ++/*static void */ ++/*Putword(int w, gdIOCtx *fp) */ ++/*{ */ ++/* fputc( w & 0xff, fp ); */ ++/* fputc( (w / 256) & 0xff, fp ); */ ++/*} */ ++ ++#define GIFBITS 12 ++ ++/*----------------------------------------------------------------------- ++ * ++ * miGIF Compression - mouse and ivo's GIF-compatible compression ++ * ++ * -run length encoding compression routines- ++ * ++ * Copyright (C) 1998 Hutchison Avenue Software Corporation ++ * http://www.hasc.com ++ * info@hasc.com ++ * ++ * Permission to use, copy, modify, and distribute this software and its ++ * documentation for any purpose and without fee is hereby granted, provided ++ * that the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation. This software is provided "AS IS." The Hutchison Avenue ++ * Software Corporation disclaims all warranties, either express or implied, ++ * including but not limited to implied warranties of merchantability and ++ * fitness for a particular purpose, with respect to this code and accompanying ++ * documentation. ++ * ++ * The miGIF compression routines do not, strictly speaking, generate files ++ * conforming to the GIF spec, since the image data is not LZW-compressed ++ * (this is the point: in order to avoid transgression of the Unisys patent ++ * on the LZW algorithm.) However, miGIF generates data streams that any ++ * reasonably sane LZW decompresser will decompress to what we want. ++ * ++ * miGIF compression uses run length encoding. It compresses horizontal runs ++ * of pixels of the same color. This type of compression gives good results ++ * on images with many runs, for example images with lines, text and solid ++ * shapes on a solid-colored background. It gives little or no compression ++ * on images with few runs, for example digital or scanned photos. ++ * ++ * der Mouse ++ * mouse@rodents.montreal.qc.ca ++ * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B ++ * ++ * ivo@hasc.com ++ * ++ * The Graphics Interchange Format(c) is the Copyright property of ++ * CompuServe Incorporated. GIF(sm) is a Service Mark property of ++ * CompuServe Incorporated. ++ * ++ */ ++ ++static int rl_pixel; ++static int rl_basecode; ++static int rl_count; ++static int rl_table_pixel; ++static int rl_table_max; ++static int just_cleared; ++static int out_bits; ++static int out_bits_init; ++static int out_count; ++static int out_bump; ++static int out_bump_init; ++static int out_clear; ++static int out_clear_init; ++static int max_ocodes; ++static int code_clear; ++static int code_eof; ++static unsigned int obuf; ++static int obits; ++static gdIOCtx *ofile; ++static unsigned char oblock[256]; ++static int oblen; ++ ++/* Used only when debugging GIF compression code */ ++/* #define DEBUGGING_ENVARS */ ++ ++#ifdef DEBUGGING_ENVARS ++ ++static int verbose_set = 0; ++static int verbose; ++#define VERBOSE (verbose_set?verbose:set_verbose()) ++ ++static int set_verbose(void) ++{ ++ verbose = !!getenv("GIF_VERBOSE"); ++ verbose_set = 1; ++ return(verbose); ++} ++ ++#else ++ ++#define VERBOSE 0 ++ ++#endif ++ ++ ++static const char *binformat(unsigned int v, int nbits) ++{ ++ static char bufs[8][64]; ++ static int bhand = 0; ++ unsigned int bit; ++ int bno; ++ char *bp; ++ ++ bhand --; ++ if (bhand < 0) bhand = (sizeof(bufs)/sizeof(bufs[0]))-1; ++ bp = &bufs[bhand][0]; ++ for (bno=nbits-1,bit=1U<=0;bno--,bit>>=1) ++ { *bp++ = (v & bit) ? '1' : '0'; ++ if (((bno&3) == 0) && (bno != 0)) *bp++ = '.'; ++ } ++ *bp = '\0'; ++ return(&bufs[bhand][0]); ++} ++ ++static void write_block(void) ++{ ++ int i; ++ ++ if (VERBOSE) ++ { printf("write_block %d:",oblen); ++ for (i=0;i= 255) write_block(); ++} ++ ++static void block_flush(void) ++{ ++ if (VERBOSE) printf("block_flush\n"); ++ if (oblen > 0) write_block(); ++} ++ ++static void output(int val) ++{ ++ if (VERBOSE) printf("output %s [%s %d %d]\n",binformat(val,out_bits),binformat(obuf,obits),obits,out_bits); ++ obuf |= val << obits; ++ obits += out_bits; ++ while (obits >= 8) ++ { block_out(obuf&0xff); ++ obuf >>= 8; ++ obits -= 8; ++ } ++ if (VERBOSE) printf("output leaving [%s %d]\n",binformat(obuf,obits),obits); ++} ++ ++static void output_flush(void) ++{ ++ if (VERBOSE) printf("output_flush\n"); ++ if (obits > 0) block_out(obuf); ++ block_flush(); ++} ++ ++static void did_clear(void) ++{ ++ if (VERBOSE) printf("did_clear\n"); ++ out_bits = out_bits_init; ++ out_bump = out_bump_init; ++ out_clear = out_clear_init; ++ out_count = 0; ++ rl_table_max = 0; ++ just_cleared = 1; ++} ++ ++static void output_plain(int c) ++{ ++ if (VERBOSE) printf("output_plain %s\n",binformat(c,out_bits)); ++ just_cleared = 0; ++ output(c); ++ out_count ++; ++ if (out_count >= out_bump) ++ { out_bits ++; ++ out_bump += 1 << (out_bits - 1); ++ } ++ if (out_count >= out_clear) ++ { output(code_clear); ++ did_clear(); ++ } ++} ++ ++static unsigned int isqrt(unsigned int x) ++{ ++ unsigned int r; ++ unsigned int v; ++ ++ if (x < 2) return(x); ++ for (v=x,r=1;v;v>>=2,r<<=1) ; ++ while (1) ++ { v = ((x / r) + r) / 2; ++ if ((v == r) || (v == r+1)) return(r); ++ r = v; ++ } ++} ++ ++static unsigned int compute_triangle_count(unsigned int count, unsigned int nrepcodes) ++{ ++ unsigned int perrep; ++ unsigned int cost; ++ ++ cost = 0; ++ perrep = (nrepcodes * (nrepcodes+1)) / 2; ++ while (count >= perrep) ++ { cost += nrepcodes; ++ count -= perrep; ++ } ++ if (count > 0) ++ { unsigned int n; ++ n = isqrt(count); ++ while ((n*(n+1)) >= 2*count) n --; ++ while ((n*(n+1)) < 2*count) n ++; ++ cost += n; ++ } ++ return(cost); ++} ++ ++static void max_out_clear(void) ++{ ++ out_clear = max_ocodes; ++} ++ ++static void reset_out_clear(void) ++{ ++ out_clear = out_clear_init; ++ if (out_count >= out_clear) ++ { output(code_clear); ++ did_clear(); ++ } ++} ++ ++static void rl_flush_fromclear(int count) ++{ ++ int n; ++ ++ if (VERBOSE) printf("rl_flush_fromclear %d\n",count); ++ max_out_clear(); ++ rl_table_pixel = rl_pixel; ++ n = 1; ++ while (count > 0) ++ { if (n == 1) ++ { rl_table_max = 1; ++ output_plain(rl_pixel); ++ count --; ++ } ++ else if (count >= n) ++ { rl_table_max = n; ++ output_plain(rl_basecode+n-2); ++ count -= n; ++ } ++ else if (count == 1) ++ { rl_table_max ++; ++ output_plain(rl_pixel); ++ count = 0; ++ } ++ else ++ { rl_table_max ++; ++ output_plain(rl_basecode+count-2); ++ count = 0; ++ } ++ if (out_count == 0) n = 1; else n ++; ++ } ++ reset_out_clear(); ++ if (VERBOSE) printf("rl_flush_fromclear leaving table_max=%d\n",rl_table_max); ++} ++ ++static void rl_flush_clearorrep(int count) ++{ ++ int withclr; ++ ++ if (VERBOSE) printf("rl_flush_clearorrep %d\n",count); ++ withclr = 1 + compute_triangle_count(count,max_ocodes); ++ if (withclr < count) ++ { output(code_clear); ++ did_clear(); ++ rl_flush_fromclear(count); ++ } ++ else ++ { for (;count>0;count--) output_plain(rl_pixel); ++ } ++} ++ ++static void rl_flush_withtable(int count) ++{ ++ int repmax; ++ int repleft; ++ int leftover; ++ ++ if (VERBOSE) printf("rl_flush_withtable %d\n",count); ++ repmax = count / rl_table_max; ++ leftover = count % rl_table_max; ++ repleft = (leftover ? 1 : 0); ++ if (out_count+repmax+repleft > max_ocodes) ++ { repmax = max_ocodes - out_count; ++ leftover = count - (repmax * rl_table_max); ++ repleft = 1 + compute_triangle_count(leftover,max_ocodes); ++ } ++ if (VERBOSE) printf("rl_flush_withtable repmax=%d leftover=%d repleft=%d\n",repmax,leftover,repleft); ++ if (1+compute_triangle_count(count,max_ocodes) < repmax+repleft) ++ { output(code_clear); ++ did_clear(); ++ rl_flush_fromclear(count); ++ return; ++ } ++ max_out_clear(); ++ for (;repmax>0;repmax--) output_plain(rl_basecode+rl_table_max-2); ++ if (leftover) ++ { if (just_cleared) ++ { rl_flush_fromclear(leftover); ++ } ++ else if (leftover == 1) ++ { output_plain(rl_pixel); ++ } ++ else ++ { output_plain(rl_basecode+leftover-2); ++ } ++ } ++ reset_out_clear(); ++} ++ ++static void rl_flush(void) ++{ ++ /* UNUSED int table_reps; */ ++ /* UNUSED int table_extra; */ ++ ++ if (VERBOSE) printf("rl_flush [ %d %d\n",rl_count,rl_pixel); ++ if (rl_count == 1) ++ { output_plain(rl_pixel); ++ rl_count = 0; ++ if (VERBOSE) printf("rl_flush ]\n"); ++ return; ++ } ++ if (just_cleared) ++ { rl_flush_fromclear(rl_count); ++ } ++ else if ((rl_table_max < 2) || (rl_table_pixel != rl_pixel)) ++ { rl_flush_clearorrep(rl_count); ++ } ++ else ++ { rl_flush_withtable(rl_count); ++ } ++ if (VERBOSE) printf("rl_flush ]\n"); ++ rl_count = 0; ++} ++ ++static void GIFcompress(int init_bits, gdIOCtx *outfile, gdImagePtr im, int background) ++{ ++ int c; ++ ++ ofile = outfile; ++ obuf = 0; ++ obits = 0; ++ oblen = 0; ++ code_clear = 1 << (init_bits - 1); ++ code_eof = code_clear + 1; ++ rl_basecode = code_eof + 1; ++ out_bump_init = (1 << (init_bits - 1)) - 1; ++ /* for images with a lot of runs, making out_clear_init larger will ++ give better compression. */ ++ out_clear_init = (init_bits <= 3) ? 9 : (out_bump_init-1); ++#ifdef DEBUGGING_ENVARS ++ { const char *ocienv; ++ ocienv = getenv("GIF_OUT_CLEAR_INIT"); ++ if (ocienv) ++ { out_clear_init = atoi(ocienv); ++ if (VERBOSE) printf("[overriding out_clear_init to %d]\n",out_clear_init); ++ } ++ } ++#endif ++ out_bits_init = init_bits; ++ max_ocodes = (1 << GIFBITS) - ((1 << (out_bits_init - 1)) + 3); ++ did_clear(); ++ output(code_clear); ++ rl_count = 0; ++ while (1) ++ { c = GIFNextPixel(im); ++ if ((rl_count > 0) && (c != rl_pixel)) rl_flush(); ++ if (c == EOF) break; ++ if (rl_pixel == c) ++ { rl_count ++; ++ } ++ else ++ { rl_pixel = c; ++ rl_count = 1; ++ } ++ } ++ output(code_eof); ++ output_flush(); ++} ++ ++/*----------------------------------------------------------------------- ++ * ++ * End of miGIF section - See copyright notice at start of section. ++ * ++ *----------------------------------------------------------------------- ++*/ ++ ++/****************************************************************************** ++ * ++ * GIF Specific routines ++ * ++ ******************************************************************************/ ++ ++/* ++ * Number of characters so far in this 'packet' ++ */ ++static int a_count; ++ ++/* ++ * Set up the 'byte output' routine ++ */ ++ ++/* UNUSED ++* static void ++* char_init(void) ++* { ++* a_count = 0; ++* } ++*/ ++ ++/* ++ * Define the storage for the packet accumulator ++ */ ++ ++/* UNUSED static char accum[ 256 ]; */ ++ ++static void init_statics(void) { ++ /* Some of these are properly initialized later. What I'm doing ++ here is making sure code that depends on C's initialization ++ of statics doesn't break when the code gets called more ++ than once. */ ++ Width = 0; ++ Height = 0; ++ curx = 0; ++ cury = 0; ++ CountDown = 0; ++ Pass = 0; ++ Interlace = 0; ++ a_count = 0; ++} ++ ++ ++/* +-------------------------------------------------------------------+ */ ++/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */ ++/* | Permission to use, copy, modify, and distribute this software | */ ++/* | and its documentation for any purpose and without fee is hereby | */ ++/* | granted, provided that the above copyright notice appear in all | */ ++/* | copies and that both that copyright notice and this permission | */ ++/* | notice appear in supporting documentation. This software is | */ ++/* | provided "as is" without express or implied warranty. | */ ++/* +-------------------------------------------------------------------+ */ ++ +diff -Naur gd-2.0.7orig/gd_gif_in.c gd-2.0.7gif/gd_gif_in.c +--- gd-2.0.7orig/gd_gif_in.c 1970-01-01 10:00:00.000000000 +1000 ++++ gd-2.0.7gif/gd_gif_in.c 2002-11-18 11:39:01.000000000 +1100 +@@ -0,0 +1,573 @@ ++#include ++#include ++#include ++#include ++#include "gd.h" ++ ++/* Used only when debugging GIF compression code */ ++/* #define DEBUGGING_ENVARS */ ++ ++#ifdef DEBUGGING_ENVARS ++ ++static int verbose_set = 0; ++static int verbose; ++#define VERBOSE (verbose_set?verbose:set_verbose()) ++ ++static int set_verbose(void) ++{ ++ verbose = !!getenv("GIF_VERBOSE"); ++ verbose_set = 1; ++ return(verbose); ++} ++ ++#else ++ ++#define VERBOSE 0 ++ ++#endif ++ ++ ++#define MAXCOLORMAPSIZE 256 ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++#define CM_RED 0 ++#define CM_GREEN 1 ++#define CM_BLUE 2 ++ ++#define MAX_LWZ_BITS 12 ++ ++#define INTERLACE 0x40 ++#define LOCALCOLORMAP 0x80 ++#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) ++ ++#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0) ++ ++#define LM_to_uint(a,b) (((b)<<8)|(a)) ++ ++/* We may eventually want to use this information, but def it out for now */ ++#if 0 ++static struct { ++ unsigned int Width; ++ unsigned int Height; ++ unsigned char ColorMap[3][MAXCOLORMAPSIZE]; ++ unsigned int BitPixel; ++ unsigned int ColorResolution; ++ unsigned int Background; ++ unsigned int AspectRatio; ++} GifScreen; ++#endif ++ ++static struct { ++ int transparent; ++ int delayTime; ++ int inputFlag; ++ int disposal; ++} Gif89 = { -1, -1, -1, 0 }; ++ ++static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]); ++static int DoExtension (gdIOCtx *fd, int label, int *Transparent); ++static int GetDataBlock (gdIOCtx *fd, unsigned char *buf); ++static int GetCode (gdIOCtx *fd, int code_size, int flag); ++static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size); ++ ++static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace); /*1.4//, int ignore); */ ++ ++int ZeroDataBlock; ++ ++gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource) ++{ ++ gdIOCtx *in = gdNewSSCtx(inSource, NULL); ++ gdImagePtr im; ++ ++ im = gdImageCreateFromGifCtx(in); ++ ++ in->gd_free(in); ++ ++ return im; ++} ++ ++gdImagePtr ++gdImageCreateFromGif(FILE *fdFile) ++{ ++ gdIOCtx *fd = gdNewFileCtx(fdFile); ++ gdImagePtr im = 0; ++ ++ im = gdImageCreateFromGifCtx(fd); ++ ++ fd->gd_free(fd); ++ ++ return im; ++} ++ ++gdImagePtr ++gdImageCreateFromGifCtx(gdIOCtxPtr fd) ++{ ++/* 1.4 int imageNumber; */ ++ int BitPixel; ++ int ColorResolution; ++ int Background; ++ int AspectRatio; ++ int Transparent = (-1); ++ unsigned char buf[16]; ++ unsigned char c; ++ unsigned char ColorMap[3][MAXCOLORMAPSIZE]; ++ unsigned char localColorMap[3][MAXCOLORMAPSIZE]; ++ int imw, imh; ++ int useGlobalColormap; ++ int bitPixel; ++ int i; ++ /*1.4//int imageCount = 0; */ ++ char version[4]; ++ ++ gdImagePtr im = 0; ++ ZeroDataBlock = FALSE; ++ ++ /*1.4//imageNumber = 1; */ ++ if (! ReadOK(fd,buf,6)) { ++ return 0; ++ } ++ if (strncmp((char *)buf,"GIF",3) != 0) { ++ return 0; ++ } ++ strncpy(version, (char *)buf + 3, 3); ++ version[3] = '\0'; ++ ++ if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { ++ return 0; ++ } ++ if (! ReadOK(fd,buf,7)) { ++ return 0; ++ } ++ BitPixel = 2<<(buf[4]&0x07); ++ ColorResolution = (int) (((buf[4]&0x70)>>3)+1); ++ Background = buf[5]; ++ AspectRatio = buf[6]; ++ ++ if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ ++ if (ReadColorMap(fd, BitPixel, ColorMap)) { ++ return 0; ++ } ++ } ++ for (;;) { ++ if (! ReadOK(fd,&c,1)) { ++ return 0; ++ } ++ if (c == ';') { /* GIF terminator */ ++ goto terminated; ++ } ++ ++ if (c == '!') { /* Extension */ ++ if (! ReadOK(fd,&c,1)) { ++ return 0; ++ } ++ DoExtension(fd, c, &Transparent); ++ continue; ++ } ++ ++ if (c != ',') { /* Not a valid start character */ ++ continue; ++ } ++ ++ /*1.4//++imageCount; */ ++ ++ if (! ReadOK(fd,buf,9)) { ++ return 0; ++ } ++ ++ 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) { ++ if (ReadColorMap(fd, bitPixel, localColorMap)) { ++ return 0; ++ } ++ ReadImage(im, fd, imw, imh, localColorMap, ++ BitSet(buf[8], INTERLACE)); ++ /*1.4//imageCount != imageNumber); */ ++ } else { ++ ReadImage(im, fd, imw, imh, ++ ColorMap, ++ BitSet(buf[8], INTERLACE)); ++ /*1.4//imageCount != imageNumber); */ ++ } ++ if (Transparent != (-1)) { ++ gdImageColorTransparent(im, Transparent); ++ } ++ goto terminated; ++ } ++ ++terminated: ++ /* Terminator before any image was declared! */ ++ if (!im) { ++ return 0; ++ } ++ /* Check for open colors at the end, so ++ we can reduce colorsTotal and ultimately ++ BitsPerPixel */ ++ for (i=((im->colorsTotal-1)); (i>=0); i--) { ++ if (im->open[i]) { ++ im->colorsTotal--; ++ } else { ++ break; ++ } ++ } ++ return im; ++} ++ ++static int ++ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]) ++{ ++ int i; ++ unsigned char rgb[3]; ++ ++ ++ for (i = 0; i < number; ++i) { ++ if (! ReadOK(fd, rgb, sizeof(rgb))) { ++ return TRUE; ++ } ++ buffer[CM_RED][i] = rgb[0] ; ++ buffer[CM_GREEN][i] = rgb[1] ; ++ buffer[CM_BLUE][i] = rgb[2] ; ++ } ++ ++ ++ return FALSE; ++} ++ ++static int ++DoExtension(gdIOCtx *fd, int label, int *Transparent) ++{ ++ static unsigned char buf[256]; ++ ++ switch (label) { ++ case 0xf9: /* Graphic Control Extension */ ++ (void) GetDataBlock(fd, (unsigned char*) buf); ++ Gif89.disposal = (buf[0] >> 2) & 0x7; ++ Gif89.inputFlag = (buf[0] >> 1) & 0x1; ++ Gif89.delayTime = LM_to_uint(buf[1],buf[2]); ++ if ((buf[0] & 0x1) != 0) ++ *Transparent = buf[3]; ++ ++ while (GetDataBlock(fd, (unsigned char*) buf) != 0) ++ ; ++ return FALSE; ++ default: ++ break; ++ } ++ while (GetDataBlock(fd, (unsigned char*) buf) != 0) ++ ; ++ ++ return FALSE; ++} ++ ++static int ++GetDataBlock_(gdIOCtx *fd, unsigned char *buf) ++{ ++ unsigned char count; ++ ++ if (! ReadOK(fd,&count,1)) { ++ return -1; ++ } ++ ++ ZeroDataBlock = count == 0; ++ ++ if ((count != 0) && (! ReadOK(fd, buf, count))) { ++ return -1; ++ } ++ ++ return count; ++} ++ ++static int ++GetDataBlock(gdIOCtx *fd, unsigned char *buf) ++{ ++ int rv; ++ int i; ++ ++ rv = GetDataBlock_(fd,buf); ++ if (VERBOSE) ++ { printf("[GetDataBlock returning %d",rv); ++ if (rv > 0) ++ { printf(":"); ++ for (i=0;i= lastbit) { ++ if (done) { ++ if (curbit >= lastbit) { ++ /* Oh well */ ++ } ++ return -1; ++ } ++ buf[0] = buf[last_byte-2]; ++ buf[1] = buf[last_byte-1]; ++ ++ if ((count = GetDataBlock(fd, &buf[2])) == 0) ++ done = TRUE; ++ ++ last_byte = 2 + count; ++ curbit = (curbit - lastbit) + 16; ++ 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; ++ ++ curbit += code_size; ++ return ret; ++} ++ ++static int ++GetCode(gdIOCtx *fd, int code_size, int flag) ++{ ++ int rv; ++ ++ rv = GetCode_(fd,code_size,flag); ++ 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) ++{ ++ 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; ++ ++ 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); ++ ++ fresh = TRUE; ++ ++ for (i = 0; i < clear_code; ++i) { ++ table[0][i] = 0; ++ table[1][i] = i; ++ } ++ for (; i < (1< stack) ++ return *--sp; ++ ++ while ((code = GetCode(fd, code_size, FALSE)) >= 0) { ++ if (code == clear_code) { ++ for (i = 0; i < clear_code; ++i) { ++ table[0][i] = 0; ++ table[1][i] = i; ++ } ++ for (; i < (1< 0) ++ ; ++ ++ if (count != 0) ++ return -2; ++ } ++ ++ incode = code; ++ ++ if (sp == (stack + STACK_SIZE)) { ++ /* Bad compressed data stream */ ++ return -1; ++ } ++ ++ if (code >= max_code) { ++ *sp++ = firstcode; ++ code = oldcode; ++ } ++ ++ while (code >= clear_code) { ++ if (sp == (stack + STACK_SIZE)) { ++ /* Bad compressed data stream */ ++ return -1; ++ } ++ *sp++ = table[1][code]; ++ if (code == table[0][code]) { ++ /* Oh well */ ++ } ++ code = table[0][code]; ++ } ++ ++ *sp++ = firstcode = table[1][code]; ++ ++ if ((code = max_code) <(1<= max_code_size) && ++ (max_code_size < (1< stack) ++ return *--sp; ++ } ++ return code; ++} ++ ++static int ++LWZReadByte(gdIOCtx *fd, int flag, int input_code_size) ++{ ++ int rv; ++ ++ rv = LWZReadByte_(fd,flag,input_code_size); ++ if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv); ++ return(rv); ++} ++ ++static void ++ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace) /*1.4//, int ignore) */ ++{ ++ unsigned char c; ++ int v; ++ int xpos = 0, ypos = 0, pass = 0; ++ int i; ++ /* Stash the color map into the image */ ++ for (i=0; (ired[i] = cmap[CM_RED][i]; ++ im->green[i] = cmap[CM_GREEN][i]; ++ im->blue[i] = cmap[CM_BLUE][i]; ++ im->open[i] = 1; ++ } ++ /* 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) < 0) { ++ return; ++ } ++ ++ /* ++ ** If this is an "uninteresting picture" ignore it. ++ ** REMOVED For 1.4 ++ */ ++ /*if (ignore) { */ ++ /* while (LWZReadByte(fd, FALSE, c) >= 0) */ ++ /* ; */ ++ /* return; */ ++ /*} */ ++ ++ while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) { ++ /* This how we recognize which colors are actually used. */ ++ if (im->open[v]) { ++ im->open[v] = 0; ++ } ++ gdImageSetPixel(im, xpos, ypos, v); ++ ++xpos; ++ if (xpos == len) { ++ xpos = 0; ++ if (interlace) { ++ switch (pass) { ++ case 0: ++ case 1: ++ ypos += 8; break; ++ case 2: ++ ypos += 4; break; ++ case 3: ++ ypos += 2; break; ++ } ++ ++ if (ypos >= height) { ++ ++pass; ++ switch (pass) { ++ case 1: ++ ypos = 4; break; ++ case 2: ++ ypos = 2; break; ++ case 3: ++ ypos = 1; break; ++ default: ++ goto fini; ++ } ++ } ++ } else { ++ ++ypos; ++ } ++ } ++ if (ypos >= height) ++ break; ++ } ++ ++fini: ++ if (LWZReadByte(fd,FALSE,c)>=0) { ++ /* Ignore extra */ ++ } ++} ++ +diff -Naur gd-2.0.7orig/gd_gif_out.c gd-2.0.7gif/gd_gif_out.c +--- gd-2.0.7orig/gd_gif_out.c 1970-01-01 10:00:00.000000000 +1000 ++++ gd-2.0.7gif/gd_gif_out.c 2002-11-18 11:39:01.000000000 +1100 +@@ -0,0 +1,46 @@ ++#include ++#include ++#include ++#include ++#include "gd.h" ++ ++/* ++** Wrapper functions for GIF output. ++*/ ++ ++#define LZW_LICENCED ++ ++void gdImageGifToSink(gdImagePtr im, gdSinkPtr outSink) ++{ ++ gdIOCtx *out = gdNewSSCtx(NULL,outSink); ++ gdImageGifCtx(im, out); ++ out->gd_free(out); ++} ++ ++void gdImageGifCtx(gdImagePtr im, gdIOCtx *out) ++{ ++#ifdef LZW_LICENCED ++ gdImageLzwCtx(im, out); ++#else ++ gdImageBigGifCtx(im, out); ++#endif ++} ++ ++void gdImageGif(gdImagePtr im, FILE *outFile) ++{ ++#ifdef LZW_LICENCED ++ gdImageLzw(im, outFile); ++#else ++ gdImageBigGif(im, outFile); ++#endif ++} ++ ++void* gdImageGifPtr(gdImagePtr im, int *size) ++{ ++#ifdef LZW_LICENCED ++ return gdImageLzwPtr(im, size); ++#else ++ return gdImageBigGifPtr(im, size); ++#endif ++} ++ +diff -Naur gd-2.0.7orig/gd_lzw_out.c gd-2.0.7gif/gd_lzw_out.c +--- gd-2.0.7orig/gd_lzw_out.c 1970-01-01 10:00:00.000000000 +1000 ++++ gd-2.0.7gif/gd_lzw_out.c 2002-11-18 11:39:01.000000000 +1100 +@@ -0,0 +1,796 @@ ++#include ++#include ++#include ++#include ++#include ++#include "gd.h" ++ ++/* Code drawn from ppmtogif.c, from the pbmplus package ++** ++** Based on GIFENCOD by David Rowley . A ++** Lempel-Zim compression based on "compress". ++** ++** Modified by Marcel Wijkstra ++** ++** Copyright (C) 1989 by Jef Poskanzer. ++** ++** Permission to use, copy, modify, and distribute this software and its ++** documentation for any purpose and without fee is hereby granted, provided ++** that the above copyright notice appear in all copies and that both that ++** copyright notice and this permission notice appear in supporting ++** documentation. This software is provided "as is" without express or ++** implied warranty. ++** ++** The Graphics Interchange Format(c) is the Copyright property of ++** CompuServe Incorporated. GIF(sm) is a Service Mark property of ++** CompuServe Incorporated. ++*/ ++ ++/* ++ * a code_int must be able to hold 2**GIFBITS values of type int, and also -1 ++ */ ++typedef int code_int; ++ ++#ifdef SIGNED_COMPARE_SLOW ++typedef unsigned long int count_int; ++typedef unsigned short int count_short; ++#else /*SIGNED_COMPARE_SLOW*/ ++typedef long int count_int; ++#endif /*SIGNED_COMPARE_SLOW*/ ++ ++static int colorstobpp(int colors); ++static void BumpPixel (void); ++static int GIFNextPixel (gdImagePtr im); ++static void GIFEncode (gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im); ++/*static void Putword (int w, gdIOCtx *fp); */ ++static void compress (int init_bits, gdIOCtx *outfile, gdImagePtr im); ++static void output (code_int code); ++static void cl_block (void); ++static void cl_hash (register count_int hsize); ++static void char_init (void); ++static void char_out (int c); ++static void flush_char (void); ++/* Allows for reuse */ ++static void init_statics(void); ++ ++void gdImageLzwCtx(gdImagePtr im, gdIOCtx *out) ++{ ++ int interlace, transparent, BitsPerPixel; ++ ++ interlace = im->interlace; ++ transparent = im->transparent; ++ ++ BitsPerPixel = colorstobpp(im->colorsTotal); ++ /* Clear any old values in statics strewn through the GIF code */ ++ init_statics(); ++ /* All set, let's do it. */ ++ GIFEncode( ++ out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel, ++ im->red, im->green, im->blue, im); ++} ++ ++void gdImageLzw(gdImagePtr im, FILE *outFile) ++{ ++ gdIOCtx *out = gdNewFileCtx(outFile); ++ gdImageLzwCtx(im, out); ++ out->gd_free(out); ++} ++ ++void* gdImageLzwPtr(gdImagePtr im, int *size) ++{ ++ void *rv; ++ gdIOCtx *out = gdNewDynamicCtx(2048, NULL); ++ gdImageLzwCtx(im, out); ++ rv = gdDPExtractData(out,size); ++ out->gd_free(out); ++ return rv; ++} ++ ++ ++ ++static int ++colorstobpp(int colors) ++{ ++ int bpp = 0; ++ ++ if ( colors <= 2 ) ++ bpp = 1; ++ else if ( colors <= 4 ) ++ bpp = 2; ++ else if ( colors <= 8 ) ++ bpp = 3; ++ else if ( colors <= 16 ) ++ bpp = 4; ++ else if ( colors <= 32 ) ++ bpp = 5; ++ else if ( colors <= 64 ) ++ bpp = 6; ++ else if ( colors <= 128 ) ++ bpp = 7; ++ else if ( colors <= 256 ) ++ bpp = 8; ++ return bpp; ++ } ++ ++/***************************************************************************** ++ * ++ * GIFENCODE.C - GIF Image compression interface ++ * ++ * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent, ++ * BitsPerPixel, Red, Green, Blue, gdImagePtr ) ++ * ++ *****************************************************************************/ ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++static int Width, Height; ++static int curx, cury; ++static long CountDown; ++static int Pass = 0; ++static int Interlace; ++ ++/* ++ * Bump the 'curx' and 'cury' to point to the next pixel ++ */ ++static void ++BumpPixel(void) ++{ ++ /* ++ * Bump the current X position ++ */ ++ ++curx; ++ ++ /* ++ * If we are at the end of a scan line, set curx back to the beginning ++ * If we are interlaced, bump the cury to the appropriate spot, ++ * otherwise, just increment it. ++ */ ++ if( curx == Width ) { ++ curx = 0; ++ ++ if( !Interlace ) ++ ++cury; ++ else { ++ switch( Pass ) { ++ ++ case 0: ++ cury += 8; ++ if( cury >= Height ) { ++ ++Pass; ++ cury = 4; ++ } ++ break; ++ ++ case 1: ++ cury += 8; ++ if( cury >= Height ) { ++ ++Pass; ++ cury = 2; ++ } ++ break; ++ ++ case 2: ++ cury += 4; ++ if( cury >= Height ) { ++ ++Pass; ++ cury = 1; ++ } ++ break; ++ ++ case 3: ++ cury += 2; ++ break; ++ } ++ } ++ } ++} ++ ++/* ++ * Return the next pixel from the image ++ */ ++static int ++GIFNextPixel(gdImagePtr im) ++{ ++ int r; ++ ++ if( CountDown == 0 ) ++ return EOF; ++ ++ --CountDown; ++ ++ r = gdImageGetPixel(im, curx, cury); ++ ++ BumpPixel(); ++ ++ return r; ++} ++ ++/* public */ ++ ++static void ++GIFEncode(gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im) ++{ ++ int B; ++ int RWidth, RHeight; ++ int LeftOfs, TopOfs; ++ int Resolution; ++ int ColorMapSize; ++ int InitCodeSize; ++ int i; ++ ++ Interlace = GInterlace; ++ ++ ColorMapSize = 1 << BitsPerPixel; ++ ++ RWidth = Width = GWidth; ++ RHeight = Height = GHeight; ++ LeftOfs = TopOfs = 0; ++ ++ Resolution = BitsPerPixel; ++ ++ /* ++ * Calculate number of bits we are expecting ++ */ ++ CountDown = (long)Width * (long)Height; ++ ++ /* ++ * Indicate which pass we are on (if interlace) ++ */ ++ Pass = 0; ++ ++ /* ++ * The initial code size ++ */ ++ if( BitsPerPixel <= 1 ) ++ InitCodeSize = 2; ++ else ++ InitCodeSize = BitsPerPixel; ++ ++ /* ++ * Set up the current x and y position ++ */ ++ curx = cury = 0; ++ ++ /* ++ * Write the Magic header ++ */ ++ gdPutBuf( Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp ); ++ ++ /* ++ * Write out the screen width and height ++ */ ++ Putword( RWidth, fp ); ++ Putword( RHeight, fp ); ++ ++ /* ++ * Indicate that there is a global colour map ++ */ ++ B = 0x80; /* Yes, there is a color map */ ++ ++ /* ++ * OR in the resolution ++ */ ++ B |= (Resolution - 1) << 5; ++ ++ /* ++ * OR in the Bits per Pixel ++ */ ++ B |= (BitsPerPixel - 1); ++ ++ /* ++ * Write it out ++ */ ++ gdPutC( B, fp ); ++ ++ /* ++ * Write out the Background colour ++ */ ++ gdPutC( Background, fp ); ++ ++ /* ++ * Byte of 0's (future expansion) ++ */ ++ gdPutC( 0, fp ); ++ ++ /* ++ * Write out the Global Colour Map ++ */ ++ for( i=0; i= 0 ) { ++ gdPutC( '!', fp ); ++ gdPutC( 0xf9, fp ); ++ gdPutC( 4, fp ); ++ gdPutC( 1, fp ); ++ gdPutC( 0, fp ); ++ gdPutC( 0, fp ); ++ gdPutC( (unsigned char) Transparent, fp ); ++ gdPutC( 0, fp ); ++ } ++ ++ /* ++ * Write an Image separator ++ */ ++ gdPutC( ',', fp ); ++ ++ /* ++ * Write the Image header ++ */ ++ ++ Putword( LeftOfs, fp ); ++ Putword( TopOfs, fp ); ++ Putword( Width, fp ); ++ Putword( Height, fp ); ++ ++ /* ++ * Write out whether or not the image is interlaced ++ */ ++ if( Interlace ) ++ gdPutC( 0x40, fp ); ++ else ++ gdPutC( 0x00, fp ); ++ ++ /* ++ * Write out the initial code size ++ */ ++ gdPutC( InitCodeSize, fp ); ++ ++ /* ++ * Go and actually compress the data ++ */ ++ compress( InitCodeSize+1, fp, im ); ++ ++ /* ++ * Write out a Zero-length packet (to end the series) ++ */ ++ gdPutC( 0, fp ); ++ ++ /* ++ * Write the GIF file terminator ++ */ ++ gdPutC( ';', fp ); ++} ++ ++/* */ ++/* * Write out a word to the GIF file */ ++/* */ ++/*static void */ ++/*Putword(int w, FILE *fp) */ ++/*{ */ ++/* fputc( w & 0xff, fp ); */ ++/* fputc( (w / 256) & 0xff, fp ); */ ++/*} */ ++ ++ ++/*************************************************************************** ++ * ++ * GIFCOMPR.C - GIF Image compression routines ++ * ++ * Lempel-Ziv compression based on 'compress'. GIF modifications by ++ * David Rowley (mgardi@watdcsu.waterloo.edu) ++ * ++ ***************************************************************************/ ++ ++/* ++ * General DEFINEs ++ */ ++ ++#define GIFBITS 12 ++ ++#define HSIZE 5003 /* 80% occupancy */ ++ ++#ifdef NO_UCHAR ++ typedef char char_type; ++#else /*NO_UCHAR*/ ++ typedef unsigned char char_type; ++#endif /*NO_UCHAR*/ ++ ++/* ++ * ++ * GIF Image compression - modified 'compress' ++ * ++ * Based on: compress.c - File compression ala IEEE Computer, June 1984. ++ * ++ * By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) ++ * Jim McKie (decvax!mcvax!jim) ++ * Steve Davies (decvax!vax135!petsd!peora!srd) ++ * Ken Turkowski (decvax!decwrl!turtlevax!ken) ++ * James A. Woods (decvax!ihnp4!ames!jaw) ++ * Joe Orost (decvax!vax135!petsd!joe) ++ * ++ */ ++#include ++ ++#define ARGVAL() (*++(*argv) || (--argc && *++argv)) ++ ++static int n_bits; /* number of bits/code */ ++static int maxbits = GIFBITS; /* user settable max # bits/code */ ++static code_int maxcode; /* maximum code, given n_bits */ ++static code_int maxmaxcode = (code_int)1 << GIFBITS; /* should NEVER generate this code */ ++#ifdef COMPATIBLE /* But wrong! */ ++# define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1) ++#else /*COMPATIBLE*/ ++# define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1) ++#endif /*COMPATIBLE*/ ++ ++static count_int htab [HSIZE]; ++static unsigned short codetab [HSIZE]; ++#define HashTabOf(i) htab[i] ++#define CodeTabOf(i) codetab[i] ++ ++static code_int hsize = HSIZE; /* for dynamic table sizing */ ++ ++/* ++ * To save much memory, we overlay the table used by compress() with those ++ * used by decompress(). The tab_prefix table is the same size and type ++ * as the codetab. The tab_suffix table needs 2**GIFBITS characters. We ++ * get this from the beginning of htab. The output stack uses the rest ++ * of htab, and contains characters. There is plenty of room for any ++ * possible stack (stack used to be 8000 characters). ++ */ ++ ++#define tab_prefixof(i) CodeTabOf(i) ++#define tab_suffixof(i) ((char_type*)(htab))[i] ++#define de_stack ((char_type*)&tab_suffixof((code_int)1< 0 ) ++ goto probe; ++nomatch: ++ output ( (code_int) ent ); ++ ++out_count; ++ ent = c; ++#ifdef SIGNED_COMPARE_SLOW ++ if ( (unsigned) free_ent < (unsigned) maxmaxcode) { ++#else /*SIGNED_COMPARE_SLOW*/ ++ if ( free_ent < maxmaxcode ) { /* } */ ++#endif /*SIGNED_COMPARE_SLOW*/ ++ CodeTabOf (i) = free_ent++; /* code -> hashtable */ ++ HashTabOf (i) = fcode; ++ } else ++ cl_block(); ++ } ++ /* ++ * Put out the final code. ++ */ ++ output( (code_int)ent ); ++ ++out_count; ++ output( (code_int) EOFCode ); ++} ++ ++/***************************************************************** ++ * TAG( output ) ++ * ++ * Output the given code. ++ * Inputs: ++ * code: A n_bits-bit integer. If == -1, then EOF. This assumes ++ * that n_bits =< (long)wordsize - 1. ++ * Outputs: ++ * Outputs code to the file. ++ * Assumptions: ++ * Chars are 8 bits long. ++ * Algorithm: ++ * Maintain a GIFBITS character long buffer (so that 8 codes will ++ * fit in it exactly). Use the VAX insv instruction to insert each ++ * code in turn. When the buffer fills up empty it and start over. ++ */ ++ ++static unsigned long cur_accum = 0; ++static int cur_bits = 0; ++ ++static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, ++ 0x001F, 0x003F, 0x007F, 0x00FF, ++ 0x01FF, 0x03FF, 0x07FF, 0x0FFF, ++ 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; ++ ++static void ++output(code_int code) ++{ ++ cur_accum &= masks[ cur_bits ]; ++ ++ if( cur_bits > 0 ) ++ cur_accum |= ((long)code << cur_bits); ++ else ++ cur_accum = code; ++ ++ cur_bits += n_bits; ++ ++ while( cur_bits >= 8 ) { ++ char_out( (unsigned int)(cur_accum & 0xff) ); ++ cur_accum >>= 8; ++ cur_bits -= 8; ++ } ++ ++ /* ++ * If the next entry is going to be too big for the code size, ++ * then increase it, if possible. ++ */ ++ if ( free_ent > maxcode || clear_flg ) { ++ ++ if( clear_flg ) { ++ ++ maxcode = MAXCODE (n_bits = g_init_bits); ++ clear_flg = 0; ++ ++ } else { ++ ++ ++n_bits; ++ if ( n_bits == maxbits ) ++ maxcode = maxmaxcode; ++ else ++ maxcode = MAXCODE(n_bits); ++ } ++ } ++ ++ if( code == EOFCode ) { ++ /* ++ * At EOF, write the rest of the buffer. ++ */ ++ while( cur_bits > 0 ) { ++ char_out( (unsigned int)(cur_accum & 0xff) ); ++ cur_accum >>= 8; ++ cur_bits -= 8; ++ } ++ ++ flush_char(); ++ ++/* fflush( g_outfile ); */ ++/* */ ++/* if( ferror( g_outfile ) ) */ ++/* return; */ ++ } ++} ++ ++/* ++ * Clear out the hash table ++ */ ++static void ++cl_block (void) /* table clear for block compress */ ++{ ++ ++ cl_hash ( (count_int) hsize ); ++ free_ent = ClearCode + 2; ++ clear_flg = 1; ++ ++ output( (code_int)ClearCode ); ++} ++ ++static void ++cl_hash(register count_int hsize) /* reset code table */ ++ ++{ ++ ++ register count_int *htab_p = htab+hsize; ++ ++ register long i; ++ register long m1 = -1; ++ ++ i = hsize - 16; ++ do { /* might use Sys V memset(3) here */ ++ *(htab_p-16) = m1; ++ *(htab_p-15) = m1; ++ *(htab_p-14) = m1; ++ *(htab_p-13) = m1; ++ *(htab_p-12) = m1; ++ *(htab_p-11) = m1; ++ *(htab_p-10) = m1; ++ *(htab_p-9) = m1; ++ *(htab_p-8) = m1; ++ *(htab_p-7) = m1; ++ *(htab_p-6) = m1; ++ *(htab_p-5) = m1; ++ *(htab_p-4) = m1; ++ *(htab_p-3) = m1; ++ *(htab_p-2) = m1; ++ *(htab_p-1) = m1; ++ htab_p -= 16; ++ } while ((i -= 16) >= 0); ++ ++ for ( i += 16; i > 0; --i ) ++ *--htab_p = m1; ++} ++ ++/****************************************************************************** ++ * ++ * GIF Specific routines ++ * ++ ******************************************************************************/ ++ ++/* ++ * Number of characters so far in this 'packet' ++ */ ++static int a_count; ++ ++/* ++ * Set up the 'byte output' routine ++ */ ++static void ++char_init(void) ++{ ++ a_count = 0; ++} ++ ++/* ++ * Define the storage for the packet accumulator ++ */ ++static char accum[ 256 ]; ++ ++/* ++ * Add a character to the end of the current packet, and if it is 254 ++ * characters, flush the packet to disk. ++ */ ++static void ++char_out(int c) ++{ ++ accum[ a_count++ ] = c; ++ if( a_count >= 254 ) ++ flush_char(); ++} ++ ++/* ++ * Flush the packet to disk, and reset the accumulator ++ */ ++static void ++flush_char(void) ++{ ++ if( a_count > 0 ) { ++ gdPutC( a_count, g_outfile ); ++ gdPutBuf( accum, a_count, g_outfile ); ++ a_count = 0; ++ } ++} ++ ++static void init_statics(void) { ++ /* Some of these are properly initialized later. What I'm doing ++ here is making sure code that depends on C's initialization ++ of statics doesn't break when the code gets called more ++ than once. */ ++ Width = 0; ++ Height = 0; ++ curx = 0; ++ cury = 0; ++ CountDown = 0; ++ Pass = 0; ++ Interlace = 0; ++ a_count = 0; ++ cur_accum = 0; ++ cur_bits = 0; ++ g_init_bits = 0; ++ g_outfile = 0; ++ ClearCode = 0; ++ EOFCode = 0; ++ free_ent = 0; ++ clear_flg = 0; ++ offset = 0; ++ in_count = 1; ++ out_count = 0; ++ hsize = HSIZE; ++ n_bits = 0; ++ maxbits = GIFBITS; ++ maxcode = 0; ++ maxmaxcode = (code_int)1 << GIFBITS; ++} ++ ++ ++/* +-------------------------------------------------------------------+ */ ++/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */ ++/* | Permission to use, copy, modify, and distribute this software | */ ++/* | and its documentation for any purpose and without fee is hereby | */ ++/* | granted, provided that the above copyright notice appear in all | */ ++/* | copies and that both that copyright notice and this permission | */ ++/* | notice appear in supporting documentation. This software is | */ ++/* | provided "as is" without express or implied warranty. | */ ++/* +-------------------------------------------------------------------+ */ +diff -Naur gd-2.0.7orig/gdcmpgif.c gd-2.0.7gif/gdcmpgif.c +--- gd-2.0.7orig/gdcmpgif.c 1970-01-01 10:00:00.000000000 +1000 ++++ gd-2.0.7gif/gdcmpgif.c 2002-11-18 11:39:01.000000000 +1100 +@@ -0,0 +1,85 @@ ++#include ++#include /* For unlink function */ ++#include "gd.h" ++ ++/* A short program which converts a .png file into a .gd file, for ++ your convenience in creating images on the fly from a ++ basis image that must be loaded quickly. The .gd format ++ is not intended to be a general-purpose format. */ ++ ++void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2); ++ ++ ++int main(int argc, char **argv) ++{ ++ gdImagePtr im1, im2; ++ FILE *in; ++ ++ if (argc != 3) { ++ fprintf(stderr, "Usage: gdcmpgif filename.gif filename.gif\n"); ++ exit(1); ++ } ++ in = fopen(argv[1], "rb"); ++ if (!in) { ++ fprintf(stderr, "Input file does not exist!\n"); ++ exit(1); ++ } ++ im1 = gdImageCreateFromGif(in); ++ fclose(in); ++ ++ if (!im1) { ++ fprintf(stderr, "Input is not in GIF format!\n"); ++ exit(1); ++ } ++ ++ in = fopen(argv[2], "rb"); ++ if (!in) { ++ fprintf(stderr, "Input file 2 does not exist!\n"); ++ exit(1); ++ } ++ im2 = gdImageCreateFromGif(in); ++ fclose(in); ++ ++ if (!im2) { ++ fprintf(stderr, "Input 2 is not in GIF format!\n"); ++ exit(1); ++ } ++ ++ CompareImages("gdcmpgif", im1, im2); ++ ++ gdImageDestroy(im1); ++ gdImageDestroy(im2); ++ ++ return 0; ++} ++ ++void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2) ++{ ++ int cmpRes; ++ ++ cmpRes = gdImageCompare(im1, im2); ++ ++ if (cmpRes & GD_CMP_IMAGE) { ++ printf("%%%s: ERROR images differ: BAD\n",msg); ++ } else if (cmpRes != 0) { ++ printf("%%%s: WARNING images differ: WARNING - Probably OK\n",msg); ++ } else { ++ printf("%%%s: OK\n",msg); ++ return; ++ } ++ ++ if (cmpRes & (GD_CMP_SIZE_X + GD_CMP_SIZE_Y)) { ++ printf("-%s: INFO image sizes differ\n",msg); ++ } ++ ++ if (cmpRes & GD_CMP_NUM_COLORS) { ++ printf("-%s: INFO number of pallette entries differ %d Vs. %d\n",msg, ++ im1->colorsTotal, im2->colorsTotal); ++ } ++ ++ if (cmpRes & GD_CMP_COLOR) { ++ printf("-%s: INFO actual colours of pixels differ\n",msg); ++ } ++} ++ ++ +diff -Naur gd-2.0.7orig/gdtest.c gd-2.0.7gif/gdtest.c +--- gd-2.0.7orig/gdtest.c 2002-11-02 05:40:42.000000000 +1100 ++++ gd-2.0.7gif/gdtest.c 2002-11-18 11:39:01.000000000 +1100 +@@ -90,6 +90,59 @@ + gdImageDestroy (im2); + ctx->gd_free (ctx); + ++ /* */ ++ /* Send to GIF File then Ptr */ ++ /* */ ++ sprintf(of, "%s.gif", argv[1]); ++ out = fopen(of, "wb"); ++ gdImageGif(im, out); ++ fclose(out); ++ ++ in = fopen(of, "rb"); ++ if (!in) { ++ fprintf(stderr, "GIF Output file does not exist!\n"); ++ exit(1); ++ } ++ im2 = gdImageCreateFromGif(in); ++ fclose(in); ++ ++ CompareImages("GD->GIF File->GD", ref, im2); ++ ++ gdImageDestroy(im2); ++ ++ /* ++ ** Test gdImageCreateFromGifSource ++ **/ ++ ++ in = fopen(of, "rb"); ++ ++ if (!in) ++ { ++ fprintf (stderr, "GD Source: ERROR - GD Source input file does not exist - Sink may have failed!\n"); ++ }; ++ ++ imgsrc.source = freadWrapper; ++ imgsrc.context = in; ++ im2 = gdImageCreateFromGifSource(&imgsrc); ++ fclose(in); ++ ++ if (im2 == NULL) { ++ printf("GD Source (GIF): ERROR Null returned by gdImageCreateFromGifSource\n"); ++ } else { ++ CompareImages("GD Source (GIF)", ref, im2); ++ gdImageDestroy(im2); ++ }; ++ ++ unlink(of); ++ ++ iptr = gdImageGifPtr(im,&sz); ++ ctx = gdNewDynamicCtx(sz,iptr); ++ im2 = gdImageCreateFromGifCtx(ctx); ++ ++ CompareImages("GD->GIF ptr->GD", ref, im2); ++ ++ gdImageDestroy(im2); ++ ctx->gd_free(ctx); + + /* */ + /* Send to GD2 File then Ptr */ +@@ -206,8 +259,6 @@ + gdImageDestroy (im2); + }; + +- unlink (of); +- + /* */ + /* Test Extraction */ + /* */ +@@ -273,6 +324,10 @@ + printf ("[Merged Image has %d colours]\n", im2->colorsTotal); + CompareImages ("Merged (gdtest.png, gdtest_merge.png)", im2, im3); + ++ out = fopen ("test/gdtest_merge_out.png", "wb"); ++ gdImagePng(im2, out); ++ close(out); ++ + gdImageDestroy (im2); + gdImageDestroy (im3); + +diff -Naur gd-2.0.7orig/gdtestft.c gd-2.0.7gif/gdtestft.c +--- gd-2.0.7orig/gdtestft.c 2002-11-15 02:39:33.000000000 +1100 ++++ gd-2.0.7gif/gdtestft.c 2002-11-18 11:39:01.000000000 +1100 +@@ -23,6 +23,8 @@ + #define MAXY(x) MAX4(x[1],x[3],x[5],x[7]) + #define MINY(x) MIN4(x[1],x[3],x[5],x[7]) + ++void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2); ++ + int + main (int argc, char *argv[]) + { +diff -Naur gd-2.0.7orig/giftogd2.c gd-2.0.7gif/giftogd2.c +--- gd-2.0.7orig/giftogd2.c 1970-01-01 10:00:00.000000000 +1000 ++++ gd-2.0.7gif/giftogd2.c 2002-11-18 11:39:01.000000000 +1100 +@@ -0,0 +1,48 @@ ++#include ++#include ++ ++#include "gd.h" ++ ++/* A short program which converts a .gif file into a .gd file, for ++ your convenience in creating images on the fly from a ++ basis image that must be loaded quickly. The .gd format ++ is not intended to be a general-purpose format. */ ++ ++int main(int argc, char **argv) ++{ ++ gdImagePtr im; ++ FILE *in, *out; ++ int cs, fmt; ++ ++ if (argc != 5) { ++ fprintf(stderr, "Usage: giftogd2 filename.gif filename.gd2 cs fmt\n"); ++ fprintf(stderr, " where cs is the chunk size\n"); ++ fprintf(stderr, " fmt is 1 for raw, 2 for compressed\n"); ++ exit(1); ++ } ++ in = fopen(argv[1], "rb"); ++ if (!in) { ++ fprintf(stderr, "Input file does not exist!\n"); ++ exit(1); ++ } ++ im = gdImageCreateFromGif(in); ++ fclose(in); ++ if (!im) { ++ fprintf(stderr, "Input is not in GIF format!\n"); ++ exit(1); ++ } ++ out = fopen(argv[2], "wb"); ++ if (!out) { ++ fprintf(stderr, "Output file cannot be written to!\n"); ++ gdImageDestroy(im); ++ exit(1); ++ } ++ cs = atoi(argv[3]); ++ fmt = atoi(argv[4]); ++ gdImageGd2(im, out, cs, fmt); ++ fclose(out); ++ gdImageDestroy(im); ++ ++ return 0; ++} ++ +diff -Naur gd-2.0.7orig/index.html gd-2.0.7gif/index.html +--- gd-2.0.7orig/index.html 2002-11-16 11:54:40.000000000 +1100 ++++ gd-2.0.7gif/index.html 2002-11-18 11:39:01.000000000 +1100 +@@ -28,7 +28,12 @@ + more compatible with the major Web browsers than even PNG is. WBMP is + intended for wireless devices (not regular web browsers). Old + code will need modification to call gdImagePng or gdImageJpeg instead +-of gdImageGif. Please do not ask us to send you the old GIF ++of gdImageGif. ++

++Note: The version at this site also supports GIF format, for those people ++who have not yet managed to move away from GIFs. ++

++Please do not ask the original author to send you the old GIF + version of GD. Unisys holds a patent on the LZW compression + algorithm, which is used in fully compressed GIF images. The best + solution is to move to legally unencumbered, well-compressed, +@@ -116,6 +121,18 @@ + Portions relating to WBMP copyright 2000, 2001, 2002 Maurice Szmurlo and Johan Van + den Brande. +

++GIF decompression code copyright 1990, 1991, 1993, by David Koblas ++(koblas@netcom.com). ++

++Non-LZW-based GIF compression code copyright 1998, by Hutchison Avenue ++Software Corporation (http://www.hasc.com/, ++info@hasc.com). ++

++LZW-based GIF compression code David Rowley. ++Obtaining a license for the Unisys LZW compression patent is ++entirely between the user and Unisys. The authors of gd can provide ++NO assistance in this matter. ++

+ Permission has been granted to copy, distribute and modify gd in any + context without fee, including a commercial application, provided that this notice + is present in user-accessible supporting documentation. +@@ -191,6 +208,24 @@ +

    +
  • fly, by Martin Gleeson +
++

What's new in the patched version?

++ ++This version reinstates GIF support. Specifically, the following functions are added: ++ ++

++Note: While every effort has been made to ensure that the _WinNT_ build works, it has not ++been tested. +

+

What's new in version 2.0.7?

+

+@@ -418,6 +453,7 @@ + preprocessing them, this should not be a big problem. gd 2.0 should + read old .gd and .gd2 files correctly. + ++ +

What's new in version 1.8.4?

+
    +
  • Add support for FreeType2 (John Ellson ellson@lucent.com) +@@ -450,6 +486,7 @@ + corrected +
  • Updated links to fast-moving, always dodging libpng and zlib web sites +
++ +

What's new in version 1.8.1?

+
    +
  • Optional components no longer built by default (following the +@@ -527,6 +564,7 @@ + gdImageCreateFromXpm + function, if the Xpm library is available. Thanks to Caolan McNamara. +
++ +

What's new in version 1.6.3?

+ Version 1.6.3 corrects a memory leak in gd_png.c. This leak caused + a significant amount of memory to be allocated and not freed when +@@ -1047,7 +1085,8 @@ +
gdPoint (TYPE) +
+ Represents a point in the coordinate space of the image; used +-by gdImagePolygon and ++by gdImagePolygon, ++gdImageOpenPolygon, and + gdImageFilledPolygon. +
+ typedef struct {
+@@ -1057,7 +1096,8 @@
+ 
gdPointPtr (TYPE) +
+ A pointer to a gdPoint structure; passed +-as an argument to gdImagePolygon ++as an argument to gdImagePolygon, ++gdImageOpenPolygon, + and gdImageFilledPolygon. + +
gdFTStringExtra (TYPE) +@@ -1175,6 +1215,75 @@ + /* ... Use the image ... */ + gdImageDestroy(im); +
++ ++
gdImageCreateFromGif(FILE *in) ++(FUNCTION) ++
gdImageCreateFromGifCtx(gdIOCtx *in) ++(FUNCTION) ++

++

++gdImageCreateFromGif is called to load images from GIF format files. ++Invoke gdImageCreateFromGif with an already opened pointer to a file ++containing the desired image. ++gdImageCreateFromGif ++returns a gdImagePtr to the new image, or NULL ++if unable to load the image (most often because the file is corrupt or ++does not contain a GIF image). gdImageCreateFromGif does not ++close the file. You can inspect the sx and sy members of the ++image to determine its size. The image must eventually be destroyed ++using gdImageDestroy(). ++
++gdImagePtr im;
++... inside a function ...
++FILE *in;
++in = fopen("mygif.gif", "rb");
++im = gdImageCreateFromGif(in);
++fclose(in);
++/* ... Use the image ... */
++gdImageDestroy(im);
++
++
gdImageCreateFromGifSource(gdSourcePtr in) ++(FUNCTION) ++
++gdImageCreateFromGifSource is called to load a GIF from ++a data source other than a file. Usage is very similar to ++the gdImageCreateFromGif function, ++except that the programmer provides a custom data source. ++

++The programmer must write an input function which accepts ++a context pointer, a buffer, and a number of bytes to be ++read as arguments. This function must read the number of ++bytes requested, unless the end of the file has been reached, ++in which case the function should return zero, or an error ++has occurred, in which case the function should return ++-1. The programmer then creates a ++gdSource structure and sets ++the source pointer to the input function and ++the context pointer to any value which is useful to the ++programmer. ++

++The example below ++implements gdImageCreateFromGif ++by creating a custom data source and invoking gdImageCreateFromGifSource. ++

++static int freadWrapper(void *context, char *buf, int len);
++
++gdImagePtr gdImageCreateFromGif(FILE *in)
++{
++        gdSource s;
++        s.source = freadWrapper;
++        s.context = in;
++        return gdImageCreateFromGifSource(&s);
++}
++
++static int freadWrapper(void *context, char *buf, int len)
++{
++        int got = fread(buf, 1, len, (FILE *) context);
++        return got;
++}
++
++ ++ +
gdImageCreateFromPng(FILE *in) + (FUNCTION) +
gdImageCreateFromPngCtx(gdIOCtx *in) +@@ -1390,6 +1499,92 @@ + /* Now destroy it */ + gdImageDestroy(im); + ++ ++
++void gdImageGif(gdImagePtr im, FILE *out) ++(FUNCTION) ++
++gdImageGif outputs the specified image to the specified ++file in GIF format. The file must be open for writing. Under MSDOS ++and all versions of Windows, it is important to use "wb" as opposed ++to simply "w" as the mode when opening the file, and under Unix there ++is no penalty for doing so. gdImageGif does not ++close the file; your code must do so. ++
++... inside a function ...
++gdImagePtr im;
++int black, white;
++FILE *out;
++/* Create the image */
++im = gdImageCreate(100, 100);
++/* Allocate background */
++white = gdImageColorAllocate(im, 255, 255, 255);
++/* Allocate drawing color */
++black = gdImageColorAllocate(im, 0, 0, 0);
++/* Draw rectangle */
++gdImageRectangle(im, 0, 0, 99, 99, black);
++/* Open output file in binary mode */
++out = fopen("rect.gif", "wb");
++/* Write GIF */
++gdImageGif(im, out);
++/* Close file */
++fclose(out);
++/* Destroy image */
++gdImageDestroy(im);
++
++ ++
++void* gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out) ++(FUNCTION) ++
Identical to gdImageGif except that it writes the GIF to a ++gdIOCtx. ++

++

++void* gdImageGifPtr(gdImagePtr im, int *size) ++(FUNCTION) ++
Identical to gdImageGif except that it returns a pointer to a memory ++area with the GIF data. This memory must be freed by the caller when it is ++no longer needed. The 'size' parameter received the total size of the block ++of memory. ++

++ ++

gdImageGifToSink(gdImagePtr im, gdSinkPtr out) ++(FUNCTION) ++
++gdImageGifToSink is called to write a GIF to ++a data "sink" (destination) other than a file. Usage is very similar to ++the gdImageGif function, ++except that the programmer provides a custom data sink. ++

++The programmer must write an output function which accepts ++a context pointer, a buffer, and a number of bytes to be ++written as arguments. This function must write the number of ++bytes requested and return that number, unless an error ++has occurred, in which case the function should return ++-1. The programmer then creates a ++gdSink structure and sets ++the sink pointer to the output function and ++the context pointer to any value which is useful to the ++programmer. ++

++The example below ++implements gdImageGif ++by creating a custom data source and invoking gdImageGifFromSink. ++

++static int stdioSink(void *context, char *buffer, int len)
++{
++        return fwrite(buffer, 1, len, (FILE *) context);
++}
++
++void gdImageGif(gdImagePtr im, FILE *out)
++{
++        gdSink mySink;
++        mySink.context = (void *) out;
++        mySink.sink = stdioSink;
++        gdImageGifToSink(im, &mySink);
++}
++
++ +
+ void gdImageJpeg(gdImagePtr im, FILE *out, int quality) + (FUNCTION)
+@@ -1810,6 +2005,15 @@ + /* Destroy it */ + gdImageDestroy(im); + ++ ++
void gdImageOpenPolygon(gdImagePtr im, gdPointPtr points, int pointsTotal, int color) ++(FUNCTION) ++
++gdImageOpenPolygon is used to draw an open polygon (ie. series of line segments). It is almost identical ++to gdImagePolygon, except that it does not join the last point to the ++first point. ++

++ +

void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color) + (FUNCTION) +
+@@ -3784,6 +3988,9 @@ + gdImageCreateFromGd | + gdImageCreateFromGd2 | + gdImageCreateFromGd2Part | ++gdImageCreateFromGif | ++gdImageCreateFromGifCtx | ++gdImageCreateFromGifSource | + gdImageCreateFromJpeg | + gdImageCreateFromPng | + gdImageCreateFromPngSource | +@@ -3801,6 +4008,10 @@ + gdImageGetInterlaced | + gdImageGetPixel | + gdImageGetTransparent | ++gdImageGif | ++gdImageGifCtx | ++gdImageGifPtr | ++gdImageGifToSink | + gdImageGreen | + gdImageInterlace | + gdImageJpeg | +@@ -3810,6 +4021,7 @@ + gdImagePng | + gdImagePngToSink | + gdImagePolygon | ++gdImageOpenPolygon | + gdImagePtr | + gdImageWBMP | + gdImageRectangle | +diff -Naur gd-2.0.7orig/test/fttestref.png gd-2.0.7gif/test/fttestref.png +--- gd-2.0.7orig/test/fttestref.png 1970-01-01 10:00:00.000000000 +1000 ++++ gd-2.0.7gif/test/fttestref.png 2002-11-18 14:30:15.000000000 +1100 +@@ -0,0 +1,19 @@ ++‰PNG ++ ++ IHDR7=¯7ú” fIDATxœí]k’ã( V¶öø&öœÄ™“8s;'±û$NNÂþؑ[!€ ?Ò|UÔÔTژÏâ! !.Zk Šön@Nr.\.©v°àjG‘œÇC 阦Éù›Ü0 Ü*ò½_3t×uzžgNUјçYw]·´Á†‹ÖéëÜQ&2¡œ…ÜY!B®ë:˜ç´ÖÑûÜ<ÏÐu¿aœétÛ¶œ*¼SyÚ¶u>ϖÜõzåV‘íýìuŽñøR€}â¶£L(.p¥&W;ŠäΊBî¬(>”³¢øP|ø>”qYuÄ¢øPvhÇf(äΊBn Jj9……‹âCI„E?҇’ÜÑñђûhrÿæ¨tx<0MÓbï=ŸOPJ@UUÐ4ÍR²ArÍéºN+¥3$¤Ôu­û¾—lÆróŠ¼l³»¥R ++Æqܚ\–çÇãñç ðã\UÕãœý4‰äÔ;ϳ7Ó,¸½œ bäè¦l‘ÞèGˆ‹‘–¯HK‘=æ®×+Üïwçïu]/ãŒÆ‡ÑsÏçþüù·ÛÛ¬ÿÁù2ÔX¤¥mÛ¨nÖ÷ýKü¦Te‘3J¹±$Dz{x”)5©ñ‚LBz"Ü]׉\ûÀ-yÈAëïPG‰z“%‡3œ´–3ª„Ëðpö=’Æ;€[*¶!éäepK{œÀ-*?MÓ¢íìÀÇR$NnÐú°H8žX ++jܦE!õÁXäè×®ë:J«À4;¶ORîBv¤ì0 ðû÷ïåÿhmã˜1'Ó0Ѷ­\Ò&‰/Ä1Ti‘ÖvD£Ó9'Žs¸Ä£ÓcϊǎÕd‹NŸ¦i)tŒÑ1y½^Å5ŠzVrgE!wV°Dèh•4{$‘¼TUõ²ví&eCé–6Ün7PJRj÷Ô«. å¬(äΊBî¬(äΊBî¬(äΊBî¬(äΊBî¬(äΊ,Ü6`ð(ni™[ÇYXgÙõ#°åÑ -àٍœýÊ-)á âäæyN–Tˆ$c¤(~®@RZ®º‡.Fn+b1E<ΏÇš¦qÎ`ø}Ó4o!øf8>-Ó4-™JmÇÑ?£JHÍvh‚;ÓQÐ Œæ;|`“3£íðP|Ø&+ß,Ê&GÇYÛ¶›œô7ñ\ï;²õÍJ” ëÝ"ñ–Òi¡ c݆drôËmtAÓ-ÛÆy¹=»£ ”ž­Ñ&Ï4M/Á£{ŸÇ÷³ó¡Ø´½º$m8Ö¼(r¶Åúpµ%¸u®ƒ€G‹œO)>r· šPn·›S)Þ;4Šu·ñãñð¸= ++9묽&v—ÆO}#§\Äm÷\ÑC·8É쵐S Áö½äL©™±ÿ”|Î4kms& ÷U@‰¹l´Ø» ++$`~tçÕ® ++Ö²¡QÐe"ǽÛ©“$cÕ§Ú^j›9¦³­³k®>§ƒ#açy:µq»Ý–Ü ++ôˆ™£Átá¿Ôõî;˜›ä BIĎ!©ì!%¤WXÉáxK;RÇÍ|…å”mۖµvIï`‰M ++c%'1ĦìY+)ˌ•œdÚóÂÊXIqƒZgËËåt]÷Òe•R»uÓlj¿­ËÆ&Òå"»MƒK‰¹YâS 6YÄ%:.7Q¿r¶”Ôuý"a ìHâÓC%àt§çJÖî‚iÄJÀk¬né Òú5ÌWoµ˜cak {O»9ˆ| ++xÛ+ W@­nËoît<êU×õ©‰xö ++Ä.Dˆ€ïþƼ‘Ã\è{IM2Õ¹ɧC὿1¶YµÔûrš+XŽ0++¹­‹™%FyÀ)›Få\-÷&êª0­Œ rˆØì¾[KEÑ÷½nÛvQª· _·,Ñ gE!wVü,r{Þz›]qØïŽðªªò*Îû‘ã5Ùg€|׺Kqöºö‚T^èCΖ¶‹ÏSpHr2ù!»%B3Õ^«äÔß Ðµö_L>Ïóâ-SJAß÷ї¦cu]¿=ˆ9ćEI¥/@رdƒ•\È h•èÅaR­äB€R“<3‡Ž©Ý¯"Ek\:lþ.ä»^EŠ‡$Vк²,Áþ]2_­WBKa_h)©dSsg×Û:Ñí.i¢Ðº”À…–컍¥¦n[*.Dn¥æž0¶è•XbIJG¥DëùB5$z{gÝvÓf×uË¡>3:hÇÕxͬ»<±<„+™çá0w>JJ !žß2eW(W¨b¶ó|*=› ++/IqsÝûXvyΊBî¬ÏÀm^ 𿆯rdØ^ƒÔ´{øˆ6“ ‡ÐPr¥öa““Êœ‘có…EÎ'±¶mW•gÛ9 ¬~ËPØž¤+ËW-’S §[Qƒuw“ÇTŽ%Ž•QãwWcÕœí¤€Ë‰ÄÇÑP0ºV²®]7©ëMRÓðf÷Ûo Ç¥¾«S–vEI¯³d]ÉDMÓ@]×â B—º„Ç™d3 ƒøÅÍX—È86§Oˆ\Œqñ•Ð ©b QŸ7‚(t!E·^JƒPפ撔†b5VŸÏ'üúõ+º¤<“&[òsŠ”upHr2nõŸA $]¸°Jîì'VÉåòÝo «ä$ºÄð&¹O!°bÜn7¸\.âQã›ÁµFØ@9ó¢ç€óä£I ‹©=`N…5Ýҕ2ý›9à=³ŠYš¸sã™äm ñJçèVrô¥65ˆJËÖP*ÁØÍI—ú93ëkº¢~Ðü Éäæ*Ù"eC®§Xv4ʶ…ÛU¦ˆöÙ"ecŒF“\j=øq³Xât­½ „\ÊLˆùˆ¸ðÚsk}ßG§ùà¸å"ۆÿóùLv³K)îoŠ3Þ °®gš†-ý{®.¡Àg“Ç©:MS§¬¤-—zþt‘v8ó¡ðÜäMÓ$eÆî÷{sÌ© ð̖¨éĬqÒ ²½º¥o²Y&¨Æa»ëµ“µ ÅRa%‡_зN…³éŸ!E ++«ö\ŒâlCŠòœ•m”Kz¦õàSv]7}Ò"DPë•h !蚉&™o–&¼Þ”œÖß ++0MzkJB*êgsrZûÝ¢Ç0÷ §õwv_¨õKú=Ðu!…~VüLrUUyµúiš–`ì½ò§¬Â5»®óª_t½Úûª{¼¹öÀ£~A†uNÞÙ»œ­Ûù\ ‡9JÏæÇ7Õ¨#Â;[VU}ßÃ×××bY£©@2˜T!_À§Õï•ë9ÁêݾÈTEEý:+ ++¹³â?–5ÆmBIEND®B`‚ +\ No newline at end of file diff --git a/gd.spec b/gd.spec index 878e10b..29a0e4b 100644 --- a/gd.spec +++ b/gd.spec @@ -7,17 +7,15 @@ Summary(es): Biblioteca para manipulaci Summary(pl): Biblioteka do tworzenia grafiki w formacie PNG, JPEG Summary(pt_BR): Biblioteca para manipulação de imagens Name: gd -Version: 2.0.1 -Release: 7 +Version: 2.0.9 +Release: 1 License: BSD-like Group: Libraries Source0: http://www.boutell.com/ftp-materials/boutell/gd/%{name}-%{version}.tar.gz -Patch0: %{name}-ac_am.patch -Patch1: http://downloads.rhyme.com.au/gd/patch_%{name}%{version}_gif_20011107.gz -Patch2: %{name}-gif-acam.patch -Patch3: %{name}-fontpath.patch -Patch4: %{name}-gdTiled-segv.patch -Patch5: %{name}-fixes.patch +#updated from http://downloads.rhyme.com.au/gd/patch_%{name}2.0.7_gif_20021118.gz +Patch0: %{name}-gif.patch +Patch1: %{name}-fontpath.patch +Patch2: %{name}-fixes.patch URL: http://www.boutell.com/gd/ BuildRequires: autoconf BuildRequires: automake @@ -140,12 +138,9 @@ para uso pelos programas que usam a libgd. %prep %setup -q -%patch0 -p1 -%{!?_without_gif:%patch1 -p1} -%{!?_without_gif:%patch2 -p1} -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 +%{!?_without_gif:%patch0 -p1} +%patch1 -p1 +%patch2 -p1 %build %{__libtoolize} @@ -170,12 +165,12 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(644,root,root,755) -%doc readme.txt +%doc COPYING index.html %attr(755,root,root) %{_libdir}/*.so.*.* %files devel %defattr(644,root,root,755) -%doc index.html +%attr(755,root,root) %{_bindir}/gdlib-config %attr(755,root,root) %{_libdir}/*.so %{_libdir}/*.la %{_includedir}/* @@ -186,4 +181,6 @@ rm -rf $RPM_BUILD_ROOT %files progs %defattr(644,root,root,755) -%attr(755,root,root) %{_bindir}/* +%attr(755,root,root) %{_bindir}/[!g]* +%{!?_without_gif:%attr(755,root,root) %{_bindir}/gif*} +%attr(755,root,root) %{_bindir}/gd[!l]*