- sync to 1.6.2

master
pierre 2006-04-05 15:37:05 +00:00
parent 1880992e24
commit 6223ff8d81
38 changed files with 18587 additions and 279 deletions

57
src/AUTHORS Normal file
View File

@ -0,0 +1,57 @@
Credits and license terms
In order to resolve any possible confusion regarding the authorship of
gd, the following copyright statement covers all of the authors who
have required such a statement. _If you are aware of any oversights in
this copyright notice, please contact Thomas Boutell who will be
pleased to correct them._
COPYRIGHT STATEMENT FOLLOWS THIS LINE
Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, by Cold
Spring Harbor Laboratory. Funded under Grant P41-RR02188 by the
National Institutes of Health.
Portions copyright 1996, 1997, 1998, 1999, by Boutell.Com, Inc.
Portions relating to GD2 format copyright 1999 Philip Warner.
Portions relating to PNG copyright 1999, Greg Roelofs.
Portions relating to libttf copyright 1999, John Ellson
(ellson@lucent.com).
_Permission has been granted to copy and distribute gd in any
context, including a commercial application, provided that this
notice is present in user-accessible supporting documentation._
This does not affect your ownership of the derived work itself, and
the intent is to assure proper credit for the authors of gd, not to
interfere with your productive use of gd. If you have questions,
ask. "Derived works" includes all programs that utilize the
library. Credit must be given in user-accessible documentation.
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.
Although their code does not appear in gd 1.6.2, the authors wish
to thank David Koblas, David Rowley, and Hutchison Avenue Software
Corporation for their prior contributions.
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 copyright holders disclaim 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.
END OF COPYRIGHT STATEMENT

56
src/COPYING Normal file
View File

@ -0,0 +1,56 @@
Credits and license terms
In order to resolve any possible confusion regarding the authorship of
gd, the following copyright statement covers all of the authors who
have required such a statement. _If you are aware of any oversights in
this copyright notice, please contact Thomas Boutell who will be
pleased to correct them._
COPYRIGHT STATEMENT FOLLOWS THIS LINE
Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, by Cold
Spring Harbor Laboratory. Funded under Grant P41-RR02188 by the
National Institutes of Health.
Portions copyright 1996, 1997, 1998, 1999, by Boutell.Com, Inc.
Portions relating to GD2 format copyright 1999 Philip Warner.
Portions relating to PNG copyright 1999, Greg Roelofs.
Portions relating to libttf copyright 1999, John Ellson
(ellson@lucent.com).
_Permission has been granted to copy and distribute gd in any
context, including a commercial application, provided that this
notice is present in user-accessible supporting documentation._
This does not affect your ownership of the derived work itself, and
the intent is to assure proper credit for the authors of gd, not to
interfere with your productive use of gd. If you have questions,
ask. "Derived works" includes all programs that utilize the
library. Credit must be given in user-accessible documentation.
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.
Although their code does not appear in gd 1.6.2, the authors wish
to thank David Koblas, David Rowley, and Hutchison Avenue Software
Corporation for their prior contributions.
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 copyright holders disclaim 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.
END OF COPYRIGHT STATEMENT

129
src/ChangeLog Normal file
View File

@ -0,0 +1,129 @@
990727 Thomas Boutell (TBB)
- Sorted out -lm problem that prevented PNG library
from being correctly detected or flagged as absent
- Got rid of unneeded Makefiles in test directory
- No version number change (no code changes)
990721 Philip Warner (pjw)
- Added gdImageCompare
- Various fixes, including bottom line of polygon
990720 Thomas Boutell (TBB)
- Removed automatic allocation of variably sized array
from gdImagePngCtx, replaced with malloc call
990720 Greg Roelofs
- Another new version of gd_png.c, with additional fixes
990720 John Ellson (ellson@lucent.com)
- converted to GNU autoconf/automake/libtool
- added functions: gdImageStringTTF gdImageColorResolve
- added source files: gdttf.c gdcache.c gdcche.h gdtestttf.c
- modified source files: gd.c gd.h
- renamed: HISTORY -> ChangeLog
readme.txt -> README
- updated docs: index.html, README
All changes should be fully backward compatible with gd1.6.1
If libttf is not found by configure then gdImageStringTTF is a stub.
990718 Thomas Boutell (TBB)
Incorporated Greg Roelofs' superior PNG read and write routines.
990715 Thomas Boutell (TBB)
Removed all GIF capability in favor of PNG
in order to remove any possible LZW patent concerns.
990701 Philip Warner (pjw) as documented by TBB
Implemented gdImageSink (missing in initial 1.5 release),
renamed all new source files to have a gd_ prefix.
990628 Thomas Boutell (TBB)
Removed all C++ style comments for broader compatibility.
990310 Philip Warner (pjw)
--------------------------
Broke gd.c into multiple files; gd.c now has graphics operations, and gd_<zzz> has specific
support for different formats (eg. GD, GD2, GIF).
Restructured I/O so that reading from files/streams/anything is now possible. All handled
through the IOCtx record which must define some basic I/O services. All services are defined
for files, but only some are defined for in-memory pointers. The in-memory pointer
implementation is primarily for Perl compatibility. Changed basically involved writing some
low level IO routines, and relpacing most FILE* variables with IOCtx*.
Added gdImageGdPtr, gdImageGd2Ptr, gdImageGifPtr, gdImageLzwPtr for Perl compatibility.
Broke up the GIF handling routines; gd_gif_in.c does all GIF input (this did not change when
support for LZW compression was removed). gd_gif_out.c not handles the miGif compression that
was introduced in version 1.3
Reinstated LZW support through the gdImageLzw function (defined in gd_lzw_out.c).
This is NOT built by default, and the header file must be modified to include it in the build.
Added 'GD2' support. This is a zlib-compressed internal format useful for extracting portions
of images without having to read entire image files. Informal tests suggest it is only 30% slower
than the old GD format, and file space requirements are similar to GOF. The GD2 header fields
now contain version information, so the format can probably be considered stable across versions.
Various other functions also added (see index.html).
Informal Tests
--------------
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t064.gd2 100 3000 2000 400 300
Extracting 100 times from (3000, 2000), size is 400x300
23 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t128.gd2 100 3000 2000 400 300
Extracting 100 times from (3000, 2000), size is 400x300
19 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t256.gd2 100 3000 2000 400 300
Extracting 100 times from (3000, 2000), size is 400x300
33 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t512.gd2 100 3000 2000 400 300
Extracting 100 times from (3000, 2000), size is 400x300
65 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t064.gd2 100 3000 2000 200 100
Extracting 100 times from (3000, 2000), size is 200x100
8 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t128.gd2 100 3000 2000 200 100
Extracting 100 times from (3000, 2000), size is 200x100
8 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t256.gd2 100 3000 2000 200 100
Extracting 100 times from (3000, 2000), size is 200x100
16 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t512.gd2 100 3000 2000 200 100
Extracting 100 times from (3000, 2000), size is 200x100
59 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t064.gd2 100 3000 2000 800 600
Extracting 100 times from (3000, 2000), size is 800x600
71 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t128.gd2 100 3000 2000 800 600
Extracting 100 times from (3000, 2000), size is 800x600
70 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t256.gd2 100 3000 2000 800 600
Extracting 100 times from (3000, 2000), size is 800x600
86 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t512.gd2 100 3000 2000 800 600
Extracting 100 times from (3000, 2000), size is 800x600
160 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ls -lrt t*.gd2
-rw-r--r-- 1 pjw users 1363301 Mar 10 12:03 t512.gd2
-rw-r--r-- 1 pjw users 1339003 Mar 10 12:06 t256.gd2
-rw-r--r-- 1 pjw users 1323925 Mar 10 12:09 t128.gd2
-rw-r--r-- 1 pjw users 1492096 Mar 10 12:12 t064.gd2
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t064.gd2 100 3000 2000 50 25
Extracting 100 times from (3000, 2000), size is 50x25
4 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t128.gd2 100 3000 2000 50 25
Extracting 100 times from (3000, 2000), size is 50x25
2 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t256.gd2 100 3000 2000 50 25
Extracting 100 times from (3000, 2000), size is 50x25
4 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t512.gd2 100 3000 2000 50 25
Extracting 100 times from (3000, 2000), size is 50x25
15 seconds to extract (& destroy) 100 times

View File

@ -1,14 +1,182 @@
Installing gd
=============
Basic Installation
==================
Note that this describes system level installation. Each user will
have to make a shell-alias or -function to use gd. Please see the
manual pages for how to do that.
These are generic installation instructions.
Installing gd is quite simple, just copy `gdprog' to some
bin-directory, and `gd.1' and `gdprog.1' to a matching
man/man1-directory.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
You may also execute `make install'. This will install `gdprog' in
/usr/local/bin, and `gd.1' and `gdprog.1' in /usr/local/man/man1.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

59
src/Makefile.am Normal file
View File

@ -0,0 +1,59 @@
## Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = 1.4
noinst_HEADERS = gdcache.h
lib_LTLIBRARIES = libgd.la
include_HEADERS = gd.h gd_io.h gdfontt.h gdfonts.h \
gdfontmb.h gdfontl.h gdfontg.h
libgd_la_SOURCES = gd.c gd_io.c gd_io_file.c gd_io_dp.c gd_io_ss.c \
gd_png.c gd_ss.c gd_gd.c gd_gd2.c gdfontt.c gdfonts.c gdfontmb.c \
gdfontl.c gdfontg.c gdttf.c gdcache.c \
gd.h gdcache.h gdfontl.h gdfonts.h gd_io.h gdfontg.h \
gdfontmb.h gdfontt.h
libgd_la_LIBADD = @LIBS@ -lm
bin_PROGRAMS = pngtogd pngtogd2 gdtopng gd2topng gd2copypal gdparttopng webpng
noinst_PROGRAMS = gdtest gddemo gd2time gdtestttf
gdtest_SOURCES = gdtest.c gd.h
gdtest_LDADD = libgd.la
gdtestttf_SOURCES = gdtestttf.c gd.h
gdtestttf_LDADD = libgd.la
gddemo_SOURCES = gddemo.c gd.h gdfonts.h gdfontg.h
gddemo_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

577
src/Makefile.in Normal file
View File

@ -0,0 +1,577 @@
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
AS = @AS@
CC = @CC@
DLLTOOL = @DLLTOOL@
LD = @LD@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
NM = @NM@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
VERSION = @VERSION@
AUTOMAKE_OPTIONS = 1.4
noinst_HEADERS = gdcache.h
lib_LTLIBRARIES = libgd.la
include_HEADERS = gd.h gd_io.h gdfontt.h gdfonts.h gdfontmb.h gdfontl.h gdfontg.h
libgd_la_SOURCES = gd.c gd_io.c gd_io_file.c gd_io_dp.c gd_io_ss.c gd_png.c gd_ss.c gd_gd.c gd_gd2.c gdfontt.c gdfonts.c gdfontmb.c gdfontl.c gdfontg.c gdttf.c gdcache.c gd.h gdcache.h gdfontl.h gdfonts.h gd_io.h gdfontg.h gdfontmb.h gdfontt.h
libgd_la_LIBADD = @LIBS@ -lm
bin_PROGRAMS = pngtogd pngtogd2 gdtopng gd2topng gd2copypal gdparttopng webpng
noinst_PROGRAMS = gdtest gddemo gd2time gdtestttf
gdtest_SOURCES = gdtest.c gd.h
gdtest_LDADD = libgd.la
gdtestttf_SOURCES = gdtestttf.c gd.h
gdtestttf_LDADD = libgd.la
gddemo_SOURCES = gddemo.c gd.h gdfonts.h gdfontg.h
gddemo_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
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(lib_LTLIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libgd_la_LDFLAGS =
libgd_la_DEPENDENCIES =
libgd_la_OBJECTS = gd.lo gd_io.lo gd_io_file.lo gd_io_dp.lo gd_io_ss.lo \
gd_png.lo gd_ss.lo gd_gd.lo gd_gd2.lo gdfontt.lo gdfonts.lo gdfontmb.lo \
gdfontl.lo gdfontg.lo gdttf.lo gdcache.lo
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
pngtogd_OBJECTS = pngtogd.o
pngtogd_DEPENDENCIES = libgd.la
pngtogd_LDFLAGS =
pngtogd2_OBJECTS = pngtogd2.o
pngtogd2_DEPENDENCIES = libgd.la
pngtogd2_LDFLAGS =
gdtopng_OBJECTS = gdtopng.o
gdtopng_DEPENDENCIES = libgd.la
gdtopng_LDFLAGS =
gd2topng_OBJECTS = gd2topng.o
gd2topng_DEPENDENCIES = libgd.la
gd2topng_LDFLAGS =
gd2copypal_OBJECTS = gd2copypal.o
gd2copypal_DEPENDENCIES = libgd.la
gd2copypal_LDFLAGS =
gdparttopng_OBJECTS = gdparttopng.o
gdparttopng_DEPENDENCIES = libgd.la
gdparttopng_LDFLAGS =
webpng_OBJECTS = webpng.o
webpng_DEPENDENCIES = libgd.la
webpng_LDFLAGS =
gdtest_OBJECTS = gdtest.o
gdtest_DEPENDENCIES = libgd.la
gdtest_LDFLAGS =
gddemo_OBJECTS = gddemo.o
gddemo_DEPENDENCIES = libgd.la
gddemo_LDFLAGS =
gd2time_OBJECTS = gd2time.o
gd2time_DEPENDENCIES = libgd.la
gd2time_LDFLAGS =
gdtestttf_OBJECTS = gdtestttf.o
gdtestttf_DEPENDENCIES = libgd.la
gdtestttf_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
HEADERS = $(include_HEADERS) $(noinst_HEADERS)
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
Makefile.in NEWS aclocal.m4 config.guess config.sub configure \
configure.in install-sh ltconfig ltmain.sh missing mkinstalldirs
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(libgd_la_SOURCES) $(pngtogd_SOURCES) $(pngtogd2_SOURCES) $(gdtopng_SOURCES) $(gd2topng_SOURCES) $(gd2copypal_SOURCES) $(gdparttopng_SOURCES) $(webpng_SOURCES) $(gdtest_SOURCES) $(gddemo_SOURCES) $(gd2time_SOURCES) $(gdtestttf_SOURCES)
OBJECTS = $(libgd_la_OBJECTS) $(pngtogd_OBJECTS) $(pngtogd2_OBJECTS) $(gdtopng_OBJECTS) $(gd2topng_OBJECTS) $(gd2copypal_OBJECTS) $(gdparttopng_OBJECTS) $(webpng_OBJECTS) $(gdtest_OBJECTS) $(gddemo_OBJECTS) $(gd2time_OBJECTS) $(gdtestttf_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(ACLOCAL_M4): configure.in
cd $(srcdir) && $(ACLOCAL)
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
mostlyclean-libLTLIBRARIES:
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
distclean-libLTLIBRARIES:
maintainer-clean-libLTLIBRARIES:
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(libdir)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
list='$(lib_LTLIBRARIES)'; for p in $$list; do \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
done
.c.o:
$(COMPILE) -c $<
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libgd.la: $(libgd_la_OBJECTS) $(libgd_la_DEPENDENCIES)
$(LINK) -rpath $(libdir) $(libgd_la_LDFLAGS) $(libgd_la_OBJECTS) $(libgd_la_LIBADD) $(LIBS)
mostlyclean-binPROGRAMS:
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
distclean-binPROGRAMS:
maintainer-clean-binPROGRAMS:
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
if test -f $$p; then \
echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
list='$(bin_PROGRAMS)'; for p in $$list; do \
rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
done
mostlyclean-noinstPROGRAMS:
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
distclean-noinstPROGRAMS:
maintainer-clean-noinstPROGRAMS:
pngtogd: $(pngtogd_OBJECTS) $(pngtogd_DEPENDENCIES)
@rm -f pngtogd
$(LINK) $(pngtogd_LDFLAGS) $(pngtogd_OBJECTS) $(pngtogd_LDADD) $(LIBS)
pngtogd2: $(pngtogd2_OBJECTS) $(pngtogd2_DEPENDENCIES)
@rm -f pngtogd2
$(LINK) $(pngtogd2_LDFLAGS) $(pngtogd2_OBJECTS) $(pngtogd2_LDADD) $(LIBS)
gdtopng: $(gdtopng_OBJECTS) $(gdtopng_DEPENDENCIES)
@rm -f gdtopng
$(LINK) $(gdtopng_LDFLAGS) $(gdtopng_OBJECTS) $(gdtopng_LDADD) $(LIBS)
gd2topng: $(gd2topng_OBJECTS) $(gd2topng_DEPENDENCIES)
@rm -f gd2topng
$(LINK) $(gd2topng_LDFLAGS) $(gd2topng_OBJECTS) $(gd2topng_LDADD) $(LIBS)
gd2copypal: $(gd2copypal_OBJECTS) $(gd2copypal_DEPENDENCIES)
@rm -f gd2copypal
$(LINK) $(gd2copypal_LDFLAGS) $(gd2copypal_OBJECTS) $(gd2copypal_LDADD) $(LIBS)
gdparttopng: $(gdparttopng_OBJECTS) $(gdparttopng_DEPENDENCIES)
@rm -f gdparttopng
$(LINK) $(gdparttopng_LDFLAGS) $(gdparttopng_OBJECTS) $(gdparttopng_LDADD) $(LIBS)
webpng: $(webpng_OBJECTS) $(webpng_DEPENDENCIES)
@rm -f webpng
$(LINK) $(webpng_LDFLAGS) $(webpng_OBJECTS) $(webpng_LDADD) $(LIBS)
gdtest: $(gdtest_OBJECTS) $(gdtest_DEPENDENCIES)
@rm -f gdtest
$(LINK) $(gdtest_LDFLAGS) $(gdtest_OBJECTS) $(gdtest_LDADD) $(LIBS)
gddemo: $(gddemo_OBJECTS) $(gddemo_DEPENDENCIES)
@rm -f gddemo
$(LINK) $(gddemo_LDFLAGS) $(gddemo_OBJECTS) $(gddemo_LDADD) $(LIBS)
gd2time: $(gd2time_OBJECTS) $(gd2time_DEPENDENCIES)
@rm -f gd2time
$(LINK) $(gd2time_LDFLAGS) $(gd2time_OBJECTS) $(gd2time_LDADD) $(LIBS)
gdtestttf: $(gdtestttf_OBJECTS) $(gdtestttf_DEPENDENCIES)
@rm -f gdtestttf
$(LINK) $(gdtestttf_LDFLAGS) $(gdtestttf_OBJECTS) $(gdtestttf_LDADD) $(LIBS)
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(includedir)
@list='$(include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
$(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
list='$(include_HEADERS)'; for p in $$list; do \
rm -f $(DESTDIR)$(includedir)/$$p; \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
-rm -rf $(distdir)
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
dc_install_base=`cd $(distdir)/=inst && pwd`; \
cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) dist
-rm -rf $(distdir)
@banner="$(distdir).tar.gz is ready for distribution"; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"
dist: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
dist-all: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
distdir: $(DISTFILES)
-rm -rf $(distdir)
mkdir $(distdir)
-chmod 777 $(distdir)
$(mkinstalldirs) $(distdir)/test
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
gd.lo gd.o : gd.c gd.h gd_io.h
gd2copypal.o: gd2copypal.c gd.h gd_io.h
gd2time.o: gd2time.c gd.h gd_io.h
gd2topng.o: gd2topng.c gd.h gd_io.h
gd_gd.lo gd_gd.o : gd_gd.c gd.h gd_io.h
gd_gd2.lo gd_gd2.o : gd_gd2.c gd.h gd_io.h
gd_io.lo gd_io.o : gd_io.c gd.h gd_io.h
gd_io_dp.lo gd_io_dp.o : gd_io_dp.c gd.h gd_io.h
gd_io_file.lo gd_io_file.o : gd_io_file.c gd.h gd_io.h
gd_io_ss.lo gd_io_ss.o : gd_io_ss.c gd.h gd_io.h
gd_png.lo gd_png.o : gd_png.c gd.h gd_io.h
gd_ss.lo gd_ss.o : gd_ss.c gd.h gd_io.h
gdcache.lo gdcache.o : gdcache.c gdcache.h
gddemo.o: gddemo.c gd.h gd_io.h gdfontg.h gdfonts.h
gdfontg.lo gdfontg.o : gdfontg.c gdfontg.h gd.h gd_io.h
gdfontl.lo gdfontl.o : gdfontl.c gdfontl.h gd.h gd_io.h
gdfontmb.lo gdfontmb.o : gdfontmb.c gdfontmb.h gd.h gd_io.h
gdfonts.lo gdfonts.o : gdfonts.c gdfonts.h gd.h gd_io.h
gdfontt.lo gdfontt.o : gdfontt.c gdfontt.h gd.h gd_io.h
gdparttopng.o: gdparttopng.c gd.h gd_io.h
gdtest.o: gdtest.c gd.h gd_io.h
gdtestttf.o: gdtestttf.c gd.h gd_io.h
gdtopng.o: gdtopng.c gd.h gd_io.h
gdttf.lo gdttf.o : gdttf.c gd.h gd_io.h gdcache.h
pngtogd.o: pngtogd.c gd.h gd_io.h
pngtogd2.o: pngtogd2.c gd.h gd_io.h
webpng.o: webpng.c gd.h gd_io.h
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am: install-libLTLIBRARIES install-binPROGRAMS
install-exec: install-exec-am
install-data-am: install-includeHEADERS
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am: uninstall-libLTLIBRARIES uninstall-binPROGRAMS \
uninstall-includeHEADERS
uninstall: uninstall-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) \
$(DESTDIR)$(includedir)
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-binPROGRAMS \
mostlyclean-noinstPROGRAMS mostlyclean-tags \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \
clean-binPROGRAMS clean-noinstPROGRAMS clean-tags \
clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-libLTLIBRARIES distclean-compile \
distclean-libtool distclean-binPROGRAMS \
distclean-noinstPROGRAMS distclean-tags \
distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
-rm -f config.status
maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-binPROGRAMS \
maintainer-clean-noinstPROGRAMS maintainer-clean-tags \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
-rm -f config.status
.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
distclean-compile clean-compile maintainer-clean-compile \
mostlyclean-libtool distclean-libtool clean-libtool \
maintainer-clean-libtool mostlyclean-binPROGRAMS distclean-binPROGRAMS \
clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \
install-binPROGRAMS mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
uninstall-includeHEADERS install-includeHEADERS tags mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

129
src/NEWS Normal file
View File

@ -0,0 +1,129 @@
990727 Thomas Boutell (TBB)
- Sorted out -lm problem that prevented PNG library
from being correctly detected or flagged as absent
- Got rid of unneeded Makefiles in test directory
- No version number change (no code changes)
990721 Philip Warner (pjw)
- Added gdImageCompare
- Various fixes, including bottom line of polygon
990720 Thomas Boutell (TBB)
- Removed automatic allocation of variably sized array
from gdImagePngCtx, replaced with malloc call
990720 Greg Roelofs
- Another new version of gd_png.c, with additional fixes
990720 John Ellson (ellson@lucent.com)
- converted to GNU autoconf/automake/libtool
- added functions: gdImageStringTTF gdImageColorResolve
- added source files: gdttf.c gdcache.c gdcche.h gdtestttf.c
- modified source files: gd.c gd.h
- renamed: HISTORY -> ChangeLog
readme.txt -> README
- updated docs: index.html, README
All changes should be fully backward compatible with gd1.6.1
If libttf is not found by configure then gdImageStringTTF is a stub.
990718 Thomas Boutell (TBB)
Incorporated Greg Roelofs' superior PNG read and write routines.
990715 Thomas Boutell (TBB)
Removed all GIF capability in favor of PNG
in order to remove any possible LZW patent concerns.
990701 Philip Warner (pjw) as documented by TBB
Implemented gdImageSink (missing in initial 1.5 release),
renamed all new source files to have a gd_ prefix.
990628 Thomas Boutell (TBB)
Removed all C++ style comments for broader compatibility.
990310 Philip Warner (pjw)
--------------------------
Broke gd.c into multiple files; gd.c now has graphics operations, and gd_<zzz> has specific
support for different formats (eg. GD, GD2, GIF).
Restructured I/O so that reading from files/streams/anything is now possible. All handled
through the IOCtx record which must define some basic I/O services. All services are defined
for files, but only some are defined for in-memory pointers. The in-memory pointer
implementation is primarily for Perl compatibility. Changed basically involved writing some
low level IO routines, and relpacing most FILE* variables with IOCtx*.
Added gdImageGdPtr, gdImageGd2Ptr, gdImageGifPtr, gdImageLzwPtr for Perl compatibility.
Broke up the GIF handling routines; gd_gif_in.c does all GIF input (this did not change when
support for LZW compression was removed). gd_gif_out.c not handles the miGif compression that
was introduced in version 1.3
Reinstated LZW support through the gdImageLzw function (defined in gd_lzw_out.c).
This is NOT built by default, and the header file must be modified to include it in the build.
Added 'GD2' support. This is a zlib-compressed internal format useful for extracting portions
of images without having to read entire image files. Informal tests suggest it is only 30% slower
than the old GD format, and file space requirements are similar to GOF. The GD2 header fields
now contain version information, so the format can probably be considered stable across versions.
Various other functions also added (see index.html).
Informal Tests
--------------
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t064.gd2 100 3000 2000 400 300
Extracting 100 times from (3000, 2000), size is 400x300
23 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t128.gd2 100 3000 2000 400 300
Extracting 100 times from (3000, 2000), size is 400x300
19 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t256.gd2 100 3000 2000 400 300
Extracting 100 times from (3000, 2000), size is 400x300
33 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t512.gd2 100 3000 2000 400 300
Extracting 100 times from (3000, 2000), size is 400x300
65 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t064.gd2 100 3000 2000 200 100
Extracting 100 times from (3000, 2000), size is 200x100
8 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t128.gd2 100 3000 2000 200 100
Extracting 100 times from (3000, 2000), size is 200x100
8 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t256.gd2 100 3000 2000 200 100
Extracting 100 times from (3000, 2000), size is 200x100
16 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t512.gd2 100 3000 2000 200 100
Extracting 100 times from (3000, 2000), size is 200x100
59 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t064.gd2 100 3000 2000 800 600
Extracting 100 times from (3000, 2000), size is 800x600
71 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t128.gd2 100 3000 2000 800 600
Extracting 100 times from (3000, 2000), size is 800x600
70 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t256.gd2 100 3000 2000 800 600
Extracting 100 times from (3000, 2000), size is 800x600
86 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t512.gd2 100 3000 2000 800 600
Extracting 100 times from (3000, 2000), size is 800x600
160 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ls -lrt t*.gd2
-rw-r--r-- 1 pjw users 1363301 Mar 10 12:03 t512.gd2
-rw-r--r-- 1 pjw users 1339003 Mar 10 12:06 t256.gd2
-rw-r--r-- 1 pjw users 1323925 Mar 10 12:09 t128.gd2
-rw-r--r-- 1 pjw users 1492096 Mar 10 12:12 t064.gd2
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t064.gd2 100 3000 2000 50 25
Extracting 100 times from (3000, 2000), size is 50x25
4 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t128.gd2 100 3000 2000 50 25
Extracting 100 times from (3000, 2000), size is 50x25
2 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t256.gd2 100 3000 2000 50 25
Extracting 100 times from (3000, 2000), size is 50x25
4 seconds to extract (& destroy) 100 times
pjw@Acheron:/home/pjw/work/gd1.3pjw > ./gd2time t512.gd2 100 3000 2000 50 25
Extracting 100 times from (3000, 2000), size is 50x25
15 seconds to extract (& destroy) 100 times

2488
src/README

File diff suppressed because it is too large Load Diff

510
src/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,510 @@
dnl aclocal.m4 generated automatically by aclocal 1.4
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
# Do all the work for Automake. This macro actually does too much --
# some checks are only needed if your package does certain things.
# But this isn't really a big deal.
# serial 1
dnl Usage:
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
AC_DEFUN(AM_INIT_AUTOMAKE,
[AC_REQUIRE([AC_PROG_INSTALL])
PACKAGE=[$1]
AC_SUBST(PACKAGE)
VERSION=[$2]
AC_SUBST(VERSION)
dnl test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
ifelse([$3],,
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
AC_REQUIRE([AM_SANITY_CHECK])
AC_REQUIRE([AC_ARG_PROGRAM])
dnl FIXME This is truly gross.
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
AC_REQUIRE([AC_PROG_MAKE_SET])])
#
# Check to make sure that the build environment is sane.
#
AC_DEFUN(AM_SANITY_CHECK,
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftestfile
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
if test "[$]*" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftestfile`
fi
if test "[$]*" != "X $srcdir/configure conftestfile" \
&& test "[$]*" != "X conftestfile $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "[$]2" = conftestfile
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
rm -f conftest*
AC_MSG_RESULT(yes)])
dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
dnl The program must properly implement --version.
AC_DEFUN(AM_MISSING_PROG,
[AC_MSG_CHECKING(for working $2)
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if ($2 --version) < /dev/null > /dev/null 2>&1; then
$1=$2
AC_MSG_RESULT(found)
else
$1="$3/missing $2"
AC_MSG_RESULT(missing)
fi
AC_SUBST($1)])
# serial 40 AC_PROG_LIBTOOL
AC_DEFUN(AC_PROG_LIBTOOL,
[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
# Save cache, so that ltconfig can load it
AC_CACHE_SAVE
# Actually configure libtool. ac_aux_dir is where install-sh is found.
CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
|| AC_MSG_ERROR([libtool configure failed])
# Reload cache, that may have been modified by ltconfig
AC_CACHE_LOAD
# This can be used to rebuild libtool when needed
LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
# Always use our own libtool.
LIBTOOL='$(SHELL) $(top_builddir)/libtool'
AC_SUBST(LIBTOOL)dnl
# Redirect the config.log output again, so that the ltconfig log is not
# clobbered by the next message.
exec 5>>./config.log
])
AC_DEFUN(AC_LIBTOOL_SETUP,
[AC_PREREQ(2.13)dnl
AC_REQUIRE([AC_ENABLE_SHARED])dnl
AC_REQUIRE([AC_ENABLE_STATIC])dnl
AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
AC_REQUIRE([AC_PROG_RANLIB])dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_LD])dnl
AC_REQUIRE([AC_PROG_NM])dnl
AC_REQUIRE([AC_PROG_LN_S])dnl
dnl
# Check for any special flags to pass to ltconfig.
libtool_flags="--cache-file=$cache_file"
test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
[libtool_flags="$libtool_flags --enable-dlopen"])
ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
[libtool_flags="$libtool_flags --enable-win32-dll"])
AC_ARG_ENABLE(libtool-lock,
[ --disable-libtool-lock avoid locking (might break parallel builds)])
test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case "$host" in
*-*-irix6*)
# Find out which ABI we are using.
echo '[#]line __oline__ "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case "`/usr/bin/file conftest.o`" in
*32-bit*)
LD="${LD-ld} -32"
;;
*N32*)
LD="${LD-ld} -n32"
;;
*64-bit*)
LD="${LD-ld} -64"
;;
esac
fi
rm -rf conftest*
;;
*-*-sco3.2v5*)
# On SCO OpenServer 5, we need -belf to get full-featured binaries.
SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -belf"
AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
[AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
if test x"$lt_cv_cc_needs_belf" != x"yes"; then
# this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
CFLAGS="$SAVE_CFLAGS"
fi
;;
ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
[*-*-cygwin* | *-*-mingw*)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
])
esac
])
# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
# AC_ENABLE_SHARED - implement the --enable-shared flag
# Usage: AC_ENABLE_SHARED[(DEFAULT)]
# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
# `yes'.
AC_DEFUN(AC_ENABLE_SHARED, [dnl
define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE(shared,
changequote(<<, >>)dnl
<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case "$enableval" in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
for pkg in $enableval; do
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$ac_save_ifs"
;;
esac],
enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
])
# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_SHARED(no)])
# AC_ENABLE_STATIC - implement the --enable-static flag
# Usage: AC_ENABLE_STATIC[(DEFAULT)]
# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
# `yes'.
AC_DEFUN(AC_ENABLE_STATIC, [dnl
define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE(static,
changequote(<<, >>)dnl
<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case "$enableval" in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
for pkg in $enableval; do
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$ac_save_ifs"
;;
esac],
enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
])
# AC_DISABLE_STATIC - set the default static flag to --disable-static
AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_STATIC(no)])
# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
# `yes'.
AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE(fast-install,
changequote(<<, >>)dnl
<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case "$enableval" in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
for pkg in $enableval; do
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$ac_save_ifs"
;;
esac],
enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
])
# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_FAST_INSTALL(no)])
# AC_PROG_LD - find the path to the GNU or non-GNU linker
AC_DEFUN(AC_PROG_LD,
[AC_ARG_WITH(gnu-ld,
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
ac_prog=ld
if test "$ac_cv_prog_gcc" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by GCC])
ac_prog=`($CC -print-prog-name=ld) 2>&5`
case "$ac_prog" in
# Accept absolute paths.
changequote(,)dnl
[\\/]* | [A-Za-z]:[\\/]*)
re_direlt='/[^/][^/]*/\.\./'
changequote([,])dnl
# Canonicalize the path of ld
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
done
test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
ac_prog=ld
;;
*)
# If it is relative, then search for the first ld in PATH.
with_gnu_ld=unknown
;;
esac
elif test "$with_gnu_ld" = yes; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL(ac_cv_path_LD,
[if test -z "$LD"; then
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
ac_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some GNU ld's only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
test "$with_gnu_ld" != no && break
else
test "$with_gnu_ld" != yes && break
fi
fi
done
IFS="$ac_save_ifs"
else
ac_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
LD="$ac_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT($LD)
else
AC_MSG_RESULT(no)
fi
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
AC_SUBST(LD)
AC_PROG_LD_GNU
])
AC_DEFUN(AC_PROG_LD_GNU,
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
ac_cv_prog_gnu_ld=yes
else
ac_cv_prog_gnu_ld=no
fi])
])
# AC_PROG_NM - find the path to a BSD-compatible name lister
AC_DEFUN(AC_PROG_NM,
[AC_MSG_CHECKING([for BSD-compatible nm])
AC_CACHE_VAL(ac_cv_path_NM,
[if test -n "$NM"; then
# Let the user override the test.
ac_cv_path_NM="$NM"
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
# Check to see if the nm accepts a BSD-compat flag.
# Adding the `sed 1q' prevents false positives on HP-UX, which says:
# nm: unknown option "B" ignored
if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
ac_cv_path_NM="$ac_dir/nm -B"
break
elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
ac_cv_path_NM="$ac_dir/nm -p"
break
else
ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
continue # so that we can try to find one that supports BSD flags
fi
fi
done
IFS="$ac_save_ifs"
test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
fi])
NM="$ac_cv_path_NM"
AC_MSG_RESULT([$NM])
AC_SUBST(NM)
])
# AC_CHECK_LIBM - check for math library
AC_DEFUN(AC_CHECK_LIBM,
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
LIBM=
case "$host" in
*-*-beos* | *-*-cygwin*)
# These system don't have libm
;;
*-ncr-sysv4.3*)
AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
;;
*)
AC_CHECK_LIB(m, main, LIBM="-lm")
;;
esac
])
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
# the libltdl convenience library, adds --enable-ltdl-convenience to
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
# '${top_builddir}/' (note the single quotes!) if your package is not
# flat, and, if you're not using automake, define top_builddir as
# appropriate in the Makefiles.
AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
case "$enable_ltdl_convenience" in
no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
"") enable_ltdl_convenience=yes
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
esac
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
])
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
# the libltdl installable library, and adds --enable-ltdl-install to
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
# '${top_builddir}/' (note the single quotes!) if your package is not
# flat, and, if you're not using automake, define top_builddir as
# appropriate in the Makefiles.
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_CHECK_LIB(ltdl, main,
[test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
[if test x"$enable_ltdl_install" = xno; then
AC_MSG_WARN([libltdl not installed, but installation disabled])
else
enable_ltdl_install=yes
fi
])
if test x"$enable_ltdl_install" = x"yes"; then
ac_configure_args="$ac_configure_args --enable-ltdl-install"
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
else
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
LIBLTDL="-lltdl"
INCLTDL=
fi
])
dnl old names
AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
dnl This is just to silence aclocal about the macro not being used
ifelse([AC_DISABLE_FAST_INSTALL])dnl

1087
src/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1215
src/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

2061
src/configure vendored Executable file

File diff suppressed because it is too large Load Diff

28
src/configure.in Normal file
View File

@ -0,0 +1,28 @@
dnl Process this file with autoconf to produce a configure script
AC_INIT(configure.in)
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE(gd, 1.6.2)
AC_PROG_CC
AC_ISC_POSIX
AM_PROG_LIBTOOL
AC_PROG_INSTALL
dnl Set LDFLAGS and CPPFLAGS so that AC_CHECK_LIBS can find installed libs in --prefix dir
LDFLAGS="$LDFLAGS -L$libdir"
CPPFLAGS="$CPPFLAGS -I$includedir"
dnl Sometimes math libs are in libc, so no warning if libm not found
AC_CHECK_LIB(m,main)
dnl The libraries libz and libpng are required.
AC_CHECK_LIB(z,main,,AC_MSG_ERROR(libz not found.))
AC_CHECK_LIB(png,main,,AC_MSG_ERROR(libpng not found.))
dnl The libraries libttf is optional.
AC_CHECK_LIB(ttf,main,,AC_MSG_WARN(libgd will be built without support for TrueType fonts.))
AC_OUTPUT(Makefile)

852
src/gd.c
View File

@ -4,7 +4,11 @@
#include <stdlib.h>
#include <zlib.h>
#include "gd.h"
#include "mtables.c"
#define costScale 1024
static int cost[];
#define sintScale 1024
static int sint[];
static void gdImageBrushApply(gdImagePtr im, int x, int y);
static void gdImageTileApply(gdImagePtr im, int x, int y);
@ -123,6 +127,56 @@ int gdImageColorAllocate(gdImagePtr im, int r, int g, int b)
return ct;
}
/*
* gdImageColorResolve is an alternative for the code fragment:
*
* if ((color=gdImageColorExact(im,R,G,B)) < 0)
* if ((color=gdImageColorAllocate(im,R,G,B)) < 0)
* color=gdImageColorClosest(im,R,G,B);
*
* in a single function. Its advantage is that it is guaranteed to
* return a color index in one search over the color table.
*/
int gdImageColorResolve(gdImagePtr im, int r, int g, int b)
{
int c;
int ct = -1;
int op = -1;
long rd, gd, bd, dist;
long mindist = 3*255*255; /* init to max poss dist */
for (c = 0; c < im->colorsTotal; c++) {
if (im->open[c]) {
op = c; /* Save open slot */
continue; /* Color not in use */
}
rd = (long)(im->red [c] - r);
gd = (long)(im->green[c] - g);
bd = (long)(im->blue [c] - b);
dist = rd * rd + gd * gd + bd * bd;
if (dist < mindist) {
if (dist == 0) {
return c; /* Return exact match color */
}
mindist = dist;
ct = c;
}
}
/* no exact match. We now know closest, but first try to allocate exact */
if (op == -1) {
op = im->colorsTotal;
if (op == gdMaxColors) { /* No room for more colors */
return ct; /* Return closest available color */
}
im->colorsTotal++;
}
im->red [op] = r;
im->green[op] = g;
im->blue [op] = b;
im->open [op] = 0;
return op; /* Return newly allocated color */
}
void gdImageColorDeallocate(gdImagePtr im, int color)
{
/* Mark it open. */
@ -1242,7 +1296,7 @@ void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c)
}
}
/* Fix in 1.3: count a vertex only once */
for (y=miny; (y < maxy); y++) {
for (y=miny; (y <= maxy); y++) {
/*1.4 int interLast = 0; */
/* int dirLast = 0; */
/* int interFirst = 1; */
@ -1270,6 +1324,8 @@ void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c)
}
if ((y >= y1) && (y < y2)) {
im->polyInts[ints++] = (y-y1) * (x2-x1) / (y2-y1) + x1;
} else if ((y == maxy) && (y > y1) && (y <= y2)) {
im->polyInts[ints++] = (y-y1) * (x2-x1) / (y2-y1) + x1;
}
}
qsort(im->polyInts, ints, sizeof(int), gdCompareInt);
@ -1354,3 +1410,795 @@ void gdImageInterlace(gdImagePtr im, int interlaceArg)
{
im->interlace = interlaceArg;
}
int gdImageCompare(gdImagePtr im1, gdImagePtr im2)
{
int x, y;
int p1, p2;
int cmpStatus = 0;
int sx, sy;
if (im1->interlace != im2->interlace) {
cmpStatus |= GD_CMP_INTERLACE;
}
if (im1->transparent != im2->transparent) {
cmpStatus |= GD_CMP_TRANSPARENT;
}
if (im1->sx != im2->sx) {
cmpStatus |= GD_CMP_SIZE_X + GD_CMP_IMAGE;
if (im1->sx < im2->sx) {
sx = im1->sx;
} else {
sx = im2->sx;
}
} else {
sx = im1->sx;
}
if (im1->sy != im2->sy) {
cmpStatus |= GD_CMP_SIZE_Y + GD_CMP_IMAGE;
if (im1->sy < im2->sy) {
sy = im1->sy;
} else {
sy = im2->sy;
}
}
if (im1->colorsTotal != im2->colorsTotal) {
cmpStatus |= GD_CMP_NUM_COLORS;
}
for ( y = 0 ; (y<im1->sy) ; y++ ) {
for ( x = 0 ; (x < im1->sx) ; x++ ) {
p1 = im1->pixels[y][x];
p2 = im2->pixels[y][x];
if (im1->red[p1] != im2->red[p2]) {
cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE;
break;
}
if (im1->green[p1] != im2->green[p2]) {
cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE;
break;
}
if (im1->blue[p1] != im2->blue[p2]) {
cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE;
break;
}
}
if (cmpStatus & GD_CMP_COLOR) { break; };
}
return cmpStatus;
}
int cost[] = {
1024,
1023,
1023,
1022,
1021,
1020,
1018,
1016,
1014,
1011,
1008,
1005,
1001,
997,
993,
989,
984,
979,
973,
968,
962,
955,
949,
942,
935,
928,
920,
912,
904,
895,
886,
877,
868,
858,
848,
838,
828,
817,
806,
795,
784,
772,
760,
748,
736,
724,
711,
698,
685,
671,
658,
644,
630,
616,
601,
587,
572,
557,
542,
527,
512,
496,
480,
464,
448,
432,
416,
400,
383,
366,
350,
333,
316,
299,
282,
265,
247,
230,
212,
195,
177,
160,
142,
124,
107,
89,
71,
53,
35,
17,
0,
-17,
-35,
-53,
-71,
-89,
-107,
-124,
-142,
-160,
-177,
-195,
-212,
-230,
-247,
-265,
-282,
-299,
-316,
-333,
-350,
-366,
-383,
-400,
-416,
-432,
-448,
-464,
-480,
-496,
-512,
-527,
-542,
-557,
-572,
-587,
-601,
-616,
-630,
-644,
-658,
-671,
-685,
-698,
-711,
-724,
-736,
-748,
-760,
-772,
-784,
-795,
-806,
-817,
-828,
-838,
-848,
-858,
-868,
-877,
-886,
-895,
-904,
-912,
-920,
-928,
-935,
-942,
-949,
-955,
-962,
-968,
-973,
-979,
-984,
-989,
-993,
-997,
-1001,
-1005,
-1008,
-1011,
-1014,
-1016,
-1018,
-1020,
-1021,
-1022,
-1023,
-1023,
-1024,
-1023,
-1023,
-1022,
-1021,
-1020,
-1018,
-1016,
-1014,
-1011,
-1008,
-1005,
-1001,
-997,
-993,
-989,
-984,
-979,
-973,
-968,
-962,
-955,
-949,
-942,
-935,
-928,
-920,
-912,
-904,
-895,
-886,
-877,
-868,
-858,
-848,
-838,
-828,
-817,
-806,
-795,
-784,
-772,
-760,
-748,
-736,
-724,
-711,
-698,
-685,
-671,
-658,
-644,
-630,
-616,
-601,
-587,
-572,
-557,
-542,
-527,
-512,
-496,
-480,
-464,
-448,
-432,
-416,
-400,
-383,
-366,
-350,
-333,
-316,
-299,
-282,
-265,
-247,
-230,
-212,
-195,
-177,
-160,
-142,
-124,
-107,
-89,
-71,
-53,
-35,
-17,
0,
17,
35,
53,
71,
89,
107,
124,
142,
160,
177,
195,
212,
230,
247,
265,
282,
299,
316,
333,
350,
366,
383,
400,
416,
432,
448,
464,
480,
496,
512,
527,
542,
557,
572,
587,
601,
616,
630,
644,
658,
671,
685,
698,
711,
724,
736,
748,
760,
772,
784,
795,
806,
817,
828,
838,
848,
858,
868,
877,
886,
895,
904,
912,
920,
928,
935,
942,
949,
955,
962,
968,
973,
979,
984,
989,
993,
997,
1001,
1005,
1008,
1011,
1014,
1016,
1018,
1020,
1021,
1022,
1023,
1023
};
int sint[] = {
0,
17,
35,
53,
71,
89,
107,
124,
142,
160,
177,
195,
212,
230,
247,
265,
282,
299,
316,
333,
350,
366,
383,
400,
416,
432,
448,
464,
480,
496,
512,
527,
542,
557,
572,
587,
601,
616,
630,
644,
658,
671,
685,
698,
711,
724,
736,
748,
760,
772,
784,
795,
806,
817,
828,
838,
848,
858,
868,
877,
886,
895,
904,
912,
920,
928,
935,
942,
949,
955,
962,
968,
973,
979,
984,
989,
993,
997,
1001,
1005,
1008,
1011,
1014,
1016,
1018,
1020,
1021,
1022,
1023,
1023,
1024,
1023,
1023,
1022,
1021,
1020,
1018,
1016,
1014,
1011,
1008,
1005,
1001,
997,
993,
989,
984,
979,
973,
968,
962,
955,
949,
942,
935,
928,
920,
912,
904,
895,
886,
877,
868,
858,
848,
838,
828,
817,
806,
795,
784,
772,
760,
748,
736,
724,
711,
698,
685,
671,
658,
644,
630,
616,
601,
587,
572,
557,
542,
527,
512,
496,
480,
464,
448,
432,
416,
400,
383,
366,
350,
333,
316,
299,
282,
265,
247,
230,
212,
195,
177,
160,
142,
124,
107,
89,
71,
53,
35,
17,
0,
-17,
-35,
-53,
-71,
-89,
-107,
-124,
-142,
-160,
-177,
-195,
-212,
-230,
-247,
-265,
-282,
-299,
-316,
-333,
-350,
-366,
-383,
-400,
-416,
-432,
-448,
-464,
-480,
-496,
-512,
-527,
-542,
-557,
-572,
-587,
-601,
-616,
-630,
-644,
-658,
-671,
-685,
-698,
-711,
-724,
-736,
-748,
-760,
-772,
-784,
-795,
-806,
-817,
-828,
-838,
-848,
-858,
-868,
-877,
-886,
-895,
-904,
-912,
-920,
-928,
-935,
-942,
-949,
-955,
-962,
-968,
-973,
-979,
-984,
-989,
-993,
-997,
-1001,
-1005,
-1008,
-1011,
-1014,
-1016,
-1018,
-1020,
-1021,
-1022,
-1023,
-1023,
-1024,
-1023,
-1023,
-1022,
-1021,
-1020,
-1018,
-1016,
-1014,
-1011,
-1008,
-1005,
-1001,
-997,
-993,
-989,
-984,
-979,
-973,
-968,
-962,
-955,
-949,
-942,
-935,
-928,
-920,
-912,
-904,
-895,
-886,
-877,
-868,
-858,
-848,
-838,
-828,
-817,
-806,
-795,
-784,
-772,
-760,
-748,
-736,
-724,
-711,
-698,
-685,
-671,
-658,
-644,
-630,
-616,
-601,
-587,
-572,
-557,
-542,
-527,
-512,
-496,
-480,
-464,
-448,
-432,
-416,
-400,
-383,
-366,
-350,
-333,
-316,
-299,
-282,
-265,
-247,
-230,
-212,
-195,
-177,
-160,
-142,
-124,
-107,
-89,
-71,
-53,
-35,
-17
};

View File

@ -131,6 +131,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);
char *gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontname,
double ptsize, double angle, int x, int y, char *string);
/* Point type for use in polygon drawing. */
typedef struct {
@ -143,6 +146,7 @@ void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c);
int gdImageColorAllocate(gdImagePtr im, int r, int g, int b);
int gdImageColorClosest(gdImagePtr im, int r, int g, int b);
int gdImageColorExact(gdImagePtr im, int r, int g, int b);
int gdImageColorResolve(gdImagePtr im, int r, int g, int b);
void gdImageColorDeallocate(gdImagePtr im, int color);
void gdImageColorTransparent(gdImagePtr im, int color);
void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src);
@ -210,4 +214,15 @@ void* gdDPExtractData(struct gdIOCtx* ctx, int *size);
#define GD2_FMT_RAW 1
#define GD2_FMT_COMPRESSED 2
/* Image comparison definitions */
int gdImageCompare(gdImagePtr im1, gdImagePtr im2);
#define GD_CMP_IMAGE 1 /* Actual image IS different */
#define GD_CMP_NUM_COLORS 2 /* Number of Colours in pallette differ */
#define GD_CMP_COLOR 4 /* Image colours differ */
#define GD_CMP_SIZE_X 8 /* Image width differs */
#define GD_CMP_SIZE_Y 16 /* Image heights differ */
#define GD_CMP_TRANSPARENT 32 /* Transparent colour */
#define GD_CMP_BACKGROUND 64 /* Background colour */
#define GD_CMP_INTERLACE 128 /* Interlaced setting */
#endif

View File

@ -51,5 +51,7 @@ int main(int argc, char **argv)
fclose(out);
gdImageDestroy(pal);
gdImageDestroy(im);
return 0;
}

View File

@ -1,4 +1,6 @@
#include <stdio.h>
#include <stdlib.h> /* for atoi */
#include <time.h> /* For time */
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
@ -9,7 +11,7 @@
int main(int argc, char **argv)
{
gdImagePtr im;
FILE *in, *out;
FILE *in;
int x, y, w, h;
int c;
int i;
@ -47,5 +49,7 @@ int main(int argc, char **argv)
};
t0 = time(0) - t0;
printf("%d seconds to extract (& destroy) %d times\n",t0, c);
return 0;
}

View File

@ -34,5 +34,7 @@ int main(int argc, char **argv)
gdImagePng(im, out);
fclose(out);
gdImageDestroy(im);
return 0;
}

View File

@ -63,8 +63,6 @@ fail1:
static
gdImagePtr _gdCreateFromFile(gdIOCtx *in, int *sx, int *sy)
{
int x, y;
int i;
gdImagePtr im;
if (!gdGetWord(sx, in)) {
@ -106,7 +104,6 @@ gdImagePtr gdImageCreateFromGdCtx(gdIOCtxPtr in)
{
int sx, sy;
int x, y;
int i;
gdImagePtr im;
/* Read the header */
@ -139,7 +136,6 @@ fail1:
void _gdPutColors(gdImagePtr im, gdIOCtx *out)
{
int x, y;
int i;
int trans;

View File

@ -31,6 +31,9 @@ typedef struct {
int size;
} t_chunk_info;
extern int _gdGetColors(gdIOCtx *in, gdImagePtr im);
extern void _gdPutColors(gdImagePtr im, gdIOCtx *out);
/* */
/* Read the extra info in the gd2 header. */
/* */
@ -43,7 +46,7 @@ int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy,
char id[5];
t_chunk_info *cidx;
int sidx;
int nc, csz;
int nc;
GD2_DBG(printf("Reading gd2 header info\n"));
@ -167,7 +170,7 @@ gdImagePtr _gd2CreateFromFile(gdIOCtxPtr in, int *sx, int *sy,
GD2_DBG(printf("Could not read color palette\n"));
goto fail2;
}
GD2_DBG(printf("Image palette completed\n"));
GD2_DBG(printf("Image palette completed: %d colours\n", im->colorsTotal));
return im;
@ -339,7 +342,6 @@ gdImagePtr gdImageCreateFromGd2Ctx(gdIOCtxPtr in)
fail2:
gdImageDestroy(im);
fail1:
free(chunkBuf);
free(compBuf);
free(chunkIdx);
@ -361,7 +363,7 @@ gdImagePtr gdImageCreateFromGd2Part(FILE *inFile, int srcx, int srcy, int w, int
gdImagePtr gdImageCreateFromGd2PartCtx(gdIOCtx *in, int srcx, int srcy, int w, int h)
{
int sx, sy, scx, scy, ecx, ecy, fsx, fsy;
int scx, scy, ecx, ecy, fsx, fsy;
int nc, ncx, ncy, cs, cx, cy;
int x, y, ylo, yhi, xlo, xhi;
int dstart, dpos;
@ -398,6 +400,7 @@ gdImagePtr gdImageCreateFromGd2PartCtx(gdIOCtx *in, int srcx, int srcy, int w, i
if (!_gdGetColors(in, im)) {
goto fail2;
}
GD2_DBG(printf("Image palette completed: %d colours\n", im->colorsTotal));
/* Process the header info */
nc = ncx * ncy;
@ -555,7 +558,6 @@ static void _gdImageGd2(gdImagePtr im, gdIOCtx *out, int cs, int fmt)
{
int ncx, ncy, cx, cy;
int x, y, ylo, yhi, xlo, xhi;
int i;
int chunkLen;
int chunkNum = 0;
char *chunkData = NULL; /* So we can free it with impunity. */
@ -573,7 +575,7 @@ static void _gdImageGd2(gdImagePtr im, gdIOCtx *out, int cs, int fmt)
/* Force fmt to a valid value since we don't return anything. */
/* */
if ( (fmt == 0) || ( (fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED) ) ) {
fmt == GD2_FMT_COMPRESSED;
fmt = GD2_FMT_COMPRESSED;
};
/* */

View File

@ -46,7 +46,6 @@ static int allocDynamic (dynamicPtr* dp,int initialSize, void *data);
static int appendDynamic (dynamicPtr* dp, const void* src, int size);
static int reallocDynamic (dynamicPtr* dp, int required);
static int trimDynamic (dynamicPtr* dp);
static void freeDynamic (dynamicPtr* dp);
static void freeDynamicCtx(struct gdIOCtx* ctx);
static dynamicPtr* newDynamic(int initialSize, void *data);
@ -134,9 +133,14 @@ void freeDynamicCtx(struct gdIOCtx* ctx)
/* clean up the data block and return it */
if (dp->data != NULL) {
free(dp->data);
dp->data = NULL;
}
dp->realSize=0;
dp->logicalSize=0;
free(dp);
}
static long dynamicTell(struct gdIOCtx* ctx)
@ -150,7 +154,6 @@ static long dynamicTell(struct gdIOCtx* ctx)
static int dynamicSeek(struct gdIOCtx* ctx, const int pos)
{
int bytesNeeded;
char* tmp;
dynamicPtr *dp;
dpIOCtx *dctx;
@ -244,7 +247,7 @@ dynamicGetbuf( gdIOCtxPtr ctx, void *buf, int len)
rlen = remain;
}
memcpy(buf, (void*)((int)dp->data + dp->pos), rlen);
memcpy(buf, (void*)((char*)dp->data + dp->pos), rlen);
dp->pos += rlen;
return rlen;
@ -335,7 +338,7 @@ reallocDynamic (dynamicPtr* dp, int required) {
/* First try realloc(). If that doesn't work, make a new
memory block and copy. */
if (newPtr = realloc(dp->data,required)) {
if ( (newPtr = realloc(dp->data,required)) ) {
dp->realSize = required;
dp->data = newPtr;
return TRUE;
@ -363,13 +366,3 @@ trimDynamic (dynamicPtr* dp) {
return reallocDynamic(dp,dp->logicalSize);
}
/* dispose of the dynamic pointer */
static void
freeDynamic (dynamicPtr* dp) {
if (dp->data != NULL) {
free(dp->data);
dp->data = NULL;
}
dp->realSize=0;
dp->logicalSize=0;
}

View File

@ -3,29 +3,28 @@
#include <string.h>
#include <stdlib.h>
#include "gd.h"
#include "png.h"
#include "png.h" /* includes zlib.h and setjmp.h */
#define TRUE 1
#define FALSE 0
/*---------------------------------------------------------------------------
Routines taken from (and modified slightly from):
gdpng.c Copyright 1999 Greg Roelofs
gd_png.c Copyright 1999 Greg Roelofs and Thomas Boutell
The routines in this file, gdImagePng() and gdImageCreateFromPng(), are
drop-in replacements for gdImageGif() and gdImageCreateFromGif(), except
that these functions are noisier in the case of errors (comment out all
fprintf() statements to disable that).
The routines in this file, gdImagePng*() and gdImageCreateFromPng*(),
are drop-in replacements for gdImageGif*() and gdImageCreateFromGif*(),
except that these functions are noisier in the case of errors (comment
out all fprintf() statements to disable that).
Only GIF-like PNG features are currently supported; that is, images must
be indexed-color (or they will be dithered in a fairly unattractive
fashion), and they can have, at most, a single, fully transparent
palette entry. Since gd images are artificially generated, gamma is
ignored, and there is currently no support for embedded text annotations
(a la GIF comments).
either be indexed-color to begin with or they will be converted to it,
and they can have, at most, a single, fully transparent palette entry or
color. (Alpha channels are ignored.) Since gd images are artificially
generated, gamma is also ignored, and there is currently no support for
embedded text annotations (a la GIF comments) in gd.
Last updated: 15 July 1999
Last updated: 19 July 1999
---------------------------------------------------------------------------*/
@ -35,35 +34,62 @@ typedef struct _jmpbuf_wrapper {
static jmpbuf_wrapper gdPngJmpbufStruct;
static void gdPngErrorHandler(png_structp png_ptr, png_const_charp msg);
static void gdPngErrorHandler(png_structp png_ptr, png_const_charp msg)
{
jmpbuf_wrapper *jmpbuf_ptr;
static void png_read_data(png_structp png_ptr,
/* This function, aside from the extra step of retrieving the "error
* pointer" (below) and the fact that it exists within the application
* rather than within libpng, is essentially identical to libpng's
* default error handler. The second point is critical: since both
* setjmp() and longjmp() are called from the same code, they are
* guaranteed to have compatible notions of how big a jmp_buf is,
* regardless of whether _BSD_SOURCE or anything else has (or has not)
* been defined. */
fprintf(stderr, "gd-png: fatal libpng error: %s\n", msg);
fflush(stderr);
jmpbuf_ptr = png_get_error_ptr(png_ptr);
if (jmpbuf_ptr == NULL) { /* we are completely hosed now */
fprintf(stderr,
"gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n");
fflush(stderr);
exit(99);
}
longjmp(jmpbuf_ptr->jmpbuf, 1);
}
static void gdPngReadData(png_structp png_ptr,
png_bytep data, png_size_t length)
{
gdGetBuf(data, length, (gdIOCtx *)
png_get_io_ptr(png_ptr));
png_get_io_ptr(png_ptr));
}
static void png_write_data(png_structp png_ptr,
static void gdPngWriteData(png_structp png_ptr,
png_bytep data, png_size_t length)
{
gdPutBuf(data, length, (gdIOCtx *)
png_get_io_ptr(png_ptr));
png_get_io_ptr(png_ptr));
}
static void png_flush_data(png_structp png_ptr)
static void gdPngFlushData(png_structp png_ptr)
{
}
gdImagePtr gdImageCreateFromPng(FILE *inFile)
{
gdImagePtr im;
gdIOCtx *in = gdNewFileCtx(inFile);
im = gdImageCreateFromPngCtx(in);
gdIOCtx *in = gdNewFileCtx(inFile);
im = gdImageCreateFromPngCtx(in);
in->free(in);
return im;
}
/* This routine is based in part on the Chapter 13 demo code in "PNG: The
* Definitive Guide" (http://www.cdrom.com/pub/png/pngbook.html).
*/
@ -76,15 +102,19 @@ gdImagePtr gdImageCreateFromPngCtx(gdIOCtx *infile)
int bit_depth, color_type, interlace_type;
int num_palette, num_trans;
png_colorp palette;
png_color_16p trans_gray_rgb;
png_bytep trans;
png_bytep image_data = NULL;
png_bytepp row_pointers = NULL;
gdImagePtr im = NULL;
int i, j, *open;
volatile int transparent = -1;
volatile int palette_allocated = FALSE;
/* Make sure the signature can't match by dumb luck -- TBB */
/* GRR: isn't sizeof(infile) equal to the size of the pointer? */
memset(infile, 0, sizeof(infile));
/* first do a quick check that the file really is a PNG image; could
* have used slightly more general png_sig_cmp() function instead */
gdGetBuf(sig, 8, infile);
@ -116,65 +146,171 @@ gdImagePtr gdImageCreateFromPngCtx(gdIOCtx *infile)
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;
}
png_set_read_fn(png_ptr, (void *) infile, png_read_data);
png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */
png_set_read_fn(png_ptr, (void *)infile, gdPngReadData);
png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, NULL, NULL);
png_set_strip_16(png_ptr);
if (color_type != PNG_COLOR_TYPE_PALETTE) {
/* Turn non-palette PNGs into palette PNGs. This will
go away in a future 24-bit GD. It's not a very
good way of doing things. */
png_colorp std_color_cube;
int r, g, b;
int i = 0;
std_color_cube = malloc(sizeof(png_color) * 216);
for (r = 0; (r < 6); r++) {
for (g = 0; (g < 6); g++) {
for (b = 0; (b < 6); b++) {
std_color_cube[i].red =
r * 51;
std_color_cube[i].green =
g * 51;
std_color_cube[i].blue =
b * 51;
i++;
}
}
}
png_set_dither(png_ptr, std_color_cube,
216, 216,
NULL, 0);
}
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
int real_num_trans = 0, idx_first_trans = -1;
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
for (i = 0; i < num_trans; ++i) {
if (trans[i] < 255) {
++real_num_trans;
if (idx_first_trans < 0)
idx_first_trans = i;
}
}
if (real_num_trans > 0) {
if (real_num_trans > 1 || trans[idx_first_trans] != 0) {
fprintf(stderr, "gd-png warning: only single-color, 100%%"
" transparency supported\n");
} else {
transparent = idx_first_trans;
}
}
}
if (bit_depth < 8)
if (bit_depth == 16)
png_set_strip_16(png_ptr);
else if (bit_depth < 8)
png_set_packing(png_ptr); /* expand to 1 byte per pixel */
if (color_type & PNG_COLOR_MASK_ALPHA) {
fprintf(stderr, "gd-png warning: alpha channel not supported\n");
png_set_strip_alpha(png_ptr);
}
switch (color_type) {
case PNG_COLOR_TYPE_PALETTE:
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
int real_num_trans = 0, idx_first_trans = -1;
int min_trans = 256, idx_min_trans = -1;
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
for (i = 0; i < num_trans; ++i) {
if (trans[i] < 255) {
++real_num_trans;
if (idx_first_trans < 0)
idx_first_trans = i;
if (trans[i] < min_trans) {
min_trans = trans[i];
idx_min_trans = i;
}
}
}
if (real_num_trans > 0) {
if (real_num_trans > 1 || trans[idx_first_trans] != 0) {
fprintf(stderr, "gd-png warning: only single-color, "
"100%% transparency supported\n");
transparent = idx_min_trans;
} else {
transparent = idx_first_trans;
}
}
}
break;
case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_GRAY_ALPHA:
/* create a fake palette and check for single-shade transparency */
if ((palette = (png_colorp)malloc(256*sizeof(png_color))) == NULL) {
fprintf(stderr, "gd-png error: cannot allocate gray palette\n");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;
}
palette_allocated = TRUE;
num_palette = 256;
for (i = 0; i < 256; ++i) {
palette[i].red = palette[i].green = palette[i].blue = i;
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb);
if (bit_depth == 16) /* png_set_strip_16() not yet in effect */
transparent = trans_gray_rgb->gray >> 8;
else
transparent = trans_gray_rgb->gray;
/* Note slight error in 16-bit case: up to 256 16-bit shades
* may get mapped to a single 8-bit shade, and only one of them
* is supposed to be transparent. IOW, both opaque pixels and
* transparent pixels will be mapped into the transparent entry.
* There is no particularly good way around this in the case
* that all 256 8-bit shades are used, but one could write some
* custom 16-bit code to handle the case where there are free
* palette entries. This error will be extremely rare in
* general, though. (Quite possibly there is only one such
* image in existence.) */
}
break;
case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_RGB_ALPHA:
/* allocate a palette and check for single-shade transparency */
if ((palette = (png_colorp)malloc(256*sizeof(png_color))) == NULL) {
fprintf(stderr, "gd-png error: cannot allocate RGB palette\n");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;
}
palette_allocated = TRUE;
num_palette = 256;
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb);
if (bit_depth == 16) { /* png_set_strip_16() not yet active */
palette[0].red = trans_gray_rgb->red >> 8;
palette[0].green = trans_gray_rgb->green >> 8;
palette[0].blue = trans_gray_rgb->blue >> 8;
} else {
palette[0].red = trans_gray_rgb->red;
palette[0].green = trans_gray_rgb->green;
palette[0].blue = trans_gray_rgb->blue;
}
transparent = 0;
/* Note that the same error exists in the 16-bit RGB case as in
* the grayscale case, except that the degeneracy is now 16.8
* million to 1 (at a minimum--actually more than that due to
* quantization). Again, this is an extremely rare problem.
* Unfortunately, it also affects 8-bit-per-sample RGB images
* (quantization), unless libpng is doing something sneaky... */
} else {
palette[0].red = palette[0].green = palette[0].blue = 224;
}
#if 0 /* libpng.txt demo code looks broken--need to check both PLTE and hIST */
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) {
png_color_16p histogram;
png_get_hIST(png_ptr, info_ptr, &histogram);
png_set_dither(png_ptr, palette, num_palette,
max_screen_colors, histogram, 1);
} else
#endif
{
int idx, red, green, blue;
#ifdef PALETTE_6x7x6
/* allocate a 6x7x6 color cube, starting at index 4 */
idx = 4;
for (red = 0; red < 256; red += 51) {
for (i = 0; i < 7; ++i) {
green = (i * 425) / 10; /* i.e., 42.5 */
for (blue = 0; blue < 256; blue += 51) {
palette[idx].red = red;
palette[idx].green = green;
palette[idx].blue = blue;
++idx;
}
}
}
/* fill in remaining entries (1-3) with common gray values */
palette[1].red = palette[1].green = palette[1].blue = 192;
palette[2].red = palette[2].green = palette[2].blue = 128;
palette[3].red = palette[3].green = palette[3].blue = 64;
/* final argument (full_dither) *must* be 1: */
png_set_dither(png_ptr, palette, 256, 256, NULL, 1);
#else
/* allocate a 6x6x6 color cube, starting at index 0 or 1 */
idx = (transparent < 0)? 0 : 1;
for (red = 0; red < 256; red += 51) {
for (green = 0; green < 256; green += 51) {
for (blue = 0; blue < 256; blue += 51) {
palette[idx].red = red;
palette[idx].green = green;
palette[idx].blue = blue;
++idx;
}
}
}
png_set_dither(png_ptr, palette, idx, idx, NULL, 1);
#endif
}
break;
}
png_read_update_info(png_ptr, info_ptr);
/* allocate space for the PNG image data */
@ -192,8 +328,9 @@ gdImagePtr gdImageCreateFromPngCtx(gdIOCtx *infile)
}
/* set the individual row_pointers to point at the correct offsets */
for (j = 0; j < height; ++j)
for (j = 0; j < height; ++j) {
row_pointers[j] = image_data + j*rowbytes;
}
png_read_image(png_ptr, row_pointers); /* read whole image... */
png_read_end(png_ptr, NULL); /* ...done! */
@ -218,8 +355,9 @@ gdImagePtr gdImageCreateFromPngCtx(gdIOCtx *infile)
im->blue[i] = palette[i].blue;
open[i] = 1;
}
for (i = num_palette; i < gdMaxColors; ++i)
for (i = num_palette; i < gdMaxColors; ++i) {
open[i] = 1;
}
/* can't nuke structs until done with palette */
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
@ -228,16 +366,12 @@ gdImagePtr gdImageCreateFromPngCtx(gdIOCtx *infile)
for (j = 0; j < height; ++j) {
for (i = 0; i < width; ++i) {
register png_byte idx = row_pointers[j][i];
im->pixels[j][i] = idx;
open[idx] = 0;
}
}
/* decrement the total (used) colors if any palette entries are not used */
for (i = 0; i < num_palette; ++i) {
if (open[i]) {
--im->colorsTotal;
}
}
#ifdef DEBUG
for (i = num_palette; i < gdMaxColors; ++i) {
if (!open[i]) {
@ -247,25 +381,28 @@ gdImagePtr gdImageCreateFromPngCtx(gdIOCtx *infile)
}
#endif
if (palette_allocated)
free(palette);
free(image_data);
free(row_pointers);
return im;
}
void gdImagePng(gdImagePtr im, FILE *outFile)
{
gdIOCtx *out = gdNewFileCtx(outFile);
gdImagePngCtx(im, out);
gdIOCtx *out = gdNewFileCtx(outFile);
gdImagePngCtx(im, out);
out->free(out);
}
void* gdImagePngPtr(gdImagePtr im, int *size)
{
void *rv;
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
gdImagePngCtx(im, out);
rv = gdDPExtractData(out, size);
void *rv;
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
gdImagePngCtx(im, out);
rv = gdDPExtractData(out, size);
out->free(out);
return rv;
}
@ -274,19 +411,19 @@ void* gdImagePngPtr(gdImagePtr im, int *size)
* and in part on demo code from Chapter 15 of "PNG: The Definitive Guide"
* (http://www.cdrom.com/pub/png/pngbook.html).
*/
void gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile)
{
int i, j, bit_depth, interlace_type;
int width = im->sx;
int height = im->sy;
int colors = im->colorsTotal;
int transparent = im->transparent;
int mapping[gdMaxColors];
int *open = im->open;
int mapping[gdMaxColors]; /* mapping[gif_index] == png_index */
png_byte trans_value = 0;
png_color palette[gdMaxColors];
png_structp png_ptr;
png_infop info_ptr;
volatile int transparent = im->transparent;
volatile int remap = FALSE;
@ -310,10 +447,7 @@ void gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile)
return;
}
png_set_write_fn(png_ptr,
(void *) outfile,
png_write_data,
png_flush_data);
png_set_write_fn(png_ptr, (void *)outfile, gdPngWriteData, gdPngFlushData);
/* For now gd only supports palette images, for which filter type NONE is
* almost guaranteed to be the best. But that's what libpng defaults to
@ -327,6 +461,27 @@ void gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile)
* image data is 16K or less; will save some decoder memory [min == 8] */
/* png_set_compression_window_bits(png_ptr, 15); */
if (transparent >= im->colorsTotal ||
(transparent >= 0 && open[transparent]))
transparent = -1;
for (i = 0; i < gdMaxColors; ++i)
mapping[i] = -1;
/* count actual number of colors used (colorsTotal == high-water mark) */
colors = 0;
for (i = 0; i < im->colorsTotal; ++i) {
if (!open[i]) {
mapping[i] = colors;
++colors;
}
}
if (colors < im->colorsTotal) {
remap = TRUE;
if (transparent >= 0)
transparent = mapping[transparent];
}
if (colors <= 2)
bit_depth = 1;
else if (colors <= 4)
@ -342,13 +497,15 @@ void gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile)
PNG_COLOR_TYPE_PALETTE, interlace_type,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
if (transparent >= 0 && transparent < colors) {
if (transparent >= 0) {
/* always write PNG files with the transparent palette entry first to
* minimize size of the tRNS chunk; swap if necessary */
if (transparent != 0) {
remap = TRUE;
for (i = 0; i < colors; ++i)
mapping[i] = i;
if (!remap) { /* so colors == im->colorsTotal */
remap = TRUE;
for (i = 0; i < colors; ++i)
mapping[i] = i;
}
mapping[transparent] = 0;
mapping[0] = transparent;
}
@ -356,19 +513,20 @@ void gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile)
}
/* convert GIF palette to libpng layout */
if (remap) {
for (i = 0; i < colors; ++i) {
palette[i].red = im->red[mapping[i]];
palette[i].green = im->green[mapping[i]];
palette[i].blue = im->blue[mapping[i]];
if (remap)
for (i = 0; i < im->colorsTotal; ++i) {
if (mapping[i] < 0)
continue;
palette[mapping[i]].red = im->red[i];
palette[mapping[i]].green = im->green[i];
palette[mapping[i]].blue = im->blue[i];
}
} else {
else
for (i = 0; i < colors; ++i) {
palette[i].red = im->red[i];
palette[i].green = im->green[i];
palette[i].blue = im->blue[i];
}
}
png_set_PLTE(png_ptr, info_ptr, palette, colors);
@ -385,8 +543,11 @@ void gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile)
* The remapping case could be accomplished with less memory for non-
* interlaced images, but interlacing causes some serious complications. */
if (remap) {
png_bytep row_pointers[height];
png_bytep *row_pointers;
row_pointers = malloc(sizeof(png_bytep) * height);
if (row_pointers == NULL) {
fprintf(stderr, "gd-png error: unable to allocate row_pointers\n");
}
for (j = 0; j < height; ++j) {
if ((row_pointers[j] = (png_bytep)malloc(width)) == NULL) {
fprintf(stderr, "gd-png error: unable to allocate rows\n");
@ -403,36 +564,9 @@ void gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile)
for (j = 0; j < height; ++j)
free(row_pointers[j]);
free(row_pointers);
} else {
png_write_image(png_ptr, im->pixels);
png_write_end(png_ptr, info_ptr);
}
}
static void gdPngErrorHandler (png_structp png_ptr, png_const_charp msg)
{
jmpbuf_wrapper *jmpbuf_ptr;
/* This function, aside from the extra step of retrieving the "error
* pointer" (below) and the fact that it exists within the application
* rather than within libpng, is essentially identical to libpng's
* default error handler. The second point is critical: since both
* setjmp() and longjmp() are called from the same code, they are
* guaranteed to have compatible notions of how big a jmp_buf is,
* regardless of whether _BSD_SOURCE or anything else has (or has not)
* been defined. */
fprintf(stderr, "gd-png: fatal libpng error: %s\n", msg);
fflush(stderr);
jmpbuf_ptr = png_get_error_ptr(png_ptr);
if (jmpbuf_ptr == NULL) { /* we are completely hosed now */
fprintf(stderr,
"gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n");
fflush(stderr);
exit(99);
}
longjmp(jmpbuf_ptr->jmpbuf, 1);
}

194
src/gdcache.c Normal file
View File

@ -0,0 +1,194 @@
#ifdef HAVE_LIBTTF
/*
* gdcache.c
*
* Caches of pointers to user structs in which the least-recently-used
* element is replaced in the event of a cache miss after the cache has
* reached a given size.
*
* John Ellson (ellson@lucent.com) Oct 31, 1997
*
* Test this with:
* gcc -o gdcache -g -Wall -DTEST gdcache.c
*
* The cache is implemented by a singly-linked list of elements
* each containing a pointer to a user struct that is being managed by
* the cache.
*
* The head structure has a pointer to the most-recently-used
* element, and elements are moved to this position in the list each
* time they are used. The head also contains pointers to three
* user defined functions:
* - a function to test if a cached userdata matches some keydata
* - a function to provide a new userdata struct to the cache
* if there has been a cache miss.
* - a function to release a userdata struct when it is
* no longer being managed by the cache
*
* In the event of a cache miss the cache is allowed to grow up to
* a specified maximum size. After the maximum size is reached then
* the least-recently-used element is discarded to make room for the
* new. The most-recently-returned value is always left at the
* beginning of the list after retrieval.
*
* In the current implementation the cache is traversed by a linear
* search from most-recent to least-recent. This linear search
* probably limits the usefulness of this implementation to cache
* sizes of a few tens of elements.
*/
#include "gdcache.h"
/*********************************************************/
/* implementation */
/*********************************************************/
/* create a new cache */
gdCache_head_t *
gdCacheCreate(
int size,
gdCacheTestFn_t gdCacheTest,
gdCacheFetchFn_t gdCacheFetch,
gdCacheReleaseFn_t gdCacheRelease )
{
gdCache_head_t *head;
head = (gdCache_head_t *)malloc(sizeof(gdCache_head_t));
head->mru = NULL;
head->size = size;
head->gdCacheTest = gdCacheTest;
head->gdCacheFetch = gdCacheFetch;
head->gdCacheRelease = gdCacheRelease;
return head;
}
void
gdCacheDelete( gdCache_head_t *head )
{
gdCache_element_t *elem, *prev;
elem = head->mru;
while(elem) {
(*(head->gdCacheRelease))(elem->userdata);
prev = elem;
elem = elem->next;
free((char *)prev);
}
free((char *)head);
}
void *
gdCacheGet( gdCache_head_t *head, void *keydata )
{
int i=0;
gdCache_element_t *elem, *prev = NULL, *prevprev = NULL;
void *userdata;
elem = head->mru;
while(elem) {
if ((*(head->gdCacheTest))(elem->userdata, keydata)) {
if (i) { /* if not already most-recently-used */
/* relink to top of list */
prev->next = elem->next;
elem->next = head->mru;
head->mru = elem;
}
return elem->userdata;
}
prevprev = prev;
prev = elem;
elem = elem->next;
i++;
}
userdata = (*(head->gdCacheFetch))(&(head->error), keydata);
if (! userdata) {
/* if there was an error in the fetch then don't cache */
return NULL;
}
if (i < head->size) { /* cache still growing - add new elem */
elem = (gdCache_element_t *)malloc(sizeof(gdCache_element_t));
}
else { /* cache full - replace least-recently-used */
/* preveprev becomes new end of list */
prevprev->next = NULL;
elem = prev;
(*(head->gdCacheRelease))(elem->userdata);
}
/* relink to top of list */
elem->next = head->mru;
head->mru = elem;
elem->userdata = userdata;
return userdata;
}
/*********************************************************/
/* test stub */
/*********************************************************/
#ifdef TEST
#include <stdio.h>
typedef struct {
int key;
int value;
} key_value_t;
static int
cacheTest( void *map, void *key )
{
return (((key_value_t *)map)->key == *(int *)key);
}
static void *
cacheFetch( char **error, void *key )
{
key_value_t *map;
map = (key_value_t *)malloc(sizeof(key_value_t));
map->key = *(int *)key;
map->value = 3;
*error = NULL;
return (void *)map;
}
static void
cacheRelease( void *map)
{
free( (char *)map );
}
int
main(char *argv[], int argc)
{
gdCache_head_t *cacheTable;
int elem, key;
cacheTable = gdCacheCreate(3, cacheTest, cacheFetch, cacheRelease);
key = 20;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 30;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 40;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 50;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 30;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 30;
elem = *(int *)gdCacheGet(cacheTable, &key);
gdCacheDelete(cacheTable);
return 0;
}
#endif /* TEST */
#endif /* HAVE_LIBTTF */

83
src/gdcache.h Normal file
View File

@ -0,0 +1,83 @@
/*
* gdcache.h
*
* Caches of pointers to user structs in which the least-recently-used
* element is replaced in the event of a cache miss after the cache has
* reached a given size.
*
* John Ellson (ellson@lucent.com) Oct 31, 1997
*
* Test this with:
* gcc -o gdcache -g -Wall -DTEST gdcache.c
*
* The cache is implemented by a singly-linked list of elements
* each containing a pointer to a user struct that is being managed by
* the cache.
*
* The head structure has a pointer to the most-recently-used
* element, and elements are moved to this position in the list each
* time they are used. The head also contains pointers to three
* user defined functions:
* - a function to test if a cached userdata matches some keydata
* - a function to provide a new userdata struct to the cache
* if there has been a cache miss.
* - a function to release a userdata struct when it is
* no longer being managed by the cache
*
* In the event of a cache miss the cache is allowed to grow up to
* a specified maximum size. After the maximum size is reached then
* the least-recently-used element is discarded to make room for the
* new. The most-recently-returned value is always left at the
* beginning of the list after retrieval.
*
* In the current implementation the cache is traversed by a linear
* search from most-recent to least-recent. This linear search
* probably limits the usefulness of this implementation to cache
* sizes of a few tens of elements.
*/
/*********************************************************/
/* header */
/*********************************************************/
#include <malloc.h>
#ifndef NULL
#define NULL (void *)0
#endif
/* user defined function templates */
typedef int (*gdCacheTestFn_t)(void *userdata, void *keydata);
typedef void *(*gdCacheFetchFn_t)(char **error, void *keydata);
typedef void (*gdCacheReleaseFn_t)(void *userdata);
/* element structure */
typedef struct gdCache_element_s gdCache_element_t;
struct gdCache_element_s {
gdCache_element_t *next;
void *userdata;
};
/* head structure */
typedef struct gdCache_head_s gdCache_head_t;
struct gdCache_head_s {
gdCache_element_t *mru;
int size;
char *error;
gdCacheTestFn_t gdCacheTest;
gdCacheFetchFn_t gdCacheFetch;
gdCacheReleaseFn_t gdCacheRelease;
};
/* function templates */
gdCache_head_t *
gdCacheCreate(
int size,
gdCacheTestFn_t gdCacheTest,
gdCacheFetchFn_t gdCacheFetch,
gdCacheReleaseFn_t gdCacheRelease );
void
gdCacheDelete( gdCache_head_t *head );
void *
gdCacheGet( gdCache_head_t *head, void *keydata );

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h> /* For atoi */
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
@ -44,5 +45,7 @@ int main(int argc, char **argv)
gdImagePng(im, out);
fclose(out);
gdImageDestroy(im);
return 0;
}

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <unistd.h> /* For unlink function */
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
@ -15,13 +16,11 @@ int main(int argc, char **argv)
{
gdImagePtr im, ref, im2, im3;
FILE *in, *out;
int cs, fmt;
void *iptr;
int sz;
gdIOCtxPtr ctx;
char of[256];
int colRed, colBlu;
int idx;
gdSource imgsrc;
gdSink imgsnk;
@ -206,7 +205,7 @@ int main(int argc, char **argv)
im3 = gdImageCreateFromGd2Part(in, 200, 300, 150, 100);
fclose(in);
CompareImages("GD2Part (gdtest.gd2, gdtest_200_300_150_100.png)", im2, im3);
CompareImages("GD2Part (gdtest_200_300_150_100.png, gdtest.gd2(part))", im2, im3);
gdImageDestroy(im2);
gdImageDestroy(im3);
@ -257,60 +256,35 @@ int main(int argc, char **argv)
gdImageDestroy(im);
gdImageDestroy(ref);
return 0;
}
void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2)
{
int x, y;
int bad;
int p1, p2;
int cmpRes;
bad = (1==0);
if (im1->sx != im2->sx) {
printf("%s: ERROR image x-size differs\n",msg);
bad = (1==1);
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 (im1->sy != im2->sy) {
printf("%s: image y-size differs\n",msg);
bad = (1==1);
if (cmpRes & (GD_CMP_SIZE_X + GD_CMP_SIZE_Y)) {
printf("-%s: INFO image sizes differ\n",msg);
}
if (!bad) {
if (im1->colorsTotal != im2->colorsTotal) {
printf("Mismatch in number of colours: %d Vs. %d\n",im1->colorsTotal, im2->colorsTotal);
}
for ( y = 0 ; (y<im1->sy) ; y++ ) {
for ( x = 0 ; (x < im1->sx) ; x++ ) {
p1 = im1->pixels[y][x];
p2 = im2->pixels[y][x];
if (im1->red[p1] != im2->red[p2]) {
printf("%s: ERROR image colours differ\n",msg);
bad = (1==1);
break;
}
if (im1->green[p1] != im2->green[p2]) {
printf("%s: ERROR image colours differ\n",msg);
bad = (1==1);
break;
}
if (im1->blue[p1] != im2->blue[p2]) {
printf("%s: ERROR image colours differ\n",msg);
bad = (1==1);
break;
}
}
if (bad) { break; };
}
if (cmpRes & GD_CMP_NUM_COLORS) {
printf("-%s: INFO number of pallette entries differ %d Vs. %d\n",msg,
im1->colorsTotal, im2->colorsTotal);
}
if (!bad) {
printf("%s: OK\n",msg);
if (cmpRes & GD_CMP_COLOR) {
printf("-%s: INFO actual colours of pixels differ\n",msg);
}
}

43
src/gdtestttf.c Normal file
View File

@ -0,0 +1,43 @@
#include "gd.h"
#include <string.h>
int main(int argc, char *argv[])
{
gdImagePtr im;
int black;
int white;
int brect[8];
int x, y;
char *err;
char *s = "Hello. Qyjpqg,"; /* String to draw. */
double sz = 40.;
char *f = "/usr/local/share/ttf/times.ttf"; /* TrueType font */
/* obtain brect so that we can size the image */
err = gdImageStringTTF((gdImagePtr)NULL,&brect[0],0,f,sz,0.,0,0,s);
if (err) {fprintf(stderr,err); return 1;}
/* create an image just big enough for the string */
x = brect[2]-brect[6] + 6;
y = brect[3]-brect[7] + 6;
im = gdImageCreate(x,y);
/* Background color (first allocated) */
white = gdImageColorResolve(im, 255, 255, 255);
black = gdImageColorResolve(im, 0, 0, 0);
/* render the string, offset origin to center string*/
x = 0-brect[6] + 3;
y = 0-brect[7] + 3;
err = gdImageStringTTF(im,&brect[0],black,f,sz,0.0,x,y,s);
if (err) {fprintf(stderr,err); return 1;}
/* Write img to stdout */
gdImagePng(im, stdout);
/* Destroy it */
gdImageDestroy(im);
return 0;
}

View File

@ -34,5 +34,7 @@ int main(int argc, char **argv)
gdImagePng(im, out);
fclose(out);
gdImageDestroy(im);
return 0;
}

819
src/gdttf.c Normal file
View File

@ -0,0 +1,819 @@
/********************************************/
/* gd interface to freetype library */
/* */
/* John Ellson ellson@lucent.com */
/********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "gd.h"
#ifndef HAVE_LIBTTF
char * gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontname,
double ptsize, double angle, int x, int y, char *string)
{
return "libgd was not built with TrueType font support\n";
}
#else
#include "gdcache.h"
#include "freetype.h"
/* number of fonts cached before least recently used is replaced */
#define FONTCACHESIZE 6
/* number of character glyphs cached per font before
least-recently-used is replaced */
#define GLYPHCACHESIZE 120
/* number of bitmaps cached per glyph before
least-recently-used is replaced */
#define BITMAPCACHESIZE 8
/* number of antialias color lookups cached */
#define TWEENCOLORCACHESIZE 32
/* ptsize below which anti-aliasing is ineffective */
#define MINANTIALIASPTSIZE 0
/* display resolution - (Not really. This has to be 96 or hinting is wrong) */
#define RESOLUTION 96
/* Number of colors used for anti-aliasing */
#define NUMCOLORS 4
/* Line separation as a factor of font height.
No space between if LINESPACE = 1.00
Line separation will be rounded up to next pixel row*/
#define LINESPACE 1.05
#ifndef TRUE
#define FALSE 0
#define TRUE !FALSE
#endif
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
typedef struct {
char *fontname; /* key */
double ptsize; /* key */
double angle; /* key */
double sin_a, cos_a;
TT_Engine *engine;
TT_Face face;
TT_Face_Properties properties;
TT_Instance instance;
TT_CharMap char_map_Unicode, char_map_Big5, char_map_Roman;
int have_char_map_Unicode, have_char_map_Big5, have_char_map_Roman;
TT_Matrix matrix;
TT_Instance_Metrics imetrics;
gdCache_head_t *glyphCache;
} font_t;
typedef struct {
char *fontname; /* key */
double ptsize; /* key */
double angle; /* key */
TT_Engine *engine;
} fontkey_t;
typedef struct {
int character; /* key */
int hinting; /* key */
TT_Glyph glyph;
TT_Glyph_Metrics metrics;
TT_Outline outline;
TT_Pos oldx, oldy;
TT_Raster_Map Bit;
int gray_render;
int xmin, xmax, ymin, ymax;
gdCache_head_t *bitmapCache;
} glyph_t;
typedef struct {
int character; /* key */
int hinting; /* key */
font_t *font;
} glyphkey_t;
typedef struct {
int xoffset; /* key */
int yoffset; /* key */
char *bitmap;
} bitmap_t;
typedef struct {
int xoffset; /* key */
int yoffset; /* key */
glyph_t *glyph;
} bitmapkey_t;
typedef struct {
unsigned char pixel; /* key */
unsigned char bgcolor; /* key */
int fgcolor; /* key */ /* -ve means no antialias */
gdImagePtr im; /* key */
unsigned char tweencolor;
} tweencolor_t;
typedef struct {
unsigned char pixel; /* key */
unsigned char bgcolor; /* key */
int fgcolor; /* key */ /* -ve means no antialias */
gdImagePtr im; /* key */
} tweencolorkey_t;
/* forward declarations so that glyphCache can be initialized by font code */
static int glyphTest ( void *element, void *key );
static void *glyphFetch ( char **error, void *key );
static void glyphRelease( void *element );
/* forward declarations so that bitmapCache can be initialized by glyph code */
static int bitmapTest ( void *element, void *key );
static void *bitmapFetch ( char **error, void *key );
static void bitmapRelease( void *element );
/********************************************************************
* gdTcl_UtfToUniChar is borrowed from ...
*/
/*
* tclUtf.c --
*
* Routines for manipulating UTF-8 strings.
*
* Copyright (c) 1997-1998 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* SCCS: @(#) tclUtf.c 1.25 98/01/28 18:02:43
*/
/*
*---------------------------------------------------------------------------
*
* gdTcl_UtfToUniChar --
*
* Extract the Tcl_UniChar represented by the UTF-8 string. Bad
* UTF-8 sequences are converted to valid Tcl_UniChars and processing
* continues. Equivalent to Plan 9 chartorune().
*
* The caller must ensure that the source buffer is long enough that
* this routine does not run off the end and dereference non-existent
* memory looking for trail bytes. If the source buffer is known to
* be '\0' terminated, this cannot happen. Otherwise, the caller
* should call Tcl_UtfCharComplete() before calling this routine to
* ensure that enough bytes remain in the string.
*
* Results:
* *chPtr is filled with the Tcl_UniChar, and the return value is the
* number of bytes from the UTF-8 string that were consumed.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
#define Tcl_UniChar int
#define TCL_UTF_MAX 3
static int
gdTcl_UtfToUniChar(char *str, Tcl_UniChar *chPtr)
/* str is the UTF8 next character pointer */
/* chPtr is the int for the result */
{
int byte;
/* HTML4.0 entities in decimal form, e.g. &#197; */
byte = *((unsigned char *) str);
if (byte == '&') {
int i, n=0;
byte = *((unsigned char *) (str+1));
if (byte == '#') {
for (i = 2; i < 8; i++) {
byte = *((unsigned char *) (str+i));
if (byte >= '0' && byte <= '9') {
n = (n * 10) + (byte - '0');
}
else
break;
}
if (byte == ';') {
*chPtr = (Tcl_UniChar) n;
return ++i;
}
}
}
/*
* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones.
*/
byte = *((unsigned char *) str);
if (byte < 0xC0) {
/*
* Handles properly formed UTF-8 characters between 0x01 and 0x7F.
* Also treats \0 and naked trail bytes 0x80 to 0xBF as valid
* characters representing themselves.
*/
*chPtr = (Tcl_UniChar) byte;
return 1;
} else if (byte < 0xE0) {
if ((str[1] & 0xC0) == 0x80) {
/*
* Two-byte-character lead-byte followed by a trail-byte.
*/
*chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (str[1] & 0x3F));
return 2;
}
/*
* A two-byte-character lead-byte not followed by trail-byte
* represents itself.
*/
*chPtr = (Tcl_UniChar) byte;
return 1;
} else if (byte < 0xF0) {
if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) {
/*
* Three-byte-character lead byte followed by two trail bytes.
*/
*chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12)
| ((str[1] & 0x3F) << 6) | (str[2] & 0x3F));
return 3;
}
/*
* A three-byte-character lead-byte not followed by two trail-bytes
* represents itself.
*/
*chPtr = (Tcl_UniChar) byte;
return 1;
}
#if TCL_UTF_MAX > 3
else {
int ch, total, trail;
total = totalBytes[byte];
trail = total - 1;
if (trail > 0) {
ch = byte & (0x3F >> trail);
do {
str++;
if ((*str & 0xC0) != 0x80) {
*chPtr = byte;
return 1;
}
ch <<= 6;
ch |= (*str & 0x3F);
trail--;
} while (trail > 0);
*chPtr = ch;
return total;
}
}
#endif
*chPtr = (Tcl_UniChar) byte;
return 1;
}
/********************************************************************/
/* font cache functions */
static int
fontTest ( void *element, void *key )
{
font_t *a=(font_t *)element;
fontkey_t *b=(fontkey_t *)key;
return ( strcmp(a->fontname, b->fontname) == 0
&& a->ptsize == b->ptsize
&& a->angle == b->angle);
}
static void *
fontFetch ( char **error, void *key )
{
TT_Error err;
font_t *a;
fontkey_t *b=(fontkey_t *)key;
int i, n, map_found;
short platform, encoding;
a = (font_t *)malloc(sizeof(font_t));
a->fontname = (char *)malloc(strlen(b->fontname) + 1);
strcpy(a->fontname,b->fontname);
a->ptsize = b->ptsize;
a->angle = b->angle;
a->sin_a = sin(a->angle);
a->cos_a = cos(a->angle);
a->engine = b->engine;
if ((err = TT_Open_Face(*b->engine, a->fontname, &a->face))) {
if (err == TT_Err_Could_Not_Open_File) {
*error = "Could not find/open font";
}
else {
*error = "Could not read font";
}
return NULL;
}
/* get face properties and allocate preload arrays */
TT_Get_Face_Properties(a->face, &a->properties);
/* create instance */
if (TT_New_Instance(a->face, &a->instance)) {
*error = "Could not create face instance";
return NULL;
}
if (TT_Set_Instance_Resolutions(a->instance, RESOLUTION, RESOLUTION)) {
*error = "Could not set device resolutions";
return NULL;
}
if (TT_Set_Instance_CharSize(a->instance, (TT_F26Dot6)(a->ptsize*64))) {
*error = "Could not set character size";
return NULL;
}
TT_Get_Instance_Metrics(a->instance, &a->imetrics);
/* FIXME - This mapping stuff is imcomplete - where is the spec? */
n = TT_Get_CharMap_Count(a->face);
map_found = 0;
a->have_char_map_Unicode = 0;
a->have_char_map_Big5 = 0;
a->have_char_map_Roman = 0;
for (i = 0; i < n; i++) {
TT_Get_CharMap_ID(a->face, i, &platform, &encoding);
if ((platform == 3 && encoding == 1) /* Windows Unicode */
|| (platform == 2 && encoding == 1) /* ISO Unicode */
|| (platform == 0)) { /* Apple Unicode */
TT_Get_CharMap(a->face, i, &a->char_map_Unicode);
a->have_char_map_Unicode = 1;
map_found++;
} else if (platform == 3 && encoding == 4) { /* Windows Big5 */
TT_Get_CharMap(a->face, i, &a->char_map_Big5);
a->have_char_map_Big5 = 1;
map_found++;
} else if ((platform == 1 && encoding == 0) /* Apple Roman */
|| (platform == 2 && encoding == 0)) { /* ISO ASCII */
TT_Get_CharMap(a->face, i, &a->char_map_Roman);
a->have_char_map_Roman = 1;
map_found++;
}
}
if (! map_found) {
*error = "Unable to find a CharMap that I can handle";
return NULL;
}
a->matrix.xx = (TT_Fixed) (a->cos_a * (1<<16));
a->matrix.yx = (TT_Fixed) (a->sin_a * (1<<16));
a->matrix.xy = - a->matrix.yx;
a->matrix.yy = a->matrix.xx;
a->glyphCache = gdCacheCreate( GLYPHCACHESIZE,
glyphTest, glyphFetch, glyphRelease);
return (void *)a;
}
static void
fontRelease( void *element )
{
font_t *a=(font_t *)element;
gdCacheDelete(a->glyphCache);
TT_Done_Instance(a->instance);
TT_Close_Face(a->face);
free(a->fontname);
free( (char *)element );
}
/********************************************************************/
/* glyph cache functions */
static int
glyphTest ( void *element, void *key )
{
glyph_t *a=(glyph_t *)element;
glyphkey_t *b=(glyphkey_t *)key;
return (a->character == b->character
&& a->hinting == b->hinting);
}
static void *
glyphFetch ( char **error, void *key )
{
glyph_t *a;
glyphkey_t *b=(glyphkey_t *)key;
short glyph_code;
int flags, err;
int crect[8], xmin, xmax, ymin, ymax;
double cos_a, sin_a;
a = (glyph_t *)malloc(sizeof(glyph_t));
a->character = b->character;
a->hinting = b->hinting;
a->gray_render = (b->font->ptsize < MINANTIALIASPTSIZE)?FALSE:TRUE;
a->oldx = a->oldy = 0;
/* create glyph container */
if ((TT_New_Glyph(b->font->face, &a->glyph))) {
*error = "Could not create glyph container";
return NULL;
}
flags = TTLOAD_SCALE_GLYPH;
if (a->hinting && b->font->angle == 0.0) {
flags |= TTLOAD_HINT_GLYPH;
}
if (b->font->have_char_map_Unicode) {
glyph_code = TT_Char_Index(b->font->char_map_Unicode, a->character);
} else if (a->character < 161 && b->font->have_char_map_Roman) {
glyph_code = TT_Char_Index(b->font->char_map_Roman, a->character);
} else if ( b->font->have_char_map_Big5) {
glyph_code = TT_Char_Index(b->font->char_map_Big5, a->character);
}
if ((err=TT_Load_Glyph(b->font->instance, a->glyph, glyph_code, flags))) {
*error = "TT_Load_Glyph problem";
return NULL;
}
TT_Get_Glyph_Metrics(a->glyph, &a->metrics);
if (b->font->angle != 0.0) {
TT_Get_Glyph_Outline(a->glyph, &a->outline);
TT_Transform_Outline(&a->outline, &b->font->matrix);
}
/* calculate bitmap size */
xmin = a->metrics.bbox.xMin -64;
ymin = a->metrics.bbox.yMin -64;
xmax = a->metrics.bbox.xMax +64;
ymax = a->metrics.bbox.yMax +64;
cos_a = b->font->cos_a;
sin_a = b->font->sin_a;
crect[0] = (int)(xmin * cos_a - ymin * sin_a);
crect[1] = (int)(xmin * sin_a + ymin * cos_a);
crect[2] = (int)(xmax * cos_a - ymin * sin_a);
crect[3] = (int)(xmax * sin_a + ymin * cos_a);
crect[4] = (int)(xmax * cos_a - ymax * sin_a);
crect[5] = (int)(xmax * sin_a + ymax * cos_a);
crect[6] = (int)(xmin * cos_a - ymax * sin_a);
crect[7] = (int)(xmin * sin_a + ymax * cos_a);
a->xmin = MIN(MIN(crect[0],crect[2]),MIN(crect[4],crect[6]));
a->xmax = MAX(MAX(crect[0],crect[2]),MAX(crect[4],crect[6]));
a->ymin = MIN(MIN(crect[1],crect[3]),MIN(crect[5],crect[7]));
a->ymax = MAX(MAX(crect[1],crect[3]),MAX(crect[5],crect[7]));
/* allocate bitmap large enough for character */
a->Bit.rows = (a->ymax - a->ymin + 32 + 64) / 64;
a->Bit.width = (a->xmax - a->xmin + 32 + 64) / 64;
a->Bit.flow = TT_Flow_Up;
if (a->gray_render) {
a->Bit.cols = a->Bit.width; /* 1 byte per pixel */
}
else {
a->Bit.cols = (a->Bit.width + 7) / 8; /* 1 bit per pixel */
}
a->Bit.cols = (a->Bit.cols + 3) & ~3; /* pad to 32 bits */
a->Bit.size = a->Bit.rows * a->Bit.cols; /* # of bytes in buffer */
a->Bit.bitmap = NULL;
a->bitmapCache = gdCacheCreate( BITMAPCACHESIZE,
bitmapTest, bitmapFetch, bitmapRelease);
return (void *)a;
}
static void
glyphRelease( void *element )
{
glyph_t *a=(glyph_t *)element;
gdCacheDelete(a->bitmapCache);
TT_Done_Glyph( a->glyph );
free( (char *)element );
}
/********************************************************************/
/* bitmap cache functions */
static int
bitmapTest ( void *element, void *key )
{
bitmap_t *a=(bitmap_t *)element;
bitmapkey_t *b=(bitmapkey_t *)key;
if (a->xoffset == b->xoffset && a->yoffset == b->yoffset) {
b->glyph->Bit.bitmap = a->bitmap;
return TRUE;
}
return FALSE;
}
static void *
bitmapFetch ( char **error, void *key )
{
bitmap_t *a;
bitmapkey_t *b=(bitmapkey_t *)key;
a = (bitmap_t *)malloc(sizeof(bitmap_t));
a->xoffset = b->xoffset;
a->yoffset = b->yoffset;
b->glyph->Bit.bitmap = a->bitmap = (char *)malloc(b->glyph->Bit.size);
memset(a->bitmap, 0, b->glyph->Bit.size);
/* render glyph */
if (b->glyph->gray_render) {
TT_Get_Glyph_Pixmap(b->glyph->glyph, &b->glyph->Bit,
a->xoffset, a->yoffset);
}
else {
TT_Get_Glyph_Bitmap(b->glyph->glyph, &b->glyph->Bit,
a->xoffset, a->yoffset);
}
return (void *)a;
}
static void
bitmapRelease( void *element )
{
bitmap_t *a=(bitmap_t *)element;
free( a->bitmap );
free( (char *)element );
}
/********************************************************************/
/* tweencolor cache functions */
static int
tweenColorTest (void *element, void *key)
{
tweencolor_t *a=(tweencolor_t *)element;
tweencolorkey_t *b=(tweencolorkey_t *)key;
return (a->pixel == b->pixel
&& a->bgcolor == b->bgcolor
&& a->fgcolor == b->fgcolor
&& a->im == b->im);
}
static void *
tweenColorFetch (char **error, void *key)
{
tweencolor_t *a;
tweencolorkey_t *b=(tweencolorkey_t *)key;
int pixel, npixel, bg, fg;
gdImagePtr im;
a = (tweencolor_t *)malloc(sizeof(tweencolor_t));
pixel = a->pixel = b->pixel;
bg = a->bgcolor = b->bgcolor;
fg = a->fgcolor = b->fgcolor;
im = b->im;
/* if fg is specified by a negative color idx, then don't antialias */
if (fg <0) {
a->tweencolor = -fg;
} else {
npixel = NUMCOLORS - pixel;
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);
}
*error = NULL;
return (void *)a;
}
static void
tweenColorRelease(void *element)
{
free((char *)element);
}
/********************************************************************/
/* gdttfchar - render one character onto a gd image */
char *
gdttfchar(gdImage *im, int fg, font_t *font,
int x, int y, /* string start pos in pixels */
TT_F26Dot6 x1, TT_F26Dot6 y1, /* char start offset (*64) from x,y */
TT_F26Dot6 *advance,
TT_BBox **bbox,
char **next)
{
int pc, ch, len;
int row, col;
int x2, y2; /* char start pos in pixels */
int x3, y3; /* current pixel pos */
unsigned char *pixel;
glyph_t *glyph;
glyphkey_t glyphkey;
bitmapkey_t bitmapkey;
tweencolor_t *tweencolor;
tweencolorkey_t tweencolorkey;
/****** set up tweenColorCache on first call ************/
static gdCache_head_t *tweenColorCache;
if (! tweenColorCache)
tweenColorCache = gdCacheCreate(TWEENCOLORCACHESIZE,
tweenColorTest, tweenColorFetch, tweenColorRelease);
/**************/
if (font->have_char_map_Unicode) { /* use UTF-8 mapping from ASCII */
len = gdTcl_UtfToUniChar(*next, &ch);
*next += len;
} else {
/*
* Big 5 mapping:
* use "JIS-8 half-width katakana" coding from 8-bit characters. Ref:
* ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs
*/
ch = (**next) & 255; /* don't extend sign */
(*next)++;
if (ch >= 161 /* first code of JIS-8 pair */
&& **next) { /* don't advance past '\0' */
ch = (ch * 256) + **next;
(*next)++;
}
}
glyphkey.character = ch;
glyphkey.hinting = 1;
glyphkey.font = font;
glyph = (glyph_t *)gdCacheGet(font->glyphCache, &glyphkey);
if (! glyph)
return font->glyphCache->error;
*bbox = &glyph->metrics.bbox;
*advance = glyph->metrics.advance;
/* if null *im, or invalid color, then assume user just wants brect */
if (!im || fg > 255 || fg < -255)
return (char *)NULL;
/* render (via cache) a bitmap for the current fractional offset */
bitmapkey.xoffset = ((x1+32) & 63) - 32 - ((glyph->xmin+32) & -64);
bitmapkey.yoffset = ((y1+32) & 63) - 32 - ((glyph->ymin+32) & -64);
bitmapkey.glyph = glyph;
gdCacheGet(glyph->bitmapCache, &bitmapkey);
/* copy to gif, mapping colors */
x2 = x + (((glyph->xmin+32) & -64) + ((x1+32) & -64)) / 64;
y2 = y - (((glyph->ymin+32) & -64) + ((y1+32) & -64)) / 64;
tweencolorkey.fgcolor = fg;
tweencolorkey.im = im;
for (row = 0; row < glyph->Bit.rows; row++) {
if (glyph->gray_render)
pc = row * glyph->Bit.cols;
else
pc = row * glyph->Bit.cols * 8;
y3 = y2 - row;
if (y3 >= im->sy || y3 < 0) continue;
for (col = 0; col < glyph->Bit.width; col++, pc++) {
if (glyph->gray_render) {
tweencolorkey.pixel =
*((unsigned char *)(glyph->Bit.bitmap) + pc);
} else {
tweencolorkey.pixel =
(((*((unsigned char *)(glyph->Bit.bitmap) + pc/8))
<<(pc%8))&128)?4:0;
}
/* if not background */
if (tweencolorkey.pixel > 0) {
x3 = x2 + col;
if (x3 >= im->sx || x3 < 0) continue;
pixel = &im->pixels[y3][x3];
tweencolorkey.bgcolor = *pixel;
tweencolor = (tweencolor_t *)gdCacheGet(
tweenColorCache, &tweencolorkey);
*pixel = tweencolor->tweencolor;
}
}
}
return (char *)NULL;
}
/********************************************************************/
/* gdImageStringTTF - render a utf8 string onto a gd image */
char * gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontname,
double ptsize, double angle, int x, int y, char *string)
{
TT_F26Dot6 ur_x=0, ur_y=0, ll_x=0, ll_y=0;
TT_F26Dot6 advance_x, advance_y, advance, x1, y1;
TT_BBox *bbox;
double sin_a, cos_a;
int i=0, ch;
font_t *font;
fontkey_t fontkey;
char *error, *next;
/****** initialize font engine on first call ************/
static gdCache_head_t *fontCache;
static TT_Engine engine;
if (! fontCache) {
if (TT_Init_FreeType(&engine)) {
return "Failure to initialize font engine";
}
fontCache = gdCacheCreate( FONTCACHESIZE,
fontTest, fontFetch, fontRelease);
}
/**************/
/* get the font (via font cache) */
fontkey.fontname = fontname;
fontkey.ptsize = ptsize;
fontkey.angle = angle;
fontkey.engine = &engine;
font = (font_t *)gdCacheGet(fontCache, &fontkey);
if (! font) {
return fontCache->error;
}
sin_a = font->sin_a;
cos_a = font->cos_a;
advance_x = advance_y = 0;
next=string;
while (*next) {
ch = *next;
/* carriage returns */
if (ch == '\r') {
advance_x = 0;
next++;
continue;
}
/* newlines */
if (ch == '\n') {
advance_y -= (TT_F26Dot6)(font->imetrics.y_ppem * LINESPACE * 64);
advance_y = (advance_y-32) & -64; /* round to next pixel row */
next++;
continue;
}
x1 = (TT_F26Dot6)(advance_x * cos_a - advance_y * sin_a);
y1 = (TT_F26Dot6)(advance_x * sin_a + advance_y * cos_a);
if ((error=gdttfchar(im, fg, font, x, y, x1, y1, &advance, &bbox, &next)))
return error;
if (! i++) { /* if first character, init BB corner values */
ll_x = bbox->xMin;
ll_y = bbox->yMin;
ur_x = bbox->xMax;
ur_y = bbox->yMax;
}
else {
if (! advance_x) ll_x = MIN(bbox->xMin, ll_x);
ll_y = MIN(advance_y + bbox->yMin, ll_y);
ur_x = MAX(advance_x + bbox->xMax, ur_x);
if (! advance_y) ur_y = MAX(bbox->yMax, ur_y);
}
advance_x += advance;
}
/* rotate bounding rectangle */
brect[0] = (int)(ll_x * cos_a - ll_y * sin_a);
brect[1] = (int)(ll_x * sin_a + ll_y * cos_a);
brect[2] = (int)(ur_x * cos_a - ll_y * sin_a);
brect[3] = (int)(ur_x * sin_a + ll_y * cos_a);
brect[4] = (int)(ur_x * cos_a - ur_y * sin_a);
brect[5] = (int)(ur_x * sin_a + ur_y * cos_a);
brect[6] = (int)(ll_x * cos_a - ur_y * sin_a);
brect[7] = (int)(ll_x * sin_a + ur_y * cos_a);
/* scale, round and offset brect */
i = 0;
while (i<8) {
brect[i] = x + (brect[i] + 32) / 64;
i++;
brect[i] = y - (brect[i] + 32) / 64;
i++;
}
return (char *)NULL;
}
#endif /* HAVE_LIBTTF */

View File

@ -1,16 +1,40 @@
<HTML>
<HEAD>
<TITLE>gd 1.6.1</TITLE>
<TITLE>gd 1.6.2</TITLE>
</HEAD>
<BODY>
<H1>gd 1.6.1</H1>
<H1>gd 1.6.2</H1>
<H2>A graphics library for fast image creation</H2>
<H2>Follow this link to the
<A HREF="http://www.boutell.com/gd/">latest version
of this document</A>.</H2>
<blockquote>
<strong>HEY! READ THIS!</strong>
gd 1.6.2 creates PNG images, not GIF images. This is a good thing.
PNG is a more compact format, and full compression is available.
Existing code will need modification to call gdImagePng instead
of gdImageGif. <strong>Please do not ask us to send you the old GIF
version of GD.</strong> Unisys holds a patent on the LZW compression
algorithm, which is used in fully compressed GIF images. We are
still investigating the legal issues surrounding various
alternative means of producing a valid GIF file.
<p>
gd 1.6.2 <strong>requires</strong> that the following libraries
also be installed:
<p>
libpng
<p>
zlib
<p>
Please read the documentation and install the required libraries.
Do not send email asking why <code>png.h</code> is not found.
See the <a href="#required">requirements section</a> for more
information. Thank you!
</blockquote>
<H3>Table of Contents</H3>
<UL>
<LI><A HREF="#notice">Credits and license terms</A>
<LI><A HREF="#whatsnew1.6.2">What's new in version 1.6.2?</A>
<LI><A HREF="#whatsnew1.6.1">What's new in version 1.6.1?</A>
<LI><A HREF="#whatsnew1.6">What's new in version 1.6?</A>
<LI><A HREF="#whatis">What is gd?</A>
@ -19,7 +43,7 @@ of this document</A>.</H2>
<LI><A HREF="#getgd">How do I get gd?</A>
<LI><A HREF="#buildgd">How do I build gd?</A>
<LI><A HREF="#basics">gd basics: using gd in your program</A>
<LI><A HREF="#webgif">webgif: a useful example</A>
<LI><A HREF="#webpng">webpng: a useful example</A>
<LI><A HREF="#reference">Function and type reference by category</A>
<LI><A HREF="#gdformat">About the additional .gd image file format</A>
<LI><A HREF="#informing"><strong>Please</strong>
@ -52,6 +76,8 @@ Portions relating to GD2 format copyright 1999 Philip Warner.
<p>
Portions relating to PNG copyright 1999, Greg Roelofs.
<p>
Portions relating to libttf copyright 1999, John Ellson (ellson@lucent.com).
<p>
<strong>Permission has been granted to copy and distribute gd in any
context, including a commercial application, provided that this notice
is present in user-accessible supporting documentation.</strong>
@ -69,7 +95,7 @@ copyright notice and this permission notice appear in supporting
documentation. This software is provided "as is" without express or
implied warranty.
<p>
Although their code does not appear in gd 1.6.1, the authors wish to
Although their code does not appear in gd 1.6.2, the authors wish to
thank David Koblas, David Rowley, and Hutchison Avenue Software
Corporation for their prior contributions.
<p>
@ -102,7 +128,7 @@ in the wrong place.
<P>
gd does not provide for every possible desirable graphics
operation. It is not necessary or desirable for gd to become
a kitchen-sink graphics package, but version 1.6.1 incorporates
a kitchen-sink graphics package, but version 1.6.2 incorporates
most of the commonly requested features for an 8-bit 2D package.
Support for scalable fonts, and truecolor images, JPEG and
truecolor PNG is planned for version 2.0.
@ -114,18 +140,43 @@ gd can also be used from Perl, courtesy of
Lincoln Stein's
<a href="http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.html">
GD.pm</a> library, which uses gd as the basis for a set of
Perl 5.x classes. Not yet updated for gd 1.6.1.
Perl 5.x classes. Not yet updated for gd 1.6.2.
<h4>Tcl</h4>
gd can be used from Tcl with John Ellson's
<a href=http://www.tcltk.com/ftp/ellson/>Gdtclft</a>
dynamically loaded extension package.
(Gdtclft2.0 or later is needed for gd-1.6.2 with PNG output.)
<h4>Any Language</h4>
There are, at the moment, at least three simple interpreters that
perform gd operations. You can output the desired commands to a simple
text file from whatever scripting language you prefer to use, then
invoke the interpreter.
<p>
These packages have not been updated to gd 1.6.1 as of this writing.
These packages have not been updated to gd 1.6.2 as of this writing.
<ul>
<li><a href="http://s27w007.pswfs.gov/tgd/">tgd</a>, by Bradley K. Sherman
<li><a href="http://www.unimelb.edu.au/fly/fly.html">fly</a>, by Martin Gleeson
</ul>
<P><A NAME="whatsnew1.6.2"><H3>What's new in version 1.6.2?</H3></A>
Version 1.6.2 from John Ellson <ellson@lucent.com> adds two new functions:
<ul>
<li>gdImageStringTTF - scalable, rotatable, anti-aliased, TrueType strings using
the FreeType library, but only if libttf is found by configure.
<strong>We do not provide TrueType fonts. Obtaining them
is entirely up to you.</strong>
<li>gdImageColorResolve - an efficient alternative for the
common code fragment:
<pre>
if ((color=gdImageColorExact(im,R,G,B)) < 0)
if ((color=gdImageColorAllocate(im,R,G,B)) < 0)
color=gdImageColorClosest(im,R,G,B);
</pre>
</ul>
<p>
Also in this release the build process has been converted to
GNU autoconf/automake/libtool conventions so that both (or either)
static and shared libraries can be built.
<P><A NAME="whatsnew1.6.1"><H3>What's new in version 1.6.1?</H3></A>
Version 1.6.1 incorporates superior PNG reading and writing code
from Greg Roelofs, with minor modifications by Tom Boutell.
@ -241,8 +292,8 @@ to gd fonts.
<dd>Although no such fonts are provided in the distribution,
fonts containing more than 256 characters should work if the
gdImageString16 and gdImageStringUp16 routines are used.
<dt>Improvements to the "webgif" example/utility
<dd>The "webgif" utility is now a slightly more useful application. Thanks to
<dt>Improvements to the "webpng" example/utility
<dd>The "webpng" utility is now a slightly more useful application. Thanks to
Brian Dowling for this code.
<dt>Corrections to the color resolution field of GIF output
<dd>Thanks to Bruno Aureli.
@ -273,11 +324,14 @@ gcc is free, ANSI compliant and a de facto industry standard.
Ask your ISP why it is missing.</strong>
<P>
As of version 1.6, you also need the zlib compression library,
and the libpng library.
and the libpng library. As of version 1.6.2, you can draw text
using antialiased TrueType fonts if you also have the libttf
library installed, but this is not mandatory.
zlib is available for a variety of platforms from
<a href="http://www.cdrom.com/pub/infozip/zlib/">the zlib web site</a>.
libpng is available for a variety of platforms from
<a href="http://www.cdrom.com/pub/png/">the PNG web site</a>.
<P>
You will also want a PNG viewer, if you do not already have
one for your system, since you will need a good way to check the
@ -291,13 +345,13 @@ newsgroups relevant to your particular system.
<A NAME="getgd"><H3>How do I get gd?</H3></A>
<h4>By HTTP</h4>
<ul>
<li><a href="http://www.boutell.com/gd/http/gd1.6.1.tar.gz">Gzipped Tar File (Unix)</a>
<li><a href="http://www.boutell.com/gd/http/gd161.zip">.ZIP File (Windows)</a>
<li><a href="http://www.boutell.com/gd/http/gd-1.6.2.tar.gz">Gzipped Tar File (Unix)</a>
<li><a href="http://www.boutell.com/gd/http/gd162.zip">.ZIP File (Windows)</a>
</ul>
<h4>By FTP</h4>
<ul>
<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd1.6.1.tar.gz">Gzipped Tar File (Unix)</a>
<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd161.zip">.ZIP File (Windows)</a>
<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd-1.6.2.tar.gz">Gzipped Tar File (Unix)</a>
<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd162.zip">.ZIP File (Windows)</a>
</ul>
<P>
<A NAME="buildgd"><H3>How do I build gd?</H3></A>
@ -308,29 +362,22 @@ downloaded. If you are not familiar with <code>tar</code> and
consult with an experienced user of your system. Sorry, we cannot
answer questions about basic Internet skills.
<p>
Unpacking the archive will produce a directory called "gd1.6.1".
Unpacking the archive will produce a directory called "gd-1.6.2".
<p>
<h4>For Unix</h4>
<code>cd</code> to the gd1.6.1 directory and examine the Makefile, which
you will probably need to change slightly depending on your operating
system and your needs.
<code>cd</code> to the gd-1.6.2 directory and type "./configure",
followed by "make". If you are the system administrator, and you
wish to make the gd library available to other programs, you may
also wish to type "make install".
<h4>For Windows, Mac, Et Cetera</h4>
Create a project using your favorite programming environment.
Copy all of the gd files to the project directory. Add <code>gd.c</code>
to your project. Add other source files as appropriate. Learning the
basic skills of creating projects with your chosen C environment
is up to you.
is up to you.
<P>
Now, to build the demonstration program, just type "make gddemo"
if you are working in a command-line environment, or build a project
that includes gddemo.c if you are using a graphical environment. If all
goes well, the program "gddemo" will be compiled and linked without incident.
Depending on your system you may need to edit the Makefile.
Understanding the basic techniques of compiling and linking
programs on your system is up to you.
<P>
You have now built a demonstration program which shows off
the capabilities of gd. To see it in action, type
You have now built both the gd library and a demonstration program which
shows off the capabilities of gd. To see it in action, type
"gddemo".
<P>
gddemo should execute without incident, creating the file
@ -355,9 +402,11 @@ library produced by "make libgd.a", under Unix. Under other
operating systems you will add gd.c to your own project.
<P>
If you want to use the provided fonts, include
gdfontt.h, gdfonts.h, gdfontmb.h, gdfontl.h and/or gdfontg.h. If you
are not using the provided Makefile and/or a library-based approach, be
sure to include the source modules as well in your
gdfontt.h, gdfonts.h, gdfontmb.h, gdfontl.h and/or gdfontg.h. For
more impressive results, install libttf and use the new
<a href="#gdImageStringTTF">gdImageStringTTF</a>
function. If you are not using the provided Makefile and/or a
library-based approach, be sure to include the source modules as well in your
project. (They may be too large for 16-bit memory models,
that is, 16-bit DOS and Windows.)
<P>
@ -1509,8 +1558,9 @@ void gdImageChar(gdImagePtr im, gdFontPtr font, int x, int y,
gdImageChar is used to draw single characters on the image.
(To draw multiple characters, use <A HREF="#gdImageString">
gdImageString</A> or <A HREF="#gdImageString16">
gdImageString16</A>.) The second argument is a
pointer to a font definition structure; five fonts are
gdImageString16</A>.
See also <A HREF="#gdImageStringTTF">gdImageStringTTF</A>, new with gd-1.6.2.)
The second argument is a pointer to a font definition structure; five fonts are
provided with gd, gdFontTiny, gdFontSmall, gdFontMediumBold,
gdFontLarge, and gdFontGiant. You must
include the files "gdfontt.h", "gdfonts.h", "gdfontmb.h",
@ -1599,8 +1649,9 @@ corresponding .c files to use the provided fonts.
The null-terminated C string specified
by the fifth argument is drawn from left to right in the specified
color. (See <A HREF="#gdImageStringUp">gdImageStringUp</A> for a way
of drawing vertical text.) Pixels not
set by a particular character retain their previous color.
of drawing vertical text.
See also <A HREF="#gdImageStringTTF">gdImageStringTTF</A>, new with gd-1.6.2.)
Pixels not set by a particular character retain their previous color.
<PRE>
#include "gd.h"
#include "gdfontl.h"
@ -1720,7 +1771,103 @@ set by a particular character retain their previous color.
<p>
This function was added in gd1.3 to provide a means of rendering
fonts with more than 256 characters for those who have them. A
more frequently used routine is <a href="#gdImageStringUp">gdImageStringUp</a>.</DL>
more frequently used routine is <a href="#gdImageStringUp">gdImageStringUp</a>.
<DT><A NAME="gdImageStringTTF">
char *gdImageStringTTF(gdImagePtr im, int *brect,
int fg, char *fontname, double ptsize, double angle,
int x, int y, char *string)</A>
<STRONG>(FUNCTION)</STRONG>
<DD>
gdImageStringTTF is draws a string of anti-aliased characters on the image
using the
<A HREF=http://www.freetype.org/>FreeType</A>
library to print from user-supplied TrueType fonts.
<strong>We do not provide TrueType fonts. Obtaining them
is entirely up to you.</strong>
The string is anti-aliased, meaning that there should be less "jaggies."
The fontname is the full pathname to a TrueType font file.
The string may be arbitrarily scaled (ptsize) and rotated (angle in radians).
<p>
The user-supplied int brect[8] array is filled on return from gdImageStringTTF
with the 8 elements representing the 4 corner coordinates of the
bounding rectangle.
<TABLE BORDER="1">
<TR><TD ALIGN="LEFT" VALIGN="TOP" >0</TD><TD ALIGN="LEFT" VALIGN="TOP">
lower left corner, X position</TD></TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP >1</T ><TD ALIGN="LEFT" VALIGN="TOP">
lower left corner, Y position</TD></TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP >2</T ><TD ALIGN="LEFT" VALIGN="TOP">
lower right corner, X position</TD></TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP">3</TD><TD ALIGN="LEFT" VALIGN="TOP">
lower right corner, Y position</TD></TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP">4</TD><TD ALIGN="LEFT" VALIGN="TOP">
upper right corner, X position</TD></TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP">5</TD><TD ALIGN="LEFT" VALIGN="TOP">
upper right corner, Y position</TD></TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP">6</TD><TD ALIGN="LEFT" VALIGN="TOP">
upper left corner, X position</TD></TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP">7</TD><TD ALIGN="LEFT" VALIGN="TOP">
upper left corner, Y position</TD></TR>
</TABLE>
<p>
The points are relative to the text regardless of the angle, so "upper left"
means in the top left-hand corner seeing the text horizontally.
<p>
Use a NULL gdImagePtr to get the bounding rectangle without rendering.
This is a relatively cheap operation if followed by a rendering of the same
string, because of the caching of the partial rendering during bounding
rectangle calculation.
<p>
The string is rendered in the color indicated by the gf color index.
Use the negative of the desired color index to disable anti-aliasing.
<p>
The string may contain UTF-8 sequences like: "&amp;#192;"
<p>
gdImageStringTTF will return a null char* on success, or an error
string on failure.
<PRE>
#include "gd.h"
#include &lt;string.h&gt;
... inside a function ...
<A HREF="#gdImagePtr">gdImagePtr</A> im;
int black;
int white;
int brect[8];
int x, y;
char *err;
char *s = "Hello."; /* String to draw. */
double sz = 40.;
char *f = "/usr/local/share/ttf/Times.ttf"; /* User supplied font */
/* obtain brect so that we can size the image */
err = <A HREF="#gdImageStringTTF">gdImageStringTTF</A>(NULL,&brect[0],0,f,sz,0.,0,0,s);
if (err) {fprintf(stderr,err); return 1;}
/* create an image big enough for the string plus a little whitespace */
x = brect[2]-brect[6] + 6;
y = brect[3]-brect[7] + 6;
im = <A HREF="#gdImageCreate">gdImageCreate</A>(x,y);
/* Background color (first allocated) */
white = <A HREF="#gdImageColorResolve">gdImageColorResolve</A>(im, 255, 255, 255);
black = <A HREF="#gdImageColorResolve">gdImageColorResolve</A>(im, 0, 0, 0);
/* render the string, offset origin to center string*/
/* note that we use top-left coordinate for adjustment
* since gd origin is in top-left with y increasing downwards. */
x = 3 - brect[6];
y = 3 - brect[7];
err = <A HREF="#gdImageStringTTF">gdImageStringTTF</A>(im,&brect[0],black,f,sz,0.0,x,y,s);
if (err) {fprintf(stderr,err); return 1;}
/* Write img to stdout */
<A HREF="#gdImagePng">gdImagePng</A>(im, stdout);
/* Destroy it */
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
</PRE>
</DL>
<H3><A NAME="colors">Color-handling functions</A></H3>
<DL>
<DT><A NAME="gdImageColorAllocate">
@ -1744,6 +1891,8 @@ see <A HREF="#gdImageColorExact">gdImageColorExact</A>
and <A HREF="#gdImageColorClosest">gdImageColorClosest</A>
for ways to locate existing colors that approximate the
color desired in situations where a new color is not available.
Also see <A HREF="#gdImageColorResolve">gdImageColorResolve</A>,
new in gd-1.6.2.
<PRE>
... inside a function ...
<A HREF="#gdImagePtr">gdImagePtr</A> im;
@ -1839,6 +1988,35 @@ gdImageDashedLine(im, 0, 0, 99, 99, red);
/* Destroy it */
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
</PRE>
<DT><A NAME="gdImageColorResolve">
int gdImageColorResolve(gdImagePtr im, int r, int g, int b)</A>
<STRONG>(FUNCTION)</STRONG>
<DD>
gdImageColorResolve searches the colors which have been
defined thus far in the image specified and returns the
index of the first color with RGB values which exactly
match those of the request. If no allocated color matches the
request precisely, then gdImageColorResolve tries to allocate the
exact color. If there is no space left in the color table then
gdImageColorResolve returns the closest color (as in gdImageColorClosest).
This function always returns an index of a color.
<PRE>
... inside a function ...
<A HREF="#gdImagePtr">gdImagePtr</A> im;
int red;
in = fopen("photo.png", "rb");
im = <A HREF="#gdImageCreateFromPng">gdImageCreateFromPng</A>(in);
fclose(in);
/* The image may already contain red; if it does, we'll save a slot
in the color table by using that color. */
/* Get index of red, or color closest to red */
red = gdImageColorResolve(im, 255, 0, 0);
/* Draw a dashed line from the upper left corner to the lower right corner */
gdImageDashedLine(im, 0, 0, 99, 99, red);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
</PRE>
<DT><A NAME="gdImageColorsTotal">
int gdImageColorsTotal(gdImagePtr im)</A>
<STRONG>(MACRO)</STRONG>
@ -2140,6 +2318,20 @@ in the source palette.
</DL>
<H3><A NAME="misc">Miscellaneous Functions</A></H3>
<DL>
<DT><A NAME="gdImageCompare">int gdImageCompare(gdImagePtr im1, gdImagePtr im2)
<STRONG> (FUNCTION)</STRONG>
<DD>
gdImageCompare returns a bitmap indicating if the two images are different. The members of the
bitmap are defined in gd.h, but the most important is GD_CMP_IMAGE, which indicated that the images
will actually appear different when displayed. Other, less important, differences relate to pallette
entries. Any difference in the transparent colour is assumed to make images display differently,
even if the transparent colour is not used.
<PRE>
... Inside a function ...
cmpMask = gdImageCompare(im1, im2);
</PRE>
<DT><A NAME="gdImageInterlace">gdImageInterlace(gdImagePtr im, int interlace)</A> <strong>(FUNCTION)</strong>
<DD>
gdImageInterlace is used to determine whether an image should be stored
@ -2372,6 +2564,7 @@ Be sure to read this manual carefully first.
<A HREF="#gdImageColorClosest">gdImageColorClosest</A> |
<A HREF="#gdImageColorDeallocate">gdImageColorDeallocate</A> |
<A HREF="#gdImageColorExact">gdImageColorExact</A> |
<A HREF="#gdImageColorResolve">gdImageColorResolve</A> |
<A HREF="#gdImageColorTransparent">gdImageColorTransparent</A> |
<A HREF="#gdImageCopy">gdImageCopy</A> |
<A HREF="#gdImageCopyResized">gdImageCopyResized</A> |
@ -2409,6 +2602,7 @@ Be sure to read this manual carefully first.
<A HREF="#gdImageSetTile">gdImageSetTile</A> |
<A HREF="#gdImageString">gdImageString</A> |
<A HREF="#gdImageString16">gdImageString16</A> |
<A HREF="#gdImageStringTTF">gdImageStringTTF</A> |
<A HREF="#gdImageStringUp">gdImageStringUp</A> |
<A HREF="#gdImageStringUp">gdImageStringUp16</A> |
<A HREF="#gdMaxColors">gdMaxColors</A> |

251
src/install-sh Executable file
View File

@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

3017
src/ltconfig Executable file

File diff suppressed because it is too large Load Diff

3975
src/ltmain.sh Normal file

File diff suppressed because it is too large Load Diff

190
src/missing Executable file
View File

@ -0,0 +1,190 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing - GNU libit 0.0"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`configure.in'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`configure.in'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`configure.in'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequirements for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0

40
src/mkinstalldirs Executable file
View File

@ -0,0 +1,40 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id$
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

View File

@ -34,5 +34,7 @@ int main(int argc, char **argv)
gdImageGd(im, out);
fclose(out);
gdImageDestroy(im);
return 0;
}

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
@ -40,5 +41,7 @@ int main(int argc, char **argv)
gdImageGd2(im, out, cs, fmt);
fclose(out);
gdImageDestroy(im);
return 0;
}

View File

@ -3,7 +3,9 @@
/* Bring in standard I/O and string manipulation functions */
#include <stdio.h>
#include <stdlib.h> /* for atoi() */
#include <string.h>
#include <unistd.h> /* for getpid(), unlink() */
int main(int argc, char **argv)
{
@ -46,7 +48,7 @@ int main(int argc, char **argv)
/* If the load failed, it must not be a PNG file. */
if (!im) {
fprintf(stderr,
"Error: %s is not a valid png file.\n", argv[argc-1]);
"Error: %s is not a valid PNG file.\n", argv[argc-1]);
exit(1);
}
/* Consider each argument in turn. */
@ -140,11 +142,11 @@ usage:
if (no) {
/* If the command failed, output an explanation. */
fprintf(stderr,
"Usage: webpng [-i y|n ] [-l] [-t index|off ] [-d] pngname.png\n"
"Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n"
" -i [y|n] Turns on/off interlace\n"
" -l Prints the table of color indexes\n"
" -t [index] Set the transparent color to the specified index (0-255 or none)\n"
" -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n"
" -d Reports the dimensions and other characteristics of the image.\n"
"\n"
"If you specify '-' as the input file, stdin/stdout will be used input/output.\n"
@ -167,12 +169,12 @@ usage:
}
}
/* Write the new png. */
/* Write the new PNG. */
gdImagePng(im, out);
if (!useStdinStdout) {
fclose(out);
/* Erase the old png. */
/* Erase the old PNG. */
unlink(argv[argc-1]);
/* Rename the new to the old. */
if (rename(outFn, argv[argc-1])!=0) {