GD-2.66/0000755000076500001200000000000013077123434011103 5ustar rurbanadminGD-2.66/bdf_scripts/0000755000076500001200000000000013077123433013404 5ustar rurbanadminGD-2.66/bdf_scripts/bdf2gdfont_pl.PL0000644000076500001200000001233013076515043016353 0ustar rurbanadmin#!perl use Config; use File::Basename qw(&basename &dirname); use Cwd; my $origdir = cwd; my $dir = dirname($0); chdir $dir; my $file = 'bdf2gdfont'; $file .= $^O eq 'VMS' ? '.com' : '.pl'; open OUT,">",$file or die "Can't create $file: $!"; print "Extracting $file (with variable substitutions)\n"; print OUT <<"!GROK!THIS!"; $Config{startperl} !GROK!THIS! # In the following, perl variables are not expanded during extraction. print OUT <<'!NO!SUBS!'; # # Simple convertor from bdf to loadable GD font format. # # Author: Lincoln Stein , heavily adopted from bdftogd from # Jan Pazdziora # # Example of use: # fstobdf -s fontserverhost:7100 -fn 8x16 | bdftofnt > myfont.fnt # use strict; our $VERSION = '1.00'; if ($ARGV[0] =~ /^--?h/) { exec "perldoc $0"; } my ($width, $height); my (@data, @left, @bottom); my ($globalleft, $globaltop); my ($minchar, $maxchar); my ($copyright, $fontdef); my $currentchar; my $gobitmap = 0; foreach (@ARGV) { $_ = "gunzip -c $_ |" if /\.gz$/; } while (<>) { chomp; s/\r$//; next unless $_; my ($tag, $value) = split / /, $_, 2; die "Font is not fixed width\n" if $tag eq 'SPACING' and not $value =~ /[CM]/i; $currentchar = $value if $tag eq 'ENCODING'; $minchar = $currentchar if not defined $minchar or ($currentchar < $minchar && $currentchar >= 0); $maxchar = $currentchar if not defined $maxchar or ($currentchar > $maxchar && $currentchar >= 0); if ($tag eq 'ENDCHAR') { next if $currentchar < 0; $gobitmap = 0; my $bottom = $globaltop - $bottom[$currentchar]; if ($bottom > 0) { $data[$currentchar] = substr $data[$currentchar], 0, length($data[$currentchar]) - $bottom * $width; } else { $data[$currentchar] .= '0' x (-$bottom * $width); } } if ($tag eq 'FONTBOUNDINGBOX') { my ($tag, $wid, $hei, $left, $top) = split / /; if (defined $top) { $globalleft = $left; $globaltop = $top; $height = $hei; $width = $wid; } } if ($tag eq 'FONT' and not defined $fontdef) { $fontdef = $value; } if ($tag eq 'COPYRIGHT' and not defined $copyright) { $copyright = $value; } if ($tag eq 'BBX') { my ($tag, $wid, $hei, $left, $bottom) = split / /; if (defined $bottom) { $left[$currentchar] = $left; $bottom[$currentchar] = $bottom; } } if ($gobitmap) { my $value = pack 'H*', $_; my $bits = unpack 'B*', $value; $bits = ('0' x $left[$currentchar]) . $bits; $bits .= '0' x ($width - length $bits); $bits = substr $bits, 0, $width; $data[$currentchar] .= $bits; } if ($tag eq 'BITMAP') { $gobitmap = 1; $data[$currentchar] = ''; } } $minchar = 0 unless defined $minchar; $maxchar = 255 unless defined $maxchar; binmode STDOUT; # for DOS/Windows systems my $length = $maxchar-$minchar+1; print pack ('VVVV',$length,$minchar,$width,$height); # header for (my $i = $minchar; $i <= $maxchar; $i++) { $data[$i] = '' unless defined $data[$i]; $data[$i] = '0' x ($width * $height - length $data[$i]) . $data[$i]; print pack('C*',split '',$data[$i]); } print STDERR "Successfully converted $length ${width}x$}height} characters\n"; __END__ =head1 NAME bdf2gdfont.pl - Convert X11 "BDF" fonts into a loadable font format for GD. =head1 SYNOPSIS % bdf2gdfont.pl courR12.bdf > courR12.fnt =head1 DESCRIPTION This script converts BDF-style X11 font files into a format that can be loaded by the GD module using the GD::Font->load() method. There are a number of ways to obtain BDF fonts. =over 4 =item 1. The font is already present on your system. Some BDF fonts can be found in the standard X11R6 distribution. This script will automatically uncompress gzipped font files if their extension ends with .gz (the gunzip program must be on your path). =item 2. From a font server. The "fstobdf" utility, a standard X11 utility, will read a named font from the font server of your choice and return it in BDF format. You can pipe it to bdf2gdfont.pl: fstobdf -s fontserverhost:7100 -fn 8x16 | bdf2gdfont.pl > newfont.fnt Use xlsfonts to find out what fonts are available. Most fonts will have long names like -B&H-LucidaTypewriter-Bold-R-Normal-Sans-18-180-75-75-M-110-ISO8859-10. =item 3. Using the pcf2bdf utility. Some fonts are only available in PCF (compiled) format. To obtain these, you can either turn on a font server and follow recipe (2), or use TAGA Nayuta's pcf2bdf utility. This utility is available from http://www.tsg.ne.jp/GANA/S/pcf2bdf/ (page is in Japanese, but you can find the download link). =back =head2 Limitations This font converter only works with fixed-width fonts. If used with a TrueType or proportional font it will die with an error message. =head1 SEE ALSO L =head1 AUTHOR Lincoln Stein , heavily adapted from bdftogd from Jan Pazdziora . Copyright (c) 2004 Cold Spring Harbor Laboratory This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut !NO!SUBS! close OUT or die "Can't close $file: $!"; chmod 0755, $file or die "Can't reset permissions for $file: $!\n"; exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':'; chdir $origdir; GD-2.66/bdf_scripts/bdftogd0000755000076500001200000000776213075665264014772 0ustar rurbanadmin#!/usr/bin/perl -w # # Simple convertor from bdf to gd font format. # # Author: Jan Pazdziora, adelton@fi.muni.cz, http://www.fi.muni.cz/~adelton/ # at Faculty of Informatics, Masaryk University in Brno, Czech Republic. # # Example of use: # fstobdf -s fontserverhost:7100 -fn 8x16 | ./bdftogd FontLarge gdfontl # use strict; my $VERSION = '0.60'; my $now = localtime; if (@ARGV < 2) { die "usage: bdftogd fontname filename, eg. bdftogd FontLarge gdfontl\n"; } my $gdname = shift; $gdname = 'gd' . $gdname unless $gdname =~ /^gd/i; my $filename = shift; $filename = 'gd' . $filename unless $filename =~ /^gd/i; if (-f "$filename.c") { die "File $filename.c already exists, won't overwrite\n"; } if (-f "$filename.h") { die "File $filename.h already exists, won't overwrite\n"; } my ($width, $height); my (@data, @left, @bottom); my ($globalleft, $globaltop); my ($minchar, $maxchar); my ($copyright, $fontdef); my $currentchar; my $gobitmap = 0; while (<>) { chomp; s/\r$//; my ($tag, $value) = split / /, $_, 2; die "Font is not fixed width\n" if $tag eq 'SPACING' and not $value =~ /[CM]/i; $currentchar = $value if $tag eq 'ENCODING'; $minchar = $currentchar if not defined $minchar or ($currentchar < $minchar && $currentchar >= 0); $maxchar = $currentchar if not defined $maxchar or ($currentchar > $maxchar && $currentchar >= 0); if ($tag eq 'ENDCHAR') { next if $currentchar < 0; $gobitmap = 0; my $bottom = $globaltop - $bottom[$currentchar]; if ($bottom > 0) { $data[$currentchar] = substr $data[$currentchar], 0, length($data[$currentchar]) - $bottom * $width; } else { $data[$currentchar] .= '0' x (-$bottom * $width); } } if ($tag eq 'FONTBOUNDINGBOX') { my ($tag, $wid, $hei, $left, $top) = split / /; if (defined $top) { $globalleft = $left; $globaltop = $top; $height = $hei; $width = $wid; } } if ($tag eq 'FONT' and not defined $fontdef) { $fontdef = $value; } if ($tag eq 'COPYRIGHT' and not defined $copyright) { $copyright = $value; } if ($tag eq 'BBX') { my ($tag, $wid, $hei, $left, $bottom) = split / /; if (defined $bottom) { $left[$currentchar] = $left; $bottom[$currentchar] = $bottom; } } if ($gobitmap) { my $value = pack 'H*', $_; my $bits = unpack 'B*', $value; $bits = ('0' x $left[$currentchar]) . $bits; $bits .= '0' x ($width - length $bits); $bits = substr $bits, 0, $width; $data[$currentchar] .= $bits; } if ($tag eq 'BITMAP') { $gobitmap = 1; $data[$currentchar] = ''; } } my $info = <<"EOF"; /* This is a header file for gd font, generated using bdftogd version $VERSION by Jan Pazdziora, adelton\@fi.muni.cz from bdf font $fontdef at $now. EOF if (defined $copyright) { $info .= <<"EOF"; The original bdf was holding following copyright: $copyright */ EOF } else { $info .= <<"EOF"; No copyright info was found in the original bdf. */ EOF } open FILEC, "> $filename.c" or die "Error writing $filename.c: $!\n"; open FILEH, "> $filename.h" or die "Error writing $filename.h: $!\n"; print FILEC <<"EOF"; $info #include "$filename.h" char ${gdname}Data[] = { EOF $minchar = 0 unless defined $minchar; $maxchar = 255 unless defined $maxchar; for (my $i = $minchar; $i <= $maxchar; $i++) { $data[$i] = '' unless defined $data[$i]; $data[$i] = '0' x ($width * $height - length $data[$i]) . $data[$i]; print FILEC "/* Char $i */\n"; for my $line (0 .. $height - 1) { print FILEC join ',', split(//, substr($data[$i], $line * $width, $width)), "\n"; } print FILEC "\n"; next; for my $line (0 .. $height - 1) { print substr($data[$i], $line * $width, $width), "\n"; } } my $capdef = "\U_${filename}_H_"; print FILEC <<"EOF"; }; gdFont ${gdname}Rep = { @{[ $maxchar - $minchar + 1]}, $minchar, $width, $height, ${gdname}Data }; gdFontPtr ${gdname} = &${gdname}Rep; /* This file has not been truncated. */ EOF close FILEC; print FILEH <<"EOF"; #ifndef $capdef #define $capdef 1 $info #include "gd.h" extern gdFontPtr $gdname; #endif EOF 1; GD-2.66/bdf_scripts/cvtbdf.pl0000755000076500001200000001614013076515043015217 0ustar rurbanadmin#!/usr/local/bin/perl # Filename - cvtbdf.pl # Author - Geoff Baysinger (gbaysing@HiWAAY.net) # Purpose - Allows "simple" installation of additional BDF fonts for GD.pm # Usage - "cvtbdf.pl" (no arguments, see instructions) # License - Freely given to be distributed with the GD.pm libraries # (you may modify this script to your heart's content, # but it may only be distributed by the author or via the GD.pm # package.) # # Summary - # Uses "bdftogd", (provided with GD.pm) to convert BDF fonts to GD format. # It should makes the edits necessary to the GD.pm source files so that. # the "bdftogd" process is automated and all the user needs do is recompile # the GD.pm package (only "GD.so" is changed during compilation). # # Instructions - # 1) go to your GD.pm source installation directory # note: if you have already installed GD.pm, run a "make clean" # 2) create a subdirectory called "fonts" (mkdir fonts) # 3) copy the BDF font files you wish to convert to the "fonts" directory # note: The BDF font must be a type that "bdftogd" can convert, hence # it must be a standard monospaced character font, not a BDF # cursor file. Some monospaced fonts may still not work. Test # with "bdftogd" before running this script if you are unsure. # 4) copy "bdftogd" and "cvtbdf.pl" to the "fonts" directory # 5) run "cvtbdf.pl" # 6) go to your GD.pm source installation directory and install the new # version via a "make" and "make install" # # Notes - # A) Keep the "fonts" subdirectory and all fonts you wish to use in the # future. Each time you want to add a font you will need the old ones # in the directory, or they will disappear during the next recompile. # B) Add new fonts in the future is as easy as copying the .bdf file to # the "fonts" directory and running steps #5 and #6 again. # # Thanks - # To Lincoln Stein for the use of CGI.pm and GD.pm and to all other # contributors of those packages. # make sure we have the conversion program if (! -x "bdftogd") { die "OOPS!\n Can't execute 'bdftogd', is it even there?\n error: $!\n\n"; } &badnames; &saveorig("GD.pm","GD.xs","libgd/Makefile.PL"); ©orig("GD.pm","GD.xs","libgd/Makefile.PL"); for $i (@files) { open(OLDXS,"../GD.xs") || die "OOPS!\n Can't open '../GD.xs' for reading\n Make sure you're in a 'fonts' subdirectory\n error: $!\n\n"; open(NEWXS,"> ../GD.xs.fonts") || die "OOPS!\n Can't open '../GD.xs.fonts' for writing\n Make sure you're in a 'fonts' subdirectory\n error: $!\n\n"; open(OLDPM,"../GD.pm") || die "OOPS!\n Can't open '../GD.pm' for reading\n Make sure you're in a 'fonts' subdirectory\n error: $!\n\n"; open(NEWPM,"> ../GD.pm.fonts") || die "OOPS!\n Can't open '../GD.pm.fonts' for writing\n Make sure you're in a 'fonts' subdirectory\n error: $!\n\n"; open(OLDMAKE,"../libgd/Makefile.PL") || die "OOPS!\n Can't open '../libgd/Makefile.PL' for reading\n Make sure you're in a 'fonts' subdirectory\n error: $!\n\n"; open(NEWMAKE,"> ../libgd/Makefile.PL.fonts") || die "OOPS!\n Can't open '../libgd/Makefile.PL.fonts' for writing\n Make sure you're in a 'fonts' subdirectory\n error: $!\n\n"; # some state-keeping variables my $extern; my $package; my $export; my $preload; my $h; my $c; # figure out our "name" my $name = "BDF" . $i; $name =~ /(.*)\.bdf/; $name = $1; print "=> name = $name\n"; # do the actual font conversion: open(FONT,"$i"); # usage: bdftogd fontname filename, eg. bdftogd FontLarge gdfontl } my $fontname = "Font" . $name; my $filename = "font" . $name; my $gdname = "gdfont" . $name; open(CONVERT,"| bdftogd $fontname $filename"); while () { print CONVERT; } close CONVERT; # move the font files to "../libgd" open(OLD,"${gdname}.h"); open(NEW,"> ../libgd/${gdname}.h"); while () { print NEW; } close OLD; close NEW; unlink("${gdname}.h"); open(OLD,"${gdname}.c"); open(NEW,"> ../libgd/${gdname}.c"); while () { print NEW; } close OLD; close NEW; unlink("${gdname}.c"); ## Begin editing files # GD.xs: while () { $data = $_; if (! $extern && $data =~ /^extern[\s]{1,}gdFontPtr/) { $data = "extern gdFontPtr gdFont" . $name . ";\n" . $data; $extern = 1; } elsif (! $package && $data =~ /^MODULE[\s]*=[\s]*GD[\s]{1,}PACKAGE[\s]*=[\s]*GD::Font[\s]{1,}PREFIX=gd/) { $data .= "\nGD::Font\ngd" . $name . "(packname=\"GD::Font\")\n char * packname\n PROTOTYPE: \$\n CODE:\n {\n RETVAL = gdFont" . $name . ";\n }\n OUTPUT:\n RETVAL\n"; $package = 1; } print NEWXS $data; } # GD.pm: while () { $data = $_; if (! $export && $data =~ /\@EXPORT = qw\(/) { $data .= " gd" . $name . "Font\n"; $export = "done"; } elsif (! $preload && $data =~ /^# Preloaded methods go here./) { $data .= "sub GD::gd" . $name . "Font {\n return &GD::Font::" . $name . ";\n}\n"; $preload = "done"; } print NEWPM $data; } # libgd/Makefile.PL: while () { $data = $_; # 'H' => [qw(gd.h gdfontl.h gdfonts.h io.h gdfontg.h gdfontmb.h gdfontt.h mtables.h)], if (! $h && $data =~ /^([\s]*'H'[\s]*\=\>[\s]*\[qw\(gd\.h[\s])(.*)/) { $data = $1 . "${gdname}.h " . $2 . "\n"; $h = "done"; } elsif (! $c && $data =~ /^([\s]*'C'[\s]*\=\>[\s]*\[qw\(gdfontg\.c[\s])(.*)/) { # 'C' => [qw(gdfontg.c gdfontmb.c gdfontt.c gdfontl.c gdfonts.c libgd.c)], $data = $1 . "${gdname}.c " . $2 . "\n"; $c = "done"; } print NEWMAKE $data; } # close the files close OLDXS; close NEWXS; close OLDPM; close NEWPM; close OLDMAKE; close NEWMAKE; # copy the files to the proper extension open(NEWXS,"../GD.xs.fonts"); open(OLDXS,"> ../GD.xs"); open(NEWPM,"../GD.pm.fonts"); open(OLDPM,"> ../GD.pm"); open(NEWMAKE,"../libgd/Makefile.PL.fonts"); open(OLDMAKE,"> ../libgd/Makefile.PL"); while () { print OLDXS; } while () { print OLDPM; } while () { print OLDMAKE; } close NEWXS; close OLDXS; close NEWPM; close OLDPM; close NEWMAKE; close OLDMAKE; # unlink the temp files unlink "../GD.pm.fonts"; unlink "../GD.xs.fonts"; unlink "../libgd/Makefile.PL.fonts"; } sub saveorig { local (@files) = @_; for $file (@files) { if (! -f "../${file}.orig") { open(OLD,"../$file") || die $!; open(ORIG,"> ../${file}.orig") || die $!; while () { print ORIG; } close OLD; close ORIG; } } } sub copyorig { local(@files) = @_; for $file (@files) { open(ORIG,"../${file}.orig") || die $!; open(NEW,"> ../$file") || die $!; while () { print NEW; } close ORIG; close NEW; } } sub badnames { @badnames = (<*.BDF>,<*.Bdf>,<*.BDf>,<*.bDf>,<*.bDF>,<*.BdF>); for $i (@badnames) { my $goodname = $i; $goodname =~ tr/A-Z/a-z/; open(BAD,"$i"); open(GOOD,"> $goodname"); while () { print GOOD; } close BAD; close GOOD; unlink $i; } @files = <*.bdf>; } GD-2.66/bdf_scripts/README0000644000076500001200000000055313075665264014302 0ustar rurbanadminThe bdf2gdfont.pl script will convert an X11 BDF font into a bitmapped font that can be loaded into GD using the GD::Font->load() method. Some restrictions apply. Run "perldoc bdf2gdfont.pl" for details. Other scripts in this directory were designed for older versions of libgd in which the fonts are compiled in. Please use with care. Lincoln Stein Fall 2004 GD-2.66/ChangeLog0000644000076500001200000002416513077120742012664 0ustar rurbanadmin2.66 * throw proper error on newFrom* with not-existing file * add t/transp.t from RT #40525 * Improve RT #54366 multiple gd.h warning * better doc for GD::Simple->arc * fix ANIMGIF with libgd 2.3.0-dev 2.65 * fix --gdlib_config_path to accept an argument (fperrad) 2.64 * Update doc for LIBGD_VERSION() * Fix 5.6.2, which does not have float in its typemap 2.63 * renamed VERSION() to LIBGD_VERSION(), RT #121307. It was treated magically by "use GD 2.18" 2.62 * fixed wrong <5.14 code generated with ExtUtils::Constants RT #121297. Don't generate const-xs.inc, only when missing. * add -liconv on hpux also (our pkgconfig parser cannot handle it) 2.61 * add CONFIGURE_REQUIRES META * add --gdlib_config_path * add Image Filters: scatter, pixelate, negate, grayscale, brightness, contrast, color, selectiveBlur, edgeDetectQuick, gaussianBlur, emboss, meanRemoval, smooth, copyGaussianBlurred * add palette methods: createPaletteFromTrueColor, neuQuant (but discouraged), colorMatch. * add interpolation methods: copyScale, copyRotateInterpolated, interpolationMethod. * add double GD::VERSION * add all gd.h constants 2.60 * add missing methods newFromWBMP, newFromXbm, (RT #68784) and some missing docs * Add --lib_fontconfig_path, --fcgi options * rewrote most of the XS code * cleanup Makefile.PL #20 2.59 * error on failing libgd calls * fix colorClosestAlpha, colorAllocateAlpha * add missing documentation 2.58 * fix VERSION_STRING for 2.0.x * honor --lib_gd_path specific gdlib-config * Loosen the comparison tests with GDIMAGETYPE ne gd2 * Improve gdlib-config parsing (PR #17), esp. with 2.0.34 2.57 * fix Jpeg magic number detection RT #26146 * fix RGB - HSV roundtrips: RT #120572 by J2N-FORGET * fix -print-search-dirs errors RT #106265 * co-maint to rurban * add hv_fetchs, CI smokers * add GD::VERSION_STRING api 2.56_03 * add alpha method * improve option handling * fix meta data 2.56_02 * fix feature extraction >= 2.2 [RT #119459] 2.56_01 * rm Build.PL, fix permissions, fix for missing gdlib-config 2.56 * Fix Makefile.PL so that it works again. 2.55 * Great simplification of regression framework ought to fix make test problems. * Replace ExtUtils::MakeMaker script with Module::Build system (just in time for Module::Build to be deprecated). * Remove archaic qd.pl (for creating QuickDraw picts) from distribution. 2.54 Patch from yurly@unet.net to fix image corruption in rotate180 when image height is odd. 2.53 Points to Gabor Szabo's GD::Simple tutorial, and fix link to repository. 2.52 Fix regression tests to run on Ubuntu 12.04 64bit. 2.51 Fix misleading warning message about location of gd.h file. 2.50 Fix gdUseFontConfig so that it can be called as a class method. 2.49 Add GitHub information to README. 2.48 Fix compile crash on windows and strawberry (https://rt.cpan.org/Public/Bug/Display.html?id=67990). 2.47 Fix compilation on older perl's without the Newxz macros. 2.46 Added a basic "use" test for GD::Simple 2.45 Clarified the GD license. There is now a formal LICENSE file in the package. 2.44 GD::Group now installed properly. Quenched compiler warning caused by Newxs() calls. 2.43 Added "transparent" color to GD::Simple. Fixed Makefile so that GD/Image.pm depends both on GD/Image.pm.PLS and .config.cache 2.42 Fixed magic number detection to autodetect certain missed jpeg files (thanks to Mike Walker) 2.41 Added backend support for grouping features in GD::SVG module. 2.40 ** Do not use - contains a bug ** 2.39 Makefile.PL will refuse to run if the proper version of libgd is unavailable. 2.38 Fixed bizarre warning about /usr/include/gd.h != /usr/include/gd.h. 2.37 GD/Image.pm did not bring in croak() properly, meaning that incorrect error messages are printed out when any of the newFromXXX() calls are made. 2.36 Instructions on using gdAntiAliased with palette images. 2.35 Some instructions on installation for Windows users. Doesn't push libpng onto @LIBS unless png support is requested. Supports Storable's freeze/thaw via a custom serializer. Remove "scale redefined" message during compilation of Polyline. 2.34 Added a check for stray gd.h include files from older installations. If any are found, Makefile.PL will issue a warning. Fixed incorrect documentation of GD::Simple->string() method. The method call *does* move the pen. 2.33 Added appropriate #ifdefs to allow to compile under version 5.6.0 (due to lack of threading macros before 5.8). 2.32 Added a GD::Simple->HSVtoRGB() method. Documentation fixes from Mark Manning. Added a clear() method to GD::Polygon to remove all vertices. 2.31 Fixed GD::Simple->transparent to support symbolic color names. Made changes that should render the module thread-safe. Changed newSVpv calls to newSVpvn, in hopes of improving performance. Added a GD::Simple->HSVtoRGB() method. Fixed incorrect freeing of user-provided raw data in newFromGdData() and newFromGd2Data() (this caused segfaults; patch provided by Nigel Sandever) 2.30 Migrated polyline() support into GD::Simple. 2.29 Better support for fonts and brushed patterns in GD::Simple 2.28 Having troubles getting all the modules installed correctly. Should work now. 2.27 Reworked the way that GD.pm is created at compile time so that CPAN picks up correct version information. No code changes. 2.26 CPAN isn't propagating GD, so I'll upload another version 2.25 Fixed Makefile.PL so that GD::Polyline and GD::Simple are installed (thanks to Guy Albertelli). 2.24 Fixed gif/anim gif support so that you can't have animated gif support without having gif support. 2.23 Added patch from Slaven Rezic which makes it possible to call GD constants in an OO way (without generating warnings), and removes #! from the top of autogenerated GD.pm Rewrote tests 11 and 12 - if they continue to randomly fail on various platforms, they will be removed. 2.22 Changed the way the gd and gd2 round-trip tests are evaluated. This might fix test failures that have been reported on some platforms. 2.21 Regression tests are now functional for versions of libgd compiled exclusively with PNG, JPEG or GIF support. 2.20 GD::Image->newFromGdData() and newFromGd2Data() got broken somewhere along the line. They are now fixed (and have a regression test). Added copyRotated() method. 2.19 Added a HAVE_FTCIRCLE define to handle versions of libgd that do not have the gdImageStringFTCircle() function. 2.18 This version needs libgd 2.0.28 or higher. Fixed documentation bug in synopsis of GD::Simple. Updated Polyline to version 0.20 2.17 Added animated GIF patches from Jaakko Hyvtti. Added dynamic bitmapped font loading support. Added fontconfig support. Added a simplified API called GD::Simple. Added support for kern control and other libgd-based FT improvements. Fixed a define that caused gif functions to be miscompiled on some platforms. Documentation fixes. 2.16 Fixed bug in GIF #IFDEFs pointed out by BZAJAC Added #IFDEF for WIN32 provided by Randy Kobes 2.15 Brought back GIF support (requires libgd 2.0.28 or higher). Takes advantage of gdlib-config support in libgd 2.0.27 or higher. 2.14 Support for AMD64 libraries. 2.12 Fixed regression test 10 to succeed when used with libgd 2.0.22 2.11 More alpha functions from Cory Watson 2.10 Suppress CAPI warning. Warn about Math::Trig warning 2.09 VMS documentation patch from Martin Zinser Non-standard library finding path options from Peter Kruty 2.08 Applied 5.00503 compatibility patch from Mathieu Arnold New check for JPEG magic tag returned by some digital cameras. 2.07 Now compatible with (and requires!) libgd 2.0.12. Added setThickness() method. Added support for compression level argument to png(). Added support for antialiasing drawing using setAntiAliased() and setAntiAliasedDontBled(). Added extended options to stringFT(). Added filledArc(), ellipse() and filledEllipse() methods. Added command-line options to Makefile.PL provided by David Eisenberg. 2.06 Added saveAlpha() and alphaBlending() methods. 2.05 Alpha methods courtesy Georges Arnould. 2.041 Added a regression test to detect certain versions of freetype. 2.04 Removed the patch file since Tom has begun adding his own configure file. Changed the context member from free to gd_free to allow for compiling. Fixed the regression tests since the gd-generated images have changed slightly. 2.03 Skipped so as to remain version number compatible with libgd. 2.02 Changed Math::Trig version requirement from 0.0 to 1.0 as Perl 5.8 no long recognizes this as a valid version number. 2.01 Added Math::Trig to the prerequisites because GD::Polyline needs it. 2.00 Folded in support for gd version 2.0 from Dan Palermo Folded in support for splines (GD::Polyline) from Dan Harasty. Removed all GIF support. 1.43 Added demo of Type1 fonts to truetype demo from Slaven Rezic. 1.42 Fixed the patch_gd.pl file Version 2.0 is coming. 1.39 Fixed FreeType test, at least on some platforms. Added patches from Stephen Clouse to allow to build on 5.8.0rc1. 1.35 Patches to support Philip Warner's GIF-reinstating library maintained at http://www.rime.com.au/gd/ 1.34 Fixed problems that arise when compiling against older versions of libgd that do not have XPM support. 1.33 Updated patch file for gd 1.8.4 1.32 Added support for Tru64 UNIX v5.0 1.29 Fixed a corrupted .xpm file in the regression suite (caused test 9 to fail) 1.28 Added support for gd 1.8.3 1.27 Fixed strict refs problem on 5.00503 and earlier 1.26 Brought up to date with libgd 1.8.1 1.24-1.25 More tweaks to Makefile.PL. 1.23 Added a bunch more libraries and includes... might or might not port to other platforms now 1.22 Fix to Makefile.PL to accomodate linking static libraries. Added newFromGd2Part() method. Supports libgd 1.7.1. 1.21 Slight fix in regression tests so that test 8 doesn't fail when compiled without TrueType support. 1.20 Rewritten for libgd 1.6.3 1.19 Fixed Makefile.PL for better compilation on Windoze machines GD-2.66/const-c.inc0000644000076500001200000006405713077061577013171 0ustar rurbanadmin#define PERL_constant_NOTFOUND 1 #define PERL_constant_NOTDEF 2 #define PERL_constant_ISIV 3 #define PERL_constant_ISNO 4 #define PERL_constant_ISNV 5 #define PERL_constant_ISPV 6 #define PERL_constant_ISPVN 7 #define PERL_constant_ISSV 8 #define PERL_constant_ISUNDEF 9 #define PERL_constant_ISUV 10 #define PERL_constant_ISYES 11 #ifndef NVTYPE typedef double NV; /* 5.6 and later define NVTYPE, and typedef NV to it. */ #endif #ifndef aTHX_ #define aTHX_ /* 5.6 or later define this for threading support. */ #endif #ifndef pTHX_ #define pTHX_ /* 5.6 or later define this for threading support. */ #endif static int constant_7 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_BELL GD_SINC gdChord gdEdged gdTiled */ /* Offset 3 gives the best switch position. */ switch (name[3]) { case 'B': if (memEQ(name, "GD_BELL", 7)) { /* ^ */ #ifdef GD_BELL *iv_return = GD_BELL; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'S': if (memEQ(name, "GD_SINC", 7)) { /* ^ */ #ifdef GD_SINC *iv_return = GD_SINC; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'd': if (memEQ(name, "gdEdged", 7)) { /* ^ */ #ifdef gdEdged *iv_return = gdEdged; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'h': if (memEQ(name, "gdChord", 7)) { /* ^ */ #ifdef gdChord *iv_return = gdChord; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'i': if (memEQ(name, "gdTiled", 7)) { /* ^ */ #ifdef gdTiled *iv_return = gdTiled; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_8 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_POWER gdNoFill gdRedMax gdStyled */ /* Offset 2 gives the best switch position. */ switch (name[2]) { case 'N': if (memEQ(name, "gdNoFill", 8)) { /* ^ */ #ifdef gdNoFill *iv_return = gdNoFill; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'R': if (memEQ(name, "gdRedMax", 8)) { /* ^ */ #ifdef gdRedMax *iv_return = gdRedMax; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'S': if (memEQ(name, "gdStyled", 8)) { /* ^ */ #ifdef gdStyled *iv_return = gdStyled; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case '_': if (memEQ(name, "GD_POWER", 8)) { /* ^ */ #ifdef GD_POWER *iv_return = GD_POWER; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_9 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_BESSEL GD_LINEAR gdBlueMax gdBrushed */ /* Offset 6 gives the best switch position. */ switch (name[6]) { case 'E': if (memEQ(name, "GD_LINEAR", 9)) { /* ^ */ #ifdef GD_LINEAR *iv_return = GD_LINEAR; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'M': if (memEQ(name, "gdBlueMax", 9)) { /* ^ */ #ifdef gdBlueMax *iv_return = gdBlueMax; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'S': if (memEQ(name, "GD_BESSEL", 9)) { /* ^ */ #ifdef GD_BESSEL *iv_return = GD_BESSEL; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'h': if (memEQ(name, "gdBrushed", 9)) { /* ^ */ #ifdef gdBrushed *iv_return = gdBrushed; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_10 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_BICUBIC GD_BSPLINE GD_DEFAULT GD_HAMMING GD_HANNING GD_HERMITE gdAlphaMax gdDashSize gdGreenMax */ /* Offset 5 gives the best switch position. */ switch (name[5]) { case 'C': if (memEQ(name, "GD_BICUBIC", 10)) { /* ^ */ #ifdef GD_BICUBIC *iv_return = GD_BICUBIC; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'F': if (memEQ(name, "GD_DEFAULT", 10)) { /* ^ */ #ifdef GD_DEFAULT *iv_return = GD_DEFAULT; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'M': if (memEQ(name, "GD_HAMMING", 10)) { /* ^ */ #ifdef GD_HAMMING *iv_return = GD_HAMMING; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'N': if (memEQ(name, "GD_HANNING", 10)) { /* ^ */ #ifdef GD_HANNING *iv_return = GD_HANNING; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'P': if (memEQ(name, "GD_BSPLINE", 10)) { /* ^ */ #ifdef GD_BSPLINE *iv_return = GD_BSPLINE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'R': if (memEQ(name, "GD_HERMITE", 10)) { /* ^ */ #ifdef GD_HERMITE *iv_return = GD_HERMITE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'e': if (memEQ(name, "gdGreenMax", 10)) { /* ^ */ #ifdef gdGreenMax *iv_return = gdGreenMax; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'h': if (memEQ(name, "gdAlphaMax", 10)) { /* ^ */ #ifdef gdAlphaMax *iv_return = gdAlphaMax; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } if (memEQ(name, "gdDashSize", 10)) { /* ^ */ #ifdef gdDashSize *iv_return = gdDashSize; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_11 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_BLACKMAN GD_GAUSSIAN GD_MITCHELL GD_TRIANGLE gdMaxColors */ /* Offset 5 gives the best switch position. */ switch (name[5]) { case 'A': if (memEQ(name, "GD_BLACKMAN", 11)) { /* ^ */ #ifdef GD_BLACKMAN *iv_return = GD_BLACKMAN; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'C': if (memEQ(name, "gdMaxColors", 11)) { /* ^ */ #ifdef gdMaxColors *iv_return = gdMaxColors; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'I': if (memEQ(name, "GD_TRIANGLE", 11)) { /* ^ */ #ifdef GD_TRIANGLE *iv_return = GD_TRIANGLE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'T': if (memEQ(name, "GD_MITCHELL", 11)) { /* ^ */ #ifdef GD_MITCHELL *iv_return = GD_MITCHELL; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'U': if (memEQ(name, "GD_GAUSSIAN", 11)) { /* ^ */ #ifdef GD_GAUSSIAN *iv_return = GD_GAUSSIAN; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_12 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_CMP_COLOR GD_CMP_IMAGE GD_FLIP_BOTH GD_QUADRATIC GD_WEIGHTED4 */ /* Offset 10 gives the best switch position. */ switch (name[10]) { case 'D': if (memEQ(name, "GD_WEIGHTED4", 12)) { /* ^ */ #ifdef GD_WEIGHTED4 *iv_return = GD_WEIGHTED4; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'G': if (memEQ(name, "GD_CMP_IMAGE", 12)) { /* ^ */ #ifdef GD_CMP_IMAGE *iv_return = GD_CMP_IMAGE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'I': if (memEQ(name, "GD_QUADRATIC", 12)) { /* ^ */ #ifdef GD_QUADRATIC *iv_return = GD_QUADRATIC; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'O': if (memEQ(name, "GD_CMP_COLOR", 12)) { /* ^ */ #ifdef GD_CMP_COLOR *iv_return = GD_CMP_COLOR; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'T': if (memEQ(name, "GD_FLIP_BOTH", 12)) { /* ^ */ #ifdef GD_FLIP_BOTH *iv_return = GD_FLIP_BOTH; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_13 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_CATMULLROM GD_CMP_SIZE_X GD_CMP_SIZE_Y GD_RESOLUTION gdAlphaOpaque gdAntiAliased gdTransparent */ /* Offset 12 gives the best switch position. */ switch (name[12]) { case 'M': if (memEQ(name, "GD_CATMULLRO", 12)) { /* M */ #ifdef GD_CATMULLROM *iv_return = GD_CATMULLROM; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'N': if (memEQ(name, "GD_RESOLUTIO", 12)) { /* N */ #ifdef GD_RESOLUTION *iv_return = GD_RESOLUTION; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'X': if (memEQ(name, "GD_CMP_SIZE_", 12)) { /* X */ #ifdef GD_CMP_SIZE_X *iv_return = GD_CMP_SIZE_X; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'Y': if (memEQ(name, "GD_CMP_SIZE_", 12)) { /* Y */ #ifdef GD_CMP_SIZE_Y *iv_return = GD_CMP_SIZE_Y; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'd': if (memEQ(name, "gdAntiAliase", 12)) { /* d */ #ifdef gdAntiAliased *iv_return = gdAntiAliased; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'e': if (memEQ(name, "gdAlphaOpaqu", 12)) { /* e */ #ifdef gdAlphaOpaque *iv_return = gdAlphaOpaque; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 't': if (memEQ(name, "gdTransparen", 12)) { /* t */ #ifdef gdTransparent *iv_return = gdTransparent; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_15 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_AFFINE_SCALE GD_METHOD_COUNT gdEffectOverlay gdEffectReplace gdStyledBrushed */ /* Offset 8 gives the best switch position. */ switch (name[8]) { case 'B': if (memEQ(name, "gdStyledBrushed", 15)) { /* ^ */ #ifdef gdStyledBrushed *iv_return = gdStyledBrushed; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'D': if (memEQ(name, "GD_METHOD_COUNT", 15)) { /* ^ */ #ifdef GD_METHOD_COUNT *iv_return = GD_METHOD_COUNT; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'E': if (memEQ(name, "GD_AFFINE_SCALE", 15)) { /* ^ */ #ifdef GD_AFFINE_SCALE *iv_return = GD_AFFINE_SCALE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'O': if (memEQ(name, "gdEffectOverlay", 15)) { /* ^ */ #ifdef gdEffectOverlay *iv_return = gdEffectOverlay; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'R': if (memEQ(name, "gdEffectReplace", 15)) { /* ^ */ #ifdef gdEffectReplace *iv_return = gdEffectReplace; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_16 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_AFFINE_ROTATE GD_BICUBIC_FIXED GD_CMP_INTERLACE GD_CMP_TRUECOLOR GD_FLIP_VERTICAL GD_MAJOR_VERSION GD_MINOR_VERSION gdEffectMultiply */ /* Offset 8 gives the best switch position. */ switch (name[8]) { case 'E': if (memEQ(name, "GD_AFFINE_ROTATE", 16)) { /* ^ */ #ifdef GD_AFFINE_ROTATE *iv_return = GD_AFFINE_ROTATE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'I': if (memEQ(name, "GD_BICUBIC_FIXED", 16)) { /* ^ */ #ifdef GD_BICUBIC_FIXED *iv_return = GD_BICUBIC_FIXED; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'M': if (memEQ(name, "gdEffectMultiply", 16)) { /* ^ */ #ifdef gdEffectMultiply *iv_return = gdEffectMultiply; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'N': if (memEQ(name, "GD_CMP_INTERLACE", 16)) { /* ^ */ #ifdef GD_CMP_INTERLACE *iv_return = GD_CMP_INTERLACE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'R': if (memEQ(name, "GD_CMP_TRUECOLOR", 16)) { /* ^ */ #ifdef GD_CMP_TRUECOLOR *iv_return = GD_CMP_TRUECOLOR; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'V': if (memEQ(name, "GD_FLIP_VERTICAL", 16)) { /* ^ */ #ifdef GD_FLIP_VERTICAL *iv_return = GD_FLIP_VERTICAL; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case '_': if (memEQ(name, "GD_MAJOR_VERSION", 16)) { /* ^ */ #ifdef GD_MAJOR_VERSION *iv_return = GD_MAJOR_VERSION; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } if (memEQ(name, "GD_MINOR_VERSION", 16)) { /* ^ */ #ifdef GD_MINOR_VERSION *iv_return = GD_MINOR_VERSION; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_17 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_BILINEAR_FIXED GD_CMP_BACKGROUND GD_CMP_NUM_COLORS */ /* Offset 13 gives the best switch position. */ switch (name[13]) { case 'I': if (memEQ(name, "GD_BILINEAR_FIXED", 17)) { /* ^ */ #ifdef GD_BILINEAR_FIXED *iv_return = GD_BILINEAR_FIXED; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'L': if (memEQ(name, "GD_CMP_NUM_COLORS", 17)) { /* ^ */ #ifdef GD_CMP_NUM_COLORS *iv_return = GD_CMP_NUM_COLORS; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'O': if (memEQ(name, "GD_CMP_BACKGROUND", 17)) { /* ^ */ #ifdef GD_CMP_BACKGROUND *iv_return = GD_CMP_BACKGROUND; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_18 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_CMP_TRANSPARENT GD_RELEASE_VERSION gdAlphaTransparent gdEffectAlphaBlend */ /* Offset 5 gives the best switch position. */ switch (name[5]) { case 'L': if (memEQ(name, "GD_RELEASE_VERSION", 18)) { /* ^ */ #ifdef GD_RELEASE_VERSION *iv_return = GD_RELEASE_VERSION; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'P': if (memEQ(name, "GD_CMP_TRANSPARENT", 18)) { /* ^ */ #ifdef GD_CMP_TRANSPARENT *iv_return = GD_CMP_TRANSPARENT; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'e': if (memEQ(name, "gdEffectAlphaBlend", 18)) { /* ^ */ #ifdef gdEffectAlphaBlend *iv_return = gdEffectAlphaBlend; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'h': if (memEQ(name, "gdAlphaTransparent", 18)) { /* ^ */ #ifdef gdAlphaTransparent *iv_return = gdAlphaTransparent; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant_19 (pTHX_ const char *name, IV *iv_return) { /* When generated this function returned values for the list of names given here. However, subsequent manual editing may have added or removed some. GD_AFFINE_TRANSLATE GD_FLIP_HORINZONTAL GD_PIXELATE_AVERAGE */ /* Offset 4 gives the best switch position. */ switch (name[4]) { case 'F': if (memEQ(name, "GD_AFFINE_TRANSLATE", 19)) { /* ^ */ #ifdef GD_AFFINE_TRANSLATE *iv_return = GD_AFFINE_TRANSLATE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'I': if (memEQ(name, "GD_PIXELATE_AVERAGE", 19)) { /* ^ */ #ifdef GD_PIXELATE_AVERAGE *iv_return = GD_PIXELATE_AVERAGE; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'L': if (memEQ(name, "GD_FLIP_HORINZONTAL", 19)) { /* ^ */ #ifdef GD_FLIP_HORINZONTAL *iv_return = GD_FLIP_HORINZONTAL; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } static int constant (pTHX_ const char *name, STRLEN len, IV *iv_return) { /* Initially switch on the length of the name. */ /* When generated this function returned values for the list of names given in this section of perl code. Rather than manually editing these functions to add or remove constants, which would result in this comment and section of code becoming inaccurate, we recommend that you edit this section of code, and use it to regenerate a new set of constant functions which you then use to replace the originals. Regenerate these constant functions by feeding this entire source file to perl -x #!/usr/local/bin/perl5.24.1d-nt -w use ExtUtils::Constant qw (constant_types C_constant XS_constant); my $types = {map {($_, 1)} qw(IV)}; my @names = (qw(GD_AFFINE_ROTATE GD_AFFINE_SCALE GD_AFFINE_SHEAR_HORIZONTAL GD_AFFINE_SHEAR_VERTICAL GD_AFFINE_TRANSLATE GD_BELL GD_BESSEL GD_BICUBIC GD_BICUBIC_FIXED GD_BILINEAR_FIXED GD_BLACKMAN GD_BOX GD_BSPLINE GD_CATMULLROM GD_CMP_BACKGROUND GD_CMP_COLOR GD_CMP_IMAGE GD_CMP_INTERLACE GD_CMP_NUM_COLORS GD_CMP_SIZE_X GD_CMP_SIZE_Y GD_CMP_TRANSPARENT GD_CMP_TRUECOLOR GD_DEFAULT GD_FLIP_BOTH GD_FLIP_HORINZONTAL GD_FLIP_VERTICAL GD_GAUSSIAN GD_GENERALIZED_CUBIC GD_HAMMING GD_HANNING GD_HERMITE GD_LINEAR GD_MAJOR_VERSION GD_METHOD_COUNT GD_MINOR_VERSION GD_MITCHELL GD_NEAREST_NEIGHBOUR GD_PIXELATE_AVERAGE GD_PIXELATE_UPPERLEFT GD_POWER GD_QUADRATIC GD_RELEASE_VERSION GD_RESOLUTION GD_SINC GD_TRIANGLE GD_WEIGHTED4 gdAlphaMax gdAlphaOpaque gdAlphaTransparent gdAntiAliased gdArc gdBlueMax gdBrushed gdChord gdDashSize gdEdged gdEffectAlphaBlend gdEffectMultiply gdEffectNormal gdEffectOverlay gdEffectReplace gdGreenMax gdMaxColors gdNoFill gdPie gdRedMax gdStyled gdStyledBrushed gdTiled gdTransparent)); print constant_types(), "\n"; # macro defs foreach (C_constant ("GD", 'constant', 'IV', $types, undef, 3, @names) ) { print $_, "\n"; # C constant subs } print "\n#### XS Section:\n"; print XS_constant ("GD", $types); __END__ */ switch (len) { case 5: /* Names all of length 5. */ /* gdArc gdPie */ /* Offset 4 gives the best switch position. */ switch (name[4]) { case 'c': if (memEQ(name, "gdAr", 4)) { /* c */ #ifdef gdArc *iv_return = gdArc; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'e': if (memEQ(name, "gdPi", 4)) { /* e */ #ifdef gdPie *iv_return = gdPie; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } break; case 6: if (memEQ(name, "GD_BOX", 6)) { #ifdef GD_BOX *iv_return = GD_BOX; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 7: return constant_7 (aTHX_ name, iv_return); break; case 8: return constant_8 (aTHX_ name, iv_return); break; case 9: return constant_9 (aTHX_ name, iv_return); break; case 10: return constant_10 (aTHX_ name, iv_return); break; case 11: return constant_11 (aTHX_ name, iv_return); break; case 12: return constant_12 (aTHX_ name, iv_return); break; case 13: return constant_13 (aTHX_ name, iv_return); break; case 14: if (memEQ(name, "gdEffectNormal", 14)) { #ifdef gdEffectNormal *iv_return = gdEffectNormal; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 15: return constant_15 (aTHX_ name, iv_return); break; case 16: return constant_16 (aTHX_ name, iv_return); break; case 17: return constant_17 (aTHX_ name, iv_return); break; case 18: return constant_18 (aTHX_ name, iv_return); break; case 19: return constant_19 (aTHX_ name, iv_return); break; case 20: /* Names all of length 20. */ /* GD_GENERALIZED_CUBIC GD_NEAREST_NEIGHBOUR */ /* Offset 13 gives the best switch position. */ switch (name[13]) { case 'D': if (memEQ(name, "GD_GENERALIZED_CUBIC", 20)) { /* ^ */ #ifdef GD_GENERALIZED_CUBIC *iv_return = GD_GENERALIZED_CUBIC; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 'I': if (memEQ(name, "GD_NEAREST_NEIGHBOUR", 20)) { /* ^ */ #ifdef GD_NEAREST_NEIGHBOUR *iv_return = GD_NEAREST_NEIGHBOUR; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } break; case 21: if (memEQ(name, "GD_PIXELATE_UPPERLEFT", 21)) { #ifdef GD_PIXELATE_UPPERLEFT *iv_return = GD_PIXELATE_UPPERLEFT; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 24: if (memEQ(name, "GD_AFFINE_SHEAR_VERTICAL", 24)) { #ifdef GD_AFFINE_SHEAR_VERTICAL *iv_return = GD_AFFINE_SHEAR_VERTICAL; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; case 26: if (memEQ(name, "GD_AFFINE_SHEAR_HORIZONTAL", 26)) { #ifdef GD_AFFINE_SHEAR_HORIZONTAL *iv_return = GD_AFFINE_SHEAR_HORIZONTAL; return PERL_constant_ISIV; #else return PERL_constant_NOTDEF; #endif } break; } return PERL_constant_NOTFOUND; } GD-2.66/const-xs.inc0000644000076500001200000000512613077100745013360 0ustar rurbanadminvoid constant(sv) PREINIT: #ifdef dXSTARG dXSTARG; /* Faster if we have it. */ #else dTARGET; #endif STRLEN len; int type; IV iv = 0; /* NV nv; Uncomment this if you need to return NVs */ /* const char *pv; Uncomment this if you need to return PVs */ INPUT: SV * sv; const char * s = SvPV(sv, len); PPCODE: /* Change this to constant(aTHX_ s, len, &iv, &nv); if you need to return both NVs and IVs */ type = constant(aTHX_ s, len, &iv); /* Return 1 or 2 items. First is error message, or undef if no error. Second, if present, is found value */ switch (type) { case PERL_constant_NOTFOUND: sv = sv_2mortal(newSVpvf("%s is not a valid GD macro", s)); PUSHs(sv); break; case PERL_constant_NOTDEF: sv = sv_2mortal(newSVpvf( "Your vendor has not defined GD macro %s, used", s)); PUSHs(sv); break; case PERL_constant_ISIV: EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHi(iv); break; /* Uncomment this if you need to return NOs case PERL_constant_ISNO: EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHs(&PL_sv_no); break; */ /* Uncomment this if you need to return NVs case PERL_constant_ISNV: EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHn(nv); break; */ /* Uncomment this if you need to return PVs case PERL_constant_ISPV: EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHp(pv, strlen(pv)); break; */ /* Uncomment this if you need to return PVNs case PERL_constant_ISPVN: EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHp(pv, iv); break; */ /* Uncomment this if you need to return SVs case PERL_constant_ISSV: EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHs(sv); break; */ /* Uncomment this if you need to return UNDEFs case PERL_constant_ISUNDEF: break; */ /* Uncomment this if you need to return UVs case PERL_constant_ISUV: EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHu((UV)iv); break; */ /* Uncomment this if you need to return YESs case PERL_constant_ISYES: EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHs(&PL_sv_yes); break; */ default: sv = sv_2mortal(newSVpvf( "Unexpected return type %d while processing GD macro %s, used", type, s)); PUSHs(sv); } GD-2.66/demos/0000755000076500001200000000000013077123433012211 5ustar rurbanadminGD-2.66/demos/brushes.pl0000755000076500001200000000164113075665212014232 0ustar rurbanadmin#!/usr/local/bin/perl use GD; $im = new GD::Image(300,300); # allocate white $white = $im->colorAllocate(255, 255, 255); # allocate black $black = $im->colorAllocate(0, 0, 0); # allocate red $red = $im->colorAllocate(255, 0, 0); # allocate green $green = $im->colorAllocate(0,255,0); # allocate yellow $yellow = $im->colorAllocate(255,250,205); # Get an image from a png file open (TILE,"./tile.png") || die; $tile = newFromPng GD::Image(TILE); close TILE; # use it as a paintbrush $im->setBrush($tile); $im->arc(100,100,100,150,0,360,gdBrushed); # use it as a tiling pattern to fill a rectangle $im->setTile($tile); $im->filledRectangle(150,150,250,250,gdTiled); $im->rectangle(150,150,250,250,$black); # Draw a dotted line $im->setStyle($green,$green,$green,gdTransparent,$red,$red,$red,gdTransparent); $im->line(0,280,300,280,gdStyled); binmode STDOUT; # print the image to stdout print $im->png; GD-2.66/demos/copies.pl0000755000076500001200000000211113075665212014032 0ustar rurbanadmin#!/usr/local/bin/perl use GD; $im = new GD::Image(300,300); $white = $im->colorAllocate(255, 255, 255); $black = $im->colorAllocate(0, 0, 0); $red = $im->colorAllocate(255, 0, 0); $blue = $im->colorAllocate(0,0,255); $yellow = $im->colorAllocate(255,250,205); # Create a flat wide rectangle paintbrush $brush = new GD::Image(10,10); $brush->colorAllocate(255,255,255); # white $brush->colorAllocate(0,0,0); # black $brush->transparent($white); # white is transparent $brush->filledRectangle(0,0,5,2,$black); # a black rectangle $im->setBrush($brush); $im->arc(100,100,100,150,0,360,gdBrushed); $poly = new GD::Polygon; $poly->addPt(30,30); $poly->addPt(100,10); $poly->addPt(190,290); $poly->addPt(30,290); $im->polygon($poly,gdBrushed); $im->fill(132,62,$blue); $im->fill(100,70,$red); $im->fill(40,40,$yellow); $im->interlaced(1); # Copy the 20,20,70,70 region # to a location at 150,150 $im->copy($im,150,150,20,20,50,50); # Same thing, but doubling the size $im->copyResized($im,10,200,20,20,100,100,50,50); binmode STDOUT; # print the image to stdout print $im->png; GD-2.66/demos/draw_colors.pl0000755000076500001200000000166013076515043015073 0ustar rurbanadmin#!/usr/bin/perl -w use strict; use lib '.','./blib/lib','./blib/arch'; use GD::Simple; my @color_names = GD::Simple->color_names; my $cols = int(sqrt(@color_names)); my $rows = int(@color_names/$cols)+1; my $cell_width = 100; my $cell_height = 50; my $legend_height = 16; my $width = $cols * $cell_width; my $height = $rows * $cell_height; my $img = GD::Simple->new($width,$height); $img->font(gdSmallFont); for (my $c=0; $c<$cols; $c++) { for (my $r=0; $r<$rows; $r++) { my $color = $color_names[$c*$rows + $r] or next; my @topleft = ($c*$cell_width,$r*$cell_height); my @botright = ($topleft[0]+$cell_width,$topleft[1]+$cell_height-$legend_height); $img->bgcolor($color); $img->fgcolor($color); $img->rectangle(@topleft,@botright); $img->moveTo($topleft[0]+2,$botright[1]+$legend_height-2); $img->fgcolor('black'); $img->string($color); } } print eval {$img->png} || $img->gif; GD-2.66/demos/fills.pl0000755000076500001200000000112413075665212013664 0ustar rurbanadmin#!/usr/local/bin/perl use GD; $im = new GD::Image(100,50); # allocate black -- this will be our background $black = $im->colorAllocate(0, 0, 0); # allocate white $white = $im->colorAllocate(255, 255, 255); # allocate red $red = $im->colorAllocate(255, 0, 0); # allocate blue $blue = $im->colorAllocate(0,0,255); #Inscribe an ellipse in the image $im->arc(50, 25, 98, 48, 0, 360, $white); # Flood-fill the ellipse. Fill color is red, and will replace the # black interior of the ellipse $im->fill(50, 21, $red); binmode STDOUT; # print the image to stdout print $im->png; GD-2.66/demos/font_list.png0000644000076500001200000005307613075665212014737 0ustar rurbanadminPNG  IHDR XhXCPLTE???___///"c IDATxے0&& Ur'/%par/+L$aC$ē'=IOzғ'=Qo]*QmeVixkV"&M7-QVב m8Cd͏Q C_Ut6jo<*/onZw=o;qڀ*y_^*">H}˛#Om/8 zm hio}"ڰ_v].R/̪থ;^Z<`S羬Kțx5'2 ZCiy! QTY\}VQ^bF+ <ľ&v& H_|.+zw9%xnĔ+*'2 ĕWhmG㲬FvhU݌phDnpUd^cs|/?] @"R^l9AB`ӎz`TXy } `ƵpR=  {;d@ly;s ϶)> h-rH]"bYӽp :Y%7$QwWg{T1&Y?ߧ=1LCl`ȀoyS-u!(J$@tu;gޑtjQ6D?=Ɖ juTEb38n3Ul* YZx~~mzS_<񐫿(#KVޅ*ϒL:z)x I'&BI >: _UAHވ ؎HzwzwE! c} nE)ªh'c"i&mA{"aqUsi!0(c O3a2r6h?DwuTWu PQXySj^yU i1mpwgԇml0v,=64ĐyP2;+'bG_ꭼ{aG9 u|.ͯ*&$6J×:~_J{bO͓H'fOzғ;L;# DMrV^No)b:E#[*`h0 ‘o}.fY|Чh`HS@Zh`T\MG[ fkjGi~U|)]o̮|*sձEQs{*Ϲ^5Kix-fMEHbES1-JkL65݁z:Vv_΀$~J$F!;iQ%G :fgD`xm'f`(F.*pUOܣ'@~4iX 5?֯?(`DM1, ۋ>j"}*cse MS6M`H`q uwiX'laMuQ_JHC"f~Ofwi~$oVmH_&5A7)}j/wHct%RR ,4|hFd?M:4ñ6Ĥa:Pr(tt0lpCþ~h{.BoZRG4AMnq7Xoq^&t˪/B@o*r6G&~Eҗ4i}))XtRk Kѷmۗ0T޷jt#'tEdŸ @،~G=iT9vwGHj(xb,q)+1.6TS4=zrhM8VwBd! xEAh'9v gl+KҀ?p4fW^pR.C[aۄI[j{]32*^P}; ğ‰e @jwӾݵ_,=(`wR:jX#ԫu]H¬l+ sh+R=,6Ni-,xlLo: ^|ۊg,Ċz!P3/>`xBAdc8ƓN˃1u>ݥ^.#ƴv:/Y6Btŷt\w?ٕp tLxJvi.Eyr6(b&&!*;vV7LNBwt7^wB~wB\?WGh3"fz/aUE҅Nۃ]W =7P'Am(;+G|#&)ۥ]1/~&0ɾFRc)$Uɺ5!% tk9hƔV٩yHTECN"!䢟l*.零mjW0)JLa؅94g/ Y$fL:T~T{]CUmv_5 dw^t&x.cRk!\*h۴ ]i0J5 QK#_;'kZz\(1.^#$TXŢ+Fd"xVjpکDhߖ(A1;k7;G?.S(O k*U>K vW R26 ^"e-Jck%`tOPy Jw>TQcT Fn:hJQTMyD-zB :C9U[&6mP^~_=?^ߟ*f>y)9t?£.(rpb:?|"-ݡԇ7)qik:yûW~G;:&(JȅH#XCj,㜍 z-'/ OCm O}H׻$){AoH9Swk˦uΗ>wl;nj)dQ2@viȪln _MuF¬o&fɡlS#ocmPBIM}rm3 csSfBۨgō55)_!4ea3\%N,%]Ssj(ssdu!.3j\p/oz-5n)m08.ηCc奸k)“HN NJmM{]am)(u9n 6u`vz\ho&3r4NfgAuL01s@FÛc?[y`._wSםOqna#Avd-jx[st)S& XnͰȜo=uG%)9>ZQľIW;l#fC+\4V"[ d18`Pį'^&gIXtR;q8lxMG iu kS*WwjuRTQFsMXnI0Rm;,v7í씓NNѠעB9rv .&e¥r"7ewW@8_J~ӌko9.iwe;ECށ`7ۯwWͦo~39 Ci=.E #=pQ1wqzMNrU}kӒ !i%YiWVL^U%''RFD4 eyWTi74~:~dĊ#I(yD㎪1 cC3ɸ'qn@"aK1$b6tQ(n,{ "IlǶ]ctq? 2q˥+OGZ]H'/H_"_Bsjy YR/"dx21;Q 0+^ꣃ>潘Qw(E2YY$ }!Tf:NBm.Jس6{CK@S>S}L6!gnEo5cp(u-?`9wO@Mʥxr$`K\EPṚUW|qȒ {F@E4yYe2 za\BNu<-<lnz"9z 5Nnm/5OoTAc#DU'd=DH7I! ~* ϤZ/z=@ @R;{ǹ,R5#C! 2DȄm"5my /xȸ6+i~!mmGrI~1CΪ8s^m@@sEYsy *i/v>$@:1W;V{ #5`28ooEU6es:eÉ,]Ӱ9F)2jc(ƥȉ%YT˪G/i驫)GsoĿHiUW}# ! qa=JJ,1|oR9D&=Vze:q̑gnD2:5rhry_ɱcڮJy>DGMpmbo=)vL¯d)bOv.rc)E!w$']\*M2 Y6BN X*w)55)a2Duo[<YΘA``ΎB4ۭ $3<1밸m>*f9 dwz qN5o .vi#a.#l|Y_L&E,b\R'j(dT6"GEC;qDiXʀ\1 E5%Pm\+6ChxdbMZffq֢քZ]< $UѿZl ȫL @aAp7\Kʀ8pXlŢ \C[ [F*ÚJ5zV)Gsw* +6F cTWErYQ Q|n5A3U %F2eyYUJ;Ak$y\BIlk>7' L:>k 'K@.COo9NgQSN9畤SKi7ڷwy;tg. T4<ˬm[ f!ho@&: ˓-Fxҫ J1i{mQ o)}y|cKVVkh8S03 cRrEyWeary5(@/ 2e ޵yȯ 0uM8Δba|n$5_B uD9 FR-i|Hsě3@tҐ5+Wev:<.nO72r 5)Mbg@BaȪ X\w |t|?a4q V {Cu;Pr+x@E3AvoK@8 JgHaP&k<_>lm9WYm>~ q@DD9HΌ0wci T2Bzc^ `Ŀh 5zH*lhIy WM, aהE0C?#ijŌVlur}\C RZKa#jnGCSݙc-ua*GxF~u# ڍ{M/z܂{YLVفI`hu0[D> f!a=KIKViz):ORV *' "!# :8Dm{Cߴ y<lPeLK, '-ɢ4yhpP;b&Mtf =䄅?!3DE+=rd9 MK ++dy3B| $e"&KRM8rn߾ >&@t`5u QH,,gVdlNcD$wokHjU,o_3$tzvDG+0+HO< ^Cjso\-y}r; 區)5#ʀ$\ͦW$ue `DsX/9-O藀z-@vFUtPE[K#-@T)ڊW7:Iy!? o/{~(EHy:(C"uڒ_u^ZV>)[Ħ!*P,I5#iyl՛BjCl,Zz-OFЅoG)*1XtRsXވ<^mL<{p 4@ mH:"!fa*Nv1(tj~ Vs1(6_f2 u_Q X`['QPDdHdڀ;nVڸy.Y}GHNezfk5.Ƞ E X\rFr:BgҰʙuɗoh,`ua ȉʑ>o֓27 Hwt J#pCI=KY&R 6k Cfo _dd`T(GX= grxk_ד'Fi<ò[?Wp}^ @VPE*诐w7XiyrkZw#Nͼv!)罚7_N(8 $S(.t;xJ 릩k*K5\m1=޾ԗ\8wLv³^*-̙^cM |^F7$&)L +474$_@ K@]F?HPW=@I\;e:Q7{*yQC,pM@R01:]ڂkڢEWTQ鬼i;ZD!+]ҍ؊ZP{eURFN'ț*LʂWl+#)K"noQ֤,Cbrg@]'}FTl@^aIb ChM2|j'bzᇛ\.QypZ^6נ^9Fep"##ދBiG,^xH2D:Lq f?H,ͧu%P"V\, I U<;>R˵U7 0f{d=ZfXBDϛ&?%DAȼ&eYHKH>Lug PGJ.  ֓i7RC7Fƣ%y(e@-FUY?F +,4 Z9 jʩn63@v7]w';(G9Y &dzP;p **\m21.V"_d4֖PHΫ.Z 45{xq R,t܍+HU4˻ Ȋ29xǮN;đ&ZIrݑ@c˪lEgj9[8OWwY)Γ^W9NZ<{*ih8٦ymm[Iv Y^"/ җJc qDt!^l_^Vx#0k#fC. L13$ߜ0rQ}  Hgd|:+M# &tz䊯I]K׷]@9wc4 V43z+w*vDmT9 CT2ʩP4\Qt^^EEb!ᅹmN=R'r6hCF7Y,Hp_s)K0 ,eW$JTJ8Jr#BV2Cۆ}l49){?[ ?u861 @_\д Va] ,gWG:)7-ͳшK[rgU@h#fpK,mAUz}~A 7iZOKaty )K 0`[ʼn݉''mÝ/3)DQf#S{3Ey. *d/6n#T؁ڞC;\" &7Xp\a%ϱD 3Ȃw ysjE͟aMe]QbvЈY␕D $/gK>k-؍~z#`ъ)1Oښm^΀,(l=É+M{|!bC=Dp_= WnowQ6r&Up@<$MN\]KNY!`uDf) 1Du/z״@E홓_0A$ <ĭ .6qqUSt ۙ%MMd@&>yғ~\e\?/ ~=͖i T \ַl P(t'C ׹YBM@],R#}Ǎh 89[@Tb u N̆`h6;9 DRzMf@ts޳> y8,յbWDwh)!HR%Kx5#XBԂV=8z.p]]UX]rrͱϷ Hƨ.Kwf 9&$.4 W{:]+wS`"*ٌ9p.Y8oü@A }?e3s@`Iw] @M<`7wJ-ĒsщNV%)[x.8 G-@¼agvcXP SCkY"~#dtrrj)&UjWKע>!b>yC0Wf% <^n&j!mrx/kk\SgGB-6tTe|G"U xoFfH1L0)ڀ]QZ;X:i^&AgMX ?j}͉mz<;x'Kٳ2\0{ 3 gE@\Ig%jcHn% @L3]" rZI.i~:3̳! \$V8j+@w'T:!g w`tGB$KXcP qE@UjX/9 H<Q_UGN(gHdNY9I:/ShJho\Si7 TYF%iWtɆ<7FfB$gV&Q3 -;gsɜ>{aj_B]W¨<zdMF|@C0NI!~B 76Mcu҇}ܔLdC!GoUSJ& *ɌaTC2f L6$cV'@~g>##Tr`_28ɡ[!3WNO[N&5`"mIOb'UBK(7;OF.~`ťw߹l}Ҍ?e I6H#Zd&T}{PuI%0́{?VoVb!irRZ1Ȕ\Xa*8V>I^ڼ|k<dR9v  .%@RuVqD7&i#]Th? @$<*6H&J!'@tMżlFճP~# T)z~[,BY!%V[_3k)df=PDQ!ʰIَ'mBKg+J.هjXח*B@P\9|i6K@0oyNF}D7E_o9pvSJ)5 i#B1$,6,,p .i Ȋl'NWē[cgs#5B aϐAKex_HM#-)hRl|qWTT%GBhH"یP]i~e@=Dc\- W8Ц55a=1 "׻G_o{, ѷ҆Hy#R̴D{T)>Y||\Ѳ xt 艎3ɕr(X!tMŹm\C|/C}g q#1`ϥzS'ߥw9}D̻8w~,pw҆ 0Q_4%l+j|Ճ׊6'@-;,'*jۢ;.n䬪ݢYe]xYl l虧^%{omx}ۿAIњm2D(K Jo{D44iҢJ*>hYf4H0V;[@-/蕖ǿp2|hAFbN!@dmzm ]͆J!-s' ib 4dvZ|*)ٿI=$6 uVbt~b/L7r 1F99jG?d^2Ma  fsLqqأf#' ENwR; 8`K3_g,?GJ` 柣D}DT{ӊ#[' W|о^RkQ!VO!}г :Sg/Gnfw|btbKU 5gRֲ=窴 w< 0fVf ;@b\ʃ?wpO<0 rI һUv3gM["Osd˜o'} d8Á f w%@soR>>Y+Nc,2K@C {p<&@spQ֋IFtF.S>%f\s@g/E(i^3"D\x YrB"^21%bqa%ݳOL]pD<#1]]ܢ4# -ʍ,uc$<3oeOp^wB#ۡag1oǘ<}}U} <"d s u h3@ЙT mĉ0͞Jxޤ G.L;9\zCx(rꀜ/UϢ/jh#n F [2-~uRvRlQܬ,b-hJ)%cJd$=:q ͏ Ga$>g$B[=$.d{$aa\@i[2 h3tXyƉdIQ-t!b<ĉ:Z/yƉ+IIYI뛥'=ZRɳrΛf*Η|OIv${$HwtYhX_ݓKeU} 4o]Fe5<G)EB|M/X"jEv.wߤqKGrGH3Z0NZ"^Tπ`'mk;-I7e9W-8_?q!^{!y~e.HNGm_V'@$ m;p U4#ͻ<*˟l9ӇV >J|o#Ī*v会L5 ?׀p> a|'_%BINCV1uB]p,C:v3/:Avdwȳ% ɸF@t-Ѓ!]!$sIȃdLYe b<"E\H2Eaǔ'BcY JVfNNHC~ Ph봝v՗TsF} IGNYi挘𙵑M+e|[μ=W佥Hl|9cy5zC<.Nڔo>t1/F^| Ãb萘 !"j1M@ .' ɰnf_5yD QUl :L7mw!\"@I+sQ;H c&^IO׾']a']O@4^[j$xh R}*uvnm}rrҞPɧfW&#NJjg؄h]?m.\,OD 3vlH֩iqI$iڤwg7Ӧ%ώ/\k\J #6/i}F!|Q)8\zVIPhUy:k H[j]Aq_(:t SsWĦ&XM^>¢ b?bÐ 8,hN2!Tc~'7ѦRjJ\B㸃;1L;N&)X l]N \]YS'/Q1 㔰4AD5ЫfG=TGh(ܳkeRC.ro"D!*=¯-KiJmOeA,6! 3wH6HnY@A!0@+E48kTQhB-g\oܓGTz҇^?H'=IOA &q9] xƀXuҝHw:p9.s @HGs d9^gcC ^٤!R^/dp3Utm@n6T䰑t^="]F-\ьHz7e[,q0oոbywT)*|> R{h;vDk:ݩ]KW1_ͭ&mX-EyȿJ.݉{:Υs@8QOŻFݮorLH"|{RS) R&*X@N}M?-!SViG{}7B2> bj [ -iC~Ysуe#h`ͮN]DqP]# _»0Mi|l om+F*B!8:v2 Y Eoqg?x$KU|z:8j`;Ht`^Co ZFS?4cTvaރ(\2Q+1Nl?834rS NY'0 XكQ4Է`׌}3{*A"7AH{u\>7b*FO%_#8Y'OlX!ȹ7wyfP!NRlT]$ᏓyOWT6іYqiSĝfmKq8+;8 1jOMls_[2zڈ!"huxV]CyH*m}$ngb٪X6ĜH{i#k3zJOh@1FR(Jv2Ytti3| !k5Ij -i676gj[rPro[O:7g%JMO$᎛T`DjP5<+(n=0?Mbo=JĈ\B`1AZ]z Nv/퟈KyZrYdg@!S Y! Yrg' Pʎ)!hۍO@eMIENDB`GD-2.66/demos/fonttest0000755000076500001200000000165013075665262014020 0ustar rurbanadmin#!/usr/bin/perl -w use lib './blib/arch','./blib/lib'; use strict; use GD; use subs qw( charmap ); my $teststring = pack 'C*', 32, 1 .. 255; my $im = new GD::Image(640, 500); my ($white, $black) = ( $im->colorAllocate(255, 255, 255), $im->colorAllocate(0, 0, 0), ); # $im->transparent($white); $im->interlaced(1); charmap($im, gdGiantFont, "GiantFont 9x15", 20, 16); charmap($im, gdLargeFont, "LargeFont 8x16", 120, 16); charmap($im, gdMediumBoldFont, "gdMediumBoldFont 7x13b", 220, 13); charmap($im, gdSmallFont, "gdSmallFont 6x13", 320, 13); charmap($im, gdTinyFont, "gdTinyFont 5x8", 420, 8); binmode(STDOUT); print $im->png; sub charmap { my $im = shift; my ($font, $title, $topoffset, $lineskip) = @_; $im->string($font, 16, $topoffset, $title.':', $black); my $line; for $line (0 .. 4) { $im->string($font, 16, $topoffset + (1 + $line) * $lineskip, substr($teststring, $line * 64, 64), $black); } } GD-2.66/demos/gd_example.cgi0000755000076500001200000000126113075665212015011 0ustar rurbanadmin#!/usr/local/bin/perl use GD; print "Content-type: image/png\n\n"; # create a new image $im = new GD::Image(100,100); # allocate some colors $white = $im->colorAllocate(255,255,255); $black = $im->colorAllocate(0,0,0); $red = $im->colorAllocate(255,0,0); $blue = $im->colorAllocate(0,0,255); # make the background transparent and interlaced $im->transparent($white); $im->interlaced('true'); # Put a black frame around the picture $im->rectangle(0,0,99,99,$black); # Draw a blue oval $im->arc(50,50,95,75,0,360,$blue); # And fill it with red $im->fill(50,50,$red); binmode STDOUT; # Convert the image to PNG and print it on standard output print $im->png; GD-2.66/demos/polyline.pl0000644000076500001200000002122013075665245014410 0ustar rurbanadmin############################################################################ # # Sample code for use of Polyline.pm # # Author: Dan Harasty # Email: harasty@cpan.org # Version: 0.1 # Date: 7/20/2002 # # use GD; use GD::Polyline; $PI = 3.14159; $TWO_PI = 2 * $PI; sub r2d {$_[0] * 180 / $PI}; $splinekey = "
  • Green: original polygon or polyline
  • Blue: control points added with addControlPoints()
  • Black: spline generated by toSpline()
"; if (1) { use GD; use GD::Polyline; # create an image $image = new GD::Image (500,300); $white = $image->colorAllocate(255,255,255); $black = $image->colorAllocate( 0, 0, 0); $red = $image->colorAllocate(255, 0, 0); # create a new polyline $polyline = new GD::Polyline; # add some points $polyline->addPt( 0, 0); $polyline->addPt( 0,100); $polyline->addPt( 50,125); $polyline->addPt(100, 0); # polylines can use polygon methods (and vice versa) $polyline->offset(200,100); # rotate 60 degrees, about the centroid $polyline->rotate(3.14159/3, $polyline->centroid()); # scale about the centroid $polyline->scale(1.5, 2, $polyline->centroid()); # draw the polyline $image->polydraw($polyline,$black); # create a spline, which is also a polyine $spline = $polyline->addControlPoints->toSpline; $image->polydraw($spline,$red); # output the png #binmode STDOUT; #print $image->png; SampleImage($image, "polyline-synopsis.png", "Synopsis", "Polyline created by 'SYNOPSIS' section of documentation."); } if (1) { $image = NewImage(); $offset = 50; for $poly (new GD::Polygon, new GD::Polyline) { $table_info = []; $poly->addPt( 0, 0); $poly->addPt( 0,100); $poly->addPt( 50,125); $poly->addPt(100, 0); #print "this " . ref($poly) . " has " . $poly->length() . " points\n"; push @$table_info, ["".ref($poly).""]; push @$table_info, ['vertex number: ', 0..($poly->length()-1)]; @coords = $poly->vertices(); @coords = map {"[".int($_->[0]).",".int($_->[1])."]"} @coords; push @$table_info, ['coordinates (pre-offset): ', @coords]; @lengths = $poly->segLength(); @lengths = map {int($_+0.5)} @lengths; #print "segLengths are : @lengths\n"; #print "perimeter is : " . int($poly->segLength()) . "\n"; push @$table_info, ['segment lengths: ', @lengths]; @angles = $poly->segAngle(); @angles = map {int(r2d($_)+0.5)} @angles; #print "seg angles are : @angles\n"; push @$table_info, ['segment angles: ', @angles]; @angles = $poly->vertexAngle(); @angles = map {defined ($_) ? int(r2d($_)+0.5) : "undef"} @angles; #print "vertex angles are: @angles\n"; push @$table_info, ['vertex angles: ', @angles]; $poly->offset(50 + $offset,80); $offset += 200; # draw the original poly $image->polydraw($poly,$black); #print "\n\n"; push @$summary_table, genHTMLTable($table_info, 0); } SampleImage($image, "polyline-simple.png", "Simple", "GD::Polygon and GD::Polyline with same vertexes.

" . genHTMLTable([$summary_table], 1)); } if (1) { $image = NewImage(); $offset = 50; for $poly (new GD::Polygon, new GD::Polyline) { $poly->addPt( 0, 0); $poly->addPt( 0,100); $poly->addPt( 50,125); $poly->addPt(100, 0); $poly->offset(50 + $offset,80); $offset += 200; # draw the original poly $image->polydraw($poly,$green); # create and draw the control line for the spline $ctrlline = $poly->addControlPoints(); $image->polydraw($ctrlline,$cyan); # create and draw the spline itself $spline = $ctrlline->toSpline(); $image->polydraw($spline,$black); } SampleImage($image, "polyline-spline.png", "Spline", "Splines fit to vertices of polygon and polyline. $splinekey"); } if (1) { $image = NewImage(); $triangle = new GD::Polygon; $triangle->addPt( 0, 0); $triangle->addPt(-19, 95); $triangle->addPt( 19, 95); $triangle->offset(250,50); foreach (1..9) { $image->polydraw($triangle,gdBrushed); $triangle->rotate($TWO_PI / 9, 250, 150); } SampleImage($image, "polyline-star9.png", "Nine Pointed Star", "A triangle, rotated about a point other than the origin.
Demonstration of \$poly->rotate() and \$poly->offset()"); } if (1) { $image = NewImage(); $cloverControl = new GD::Polyline; $cloverControl->addPt(45,45); $cloverControl->addPt(10,10); $cloverControl->addPt(90,10); $cloverControl->addPt(55,45); $cloverControl->addPt(90,10); $cloverControl->addPt(90,90); $cloverControl->addPt(55,55); $cloverControl->addPt(90,90); $cloverControl->addPt(10,90); $cloverControl->addPt(45,55); $cloverControl->addPt(10,90); $cloverControl->addPt(10,10); $cloverControl->addPt(45,45); $clover = $cloverControl->toSpline(); # note that the three following transformations # could have been called on $cloverControl, instead, # followed by the above call $clover->offset($clover->centroid(-1)); $clover->scale(3, 3); $clover->offset(250, 150); $image->filledPolygon($clover,$green); SampleImage($image, "polyline-clover.png", "Clover", "Sample image generated by GD::Polygon"); } if (1) { $image = NewImage(); $polyline = new GD::Polyline; for (0..15) { $polyline->addPt(30 * $_ + 10, rand(90) + 5); } $image->polyline($polyline,$green); $ctrlline = $polyline->addControlPoints(); $ctrlline->offset(0,100); $image->polyline($ctrlline,$cyan); $spline = $ctrlline->toSpline(); $spline->offset(0,100); $image->polyline($spline,$black); SampleImage($image, "polyline-zigzag.png", "Zigzag", "Spline fit to random function. $splinekey"); } if (1) { $image = NewImage(); $ring_network = new GD::Polygon; $num_nodes = 10; $randfactor = 80; for (1..$num_nodes) { $x = 250 + 150 * cos($TWO_PI * $_/$num_nodes); $y = 150 + 100 * sin($TWO_PI * $_/$num_nodes); $x += rand($randfactor)-$randfactor/2; $y += rand($randfactor)-$randfactor/2; $ring_network->addPt($x, $y); } $image->setBrush($brush2); $image->polyline($ring_network->addControlPoints->toSpline,gdBrushed); $ring_node = new GD::Polygon; $ring_node->addPt( 0, 0); $ring_node->addPt(10, 0); $ring_node->addPt(10,10); $ring_node->addPt( 0,10); for $ring_vertex ($ring_network->vertices()) { $ring_node->offset($ring_node->centroid(-1)); $ring_node->offset(@$ring_vertex); $image->filledPolygon($ring_node,$grey); } SampleImage($image, "polyline-ring-network.png", "Ring Network", "Closed spline fit to nodes at somewhat random positions."); } WriteToFile("polyline-example.html", theHTML()); print "\n"; print "open 'polyline-example.html' in your favorite browser that supports PNG.\n"; print "\n"; print "done! " . localtime() . "\n"; ########################## # # helper functions # sub NewImage { $image = new GD::Image (500,300); $white = $image->colorAllocate(255,255,255); $black = $image->colorAllocate( 0, 0, 0); $grey = $image->colorAllocate(128,128,128); $red = $image->colorAllocate(255, 0, 0); $orange = $image->colorAllocate(255,196, 0); $green = $image->colorAllocate( 0,255, 0); $blue = $image->colorAllocate( 0, 0,255); $cyan = $image->colorAllocate( 0,255,255); $purple = $image->colorAllocate(206, 0,165); $brush_width = 2; $brush_color = [255,128,0]; $brush = new GD::Image($brush_width,$brush_width); $brush->transparent($brush->colorAllocate(255,255,255)); $brush->filledRectangle(0,0,$brush_width,$brush_width,$brush->colorAllocate(@$brush_color)); $brush1 = $brush; $brush_width = 3; $brush_color = [206,0,165]; $brush = new GD::Image($brush_width,$brush_width); $brush->transparent($brush->colorAllocate(255,255,255)); $brush->filledRectangle(0,0,$brush_width,$brush_width,$brush->colorAllocate(@$brush_color)); $brush2 = $brush; $image->setBrush($brush1); $image; } my $html; sub SampleImage { my $image = shift; my $file = shift; my $title = shift; my $text = shift; WriteToBinaryFile($file, $image->png()); $html .= "
\n"; $html .= "$title - $file
\n"; $html .= "

$text


\n"; } sub theHTML { $html; } sub WriteToFile { my $file = shift || return 0; my $contents = shift || ""; open (NEWFILE, ">" . $file) or die "couldn't write to file $file"; print NEWFILE $contents; close(NEWFILE); print "created file $file\n"; } sub WriteToBinaryFile { my $file = shift || return 0; my $contents = shift || ""; open (NEWFILE, ">" . $file) or die "couldn't write to file $file"; binmode NEWFILE; print NEWFILE $contents; close(NEWFILE); print "created file $file\n"; } sub genHTMLTable { my $array_of_arrays = shift; my $border = shift; my $html_table; $html_table .= ""; for my $array_of_items (@$array_of_arrays) { $html_table .= ""; } $html_table .= "
"; $html_table .= join("", @$array_of_items); $html_table .= "
"; $html_table; } GD-2.66/demos/polys.pl0000755000076500001200000000142713075665212013727 0ustar rurbanadmin#!/usr/local/bin/perl use GD; $im = new GD::Image(225,180); $black = $im->colorAllocate(0, 0, 0); $white = $im->colorAllocate(255, 255, 255); $red = $im->colorAllocate(255, 0, 0); $blue = $im->colorAllocate(0,0,255); $yellow = $im->colorAllocate(255,250,205); # Create a triangle $poly = new GD::Polygon; $poly->addPt(0,50); $poly->addPt(25,25); $poly->addPt(50,50); $im->filledPolygon($poly,$blue); # offset it down and to the right $poly->offset(100,100); $im->filledPolygon($poly,$red); # make it twice as wide and move it upward a bit $poly->map(50,50,100,100,10,10,110,60); $im->filledPolygon($poly,$yellow); # make it real tall $poly->map($poly->bounds,50,20,80,160); $im->filledPolygon($poly,$white); binmode STDOUT; # print the image to stdout print $im->png; GD-2.66/demos/shapes.pl0000755000076500001200000000242313075665212014041 0ustar rurbanadmin#!/usr/local/bin/perl use GD; $im = new GD::Image(300,300); ($white,$black,$red,$blue,$yellow) = ( $im->colorAllocate(255, 255, 255), $im->colorAllocate(0, 0, 0), $im->colorAllocate(255, 0, 0), $im->colorAllocate(0,0,255), $im->colorAllocate(255,250,205) ); $im->transparent($white); # white color is transparent $im->interlaced(1); # cool venetian blinds effect # Create a flat wide rectangle paintbrush $brush = new GD::Image(10,10); $brush->colorAllocate(255,255,255); # white $brush->colorAllocate(0,0,0); # black $brush->transparent($white); # white is transparent $brush->filledRectangle(0,0,5,2,$black); # a black rectangle # Draw a friendly title (ha!) $im->string(gdLargeFont,150,10,"Hello world!",$red); $im->string(gdSmallFont,150,28,"Goodbye cruel world!",$blue); $im->stringUp(gdTinyFont,280,250,"I'm climbing the wall!",$black); $im->charUp(gdMediumBoldFont,280,280,"Q",$black); # Draw an oval $im->setBrush($brush); $im->arc(100,100,100,150,0,360,gdBrushed); $poly = new GD::Polygon; $poly->addPt(30,30); $poly->addPt(100,10); $poly->addPt(190,290); $poly->addPt(30,290); $im->polygon($poly,gdBrushed); $im->fill(132,62,$blue); $im->fill(100,70,$red); $im->fill(40,40,$yellow); binmode STDOUT; # print the image to stdout print $im->png; GD-2.66/demos/tile.png0000644000076500001200000000043013075665212013655 0ustar rurbanadminPNG  IHDRR? PLTEܸ [ѧ:bKGDHIDATxc``Z:CCC?bBFCtEXtSoftware@(#)ImageMagick 4.1.0 98/09/08 cristy@mystic.es.dupont.comeB*tEXtSignature7a52b1cac1657d1b4f8ef32b4198eabc{;\tEXtPage21x22+0+0IENDB`GD-2.66/demos/transform.pl0000755000076500001200000000130013075665212014562 0ustar rurbanadmin#!/usr/local/bin/perl use GD; # test scaling, translation, transformation $im = new GD::Image(380,225); $black = $im->colorAllocate(0, 0, 0); $white = $im->colorAllocate(255, 255, 255); $red = $im->colorAllocate(255, 0, 0); $blue = $im->colorAllocate(0,0,255); $yellow = $im->colorAllocate(255,250,205); # Create a triangle $poly = new GD::Polygon; $poly->toPt(50,50); $poly->toPt(100,0); $poly->toPt(-50,50); $poly->toPt(-50,-50); $im->filledPolygon($poly,$yellow); # Stretch it a bit $poly->scale(1.8,1.0); $poly->offset(100,0); $im->filledPolygon($poly,$red); # Rotate it $poly->transform(0.55,0.20,0.0,1,-25,50); $im->filledPolygon($poly,$blue); binmode STDOUT; print $im->png; GD-2.66/demos/truetype_test0000755000076500001200000000154613075665245015077 0ustar rurbanadmin#!/usr/local/bin/perl use lib '../blib/lib','../blib/arch'; use GD 1.20; use constant FONT_DIRECTORY => '/dosc/windows/fonts'; my $directory = shift || FONT_DIRECTORY; my @fonts = <$directory/*.pfa $directory/*.pfb $directory/*.ttf>; die "Usage: $0 \nDisplays a directory of TrueType and Type1 fonts\n" unless @fonts; my $im = new GD::Image(800,600); my ($white,$black) = ( $im->colorAllocate(255, 255, 255), $im->colorAllocate(0, 0, 0)); my ($x,$y) = (20,20); my $max_x = 0; for my $font (@fonts) { my ($font_name) = $font =~ /([^\\\/]+)$/; warn "rendering $font_name\n"; (my @h = $im->stringTTF($black,$font,12.0,0.0,$x,$y,$font_name)) || next; $y = $h[1] + 12 + 5; $max_x = $max_x > $h[4] ? $max_x : $h[4]; if ($y > 600) { $y = 20; $x = $max_x + 5; } } binmode STDOUT; # print the image to stdout print $im->png; GD-2.66/demos/ttf.pl0000755000076500001200000000134613075665212013356 0ustar rurbanadmin#!/usr/local/bin/perl use lib '../blib/lib','../blib/arch'; use GD 1.20; use constant font => '../t/Generic.ttf'; $im = new GD::Image(400,250); warn $GD::VERSION; ($white,$black,$red,$blue,$yellow) = ( $im->colorAllocate(255, 255, 255), $im->colorAllocate(0, 0, 0), $im->colorAllocate(255, 0, 0), $im->colorAllocate(0,0,255), $im->colorAllocate(255,250,205) ); $im->interlaced(1); # cool venetian blinds effect # Some TTFs $im->stringTTF($black,font,12.0,0.0,20,20,"Hello world!") || die $@; $im->stringTTF($red,font,14.0,0.0,20,80,"Hello world!")|| die $@;; $im->stringTTF($blue,font,30.0,-0.5,60,100,"Goodbye cruel world!")|| die $@;; binmode STDOUT; # print the image to stdout print $im->png; GD-2.66/GD.xs0000644000076500001200000015056013077120742011757 0ustar rurbanadmin#ifdef PERL_CAPI #define WIN32IO_IS_STDIO #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include #include #include #include #include /* 2.0.x: < 2.1.0-alpha */ #ifndef GD_VERSION_STRING # if defined(GD2_VERS) && (GD2_VERS==2) # ifdef VERSION_33 # define GD_VERSION 20033 # define GD_VERSION_STRING "2.0.33" # else # define GD_VERSION 20032 # define GD_VERSION_STRING "2.0.x" # endif # else # define GD_VERSION 10000 # define GD_VERSION_STRING "?" # endif #else # define GD_VERSION ((GD_MAJOR_VERSION * 10000) +\ (GD_MINOR_VERSION * 100) +\ GD_RELEASE_VERSION) #endif #ifdef FCGI #include #else #ifdef USE_SFIO #include #else #include #endif #include #endif /* Copyright 1995 - 1998, Lincoln D. Stein. See accompanying README file for usage restrictions */ #ifndef PERL_REVISION # ifndef __PATCHLEVEL_H_INCLUDED__ # include "patchlevel.h" # endif # ifndef PERL_REVISION # define PERL_REVISION (5) /* Replace: 1 */ # define PERL_VERSION PATCHLEVEL # define PERL_SUBVERSION SUBVERSION /* Replace PERL_PATCHLEVEL with PERL_VERSION */ /* Replace: 0 */ # endif #endif #if (PERL_VERSION == 5) && (PERL_SUBVERSION==3) #ifndef PL_na # define PL_na na #endif #ifndef SvPV_nolen # define SvPV_nolen(sv) SvPV(sv, PL_na) #endif #endif /* 5.00503 */ #ifndef dMY_CXT # define dMY_CXT (void)0 #endif #ifndef PERL_UNUSED_ARG # define PERL_UNUSED_ARG(x) ((void)sizeof(x)) #endif #ifndef mPUSHp #define mPUSHp(p,l) PUSHs(sv_2mortal(newSVpvn((p), (l)))) #endif #ifndef mPUSHi #define mPUSHi(i) PUSHs(sv_2mortal(newSViv((i)))) #endif #ifndef mPUSHn #define mPUSHn(n) PUSHs(sv_2mortal(newSVnv((n)))) #endif #ifndef mXPUSHp # define mXPUSHp(p,l) STMT_START { EXTEND(sp,1); mPUSHp((p), (l)); } STMT_END #endif #ifndef mXPUSHi # define mXPUSHi(i) STMT_START { EXTEND(sp,1); mPUSHi((i)); } STMT_END #endif #ifndef mXPUSHn # define mXPUSHn(i) STMT_START { EXTEND(sp,1); mPUSHn((i)); } STMT_END #endif #ifndef hv_fetchs # define hv_fetchs(H, K, L) hv_fetch((H), (K), sizeof(K)-1, (L)) #endif #ifdef WIN32 # define snprintf _snprintf #endif #ifndef START_MY_CXT static int truecolor_default = 0; #endif #include "const-c.inc" typedef gdImagePtr GD__Image; typedef gdFontPtr GD__Font; typedef PerlIO * InputStream; #ifdef PERL_OBJECT # ifdef WIN32 #define GDIMAGECREATEFROMPNG(x) gdImageCreateFromPng((FILE*)x) #define GDIMAGECREATEFROMXBM(x) gdImageCreateFromXbm((FILE*)x) #define GDIMAGECREATEFROMJPEG(x) gdImageCreateFromJpeg((FILE*)x) #define GDIMAGECREATEFROMGIF(x) gdImageCreateFromGif((FILE*)x) #define GDIMAGECREATEFROMWBMP(x) gdImageCreateFromWBMP((FILE*)x) #define GDIMAGECREATEFROMGD(x) gdImageCreateFromGd((FILE*)x) #define GDIMAGECREATEFROMGD2(x) gdImageCreateFromGd2((FILE*)x) #define GDIMAGECREATEFROMGD2PART(x,a,b,c,d) gdImageCreateFromGd2Part((FILE*)x,a,b,c,d) # endif #else # ifdef USE_PERLIO #define GDIMAGECREATEFROMPNG(x) gdImageCreateFromPng(PerlIO_findFILE(x)) #define GDIMAGECREATEFROMXBM(x) gdImageCreateFromXbm(PerlIO_findFILE(x)) #define GDIMAGECREATEFROMJPEG(x) gdImageCreateFromJpeg(PerlIO_findFILE(x)) #define GDIMAGECREATEFROMGIF(x) gdImageCreateFromGif(PerlIO_findFILE(x)) #define GDIMAGECREATEFROMWBMP(x) gdImageCreateFromWBMP(PerlIO_findFILE(x)) #define GDIMAGECREATEFROMGD(x) gdImageCreateFromGd(PerlIO_findFILE(x)) #define GDIMAGECREATEFROMGD2(x) gdImageCreateFromGd2(PerlIO_findFILE(x)) #define GDIMAGECREATEFROMGD2PART(x,a,b,c,d) gdImageCreateFromGd2Part(PerlIO_findFILE(x),a,b,c,d) # else #define GDIMAGECREATEFROMPNG(x) gdImageCreateFromPng(x) #define GDIMAGECREATEFROMXBM(x) gdImageCreateFromXbm(x) #define GDIMAGECREATEFROMJPEG(x) gdImageCreateFromJpeg(x) #define GDIMAGECREATEFROMGIF(x) gdImageCreateFromGif(x) #define GDIMAGECREATEFROMWBMP(x) gdImageCreateFromWBMP(x) #define GDIMAGECREATEFROMGD(x) gdImageCreateFromGd(x) #define GDIMAGECREATEFROMGD2(x) gdImageCreateFromGd2(x) #define GDIMAGECREATEFROMGD2PART(x,a,b,c,d) gdImageCreateFromGd2Part(x,a,b,c,d) # endif #endif #define littleendian(a) \ (a[3]<<24)+(a[2]<<16)+(a[1]<<8)+a[0] /* definitions required to create images from in-memory buffers */ typedef struct bufIOCtx { gdIOCtx ctx; char* data; int length; int pos; } bufIOCtx; typedef struct bufIOCtx *bufIOCtxPtr; static int bufGetC (gdIOCtxPtr ctx) { bufIOCtxPtr bctx = (bufIOCtxPtr) ctx; if (bctx->pos >= bctx->length) return EOF; return bctx->data[bctx->pos]; } static int bufGetBuf (gdIOCtxPtr ctx, void* buf, int len) { bufIOCtxPtr bctx = (bufIOCtxPtr) ctx; int remain,rlen; remain = bctx->length - bctx->pos; if (remain >= len) { rlen = len; } else { if (remain <= 0) return EOF; rlen = remain; } memcpy(buf,(void*)(bctx->data + bctx->pos),rlen); bctx->pos += rlen; return rlen; } static int bufSeek (gdIOCtxPtr ctx, const int pos) { bufIOCtxPtr bctx = (bufIOCtxPtr) ctx; bctx->pos = pos; if (bctx->pos > bctx->length) bctx->pos = bctx->length; return TRUE; } static long bufTell (gdIOCtxPtr ctx) { bufIOCtxPtr bctx = (bufIOCtxPtr) ctx; return bctx->pos; } static void bufFree(gdIOCtxPtr ctx) { Safefree(ctx); } static gdIOCtx* newDynamicCtx (char* data, int length) { bufIOCtxPtr ctx; #ifdef Newz Newz(0,ctx,1,bufIOCtx); #else Newxz(ctx,1,bufIOCtx); #endif if (ctx == NULL) return NULL; ctx->data = data; ctx->pos = 0; ctx->length = length; ctx->ctx.getC = bufGetC; ctx->ctx.getBuf = bufGetBuf; ctx->ctx.seek = bufSeek; ctx->ctx.tell = bufTell; ctx->ctx.gd_free = bufFree; ctx->ctx.putC = NULL; ctx->ctx.putBuf = NULL; return (gdIOCtx*)ctx; } /* helper routines for image transformation */ static GD__Image gd_cloneDim(GD__Image src, int x, int y) { GD__Image dst; if (gdImageTrueColor(src)) { dst = (GD__Image) gdImageCreateTrueColor(x,y); if (!dst) croak("gdImageCreateTrueColor error"); } else { int i; dst = (GD__Image) gdImageCreatePalette(x,y); if (!dst) croak("gdImageCreatePalette error"); /* copy across the palette information */ for (i = 0; i < gdMaxColors; i++) { dst->red[i] = src->red[i]; dst->green[i] = src->green[i]; dst->blue[i] = src->blue[i]; dst->alpha[i] = src->alpha[i]; dst->open[i] = src->open[i]; } dst->colorsTotal = src->colorsTotal; dst->transparent = src->transparent; dst->interlace = src->interlace; dst->thick = src->thick; } return(dst); } void get_xformbounds(GD__Image src, int *x, int *y, int *x1, int *y1, int *x2, int *y2) { *x = gdImageSX(src); *y = gdImageSY(src); *x1 = *x - 1; *y1 = *y - 1; *x2 = *x / 2; *y2 = *y / 2; } /* helper macros for image transformations */ #define GDGetImagePixel(im,x,y) \ gdImageTrueColor(im) ? \ gdImageTrueColorPixel(im,x,y) : \ gdImagePalettePixel(im,x,y) #define GDSetImagePixel(im,x,y,p) \ gdImageTrueColor(im) ? \ (gdImageTrueColorPixel(im,x,y) = p) : \ (gdImagePalettePixel(im,x,y) = p) #define GDCopyImagePixel(dst,dx,dy,src,sx,sy) \ gdImageTrueColor(src) ? \ (gdImageTrueColorPixel(dst,dx,dy)=gdImageTrueColorPixel(src,sx,sy)) : \ (gdImagePalettePixel(dst,dx,dy)=gdImagePalettePixel(src,sx,sy)) /* Check the image format being returned */ void gd_chkimagefmt(GD__Image image, int truecolor) { if ((image != NULL) && !truecolor) { /* return a palette image */ if (gdImageTrueColor(image)) { gdImageTrueColorToPalette(image,1,gdMaxColors); } } } /* GLOBAL THREAD-SAFE DATA */ #ifdef START_MY_CXT #define MY_CXT_KEY "GD::_guts" XS_VERSION typedef struct { /* Current image true color default * 0 - create palette based images by default * 1 - create true color images by default */ int truecolor_default; } my_cxt_t; #define truecolor_default MY_CXT.truecolor_default START_MY_CXT #endif MODULE = GD PACKAGE = GD INCLUDE: const-xs.inc void VERSION_STRING() PPCODE: mXPUSHp(GD_VERSION_STRING,sizeof(GD_VERSION_STRING)-1); void LIBGD_VERSION() PPCODE: mXPUSHn(GD_VERSION/10000.0); BOOT: { #ifdef START_MY_CXT MY_CXT_INIT; #endif truecolor_default = 0; } MODULE = GD PACKAGE = GD::Image PREFIX=gd # Set the new image true color default # 0 - create palette based images by default # 1 - create true color images by default int gdtrueColor(packname="GD::Image", ...) char * packname PROTOTYPE: $$ PREINIT: dMY_CXT; int previous_value = truecolor_default; CODE: PERL_UNUSED_ARG(packname); if (items > 1) truecolor_default = (int)SvIV(ST(1)); RETVAL = previous_value; OUTPUT: RETVAL GD::Image gd_new(packname="GD::Image", x=64, y=64, ...) char * packname int x int y PROTOTYPE: $;$$$ PREINIT: gdImagePtr theImage; dMY_CXT; int truecolor = truecolor_default; CODE: PERL_UNUSED_ARG(packname); if (items > 3) truecolor = (int)SvIV(ST(3)); if (truecolor) { theImage = (GD__Image) gdImageCreateTrueColor(x,y); if (!theImage) croak("gdImageCreateTrueColor error"); } else { theImage = (GD__Image) gdImageCreate(x,y); if (!theImage) croak("gdImageCreate error"); } RETVAL = theImage; OUTPUT: RETVAL #ifdef HAVE_PNG GD::Image gd_newFromPng(packname="GD::Image", filehandle, ...) char * packname InputStream filehandle PROTOTYPE: $$;$ PREINIT: dMY_CXT; int truecolor = truecolor_default; CODE: PERL_UNUSED_ARG(packname); RETVAL = (GD__Image) GDIMAGECREATEFROMPNG(filehandle); if (!RETVAL) croak("gdImageCreateFromPng error"); if (items > 2) truecolor = (int)SvIV(ST(2)); gd_chkimagefmt(RETVAL, truecolor); OUTPUT: RETVAL GD::Image gdnewFromPngData(packname="GD::Image", imageData, ...) char * packname SV * imageData PROTOTYPE: $$;$ PREINIT: gdIOCtx* ctx; char* data; STRLEN len; dMY_CXT; int truecolor = truecolor_default; CODE: PERL_UNUSED_ARG(packname); data = SvPV(imageData,len); ctx = newDynamicCtx(data,len); RETVAL = (GD__Image) gdImageCreateFromPngCtx(ctx); (ctx->gd_free)(ctx); if (!RETVAL) croak("gdImageCreateFromPngCtx error"); if (items > 2) truecolor = (int)SvIV(ST(2)); gd_chkimagefmt(RETVAL, truecolor); OUTPUT: RETVAL #endif GD::Image gdnewFromGdData(packname="GD::Image", imageData) char * packname SV * imageData PROTOTYPE: $$ PREINIT: char* data; STRLEN len; CODE: PERL_UNUSED_ARG(packname); data = SvPV(imageData,len); RETVAL = (GD__Image) gdImageCreateFromGdPtr(len,(void*) data); if (!RETVAL) croak("gdImageCreateFromGdPtr error"); OUTPUT: RETVAL GD::Image gdnewFromGd2Data(packname="GD::Image", imageData) char * packname SV * imageData PROTOTYPE: $$ PREINIT: char* data; STRLEN len; CODE: PERL_UNUSED_ARG(packname); data = SvPV(imageData,len); RETVAL = (GD__Image) gdImageCreateFromGd2Ptr(len,(void*) data); if (!RETVAL) croak("gdImageCreateFromGd2Ptr error"); OUTPUT: RETVAL #ifdef HAVE_JPEG GD::Image gdnewFromJpegData(packname="GD::Image", imageData, ...) char * packname SV * imageData PROTOTYPE: $$;$ PREINIT: gdIOCtx* ctx; char* data; STRLEN len; dMY_CXT; int truecolor = truecolor_default; CODE: PERL_UNUSED_ARG(packname); data = SvPV(imageData,len); ctx = newDynamicCtx(data,len); RETVAL = (GD__Image) gdImageCreateFromJpegCtx(ctx); (ctx->gd_free)(ctx); if (!RETVAL) croak("gdImageCreateFromJpegCtx error"); if (items > 2) truecolor = (int)SvIV(ST(2)); gd_chkimagefmt(RETVAL, truecolor); OUTPUT: RETVAL #endif GD::Image gdnewFromWBMPData(packname="GD::Image", imageData, ...) char * packname SV * imageData PROTOTYPE: $$;$ PREINIT: gdIOCtx* ctx; char* data; STRLEN len; dMY_CXT; int truecolor = truecolor_default; CODE: PERL_UNUSED_ARG(packname); data = SvPV(imageData,len); ctx = newDynamicCtx(data,len); RETVAL = (GD__Image) gdImageCreateFromWBMPCtx(ctx); (ctx->gd_free)(ctx); if (!RETVAL) croak("gdImageCreateFromWBMPCtx error"); if (items > 2) truecolor = (int)SvIV(ST(2)); gd_chkimagefmt(RETVAL, truecolor); OUTPUT: RETVAL GD::Image gd_newFromXbm(packname="GD::Image", filehandle) char * packname InputStream filehandle PROTOTYPE: $$ CODE: PERL_UNUSED_ARG(packname); RETVAL = GDIMAGECREATEFROMXBM(filehandle); if (!RETVAL) croak("gdImageCreateFromXbm error"); OUTPUT: RETVAL GD::Image gd_newFromGd(packname="GD::Image", filehandle) char * packname InputStream filehandle PROTOTYPE: $$ CODE: PERL_UNUSED_ARG(packname); RETVAL = GDIMAGECREATEFROMGD(filehandle); if (!RETVAL) croak("gdImageCreateFromGd error"); OUTPUT: RETVAL GD::Image gd_newFromGd2(packname="GD::Image", filehandle) char * packname InputStream filehandle PROTOTYPE: $$ CODE: PERL_UNUSED_ARG(packname); RETVAL = GDIMAGECREATEFROMGD2(filehandle); if (!RETVAL) croak("gdImageCreateFromGd2 error"); OUTPUT: RETVAL #ifdef HAVE_JPEG GD::Image gd_newFromJpeg(packname="GD::Image", filehandle, ...) char * packname InputStream filehandle PROTOTYPE: $$;$ PREINIT: dMY_CXT; int truecolor = truecolor_default; CODE: PERL_UNUSED_ARG(packname); RETVAL = GDIMAGECREATEFROMJPEG(filehandle); if (!RETVAL) croak("gdImageCreateFromJpeg error"); if (items > 2) truecolor = (int)SvIV(ST(2)); gd_chkimagefmt(RETVAL, truecolor); OUTPUT: RETVAL #endif GD::Image gd_newFromWBMP(packname="GD::Image", filehandle) char * packname InputStream filehandle PROTOTYPE: $$ PREINIT: gdImagePtr img; SV* errormsg; CODE: PERL_UNUSED_ARG(packname); img = GDIMAGECREATEFROMWBMP(filehandle); if (img == NULL) { errormsg = perl_get_sv("@",0); if (errormsg != NULL) sv_setpv(errormsg,"libgd was not built with WBMP support\n"); else croak("gdImageCreateFromWbmp error"); XSRETURN_EMPTY; } RETVAL = img; OUTPUT: RETVAL GD::Image gdnewFromXpm(packname="GD::Image", filename) char * packname char * filename PROTOTYPE: $$ PREINIT: gdImagePtr img; SV* errormsg; CODE: PERL_UNUSED_ARG(packname); #ifdef HAVE_XPM img = (GD__Image) gdImageCreateFromXpm(filename); if (img == NULL) { errormsg = perl_get_sv("@",0); if (errormsg != NULL) sv_setpv(errormsg,"libgd was not built with xpm support\n"); else croak("gdImageCreateFromXpm error"); XSRETURN_EMPTY; } RETVAL = img; #else errormsg = perl_get_sv("@",0); sv_setpv(errormsg,"libgd was not built with xpm support\n"); XSRETURN_EMPTY; #endif OUTPUT: RETVAL GD::Image gd_newFromGd2Part(packname="GD::Image", filehandle,srcX,srcY,width,height) char * packname InputStream filehandle int srcX int srcY int width int height PROTOTYPE: $$$$$$ CODE: PERL_UNUSED_ARG(packname); RETVAL = GDIMAGECREATEFROMGD2PART(filehandle,srcX,srcY,width,height); if (!RETVAL) croak("gdImageCreateFromGd2Part error"); OUTPUT: RETVAL #ifdef HAVE_GIF GD::Image gd_newFromGif(packname="GD::Image", filehandle) char * packname InputStream filehandle PROTOTYPE: $$;$ CODE: PERL_UNUSED_ARG(packname); RETVAL = GDIMAGECREATEFROMGIF(filehandle); if (!RETVAL) croak("gdImageCreateFromGif error"); OUTPUT: RETVAL GD::Image gdnewFromGifData(packname="GD::Image", imageData) char * packname SV * imageData PROTOTYPE: $$;$ PREINIT: gdIOCtx* ctx; char* data; STRLEN len; CODE: PERL_UNUSED_ARG(packname); data = SvPV(imageData,len); ctx = newDynamicCtx(data,len); RETVAL = (GD__Image) gdImageCreateFromGifCtx(ctx); (ctx->gd_free)(ctx); if (!RETVAL) croak("gdImageCreateFromGifCtx error"); OUTPUT: RETVAL #endif void gdDESTROY(image) GD::Image image PROTOTYPE: $ CODE: gdImageDestroy(image); SV* gdSTORABLE_freeze(image,cloning) GD::Image image int cloning PROTOTYPE: $$ CODE: { void* data; int size; if (cloning) XSRETURN_UNDEF; data = gdImageGd2Ptr(image,0,GD2_FMT_COMPRESSED,&size); if (!data) croak("gdImageGd2Ptr error"); RETVAL = newSVpvn((char*)data,size); gdFree(data); } OUTPUT: RETVAL void gdSTORABLE_thaw(object,cloning,serialized) SV* object int cloning SV* serialized PREINIT: STRLEN length; void* data; GD__Image image; CODE: { if (cloning) XSRETURN_UNDEF; data = (void*) SvPV(serialized,length); image = gdImageCreateFromGd2Ptr(length,data); if (!image) croak("gdImageCreateFromGd2Ptr error"); sv_setiv(SvRV(object),(IV)image); } #ifdef HAVE_PNG SV* gdpng(image, ...) GD::Image image PROTOTYPE: $;$ PREINIT: CODE: { void* data; int size; int level; if (items > 1) { level = (int)SvIV(ST(1)); data = (void *) gdImagePngPtrEx(image,&size,level); if (!data) croak("gdImagePngPtrEx error"); } else { data = (void *) gdImagePngPtr(image,&size); if (!data) croak("gdImagePngPtr error"); } RETVAL = newSVpvn((char*) data,size); gdFree(data); } OUTPUT: RETVAL #endif #ifdef HAVE_JPEG SV* gdjpeg(image,quality=-1) GD::Image image int quality PROTOTYPE: $ PREINIT: SV* errormsg; void* data; int size; CODE: data = (void *) gdImageJpegPtr(image,&size,quality); if (data == NULL) { errormsg = perl_get_sv("@",0); if (errormsg != NULL) sv_setpv(errormsg,"libgd was not built with jpeg support\n"); else croak("gdImageJpegPtr error"); XSRETURN_EMPTY; } RETVAL = newSVpvn((char*) data,size); gdFree(data); OUTPUT: RETVAL #endif SV* gdgifanimbegin(image,globalcm=-1,loops=-1) GD::Image image int globalcm int loops PROTOTYPE: $$$ PREINIT: void* data; int size; CODE: #ifdef HAVE_ANIMGIF data = (void *) gdImageGifAnimBeginPtr(image,&size,globalcm,loops); if (!data) croak("gdImageGifAnimBeginPtr error"); RETVAL = newSVpvn((char*) data,size); gdFree(data); #else die("libgd 2.0.33 or higher required for animated GIF support"); #endif OUTPUT: RETVAL SV* gdgifanimadd(image,localcm=-1,leftofs=-1,topofs=-1,delay=-1,disposal=-1,previm=0) GD::Image image int localcm int leftofs int topofs int delay int disposal GD::Image previm PROTOTYPE: $$$$$$$ PREINIT: void* data; int size; CODE: #ifdef HAVE_ANIMGIF data = (void *) gdImageGifAnimAddPtr(image,&size,localcm,leftofs,topofs, delay,disposal,previm); if (!data) croak("gdImageGifAnimAddPtr error"); RETVAL = newSVpvn((char*) data,size); gdFree(data); #else die("libgd 2.0.33 or higher required for animated GIF support"); #endif OUTPUT: RETVAL SV* gdgifanimend(image) GD::Image image PROTOTYPE: $ PREINIT: void* data; int size; CODE: PERL_UNUSED_ARG(image); #ifdef HAVE_ANIMGIF data = (void *) gdImageGifAnimEndPtr(&size); if (!data) croak("gdImageGifAnimEndPtr error"); RETVAL = newSVpvn((char*) data,size); gdFree(data); #else die("libgd 2.0.33 or higher required for animated GIF support"); #endif OUTPUT: RETVAL SV* gdwbmp(image,fg) GD::Image image int fg PROTOTYPE: $ PREINIT: SV* errormsg; void* data; int size; CODE: data = (void *) gdImageWBMPPtr(image,&size,fg); if (data == NULL) { errormsg = perl_get_sv("@",0); if (errormsg != NULL) sv_setpv(errormsg,"libgd was not built with WBMP support\n"); else croak("gdImageWBMPPtr error"); XSRETURN_EMPTY; } RETVAL = newSVpvn((char*) data,size); gdFree(data); OUTPUT: RETVAL #ifdef HAVE_GIF SV* gdgif(image) GD::Image image PROTOTYPE: $ PREINIT: SV* errormsg; void* data; int size; CODE: data = (void *) gdImageGifPtr(image,&size); if (data == NULL) { errormsg = perl_get_sv("@",0); if (errormsg != NULL) sv_setpv(errormsg,"libgd was not built with gif support\n"); else croak("gdImageGifPtr error"); XSRETURN_EMPTY; } RETVAL = newSVpvn((char*) data,size); gdFree(data); OUTPUT: RETVAL #endif SV* gdgd(image) GD::Image image PROTOTYPE: $ CODE: { void* data; int size; data = gdImageGdPtr(image,&size); if (!data) croak("gdImageGdPtr error"); RETVAL = newSVpvn((char*) data,size); gdFree(data); } OUTPUT: RETVAL SV* gdgd2(image) GD::Image image PROTOTYPE: $ CODE: { void* data; int size; data = gdImageGd2Ptr(image,0,GD2_FMT_COMPRESSED,&size); if (!data) croak("gdImageGd2Ptr error"); RETVAL = newSVpvn((char*) data,size); gdFree(data); } OUTPUT: RETVAL int gdtransparent(image, ...) GD::Image image PROTOTYPE: $;$ PREINIT: int color; CODE: if (items > 1) { color=(int)SvIV(ST(1)); gdImageColorTransparent(image,color); } RETVAL = gdImageGetTransparent(image); OUTPUT: RETVAL void gdgetBounds(image) GD::Image image PROTOTYPE: $ PPCODE: mXPUSHi(gdImageSX(image)); mXPUSHi(gdImageSY(image)); int gdisTrueColor(image) GD::Image image PROTOTYPE: $ CODE: RETVAL = gdImageTrueColor(image); OUTPUT: RETVAL void gdtrueColorToPalette(image, dither=0, colors=gdMaxColors) GD::Image image int dither int colors PROTOTYPE: $;$$ CODE: gdImageTrueColorToPalette(image,dither,colors); GD::Image gdcreatePaletteFromTrueColor(image, dither=0, colors=gdMaxColors) GD::Image image int dither int colors PROTOTYPE: $;$$ CODE: RETVAL = gdImageCreatePaletteFromTrueColor(image,dither,colors); if (!RETVAL) croak("gdImageCreatePaletteFromTrueColor error"); OUTPUT: RETVAL #if GD_VERSION >= 20100 GD::Image gdneuQuant(image, colors=gdMaxColors, samplefactor=5) GD::Image image int colors int samplefactor PROTOTYPE: $;$$ CODE: RETVAL = gdImageNeuQuant(image,colors,samplefactor); if (!RETVAL) XSRETURN_UNDEF; OUTPUT: RETVAL int gdcolorMatch(image, im2) GD::Image image GD::Image im2 PROTOTYPE: $$ CODE: RETVAL = gdImageColorMatch(image,im2); OUTPUT: RETVAL #endif void gdrgb(image,color) GD::Image image int color PROTOTYPE: $$ PPCODE: mXPUSHi(gdImageRed(image,color)); mXPUSHi(gdImageGreen(image,color)); mXPUSHi(gdImageBlue(image,color)); void gdalpha(image,color) GD::Image image int color PROTOTYPE: $$ PPCODE: mXPUSHi(gdImageAlpha(image,color)); int gdboundsSafe(image,x,y) GD::Image image int x int y PROTOTYPE: $$$ CODE: RETVAL = gdImageBoundsSafe(image,x,y); if (RETVAL == 0) XSRETURN_UNDEF; OUTPUT: RETVAL int gdgetPixel(image,x,y) GD::Image image int x int y PROTOTYPE: $$$ CODE: RETVAL = gdImageGetPixel(image,x,y); OUTPUT: RETVAL void gdsetPixel(image,x,y,color) GD::Image image int x int y int color PROTOTYPE: $$$$ CODE: gdImageSetPixel(image,x,y,color); GD::Image gdcopyRotate90(src) GD::Image src PROTOTYPE: $ PREINIT: int x, y, x1, y1, x2, y2, i, j; CODE: get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2); RETVAL = gd_cloneDim(src, y, x); for (j=0;j 1) { if (SvOK(ST(1))) gdImageInterlace(image,1); else gdImageInterlace(image,0); } RETVAL = gdImageGetInterlaced(image); OUTPUT: RETVAL int compare(image1,image2) GD::Image image1 GD::Image image2 PROTOTYPE: $$ CODE: RETVAL = gdImageCompare(image1,image2); OUTPUT: RETVAL void colorDeallocate(image,color) GD::Image image int color PROTOTYPE: $$ CODE: gdImageColorDeallocate(image,color); void copy(destination,source,dstX,dstY,srcX,srcY,w,h) GD::Image destination GD::Image source int dstX int dstY int srcX int srcY int w int h PROTOTYPE: $$$$$$$$ CODE: gdImageCopy(destination,source,dstX,dstY,srcX,srcY,w,h); void copyResized(destination,source,dstX,dstY,srcX,srcY,destW,destH,srcW,srcH) GD::Image destination GD::Image source int dstX int dstY int srcX int srcY int destW int destH int srcW int srcH PROTOTYPE: $$$$$$$$$$ CODE: gdImageCopyResized(destination,source,dstX,dstY,srcX,srcY,destW,destH,srcW,srcH); void copyResampled(destination,source,dstX,dstY,srcX,srcY,destW,destH,srcW,srcH) GD::Image destination GD::Image source int dstX int dstY int srcX int srcY int destW int destH int srcW int srcH PROTOTYPE: $$$$$$$$$$ CODE: gdImageCopyResampled(destination,source,dstX,dstY,srcX,srcY,destW,destH,srcW,srcH); void copyMerge(destination,source,dstX,dstY,srcX,srcY,w,h,pct) GD::Image destination GD::Image source int dstX int dstY int srcX int srcY int w int h int pct PROTOTYPE: $$$$$$$$$ CODE: gdImageCopyMerge(destination,source,dstX,dstY,srcX,srcY,w,h,pct); void copyMergeGray(destination,source,dstX,dstY,srcX,srcY,w,h,pct) GD::Image destination GD::Image source int dstX int dstY int srcX int srcY int w int h int pct PROTOTYPE: $$$$$$$$$ CODE: gdImageCopyMergeGray(destination,source,dstX,dstY,srcX,srcY,w,h,pct); void paletteCopy(destination,source) GD::Image destination GD::Image source PROTOTYPE: $$ CODE: gdImagePaletteCopy(destination,source); void gdchar(image,font,x,y,c,color) GD::Image image GD::Font font int x int y char * c int color PROTOTYPE: $$$$$$ CODE: gdImageChar(image,font,x,y,*c,color); void gdcharUp(image,font,x,y,c,color) GD::Image image GD::Font font int x int y char * c int color PROTOTYPE: $$$$$$ CODE: gdImageCharUp(image,font,x,y,*c,color); void gdstring(image,font,x,y,s,color) GD::Image image GD::Font font int x int y char * s int color PROTOTYPE: $$$$$$ CODE: gdImageString(image,font,x,y,(unsigned char*)s,color); void gdstringUp(image,font,x,y,s,color) GD::Image image GD::Font font int x int y char * s int color PROTOTYPE: $$$$$$ CODE: gdImageStringUp(image,font,x,y,(unsigned char*)s,color); void gdstringFT(image,fgcolor,fontname,ptsize,angle,x,y,string,...) SV * image int fgcolor char * fontname double ptsize double angle int x int y char * string PROTOTYPE: $$$$$$$$;$ PREINIT: gdImagePtr img; int brect[8]; char *err; char *a; SV* errormsg; HV* hash; SV** value; int i; int hdpi; int vdpi; gdFTStringExtra strex; PPCODE: { #ifndef HAVE_FT errormsg = perl_get_sv("@",0); sv_setpv(errormsg,"libgd was not built with FreeType font support\n"); XSRETURN_EMPTY; #endif if (sv_isobject(image) && sv_derived_from(image, "GD::Image")) { IV tmp = SvIV((SV*)SvRV(image)); img = (gdImagePtr) tmp; } else { img = NULL; } if (items == 9) { /* hashref options at end */ if (SvTYPE(SvRV(ST(8))) != SVt_PVHV) croak ("Usage: $gd->stringFT(image,fgcolor,fontname,ptsize,angle,x,y,string,[{options}])"); hash = (HV*)SvRV(ST(8)); strex.flags = 0; strex.linespacing = 0; strex.charmap = 0; if ((value = hv_fetchs(hash,"linespacing",0))) { strex.flags |= gdFTEX_LINESPACE; strex.linespacing = SvNV(*value); } if ((value = hv_fetchs(hash,"charmap",0))) { strex.flags |= gdFTEX_CHARMAP; if (strEQ(SvPV_nolen(*value),"Unicode")) strex.charmap = gdFTEX_Unicode; else if (strEQ(SvPV_nolen(*value),"Shift_JIS")) strex.charmap = gdFTEX_Shift_JIS; else if (strEQ(SvPV_nolen(*value),"Big5")) strex.charmap = gdFTEX_Big5; else croak("Unknown charmap %s",SvPV_nolen(*value)); } #ifdef VERSION_33 if ((value = hv_fetchs(hash,"resolution",0))) { strex.flags |= gdFTEX_RESOLUTION; a = SvPV_nolen(*value); if (sscanf(a,"%d,%d",&hdpi,&vdpi) == 2) { strex.hdpi = hdpi; strex.vdpi = vdpi; } } if ((value = hv_fetchs(hash,"kerning",0))) { if (!SvTRUE(*value)) { strex.flags |= gdFTEX_DISABLE_KERNING; } else strex.flags &= gdFTEX_DISABLE_KERNING; } #endif err = gdImageStringFTEx(img,brect,fgcolor,fontname,ptsize,angle,x,y,string,&strex); } else { err = gdImageStringFT(img,brect,fgcolor,fontname,ptsize,angle,x,y,string); } if (err) { errormsg = perl_get_sv("@",0); if (errormsg != NULL) sv_setpv(errormsg,err); XSRETURN_EMPTY; } else { EXTEND(sp,8); for (i=0;i<8;i++) { mPUSHi(brect[i]); } } } int gdstringFTCircle(image,cx,cy,radius,textRadius,fillPortion,fontname,points,top,bottom,fgcolor) GD::Image image int cx int cy double radius double textRadius double fillPortion char * fontname double points char * top char * bottom int fgcolor PROTOTYPE: $$$$$$$$$$$ PREINIT: char* err; SV* errormsg; CODE: { #ifdef HAVE_FT #ifdef HAVE_FTCIRCLE fprintf(stderr,"cx=%d,cy=%d,radius=%f,textRadius=%f,fillPortion=%f,fontname=%s,points=%f,top=%s,bottom=%s,fgcolor=%d", cx,cy,radius,textRadius, fillPortion,fontname,points,top,bottom,fgcolor); err = gdImageStringFTCircle(image,cx,cy,radius,textRadius, fillPortion,fontname,points,top,bottom,fgcolor); if (err) { errormsg = perl_get_sv("@",0); if (errormsg != NULL) sv_setpv(errormsg,err); XSRETURN_EMPTY; } else { RETVAL = 1; } #else errormsg = perl_get_sv("@",0); sv_setpv(errormsg,"libgd must be version 2.0.33 or higher to use this function\n"); XSRETURN_EMPTY; #endif #else errormsg = perl_get_sv("@",0); sv_setpv(errormsg,"libgd was not built with FreeType support\n"); XSRETURN_EMPTY; #endif } OUTPUT: RETVAL int gduseFontConfig(image,flag) SV* image int flag PROTOTYPE: $$ CODE: { #ifdef HAVE_FONTCONFIG PERL_UNUSED_ARG(image); RETVAL = gdFTUseFontConfig(flag); #else SV* errormsg; PERL_UNUSED_ARG(image); errormsg = perl_get_sv("@",0); sv_setpv(errormsg,"libgd was not built with fontconfig support\n"); XSRETURN_EMPTY; #endif } OUTPUT: RETVAL void gdalphaBlending(image,blending) GD::Image image int blending PROTOTYPE: $$ CODE: gdImageAlphaBlending(image,blending); void gdsaveAlpha(image,saveAlphaArg) GD::Image image int saveAlphaArg PROTOTYPE: $$ CODE: gdImageSaveAlpha(image,saveAlphaArg); void gdclip(image,...) GD::Image image PROTOTYPE: $;$$$$ PREINIT: int coords[4]; int i; PPCODE: if (items == 5) { for (i=0;i<4;i++) coords[i] = (int)SvIV(ST(i+1)); gdImageSetClip(image,coords[0],coords[1],coords[2],coords[3]); } else if (items > 1) /* something weird */ croak("Usage: $gd->clip() or $gd->clip(x1,x2,y1,y2)"); gdImageGetClip(image,&coords[0],&coords[1],&coords[2],&coords[3]); EXTEND(sp,4); for (i=0;i<4;i++) mPUSHi(coords[i]); void gdsetAntiAliased(image,color) GD::Image image int color PROTOTYPE: $$ CODE: gdImageSetAntiAliased(image,color); void gdsetAntiAliasedDontBlend(image,color,flag=1) GD::Image image int color int flag PROTOTYPE: $$$ CODE: gdImageSetAntiAliasedDontBlend(image,color,flag); MODULE = GD PACKAGE = GD::Font PREFIX=gd GD::Font gdload(packname="GD::Font",fontpath) char * packname char * fontpath PROTOTYPE: $$ PREINIT: int fontfile; int datasize; SV* errormsg; char errstr[256]; gdFontPtr font; unsigned char word[4]; char* fontdata; CODE: PERL_UNUSED_ARG(packname); fontfile = open(fontpath,O_RDONLY); if (fontfile < 0) { errormsg = perl_get_sv("@",0); snprintf(errstr,256,"could not open font file %s: %s",fontpath,strerror(errno)); sv_setpv(errormsg,errstr); XSRETURN_EMPTY; } font = (gdFontPtr)safemalloc(sizeof(gdFont)); if (font == NULL) croak("safemalloc() returned NULL while trying to allocate font struct.\n"); /* read header from font - note that the file is assumed to be littleendian*/ if (read(fontfile,word,4) < 4) croak("error while reading font file: %s",strerror(errno)); font->nchars = littleendian(word); if (read(fontfile,word,4) < 4) croak("error while reading font file: %s",strerror(errno)); font->offset = littleendian(word); if (read(fontfile,word,4) < 4) croak("error while reading font file: %s",strerror(errno)); font->w = littleendian(word); if (read(fontfile,word,4) < 4) croak("error while reading font file: %s",strerror(errno)); font->h = littleendian(word); datasize = font->nchars * font->w * font->h; fontdata = (char*)safemalloc(datasize); if (fontdata == NULL) croak("safemalloc() returned NULL while trying to allocate font bitmap.\n"); if (read(fontfile,fontdata,datasize) < datasize) croak("error while reading font file: %s",strerror(errno)); font->data = fontdata; close(fontfile); /* please don't leak file descriptors! */ RETVAL = font; OUTPUT: RETVAL void gdDESTROY(self) GD::Font self PROTOTYPE: $ CODE: if (self == gdFontGetSmall() || self == gdFontGetLarge() || self == gdFontGetGiant() || self == gdFontGetMediumBold() || self == gdFontGetTiny() ) XSRETURN_EMPTY; safefree(self->data); safefree(self); GD::Font gdSmall(packname="GD::Font") char * packname PROTOTYPE: $ CODE: PERL_UNUSED_ARG(packname); RETVAL = gdFontGetSmall(); if (!RETVAL) croak("gdFontGetSmall error"); OUTPUT: RETVAL GD::Font gdLarge(packname="GD::Font") char * packname PROTOTYPE: $ CODE: PERL_UNUSED_ARG(packname); RETVAL = gdFontGetLarge(); if (!RETVAL) croak("gdFontGetLarge error"); OUTPUT: RETVAL GD::Font gdGiant(packname="GD::Font") char * packname PROTOTYPE: $ CODE: PERL_UNUSED_ARG(packname); RETVAL = gdFontGetGiant(); if (!RETVAL) croak("gdFontGetGiant error"); OUTPUT: RETVAL GD::Font gdMediumBold(packname="GD::Font") char * packname PROTOTYPE: $ CODE: PERL_UNUSED_ARG(packname); RETVAL = gdFontGetMediumBold(); if (!RETVAL) croak("gdFontGetMediumBold error"); OUTPUT: RETVAL GD::Font gdTiny(packname="GD::Font") char * packname PROTOTYPE: $ CODE: PERL_UNUSED_ARG(packname); RETVAL = gdFontGetTiny(); if (!RETVAL) croak("gdFontGetTiny error"); OUTPUT: RETVAL int gdnchars(font) GD::Font font PROTOTYPE: $ CODE: RETVAL = font->nchars; OUTPUT: RETVAL int gdoffset(font) GD::Font font PROTOTYPE: $ CODE: RETVAL = font->offset; OUTPUT: RETVAL int gdwidth(font) GD::Font font PROTOTYPE: $ CODE: RETVAL = font->w; OUTPUT: RETVAL int gdheight(font) GD::Font font PROTOTYPE: $ CODE: RETVAL = font->h; OUTPUT: RETVAL # Image filters since 2.1.0 MODULE = GD PACKAGE = GD::Image PREFIX=gd #if GD_VERSION >= 20100 bool gdscatter(image, sub, plus) GD::Image image int sub int plus PROTOTYPE: $$$ CODE: RETVAL = (bool)gdImageScatter(image,sub,plus); OUTPUT: RETVAL bool gdscatterColor(image, sub, plus, colorav) GD::Image image int sub int plus AV *colorav PROTOTYPE: $$$\@ PREINIT: int i; int *colors; int numcolors; CODE: numcolors = AvFILL(colorav); colors = safemalloc(numcolors * sizeof(int)); for (i=0;i= 20200 GD::Image gdcopyGaussianBlurred(image, radius, sigma) GD::Image image int radius double sigma PROTOTYPE: $$$ CODE: RETVAL = gdImageCopyGaussianBlurred(image, radius, sigma); if (!RETVAL) croak("gdImageCopyGaussianBlurred error"); OUTPUT: RETVAL #endif # gd_interpolation #if GD_VERSION >= 20100 GD::Image gdcopyScaleInterpolated(image, width, height) GD::Image image int width int height PROTOTYPE: $$$ CODE: RETVAL = gdImageScale(image,width,height); if (!RETVAL) XSRETURN_UNDEF; OUTPUT: RETVAL GD::Image gdcopyRotateInterpolated(image, angle, bgcolor) GD::Image image NV angle int bgcolor PROTOTYPE: $$$ CODE: RETVAL = gdImageRotateInterpolated(image,(float)angle,bgcolor); if (!RETVAL) XSRETURN_UNDEF; OUTPUT: RETVAL #endif #if GD_VERSION >= 20200 int interpolationMethod(image, interpolationmethod=-1) GD::Image image int interpolationmethod PROTOTYPE: $;$ CODE: if (items > 1 && interpolationmethod >= 0) { gdImageSetInterpolationMethod(image, interpolationmethod); } RETVAL = gdImageGetInterpolationMethod(image); OUTPUT: RETVAL #gdTransformAffineGetImage #gdTransformAffineCopy #gdTransformAffineBoundingBox #endif GD-2.66/lib/0000755000076500001200000000000013077123433011650 5ustar rurbanadminGD-2.66/lib/GD/0000755000076500001200000000000013077123433012142 5ustar rurbanadminGD-2.66/lib/GD/Group.pm0000644000076500001200000000123713076515043013600 0ustar rurbanadminpackage GD::Group; =head1 NAME GD::Group - Simple object for recursive grouping =head1 DESCRIPTION Does absolutely nothing with GD, but works nicely with GD::SVG. =cut use strict; our $AUTOLOAD; our $VERSION = 1.00; sub AUTOLOAD { my ($pack,$func_name) = $AUTOLOAD =~ /(.+)::([^:]+)$/; my $this = shift; $this->{gd}->currentGroup($this->{group}); $this->{gd}->$func_name(@_); } sub new { my $this = shift; my ($gd,$group) = @_; return bless {gd => $gd, group => $group},ref $this || $this; } sub DESTROY { my $this = shift; my $gd = $this->{gd}; my $grp = $this->{group}; $gd->endGroup($grp); } 1; GD-2.66/lib/GD/Image.pm0000644000076500001200000001122113077121042013511 0ustar rurbanadmin# DO NOT EDIT! THIS FILE IS AUTOGENERATED BY lib/GD/Image_pm.PL package GD::Image; use strict; use GD; use Symbol 'gensym','qualify_to_ref'; use vars '$VERSION'; $VERSION = '2.66'; =head1 NAME GD::Image - Image class for the GD image library =head1 SYNOPSIS See L =head1 DESCRIPTION See L =head1 AUTHOR The GD.pm interface is copyright 1995-2005, Lincoln D. Stein. It is distributed under the same terms as Perl itself. See the "Artistic License" in the Perl source code distribution for licensing terms. The latest versions of GD.pm are available on CPAN: http://www.cpan.org =head1 SEE ALSO L L, L, L, L =cut # Copyright 1995 Lincoln D. Stein. See accompanying README file for # usage information *stringTTF = \&GD::Image::stringFT; sub _make_filehandle { shift; # get rid of class no strict 'refs'; my $thing = shift; return $thing if defined(fileno $thing); # otherwise try qualifying it into caller's package my $fh; { local $^W = 0; # to avoid uninitialized variable warning from Symbol.pm $fh = qualify_to_ref($thing,caller(2)); } return $fh if defined(fileno $fh); # otherwise treat it as a file to open $fh = gensym; if (!open($fh,$thing)) { die "$thing not found: $!"; return undef; } return $fh; } sub new { my $pack = shift; if (@_ == 1) { if (my $type = _image_type($_[0])) { my $method = "newFrom${type}Data"; return unless $pack->can($method); return $pack->$method($_[0]); } return unless my $fh = $pack->_make_filehandle($_[0]); my $magic; return unless read($fh,$magic,4); return unless my $type = _image_type($magic); seek($fh,0,0); my $method = "newFrom${type}"; return $pack->$method($fh); } return $pack->_new(@_); } sub newTrueColor { my $pack = shift; return $pack->_new(@_, 1); } sub newPalette { my $pack = shift; return $pack->_new(@_, 0); } sub newFromGd { croak("Usage: newFromGd(class,filehandle)") unless @_==2; my($class,$f) = @_; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromGd($fh); } sub newFromGd2 { croak("Usage: newFromGd2(class,filehandle)") unless @_==2; my($class,$f) = @_; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromGd2($fh); } sub newFromGd2Part { croak("Usage: newFromGd2(class,filehandle,srcX,srcY,width,height)") unless @_==6; my($class,$f) = splice(@_,0,2); my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromGd2Part($fh,@_); } sub ellipse ($$$$$) { my ($self,$cx,$cy,$width,$height,$color) = @_; $self->arc($cx,$cy,$width,$height,0,360,$color); } # draws closed polygon with the specified color sub polygon { my $self = shift; my($p,$c) = @_; $self->openPolygon($p, $c); $self->line( @{$p->{'points'}->[0]}, @{$p->{'points'}->[$p->{'length'}-1]}, $c); } sub width { my $self = shift; my @bounds = $self->getBounds; $bounds[0]; } sub height { my $self = shift; my @bounds = $self->getBounds; $bounds[1]; } sub _image_type { my $data = shift; my $magic = substr($data,0,4); return 'Png' if $magic eq "\x89PNG"; return 'Jpeg' if ((substr($data,0,3) eq "\377\330\377") && ord(substr($data,3,1)) >= 0xc0); return 'Gif' if $magic eq "GIF8"; return 'Gd2' if $magic eq "gd2\000"; return 'Xpm' if substr($data,0,9) eq "/* XPM */"; return; } sub clone { croak("Usage: clone(\$image)") unless @_ == 1; my $self = shift; my ($x,$y) = $self->getBounds; my $new = $self->new($x,$y); return unless $new; $new->copy($self,0,0,0,0,$x,$y); return $new; } sub newFromPng { croak("Usage: newFromPng(class,filehandle,[truecolor])") unless @_>=2; my($class) = shift; my($f) = shift; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromPng($fh,@_); } sub newFromJpeg { croak("Usage: newFromJpeg(class,filehandle,[truecolor])") unless @_>=2; my($class) = shift; my($f) = shift; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromJpeg($fh,@_); } sub newFromGif { croak("Usage: newFromGif(class,filehandle,[truecolor])") unless @_>=2; my($class) = shift; my($f) = shift; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromGif($fh,@_); } sub newFromWBMP { croak("Usage: newFromWBMP(class,filehandle,[truecolor])") unless @_>=2; my($class) = shift; my($f) = shift; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromWBMP($fh,@_); } # Autoload methods go after __END__, and are processed by the autosplit program. 1; __END__ GD-2.66/lib/GD/Image_pm.PL0000644000076500001200000001321213077120773014120 0ustar rurbanadmin#!perl use Config; use File::Basename qw(&basename &dirname); use Cwd; my $DEFINES = ''; my $VERSION = ''; if (open F,".config.cache") { chomp($DEFINES = ); close F; } my $origdir = cwd; chdir dirname($0); my $file = 'Image.pm'; open OUT,">",$file or die "Can't create $file: $!"; print "Extracting $file (with variable substitutions)\n"; print OUT <<"!GROK!THIS!"; # DO NOT EDIT! THIS FILE IS AUTOGENERATED BY $0 !GROK!THIS! print OUT << '!NO!SUBS!'; package GD::Image; use strict; use GD; use Symbol 'gensym','qualify_to_ref'; use vars '$VERSION'; $VERSION = '2.66'; =head1 NAME GD::Image - Image class for the GD image library =head1 SYNOPSIS See L =head1 DESCRIPTION See L =head1 AUTHOR The GD.pm interface is copyright 1995-2005, Lincoln D. Stein. It is distributed under the same terms as Perl itself. See the "Artistic License" in the Perl source code distribution for licensing terms. The latest versions of GD.pm are available on CPAN: http://www.cpan.org =head1 SEE ALSO L L, L, L, L =cut # Copyright 1995 Lincoln D. Stein. See accompanying README file for # usage information *stringTTF = \&GD::Image::stringFT; sub _make_filehandle { shift; # get rid of class no strict 'refs'; my $thing = shift; return $thing if defined(fileno $thing); # otherwise try qualifying it into caller's package my $fh; { local $^W = 0; # to avoid uninitialized variable warning from Symbol.pm $fh = qualify_to_ref($thing,caller(2)); } return $fh if defined(fileno $fh); # otherwise treat it as a file to open $fh = gensym; if (!open($fh,$thing)) { die "$thing not found: $!"; return undef; } return $fh; } sub new { my $pack = shift; if (@_ == 1) { if (my $type = _image_type($_[0])) { my $method = "newFrom${type}Data"; return unless $pack->can($method); return $pack->$method($_[0]); } return unless my $fh = $pack->_make_filehandle($_[0]); my $magic; return unless read($fh,$magic,4); return unless my $type = _image_type($magic); seek($fh,0,0); my $method = "newFrom${type}"; return $pack->$method($fh); } return $pack->_new(@_); } sub newTrueColor { my $pack = shift; return $pack->_new(@_, 1); } sub newPalette { my $pack = shift; return $pack->_new(@_, 0); } sub newFromGd { croak("Usage: newFromGd(class,filehandle)") unless @_==2; my($class,$f) = @_; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromGd($fh); } sub newFromGd2 { croak("Usage: newFromGd2(class,filehandle)") unless @_==2; my($class,$f) = @_; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromGd2($fh); } sub newFromGd2Part { croak("Usage: newFromGd2(class,filehandle,srcX,srcY,width,height)") unless @_==6; my($class,$f) = splice(@_,0,2); my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromGd2Part($fh,@_); } sub ellipse ($$$$$) { my ($self,$cx,$cy,$width,$height,$color) = @_; $self->arc($cx,$cy,$width,$height,0,360,$color); } # draws closed polygon with the specified color sub polygon { my $self = shift; my($p,$c) = @_; $self->openPolygon($p, $c); $self->line( @{$p->{'points'}->[0]}, @{$p->{'points'}->[$p->{'length'}-1]}, $c); } sub width { my $self = shift; my @bounds = $self->getBounds; $bounds[0]; } sub height { my $self = shift; my @bounds = $self->getBounds; $bounds[1]; } sub _image_type { my $data = shift; my $magic = substr($data,0,4); return 'Png' if $magic eq "\x89PNG"; return 'Jpeg' if ((substr($data,0,3) eq "\377\330\377") && ord(substr($data,3,1)) >= 0xc0); return 'Gif' if $magic eq "GIF8"; return 'Gd2' if $magic eq "gd2\000"; return 'Xpm' if substr($data,0,9) eq "/* XPM */"; return; } sub clone { croak("Usage: clone(\$image)") unless @_ == 1; my $self = shift; my ($x,$y) = $self->getBounds; my $new = $self->new($x,$y); return unless $new; $new->copy($self,0,0,0,0,$x,$y); return $new; } !NO!SUBS! if ($DEFINES =~ /HAVE_PNG/) { print OUT <<'!NO!SUBS!' sub newFromPng { croak("Usage: newFromPng(class,filehandle,[truecolor])") unless @_>=2; my($class) = shift; my($f) = shift; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromPng($fh,@_); } !NO!SUBS! } if ($DEFINES =~ /HAVE_JPEG/) { print OUT <<'!NO!SUBS!' sub newFromJpeg { croak("Usage: newFromJpeg(class,filehandle,[truecolor])") unless @_>=2; my($class) = shift; my($f) = shift; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromJpeg($fh,@_); } !NO!SUBS! } if ($DEFINES =~ /HAVE_GIF/) { print OUT <<'!NO!SUBS!' sub newFromGif { croak("Usage: newFromGif(class,filehandle,[truecolor])") unless @_>=2; my($class) = shift; my($f) = shift; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromGif($fh,@_); } !NO!SUBS! } if ($DEFINES =~ /HAVE_XBM/) { print OUT <<'!NO!SUBS!' sub newFromXbm { croak("Usage: newFromXbm(class,filehandle)") unless @_==2; my($class,$f) = @_; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromXbm($fh); } !NO!SUBS! } print OUT <<'!NO!SUBS!'; sub newFromWBMP { croak("Usage: newFromWBMP(class,filehandle,[truecolor])") unless @_>=2; my($class) = shift; my($f) = shift; my $fh = $class->_make_filehandle($f); binmode($fh); $class->_newFromWBMP($fh,@_); } !NO!SUBS! print OUT <<'!NO!SUBS!'; # Autoload methods go after __END__, and are processed by the autosplit program. 1; __END__ !NO!SUBS! close OUT or die "Can't close $file: $!"; chdir $origdir; GD-2.66/lib/GD/Polygon.pm0000644000076500001200000000766113076515043014142 0ustar rurbanadminpackage GD::Polygon; use strict; use Carp 'carp'; use GD; # old documentation error *GD::Polygon::delete = \&deletePt; =head1 NAME GD::Polygon - Polygon class for the GD image library =head1 SYNOPSIS See L =head1 DESCRIPTION See L =head1 AUTHOR The GD.pm interface is copyright 1995-2005, Lincoln D. Stein. It is distributed under the same terms as Perl itself. See the "Artistic License" in the Perl source code distribution for licensing terms. The latest versions of GD.pm are available on CPAN: http://www.cpan.org =head1 SEE ALSO L L, L, L, L =cut ### The polygon object ### # create a new polygon sub new { my $class = shift; return bless { 'length'=>0,'points'=>[] },$class; } # automatic destruction of the polygon sub DESTROY { my $self = shift; undef $self->{'points'}; } sub clear { my $self = shift; $self->{'points'} = []; } # add an x,y vertex to the polygon sub addPt { my($self,$x,$y) = @_; push(@{$self->{'points'}},[$x,$y]); $self->{'length'}++; } # get a vertex sub getPt { my($self,$index) = @_; return () unless ($index>=0) && ($index<$self->{'length'}); return @{$self->{'points'}->[$index]}; } # change the value of a vertex sub setPt { my($self,$index,$x,$y) = @_; unless (($index>=0) && ($index<$self->{'length'})) { carp "Attempt to set an undefined polygon vertex"; return undef; } @{$self->{'points'}->[$index]} = ($x,$y); 1; } # return the total number of vertices sub length { my $self = shift; return $self->{'length'}; } # return the array of vertices. # each vertex is an two-member (x,y) array sub vertices { my $self = shift; return @{$self->{'points'}}; } # return the bounding box of the polygon # (smallest rectangle that contains it) sub bounds { my $self = shift; my($top,$bottom,$left,$right) = @_; $top = 99999999; $bottom =-99999999; $left = 99999999; $right = -99999999; my $v; foreach $v ($self->vertices) { $left = $v->[0] if $left > $v->[0]; $right = $v->[0] if $right < $v->[0]; $top = $v->[1] if $top > $v->[1]; $bottom = $v->[1] if $bottom < $v->[1]; } return ($left,$top,$right,$bottom); } # delete a vertex, returning it, just for fun sub deletePt { my($self,$index) = @_; unless (($index>=0) && ($index<@{$self->{'points'}})) { carp "Attempt to delete an undefined polygon vertex"; return undef; } my($vertex) = splice(@{$self->{'points'}},$index,1); $self->{'length'}--; return @$vertex; } # translate the polygon in space by deltaX and deltaY sub offset { my($self,$dh,$dv) = @_; my $size = $self->length; my($i); for ($i=0;$i<$size;$i++) { my($x,$y)=$self->getPt($i); $self->setPt($i,$x+$dh,$y+$dv); } } # map the polygon from sourceRect to destRect, # translating and resizing it if necessary sub map { my($self,$srcL,$srcT,$srcR,$srcB,$destL,$destT,$destR,$destB) = @_; my($factorV) = ($destB-$destT)/($srcB-$srcT); my($factorH) = ($destR-$destL)/($srcR-$srcL); my($vertices) = $self->length; my($i); for ($i=0;$i<$vertices;$i++) { my($x,$y) = $self->getPt($i); $x = int($destL + ($x - $srcL) * $factorH); $y = int($destT + ($y - $srcT) * $factorV); $self->setPt($i,$x,$y); } } # These routines added by Winfriend Koenig. sub toPt { my($self, $dx, $dy) = @_; unless ($self->length > 0) { $self->addPt($dx,$dy); return; } my ($x, $y) = $self->getPt($self->length-1); $self->addPt($x+$dx,$y+$dy); } sub transform($$$$$$$) { # see PostScript Ref. page 154 my($self, $a, $b, $c, $d, $tx, $ty) = @_; my $size = $self->length; for (my $i=0;$i<$size;$i++) { my($x,$y)=$self->getPt($i); $self->setPt($i, $a*$x+$c*$y+$tx, $b*$x+$d*$y+$ty); } } sub scale { my($self, $sx, $sy, $cx, $cy) = @_; $self->offset(-$cx,-$cy) if defined $cx or defined $cy; $self->transform($sx,0,0,$sy,$cx,$cy); } 1; GD-2.66/lib/GD/Polyline.pm0000644000076500001200000005371213076515043014304 0ustar rurbanadmin############################################################################ # # Polyline.pm # # Author: Dan Harasty # Email: harasty@cpan.org # Version: 0.2 # Date: 2002/08/06 # # For usage documentation: see POD at end of file # # For changes: see "Changes" file included with distribution # use strict; package GD::Polyline; ############################################################################ # # GD::Polyline # ############################################################################ # # What's this? A class with nothing but a $VERSION and @ISA? # Below, this module overrides and adds several modules to # the parent class, GD::Polygon. Those updated/new methods # act on polygons and polylines, and sometimes those behaviours # vary slightly based on whether the object is a polygon or polyline. # use vars qw($VERSION @ISA); $VERSION = "0.2"; @ISA = qw(GD::Polygon); package GD::Polygon; ############################################################################ # # new methods on GD::Polygon # ############################################################################ use GD; use Carp 'croak','carp'; use vars qw($bezSegs $csr); $bezSegs = 20; # number of bezier segs -- number of segments in each portion of the spline produces by toSpline() $csr = 1/3; # control seg ratio -- the one possibly user-tunable parameter in the addControlPoints() algorithm sub rotate { my ($self, $angle, $cx, $cy) = @_; $self->offset(-$cx,-$cy) if $cx or $cy; $self->transform(cos($angle),sin($angle),-sin($angle),cos($angle),$cx,$cy); } sub centroid { my ($self, $scale) = @_; my ($cx,$cy); $scale = 1 unless defined $scale; map {$cx += $_->[0]; $cy += $_->[1]} $self->vertices(); $cx *= $scale / $self->length(); $cy *= $scale / $self->length(); return ($cx, $cy); } sub segLength { my $self = shift; my @points = $self->vertices(); my ($p1, $p2, @segLengths); $p1 = shift @points; # put the first vertex on the end to "close" a polygon, but not a polyline push @points, $p1 unless $self->isa('GD::Polyline'); while ($p2 = shift @points) { push @segLengths, _len($p1, $p2); $p1 = $p2; } return @segLengths if wantarray; my $sum; map {$sum += $_} @segLengths; return $sum; } sub segAngle { my $self = shift; my @points = $self->vertices(); my ($p1, $p2, @segAngles); $p1 = shift @points; # put the first vertex on the end to "close" a polygon, but not a polyline push @points, $p1 unless $self->isa('GD::Polyline'); while ($p2 = shift @points) { push @segAngles, _angle_reduce2(_angle($p1, $p2)); $p1 = $p2; } return @segAngles; } sub vertexAngle { my $self = shift; my @points = $self->vertices(); my ($p1, $p2, $p3, @vertexAngle); $p1 = $points[$#points]; # last vertex $p2 = shift @points; # current point -- the first vertex # put the first vertex on the end to "close" a polygon, but not a polyline push @points, $p2 unless $self->isa('GD::Polyline'); while ($p3 = shift @points) { push @vertexAngle, _angle_reduce2(_angle($p1, $p2, $p3)); ($p1, $p2) = ($p2, $p3); } $vertexAngle[0] = undef if defined $vertexAngle[0] and $self->isa("GD::Polyline"); return @vertexAngle if wantarray; } sub toSpline { my $self = shift; my @points = $self->vertices(); # put the first vertex on the end to "close" a polygon, but not a polyline push @points, [$self->getPt(0)] unless $self->isa('GD::Polyline'); unless (@points > 1 and @points % 3 == 1) { carp "Attempt to call toSpline() with invalid set of control points"; return undef; } my ($ap1, $dp1, $dp2, $ap2); # ap = anchor point, dp = director point $ap1 = shift @points; my $bez = new ref($self); $bez->addPt(@$ap1); while (@points) { ($dp1, $dp2, $ap2) = splice(@points, 0, 3); for (1..$bezSegs) { my ($t0, $t1, $c1, $c2, $c3, $c4, $x, $y); $t1 = $_/$bezSegs; $t0 = (1 - $t1); # possible optimization: # these coefficient could be calculated just once and # cached in an array for a given value of $bezSegs $c1 = $t0 * $t0 * $t0; $c2 = 3 * $t0 * $t0 * $t1; $c3 = 3 * $t0 * $t1 * $t1; $c4 = $t1 * $t1 * $t1; $x = $c1 * $ap1->[0] + $c2 * $dp1->[0] + $c3 * $dp2->[0] + $c4 * $ap2->[0]; $y = $c1 * $ap1->[1] + $c2 * $dp1->[1] + $c3 * $dp2->[1] + $c4 * $ap2->[1]; $bez->addPt($x, $y); } $ap1 = $ap2; } # remove the last anchor point if this is a polygon -- since it will autoclose without it $bez->deletePt($bez->length()-1) unless $self->isa('GD::Polyline'); return $bez; } sub addControlPoints { my $self = shift; my @points = $self->vertices(); unless (@points > 1) { carp "Attempt to call addControlPoints() with too few vertices in polyline"; return undef; } my $points = scalar(@points); my @segAngles = $self->segAngle(); my @segLengths = $self->segLength(); my ($prevLen, $nextLen, $prevAngle, $thisAngle, $nextAngle); my ($controlSeg, $pt, $ptX, $ptY, @controlSegs); # this loop goes about creating polylines -- here called control segments -- # that hold the control points for the final set of control points # each control segment has three points, and these are colinear # the first and last will ultimately be "director points", and # the middle point will ultimately be an "anchor point" for my $i (0..$#points) { $controlSeg = new GD::Polyline; $pt = $points[$i]; ($ptX, $ptY) = @$pt; if ($self->isa('GD::Polyline') and ($i == 0 or $i == $#points)) { $controlSeg->addPt($ptX, $ptY); # director point $controlSeg->addPt($ptX, $ptY); # anchor point $controlSeg->addPt($ptX, $ptY); # director point next; } $prevLen = $segLengths[$i-1]; $nextLen = $segLengths[$i]; $prevAngle = $segAngles[$i-1]; $nextAngle = $segAngles[$i]; # make a control segment with control points (director points) # before and after the point from the polyline (anchor point) $controlSeg->addPt($ptX - $csr * $prevLen, $ptY); # director point $controlSeg->addPt($ptX , $ptY); # anchor point $controlSeg->addPt($ptX + $csr * $nextLen, $ptY); # director point # note that: # - the line is parallel to the x-axis, as the points have a common $ptY # - the points are thus clearly colinear # - the director point is a distance away from the anchor point in proportion to the length of the segment it faces # now, we must come up with a reasonable angle for the control seg # first, "unwrap" $nextAngle w.r.t. $prevAngle $nextAngle -= 2*pi() until $nextAngle < $prevAngle + pi(); $nextAngle += 2*pi() until $nextAngle > $prevAngle - pi(); # next, use seg lengths as an inverse weighted average # to "tip" the control segment toward the *shorter* segment $thisAngle = ($nextAngle * $prevLen + $prevAngle * $nextLen) / ($prevLen + $nextLen); # rotate the control segment to $thisAngle about it's anchor point $controlSeg->rotate($thisAngle, $ptX, $ptY); } continue { # save the control segment for later push @controlSegs, $controlSeg; } # post process my $controlPoly = new ref($self); # collect all the control segments' points in to a single control poly foreach my $cs (@controlSegs) { foreach my $pt ($cs->vertices()) { $controlPoly->addPt(@$pt); } } # final clean up based on poly type if ($controlPoly->isa('GD::Polyline')) { # remove the first and last control point # since they are director points ... $controlPoly->deletePt(0); $controlPoly->deletePt($controlPoly->length()-1); } else { # move the first control point to the last control point # since it is supposed to end with two director points ... $controlPoly->addPt($controlPoly->getPt(0)); $controlPoly->deletePt(0); } return $controlPoly; } # The following helper functions are for internal # use of this module. Input arguments of "points" # refer to an array ref of two numbers, [$x, $y] # as is used internally in the GD::Polygon # # _len() # Find the length of a segment, passing in two points. # Internal function; NOT a class or object method. # sub _len { # my ($p1, $p2) = @_; # return sqrt(($p2->[0]-$p1->[0])**2 + ($p2->[1]-$p1->[1])**2); my $pt = _subtract(@_); return sqrt($pt->[0] ** 2 + $pt->[1] **2); } use Math::Trig; # _angle() # Find the angle of... well, depends on the number of arguments: # - one point: the angle from x-axis to the point (origin is the center) # - two points: the angle of the vector defined from point1 to point2 # - three points: # Internal function; NOT a class or object method. # sub _angle { my ($p1, $p2, $p3) = @_; my $angle = undef; if (@_ == 1) { return atan2($p1->[1], $p1->[0]); } if (@_ == 2) { return _angle(_subtract($p1, $p2)); } if (@_ == 3) { return _angle(_subtract($p2, $p3)) - _angle(_subtract($p2, $p1)); } } # _subtract() # Find the difference of two points; returns a point. # Internal function; NOT a class or object method. # sub _subtract { my ($p1, $p2) = @_; # print(_print_point($p2), "-", _print_point($p1), "\n"); return [$p2->[0]-$p1->[0], $p2->[1]-$p1->[1]]; } # _print_point() # Returns a string suitable for displaying the value of a point. # Internal function; NOT a class or object method. # sub _print_point { my ($p1) = @_; return "[" . join(", ", @$p1) . "]"; } # _angle_reduce1() # "unwraps" angle to interval -pi < angle <= +pi # Internal function; NOT a class or object method. # sub _angle_reduce1 { my ($angle) = @_; $angle += 2 * pi() while $angle <= -pi(); $angle -= 2 * pi() while $angle > pi(); return $angle; } # _angle_reduce2() # "unwraps" angle to interval 0 <= angle < 2 * pi # Internal function; NOT a class or object method. # sub _angle_reduce2 { my ($angle) = @_; $angle += 2 * pi() while $angle < 0; $angle -= 2 * pi() while $angle >= 2 * pi(); return $angle; } ############################################################################ # # new methods on GD::Image # ############################################################################ sub GD::Image::polyline { my $self = shift; # the GD::Image my $p = shift; # the GD::Polyline (or GD::Polygon) my $c = shift; # the color my @points = $p->vertices(); my $p1 = shift @points; my $p2; while ($p2 = shift @points) { $self->line(@$p1, @$p2, $c); $p1 = $p2; } } sub GD::Image::polydraw { my $self = shift; # the GD::Image my $p = shift; # the GD::Polyline or GD::Polygon my $c = shift; # the color return $self->polyline($p, $c) if $p->isa('GD::Polyline'); return $self->polygon($p, $c); } 1; __END__ =pod =head1 NAME GD::Polyline - Polyline object and Polygon utilities (including splines) for use with GD =head1 SYNOPSIS use GD; use GD::Polyline; # create an image $image = new GD::Image (500,300); $white = $image->colorAllocate(255,255,255); $black = $image->colorAllocate( 0, 0, 0); $red = $image->colorAllocate(255, 0, 0); # create a new polyline $polyline = new GD::Polyline; # add some points $polyline->addPt( 0, 0); $polyline->addPt( 0,100); $polyline->addPt( 50,125); $polyline->addPt(100, 0); # polylines can use polygon methods (and vice versa) $polyline->offset(200,100); # rotate 60 degrees, about the centroid $polyline->rotate(3.14159/3, $polyline->centroid()); # scale about the centroid $polyline->scale(1.5, 2, $polyline->centroid()); # draw the polyline $image->polydraw($polyline,$black); # create a spline, which is also a polyine $spline = $polyline->addControlPoints->toSpline; $image->polydraw($spline,$red); # output the png binmode STDOUT; print $image->png; =head1 DESCRIPTION B extends the GD module by allowing you to create polylines. Think of a polyline as "an open polygon", that is, the last vertex is not connected to the first vertex (unless you expressly add the same value as both points). For the remainder of this doc, "polyline" will refer to a GD::Polyline, "polygon" will refer to a GD::Polygon that is not a polyline, and "polything" and "$poly" may be either. The big feature added to GD by this module is the means to create splines, which are approximations to curves. =head1 The Polyline Object GD::Polyline defines the following class: =over 5 =item C A polyline object, used for storing lists of vertices prior to rendering a polyline into an image. =item C Cnew> I Create an empty polyline with no vertices. $polyline = new GD::Polyline; $polyline->addPt( 0, 0); $polyline->addPt( 0,100); $polyline->addPt( 50,100); $polyline->addPt(100, 0); $image->polydraw($polyline,$black); In fact GD::Polyline is a subclass of GD::Polygon, so all polygon methods (such as B and B) may be used on polylines. Some new methods have thus been added to GD::Polygon (such as B) and a few updated/modified/enhanced (such as B) I. See section "New or Updated GD::Polygon Methods" for more info. =back Note that this module is very "young" and should be considered subject to change in future releases, and/or possibly folded in to the existing polygon object and/or GD module. =head1 Updated Polygon Methods The following methods (defined in GD.pm) are OVERRIDDEN if you use this module. All effort has been made to provide 100% backward compatibility, but if you can confirm that has not been achieved, please consider that a bug and let the the author of Polyline.pm know. =over 5 =item C C<$poly-Escale($sx, $sy, $cx, $cy)> I Scale a polything in along x-axis by $sx and along the y-axis by $sy, about centery point ($cx, $cy). Center point ($cx, $cy) is optional -- if these are omitted, the function will scale about the origin. To flip a polything, use a scale factor of -1. For example, to flip the polything top to bottom about line y = 100, use: $poly->scale(1, -1, 0, 100); =back =head1 New Polygon Methods The following methods are added to GD::Polygon, and thus can be used by polygons and polylines. Don't forget: a polyline is a GD::Polygon, so GD::Polygon methods like offset() can be used, and they can be used in GD::Image methods like filledPolygon(). =over 5 =item C C<$poly-Erotate($angle, $cx, $cy)> I Rotate a polything through $angle (clockwise, in radians) about center point ($cx, $cy). Center point ($cx, $cy) is optional -- if these are omitted, the function will rotate about the origin In this function and other angle-oriented functions in GD::Polyline, positive $angle corresponds to clockwise rotation. This is opposite of the usual Cartesian sense, but that is because the raster is opposite of the usual Cartesian sense in that the y-axis goes "down". =item C C<($cx, $cy) = $poly-Ecentroid($scale)> I Calculate and return ($cx, $cy), the centroid of the vertices of the polything. For example, to rotate something 180 degrees about it's centroid: $poly->rotate(3.14159, $poly->centroid()); $scale is optional; if supplied, $cx and $cy are multiplied by $scale before returning. The main use of this is to shift an polything to the origin like this: $poly->offset($poly->centroid(-1)); =item C C<@segLengths = $poly-EsegLength()> I In array context, returns an array the lengths of the segments in the polything. Segment n is the segment from vertex n to vertex n+1. Polygons have as many segments as vertices; polylines have one fewer. In a scalar context, returns the sum of the array that would have been returned in the array context. =item C C<@segAngles = $poly-EsegAngle()> I Returns an array the angles of each segment from the x-axis. Segment n is the segment from vertex n to vertex n+1. Polygons have as many segments as vertices; polylines have one fewer. Returned angles will be on the interval 0 <= $angle < 2 * pi and angles increase in a clockwise direction. =item C C<@vertexAngles = $poly-EvertexAngle()> I Returns an array of the angles between the segment into and out of each vertex. For polylines, the vertex angle at vertex 0 and the last vertex are not defined; however $vertexAngle[0] will be undef so that $vertexAngle[1] will correspond to vertex 1. Returned angles will be on the interval 0 <= $angle < 2 * pi and angles increase in a clockwise direction. Note that this calculation does not attempt to figure out the "interior" angle with respect to "inside" or "outside" the polygon, but rather, just the angle between the adjacent segments in a clockwise sense. Thus a polygon with all right angles will have vertex angles of either pi/2 or 3*pi/2, depending on the way the polygon was "wound". =item C C<$poly-EtoSpline()> I Create a new polything which is a reasonably smooth curve using cubic spline algorithms, often referred to as Bezier curves. The "source" polything is called the "control polything". If it is a polyline, the control polyline must have 4, 7, 10, or some number of vertices of equal to 3n+1. If it is a polygon, the control polygon must have 3, 6, 9, or some number of vertices of equal to 3n. $spline = $poly->toSpline(); $image->polydraw($spline,$red); In brief, groups of four points from the control polyline are considered "control points" for a given portion of the spline: the first and fourth are "anchor points", and the spline passes through them; the second and third are "director points". The spline does not pass through director points, however the spline is tangent to the line segment from anchor point to adjacent director point. The next portion of the spline reuses the previous portion's last anchor point. The spline will have a cusp (non-continuous slope) at an anchor point, unless the anchor points and its adjacent director point are colinear. In the current implementation, toSpline() return a fixed number of segments in the returned polyline per set-of-four control points. In the future, this and other parameters of the algorithm may be configurable. =item C C<$polyline-EaddControlPoints()> I So you say: "OK. Splines sound cool. But how can I get my anchor points and its adjacent director point to be colinear so that I have a nice smooth curves from my polyline?" Relax! For The Lazy: addControlPoints() to the rescue. addControlPoints() returns a polyline that can serve as the control polyline for toSpline(), which returns another polyline which is the spline. Is your head spinning yet? Think of it this way: =over 5 =item + If you have a polyline, and you have already put your control points where you want them, call toSpline() directly. Remember, only every third vertex will be "on" the spline. You get something that looks like the spline "inscribed" inside the control polyline. =item + If you have a polyline, and you want all of its vertices on the resulting spline, call addControlPoints() and then toSpline(): $control = $polyline->addControlPoints(); $spline = $control->toSpline(); $image->polyline($spline,$red); You get something that looks like the control polyline "inscribed" inside the spline. =back Adding "good" control points is subjective; this particular algorithm reveals its author's tastes. In the future, you may be able to alter the taste slightly via parameters to the algorithm. For The Hubristic: please build a better one! And for The Impatient: note that addControlPoints() returns a polyline, so you can pile up the call like this, if you'd like: $image->polyline($polyline->addControlPoints()->toSpline(),$mauve); =back =head1 New GD::Image Methods =over 5 =item C C<$image-Epolyline(polyline,color)> I $image->polyline($polyline,$black) This draws a polyline with the specified color. Both real color indexes and the special colors gdBrushed, gdStyled and gdStyledBrushed can be specified. Neither the polyline() method or the polygon() method are very picky: you can call either method with either a GD::Polygon or a GD::Polyline. The I determines if the shape is "closed" or "open" as drawn, I the object type. =item C C<$image-Epolydraw(polything,color)> I $image->polydraw($poly,$black) This method draws the polything as expected (polygons are closed, polylines are open) by simply checking the object type and calling either $image->polygon() or $image->polyline(). =back =head1 Examples Please see file "polyline-examples.pl" that is included with the distribution. =head1 See Also For more info on Bezier splines, see http://www.webreference.com/dlab/9902/bezier.html. =head1 Future Features On the drawing board are additional features such as: - polygon winding algorithms (to determine if a point is "inside" or "outside" the polygon) - new polygon from bounding box - find bounding polygon (tightest fitting simple convex polygon for a given set of vertices) - addPts() method to add many points at once - clone() method for polygon - functions to interwork GD with SVG Please provide input on other possible features you'd like to see. =head1 Author This module has been written by Daniel J. Harasty. Please send questions, comments, complaints, and kudos to him at harasty@cpan.org. Thanks to Lincoln Stein for input and patience with me and this, my first CPAN contribution. =head1 Copyright Information The Polyline.pm module is copyright 2002, Daniel J. Harasty. It is distributed under the same terms as Perl itself. See the "Artistic License" in the Perl source code distribution for licensing terms. The latest version of Polyline.pm is available at your favorite CPAN repository and/or along with GD.pm by Lincoln D. Stein at http://stein.cshl.org/WWW/software/GD. =cut # future: # addPts # boundingPolygon # addControlPoints('method' => 'fitToSegments', 'numSegs' => 10) # toSpline('csr' => 1/4); # GD::Color # colorMap('x11' | 'svg' | ) # colorByName($image, 'orange'); # setImage($image); # cbn('orange'); # # # GD-2.66/lib/GD/Simple.pm0000644000076500001200000010710313077111156013732 0ustar rurbanadminpackage GD::Simple; =head1 NAME GD::Simple - Simplified interface to GD library =head1 SYNOPSIS For a nice tutorial on using this module, see Gabor Szabo's article at http://perlmaven.com/drawing-images-using-gd-simple. use GD::Simple; # create a new image $img = GD::Simple->new(400,250); # draw a red rectangle with blue borders $img->bgcolor('red'); $img->fgcolor('blue'); $img->rectangle(10,10,50,50); # draw an empty rectangle with green borders $img->bgcolor(undef); $img->fgcolor('green'); $img->rectangle(30,30,100,100); # move to (80,80) and draw a green line to (100,190) $img->moveTo(80,80); $img->lineTo(100,190); # draw a solid orange ellipse $img->moveTo(110,100); $img->bgcolor('orange'); $img->fgcolor('orange'); $img->ellipse(40,40); # draw a black filled arc $img->moveTo(150,150); $img->fgcolor('black'); $img->arc(50,50,0,100,gdNoFill|gdEdged); # draw a string at (10,180) using the default # built-in font $img->moveTo(10,180); $img->string('This is very simple'); # draw a string at (280,210) using 20 point # times italic, angled upward 90 degrees $img->moveTo(280,210); $img->font('Times:italic'); $img->fontsize(20); $img->angle(-90); $img->string('This is very fancy'); # some turtle graphics $img->moveTo(300,100); $img->penSize(3,3); $img->angle(0); $img->line(20); # 20 pixels going to the right $img->turn(30); # set turning angle to 30 degrees $img->line(20); # 20 pixel line $img->line(20); $img->line(20); $img->turn(-90); # set turning angle to -90 degrees $img->line(50); # 50 pixel line # draw a cyan polygon edged in blue my $poly = new GD::Polygon; $poly->addPt(150,100); $poly->addPt(199,199); $poly->addPt(100,199); $img->bgcolor('cyan'); $img->fgcolor('blue'); $img->penSize(1,1); $img->polygon($poly); # convert into png data print $img->png; =head1 DESCRIPTION GD::Simple is a subclass of the GD library that shortens many of the long GD method calls by storing information about the pen color, size and position in the GD object itself. It also adds a small number of "turtle graphics" style calls for those who prefer to work in polar coordinates. In addition, the library allows you to use symbolic names for colors, such as "chartreuse", and will manage the colors for you. =head2 The Pen GD::Simple maintains a "pen" whose settings are used for line- and shape-drawing operations. The pen has the following properties: =over 4 =item fgcolor The pen foreground color is the color of lines and the borders of filled and unfilled shapes. =item bgcolor The pen background color is the color of the contents of filled shapes. =item pensize The pen size is the width of the pen. Larger sizes draw thicker lines. =item position The pen position is its current position on the canvas in (X,Y) coordinates. =item angle When drawing in turtle mode, the pen angle determines the current direction of lines of relative length. =item turn When drawing in turtle mode, the turn determines the clockwise or counterclockwise angle that the pen will turn before drawing the next line. =item font The font to use when drawing text. Both built-in bitmapped fonts and TrueType fonts are supported. =item fontsize The size of the font to use when drawing with TrueType fonts. =back One sets the position and properties of the pen and then draws. As the drawing progresses, the position of the pen is updated. =head2 Methods GD::Simple introduces a number of new methods, a few of which have the same name as GD::Image methods, and hence change their behavior. In addition to these new methods, GD::Simple objects support all of the GD::Image methods. If you make a method call that isn't directly supported by GD::Simple, it refers the request to the underlying GD::Image object. Hence one can load a JPEG image into GD::Simple and declare it to be TrueColor by using this call, which is effectively inherited from GD::Image: my $img = GD::Simple->newFromJpeg('./myimage.jpg',1); The rest of this section describes GD::Simple-specific methods. =cut use strict; use GD; use GD::Group; use Math::Trig; use Carp 'croak'; our @ISA = 'Exporter'; our @EXPORT = @GD::EXPORT; our @EXPORT_OK = @GD::EXPORT_OK; our $AUTOLOAD; my %COLORS; my $IMAGECLASS = 'GD::Image'; my $TRANSPARENT; sub AUTOLOAD { my $self = shift; my($pack,$func_name) = $AUTOLOAD=~/(.+)::([^:]+)$/; return if $func_name eq 'DESTROY'; if (ref $self && exists $self->{gd}) { $self->{gd}->$func_name(@_); } else { my @result = $IMAGECLASS->$func_name(@_); if (UNIVERSAL::isa($result[0],'GD::Image')) { return $self->new($result[0]); } else { return @result; } } } =over 4 =item $img = GD::Simple->new($x,$y [,$truecolor]) =item $img = GD::Simple->new($gd) Create a new GD::Simple object. There are two forms of new(). In the first form, pass the width and height of the desired canvas, and optionally a boolean flag to request a truecolor image. In the second form, pass a previously-created GD::Image object. =cut # dual-purpose code - beware sub new { my $pack = shift; unshift @_,(100,100) if @_ == 0; if (@_ >= 2) { # traditional GD::Image->new() call my $gd = $IMAGECLASS->new(@_); my $self = $pack->new($gd); $self->clear; return $self; } if (@_ == 1) { # initialize from existing image my $gd = shift; my $self = bless { gd => $gd, xy => [0,0], font => gdSmallFont, fontsize => 9, turningangle => 0, angle => 0, pensize => 1, },$pack; $self->{bgcolor} = $self->translate_color(255,255,255); $self->{fgcolor} = $self->translate_color(0,0,0); return $self; } } =item GD::Simple->class('GD'); =item GD::Simple->class('GD::SVG'); Select whether new() should use GD or GD::SVG internally. Call GD::Simple->class('GD::SVG') before calling new() if you wish to generate SVG images. If future GD subclasses are created, this method will subport them. =cut sub class { my $pack = shift; if (@_) { $IMAGECLASS = shift; eval "require $IMAGECLASS; 1" or die $@; $IMAGECLASS = "$IMAGECLASS\:\:Image" if $IMAGECLASS eq 'GD::SVG'; } $IMAGECLASS; } =item $img->moveTo($x,$y) This call changes the position of the pen without drawing. It moves the pen to position ($x,$y) on the drawing canvas. =cut sub moveTo { my $self = shift; croak 'Usage GD::Simple->moveTo($x,$y)' unless @_ == 2; my ($x,$y) = @_; $self->{xy} = [$x,$y]; } =item $img->move($dx,$dy) =item $img->move($dr) This call changes the position of the pen without drawing. When called with two arguments it moves the pen $dx pixels to the right and $dy pixels downward. When called with one argument it moves the pen $dr pixels along the vector described by the current pen angle. =cut sub move { my $self = shift; if (@_ == 1) { # polar coordinates -- this is r $self->{angle} += $self->{turningangle}; my $angle = deg2rad($self->{angle}); $self->{xy}[0] += $_[0] * cos($angle); $self->{xy}[1] += $_[0] * sin($angle); } elsif (@_ == 2) { # cartesian coordinates $self->{xy}[0] += $_[0]; $self->{xy}[1] += $_[1]; } else { croak 'Usage GD::Simple->move($dx,$dy) or move($r)'; } } =item $img->lineTo($x,$y) The lineTo() call simultaneously draws and moves the pen. It draws a line from the current pen position to the position defined by ($x,$y) using the current pen size and color. After drawing, the position of the pen is updated to the new position. =cut sub lineTo { my $self = shift; croak 'Usage GD::Simple->lineTo($x,$y)' unless @_ == 2; $self->gd->line($self->curPos,@_,$self->fgcolor); $self->moveTo(@_); } =item $img->line($x1,$y1,$x2,$y2 [,$color]) =item $img->line($dx,$dy) =item $img->line($dr) The line() call simultaneously draws and moves the pen. When called with two arguments it draws a line from the current position of the pen to the position $dx pixels to the right and $dy pixels down. When called with one argument, it draws a line $dr pixels long along the angle defined by the current pen angle. When called with four or five arguments, line() behaves like GD::Image->line(). =cut sub line { my $self = shift; if (@_ >= 4) { my ($x1,$x2,$y1,$y2,$color) = @_; $color ||= $self->fgcolor; return $self->gd->line($x1,$x2,$y1,$y2,$color); } croak 'Usage GD::Simple->line($dx,$dy) or line($r) or line($x1,$y1,$x2,$y2 [,$color])' unless @_ >= 1; my @curPos = $self->curPos; $self->move(@_); my @newPos = $self->curPos; return $self->gd->line(@curPos,@newPos,$self->fgcolor); } =item $img->clear This method clears the canvas by painting over it with the current background color. =cut sub clear { my $self = shift; $self->gd->filledRectangle(0,0,$self->getBounds,$self->bgcolor); } =item $img->rectangle($x1,$y1,$x2,$y2) This method draws the rectangle defined by corners ($x1,$y1), ($x2,$y2). The rectangle's edges are drawn in the foreground color and its contents are filled with the background color. To draw a solid rectangle set bgcolor equal to fgcolor. To draw an unfilled rectangle (transparent inside), set bgcolor to undef. =cut sub rectangle { my $self = shift; return $self->gd->rectangle(@_) if @_ == 5; croak 'Usage GD::Simple->rectangle($x1,$y1,$x2,$y2)' unless @_ == 4; my $gd = $self->gd; my ($bg,$fg) = ($self->bgcolor,$self->fgcolor); $gd->filledRectangle(@_,$bg) if defined $bg; $gd->rectangle(@_,$fg) if defined $fg && (!defined $bg || $bg != $fg); } =item $img->ellipse($width,$height) This method draws the ellipse centered at the current location with width $width and height $height. The ellipse's border is drawn in the foreground color and its contents are filled with the background color. To draw a solid ellipse set bgcolor equal to fgcolor. To draw an unfilled ellipse (transparent inside), set bgcolor to undef. =cut sub ellipse { my $self = shift; return $self->gd->ellipse(@_) if @_ == 5; croak 'Usage GD::Simple->ellipse($width,$height)' unless @_ == 2; my $gd = $self->gd; my ($bg,$fg) = ($self->bgcolor,$self->fgcolor); $gd->filledEllipse($self->curPos,@_,$bg) if defined $bg; $gd->ellipse($self->curPos,@_,$fg) if defined $fg && (!defined $bg || $bg != $fg); } =item $img->arc([$cx,$cy,] $width,$height,$start,$end [,$style]) This method draws filled and unfilled arcs, at the current position, with the current fore- and background colors. See L for a description of the arguments. To draw a solid arc (such as a pie wedge) set bgcolor equal to fgcolor. To draw an unfilled arc, set bgcolor to undef. =cut sub arc { my $self = shift; return $self->gd->arc(@_) if @_ == 7; croak 'Usage GD::Simple->arc($width,$height,$start,$end[,$style])' unless @_ >= 4; my ($width,$height,$start,$end,$style) = @_; my $gd = $self->gd; my ($bg,$fg) = ($self->bgcolor,$self->fgcolor); my ($cx,$cy) = $self->curPos; if ($bg) { my @args = ($cx,$cy,$width,$height,$start,$end,$bg); push @args,$style if defined $style; $gd->filledArc(@args); } else { my @args = ($cx,$cy,$width,$height,$start,$end,$fg); $gd->arc(@args); } } =item $img->polygon($poly) This method draws filled and unfilled polygon using the current settings of fgcolor for the polygon border and bgcolor for the polygon fill color. See L for a description of creating polygons. To draw a solid polygon set bgcolor equal to fgcolor. To draw an unfilled polygon, set bgcolor to undef. =cut sub polygon { my $self = shift; croak 'Usage GD::Simple->polygon($poly)' unless @_ == 1; my $gd = $self->gd; my ($bg,$fg) = ($self->bgcolor,$self->fgcolor); $gd->filledPolygon(@_,$bg) if defined $bg; $gd->openPolygon(@_,$fg) if defined $fg && (!defined $bg || $bg != $fg); } =item $img->polyline($poly) This method draws polygons without closing the first and last vertices (similar to GD::Image->unclosedPolygon()). It uses the fgcolor to draw the line. =cut sub polyline { my $self = shift; croak 'Usage GD::Simple->polyline($poly)' unless @_ == 1; my $gd = $self->gd; my $fg = $self->fgcolor; $gd->unclosedPolygon(@_,$fg); } =item $img->string($string) This method draws the indicated string starting at the current position of the pen. The pen is moved to the end of the drawn string. Depending on the font selected with the font() method, this will use either a bitmapped GD font or a TrueType font. The angle of the pen will be consulted when drawing the text. For TrueType fonts, any angle is accepted. For GD bitmapped fonts, the angle can be either 0 (draw horizontal) or -90 (draw upwards). For consistency between the TrueType and GD font behavior, the string is always drawn so that the current position of the pen corresponds to the bottom left of the first character of the text. This is different from the GD behavior, in which the first character of bitmapped fonts hangs down from the pen point. This method returns a polygon indicating the bounding box of the rendered text. If an error occurred (such as invalid font specification) it returns undef and an error message in $@. =cut sub string { my $self = shift; return $self->gd->string(@_) if @_ == 5; my $string = shift; my $font = $self->font; my @bounds; if (ref $font && $font->isa('GD::Font')) { my ($x,$y) = $self->curPos; if ($self->angle == -90) { $x -= $font->height; $y -= $font->width; $self->gd->stringUp($font,$x,$y,$string,$self->fgcolor); $self->{xy}[1] -= length($string) * $font->width; @bounds = ( ($self->{xy}[0],$y), ($x,$y), ($x,$self->{xy}[1]-$font->width), ($self->{xy}[0],$self->{xy}[1]-$font->width) ); } else { $y -= $font->height; $self->gd->string($font,$x,$y,$string,$self->fgcolor); $self->{xy}[0] += length($string) * $font->width; @bounds = ( ($x,$self->{xy}[1]), ($self->{xy}[0],$self->{xy}[1]), ($self->{xy}[0],$y), ($x,$y) ); } } else { $self->useFontConfig(1); @bounds = $self->stringFT($self->fgcolor,$font, $self->fontsize,-deg2rad($self->angle), # -pi * $self->angle/180, $self->curPos,$string); return unless @bounds; my ($delta_x,$delta_y) = $self->_string_width(@bounds); $self->{xy}[0] += $delta_x; $self->{xy}[1] += $delta_y; } my $poly = GD::Polygon->new; while (@bounds) { $poly->addPt(splice(@bounds,0,2)); } return $poly; } =item $metrics = $img->fontMetrics =item ($metrics,$width,$height) = GD::Simple->fontMetrics($font,$fontsize,$string) This method returns information about the current font, most commonly a TrueType font. It can be invoked as an instance method (on a previously-created GD::Simple object) or as a class method (on the 'GD::Simple' class). When called as an instance method, fontMetrics() takes no arguments and returns a single hash reference containing the metrics that describe the currently selected font and size. The hash reference contains the following information: xheight the base height of the font from the bottom to the top of a lowercase 'm' ascent the length of the upper stem of the lowercase 'd' descent the length of the lower step of the lowercase 'j' lineheight the distance from the bottom of the 'j' to the top of the 'd' leading the distance between two adjacent lines =cut # return %$fontmetrics # keys: 'ascent', 'descent', 'lineheight', 'xheight', 'leading' sub fontMetrics { my $self = shift; unless (ref $self) { #class invocation -- create a scratch $self = $self->new; $self->font(shift) if defined $_[0]; $self->fontsize(shift) if defined $_[0]; } my $font = $self->font; my $metrics; if (ref $font && $font->isa('GD::Font')) { my $height = $font->height; $metrics = {ascent => 0, descent => 0, lineheight => $height, xheight => $height, leading => 0}; } else { $self->useFontConfig(1); my @mbounds = GD::Image->stringFT($self->fgcolor,$font, $self->fontsize,0, 0,0,'m'); my $xheight = $mbounds[3]-$mbounds[5]; my @jbounds = GD::Image->stringFT($self->fgcolor,$font, $self->fontsize,0, 0,0,'j'); my $ascent = $mbounds[7]-$jbounds[7]; my $descent = $jbounds[3]-$mbounds[3]; my @mmbounds = GD::Image->stringFT($self->fgcolor,$font, $self->fontsize,0, 0,0,"m\nm"); my $twolines = $mmbounds[3]-$mmbounds[5]; my $lineheight = $twolines - 2*$xheight; my $leading = $lineheight - $ascent - $descent; $metrics = {ascent => $ascent, descent => $descent, lineheight => $lineheight, xheight => $xheight, leading => $leading}; } if ((my $string = shift) && wantarray) { my ($width,$height) = $self->stringBounds($string); return ($metrics,abs($width),abs($height)); } return $metrics; } =item ($delta_x,$delta_y)= $img->stringBounds($string) This method indicates the X and Y offsets (which may be negative) that will occur when the given string is drawn using the current font, fontsize and angle. When the string is drawn horizontally, it gives the width and height of the string's bounding box. =cut sub stringBounds { my $self = shift; my $string = shift; my $font = $self->font; if (ref $font && $font->isa('GD::Font')) { if ($self->angle == -90) { return ($font->height,-length($string) * $font->width); } else { return (length($string) * $font->width,$font->height); } } else { $self->useFontConfig(1); my @bounds = GD::Image->stringFT($self->fgcolor,$font, $self->fontsize,-deg2rad($self->angle), $self->curPos,$string); return $self->_string_width(@bounds); } } =item $delta_x = $img->stringWidth($string) This method indicates the width of the string given the current font, fontsize and angle. It is the same as ($img->stringBounds($string))[0] =cut sub stringWidth { return ((shift->stringBounds(@_))[0]); } sub _string_width { my $self = shift; my @bounds = @_; my $delta_x = abs($bounds[2]-$bounds[0]); my $delta_y = abs($bounds[5]-$bounds[3]); my $angle = $self->angle % 360; if ($angle >= 0 && $angle < 90) { return ($delta_x,$delta_y); } elsif ($angle >= 90 && $angle < 180) { return (-$delta_x,$delta_y); } elsif ($angle >= 180 && $angle < 270) { return (-$delta_x,-$delta_y); } elsif ($angle >= 270 && $angle < 360) { return ($delta_x,-$delta_y); } } =item ($x,$y) = $img->curPos Return the current position of the pen. Set the current position using moveTo(). =cut sub curPos { @{shift->{xy}}; } =item $font = $img->font([$newfont] [,$newsize]) Get or set the current font. Fonts can be GD::Font objects, TrueType font file paths, or fontconfig font patterns like "Times:italic" (see L). The latter feature requires that you have the fontconfig library installed and are using libgd version 2.0.33 or higher. As a shortcut, you may pass two arguments to set the font and the fontsize simultaneously. The fontsize is only valid when drawing with TrueType fonts. =cut sub font { my $self = shift; $self->{font} = shift if @_; $self->{fontsize} = shift if @_; $self->{font}; } =item $size = $img->fontsize([$newfontsize]) Get or set the current font size. This is only valid for TrueType fonts. =cut sub fontsize { my $self = shift; $self->{fontsize} = shift if @_; $self->{fontsize}; } =item $size = $img->penSize([$newpensize]) Get or set the current pen width for use during line drawing operations. =cut sub penSize { my $self = shift; if (@_) { $self->{pensize} = shift; $self->gd->setThickness($self->{pensize}); } $self->{pensize}; } =item $angle = $img->angle([$newangle]) Set the current angle for use when calling line() or move() with a single argument. Here is an example of using turn() and angle() together to draw an octagon. The first line drawn is the downward-slanting top right edge. The last line drawn is the horizontal top of the octagon. $img->moveTo(200,50); $img->angle(0); $img->turn(360/8); for (1..8) { $img->line(50) } =cut sub angle { my $self = shift; $self->{angle} = shift if @_; $self->{angle}; } =item $angle = $img->turn([$newangle]) Get or set the current angle to turn prior to drawing lines. This value is only used when calling line() or move() with a single argument. The turning angle will be applied to each call to line() or move() just before the actual drawing occurs. Angles are in degrees. Positive values turn the angle clockwise. =cut # degrees, not radians sub turn { my $self = shift; $self->{turningangle} = shift if @_; $self->{turningangle}; } =item $color = $img->fgcolor([$newcolor]) Get or set the pen's foreground color. The current pen color can be set by (1) using an (r,g,b) triple; (2) using a previously-allocated color from the GD palette; or (3) by using a symbolic color name such as "chartreuse." The list of color names can be obtained using color_names(). The special color name 'transparent' will create a completely transparent color. =cut sub fgcolor { my $self = shift; $self->{fgcolor} = $self->translate_color(@_) if @_; $self->{fgcolor}; } =item $color = $img->bgcolor([$newcolor]) Get or set the pen's background color. The current pen color can be set by (1) using an (r,g,b) triple; (2) using a previously-allocated color from the GD palette; or (3) by using a symbolic color name such as "chartreuse." The list of color names can be obtained using color_names(). The special color name 'transparent' will create a completely transparent color. =cut sub bgcolor { my $self = shift; $self->{bgcolor} = $self->translate_color(@_) if @_; $self->{bgcolor}; } =item $index = $img->translate_color(@args) Translates a color into a GD palette or TrueColor index. You may pass either an (r,g,b) triple or a symbolic color name. If you pass a previously-allocated index, the method will return it unchanged. =cut sub translate_color { my $self = shift; return unless defined $_[0]; my ($r,$g,$b); if (@_ == 1 && $_[0] =~ /^-?\d+/) { # previously allocated index return $_[0]; } elsif (@_ == 3) { # (rgb triplet) ($r,$g,$b) = @_; } elsif (lc $_[0] eq 'transparent') { return $TRANSPARENT ||= $self->alphaColor('white',127); } else { $self->read_color_table unless %COLORS; die "unknown color" unless exists $COLORS{lc $_[0]}; ($r,$g,$b) = @{$COLORS{lc $_[0]}}; } return $self->colorResolve($r,$g,$b); } sub transparent { my $self = shift; my $index = $self->translate_color(@_); $self->gd->transparent($index); } =item $index = $img->alphaColor(@args,$alpha) Creates an alpha color. You may pass either an (r,g,b) triple or a symbolic color name, followed by an integer indicating its opacity. The opacity value ranges from 0 (fully opaque) to 127 (fully transparent). =cut sub alphaColor { my $self = shift; return unless defined $_[0]; my ($r,$g,$b,$a); if (@_ == 4) { # (rgb triplet) ($r,$g,$b,$a) = @_; } else { $self->read_color_table unless %COLORS; die "unknown color" unless exists $COLORS{lc $_[0]}; ($r,$g,$b) = @{$COLORS{lc $_[0]}}; $a = $_[1]; } return $self->colorAllocateAlpha($r,$g,$b,$a); } =item @names = GD::Simple->color_names =item $translate_table = GD::Simple->color_names Called in a list context, color_names() returns the list of symbolic color names recognized by this module. Called in a scalar context, the method returns a hash reference in which the keys are the color names and the values are array references containing [r,g,b] triples. =cut sub color_names { my $self = shift; $self->read_color_table unless %COLORS; return wantarray ? sort keys %COLORS : \%COLORS; } =item $gd = $img->gd Return the internal GD::Image object. Usually you will not need to call this since all GD methods are automatically referred to this object. =cut sub gd { shift->{gd} } sub read_color_table { my $class = shift; while () { chomp; last if /^__END__/; my ($name,$r,$g,$b) = split /\s+/; $COLORS{$name} = [hex $r,hex $g,hex $b]; } } sub setBrush { my $self = shift; my $brush = shift; if ($brush->isa('GD::Simple')) { $self->gd->setBrush($brush->gd); } else { $self->gd->setBrush($brush); } } =item ($red,$green,$blue) = GD::Simple->HSVtoRGB($hue,$saturation,$value) Convert a Hue/Saturation/Value (HSV) color into an RGB triple. The hue, saturation and value are integers from 0 to 255. =cut sub HSVtoRGB { my $self = shift; @_ == 3 or croak "Usage: GD::Simple->HSVtoRGB(\$hue,\$saturation,\$value)"; my ($h,$s,$v)=@_; my ($r,$g,$b,$i,$f,$p,$q,$t); if( $s == 0 ) { ## achromatic (grey) return ($v,$v,$v); } $h %= 255; $s /= 255; ## scale saturation from 0.0-1.0 $h /= 255; ## scale hue from 0 to 1.0 $h *= 360; ## and now scale it to 0 to 360 $h /= 60; ## sector 0 to 5 $i = $h % 6; $f = $h - $i; ## factorial part of h $p = $v * ( 1 - $s ); $q = $v * ( 1 - $s * $f ); $t = $v * ( 1 - $s * ( 1 - $f ) ); if($i<1) { $r = $v; $g = $t; $b = $p; } elsif($i<2){ $r = $q; $g = $v; $b = $p; } elsif($i<3){ $r = $p; $g = $v; $b = $t; } elsif($i<4){ $r = $p; $g = $q; $b = $v; } elsif($i<5){ $r = $t; $g = $p; $b = $v; } else { $r = $v; $g = $p; $b = $q; } return (int($r+0.5),int($g+0.5),int($b+0.5)); } =item ($hue,$saturation,$value) = GD::Simple->RGBtoHSV($red,$green,$blue) Convert a Red/Green/Blue (RGB) value into a Hue/Saturation/Value (HSV) triple. The hue, saturation and value are integers from 0 to 255. =back =cut sub RGBtoHSV { my $self = shift; my ($r, $g ,$bl) = @_; my ($min,undef,$max) = sort {$a<=>$b} ($r,$g,$bl); return (0,0,0) unless $max > 0; my $v = $max; my $s = 255 * ($max - $min)/$max; my $h; my $range = $max - $min; if ($range == 0) { # all colors are equal, so monochrome return (0,0,$max); } if ($max == $r) { $h = 60 * ($g-$bl)/$range; } elsif ($max == $g) { $h = 60 * ($bl-$r)/$range + 120; } else { $h = 60 * ($r-$g)/$range + 240; } $h += 360 if $h < 0; $h = int($h*255/360 + 0.5); return ($h, $s, $v); } sub newGroup { my $self = shift; return $self->GD::newGroup(@_); } 1; __DATA__ white FF FF FF black 00 00 00 aliceblue F0 F8 FF antiquewhite FA EB D7 aqua 00 FF FF aquamarine 7F FF D4 azure F0 FF FF beige F5 F5 DC bisque FF E4 C4 blanchedalmond FF EB CD blue 00 00 FF blueviolet 8A 2B E2 brown A5 2A 2A burlywood DE B8 87 cadetblue 5F 9E A0 chartreuse 7F FF 00 chocolate D2 69 1E coral FF 7F 50 cornflowerblue 64 95 ED cornsilk FF F8 DC crimson DC 14 3C cyan 00 FF FF darkblue 00 00 8B darkcyan 00 8B 8B darkgoldenrod B8 86 0B darkgray A9 A9 A9 darkgreen 00 64 00 darkkhaki BD B7 6B darkmagenta 8B 00 8B darkolivegreen 55 6B 2F darkorange FF 8C 00 darkorchid 99 32 CC darkred 8B 00 00 darksalmon E9 96 7A darkseagreen 8F BC 8F darkslateblue 48 3D 8B darkslategray 2F 4F 4F darkturquoise 00 CE D1 darkviolet 94 00 D3 deeppink FF 14 100 deepskyblue 00 BF FF dimgray 69 69 69 dodgerblue 1E 90 FF firebrick B2 22 22 floralwhite FF FA F0 forestgreen 22 8B 22 fuchsia FF 00 FF gainsboro DC DC DC ghostwhite F8 F8 FF gold FF D7 00 goldenrod DA A5 20 gray 80 80 80 green 00 80 00 greenyellow AD FF 2F honeydew F0 FF F0 hotpink FF 69 B4 indianred CD 5C 5C indigo 4B 00 82 ivory FF FF F0 khaki F0 E6 8C lavender E6 E6 FA lavenderblush FF F0 F5 lawngreen 7C FC 00 lemonchiffon FF FA CD lightblue AD D8 E6 lightcoral F0 80 80 lightcyan E0 FF FF lightgoldenrodyellow FA FA D2 lightgreen 90 EE 90 lightgrey D3 D3 D3 lightpink FF B6 C1 lightsalmon FF A0 7A lightseagreen 20 B2 AA lightskyblue 87 CE FA lightslategray 77 88 99 lightsteelblue B0 C4 DE lightyellow FF FF E0 lime 00 FF 00 limegreen 32 CD 32 linen FA F0 E6 magenta FF 00 FF maroon 80 00 00 mediumaquamarine 66 CD AA mediumblue 00 00 CD mediumorchid BA 55 D3 mediumpurple 100 70 DB mediumseagreen 3C B3 71 mediumslateblue 7B 68 EE mediumspringgreen 00 FA 9A mediumturquoise 48 D1 CC mediumvioletred C7 15 85 midnightblue 19 19 70 mintcream F5 FF FA mistyrose FF E4 E1 moccasin FF E4 B5 navajowhite FF DE AD navy 00 00 80 oldlace FD F5 E6 olive 80 80 00 olivedrab 6B 8E 23 orange FF A5 00 orangered FF 45 00 orchid DA 70 D6 palegoldenrod EE E8 AA palegreen 98 FB 98 paleturquoise AF EE EE palevioletred DB 70 100 papayawhip FF EF D5 peachpuff FF DA B9 peru CD 85 3F pink FF C0 CB plum DD A0 DD powderblue B0 E0 E6 purple 80 00 80 red FF 00 00 rosybrown BC 8F 8F royalblue 41 69 E1 saddlebrown 8B 45 13 salmon FA 80 72 sandybrown F4 A4 60 seagreen 2E 8B 57 seashell FF F5 EE sienna A0 52 2D silver C0 C0 C0 skyblue 87 CE EB slateblue 6A 5A CD slategray 70 80 90 snow FF FA FA springgreen 00 FF 7F steelblue 46 82 B4 tan D2 B4 8C teal 00 80 80 thistle D8 BF D8 tomato FF 63 47 turquoise 40 E0 D0 violet EE 82 EE wheat F5 DE B3 whitesmoke F5 F5 F5 yellow FF FF 00 yellowgreen 9A CD 32 gradient1 00 ff 00 gradient2 0a ff 00 gradient3 14 ff 00 gradient4 1e ff 00 gradient5 28 ff 00 gradient6 32 ff 00 gradient7 3d ff 00 gradient8 47 ff 00 gradient9 51 ff 00 gradient10 5b ff 00 gradient11 65 ff 00 gradient12 70 ff 00 gradient13 7a ff 00 gradient14 84 ff 00 gradient15 8e ff 00 gradient16 99 ff 00 gradient17 a3 ff 00 gradient18 ad ff 00 gradient19 b7 ff 00 gradient20 c1 ff 00 gradient21 cc ff 00 gradient22 d6 ff 00 gradient23 e0 ff 00 gradient24 ea ff 00 gradient25 f4 ff 00 gradient26 ff ff 00 gradient27 ff f4 00 gradient28 ff ea 00 gradient29 ff e0 00 gradient30 ff d6 00 gradient31 ff cc 00 gradient32 ff c1 00 gradient33 ff b7 00 gradient34 ff ad 00 gradient35 ff a3 00 gradient36 ff 99 00 gradient37 ff 8e 00 gradient38 ff 84 00 gradient39 ff 7a 00 gradient40 ff 70 00 gradient41 ff 65 00 gradient42 ff 5b 00 gradient43 ff 51 00 gradient44 ff 47 00 gradient45 ff 3d 00 gradient46 ff 32 00 gradient47 ff 28 00 gradient48 ff 1e 00 gradient49 ff 14 00 gradient50 ff 0a 00 __END__ =head1 COLORS This script will create an image showing all the symbolic colors. #!/usr/bin/perl use strict; use GD::Simple; my @color_names = GD::Simple->color_names; my $cols = int(sqrt(@color_names)); my $rows = int(@color_names/$cols)+1; my $cell_width = 100; my $cell_height = 50; my $legend_height = 16; my $width = $cols * $cell_width; my $height = $rows * $cell_height; my $img = GD::Simple->new($width,$height); $img->font(gdSmallFont); for (my $c=0; $c<$cols; $c++) { for (my $r=0; $r<$rows; $r++) { my $color = $color_names[$c*$rows + $r] or next; my @topleft = ($c*$cell_width,$r*$cell_height); my @botright = ($topleft[0]+$cell_width,$topleft[1]+$cell_height-$legend_height); $img->bgcolor($color); $img->fgcolor($color); $img->rectangle(@topleft,@botright); $img->moveTo($topleft[0]+2,$botright[1]+$legend_height-2); $img->fgcolor('black'); $img->string($color); } } print $img->png; =head1 AUTHOR The GD::Simple module is copyright 2004, Lincoln D. Stein. It is distributed under the same terms as Perl itself. See the "Artistic License" in the Perl source code distribution for licensing terms. The latest versions of GD.pm are available at https://github.com/lstein/Perl-GD =head1 SEE ALSO L, L, L, L =cut GD-2.66/lib/GD.pm0000644000076500001200000020336113077111021012473 0ustar rurbanadminpackage GD; # Copyright 1995 Lincoln D. Stein. See accompanying README file for # usage information use strict; require 5.004; require FileHandle; require Exporter; require DynaLoader; require AutoLoader; use Carp 'croak','carp'; use GD::Image; use GD::Polygon; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD); $VERSION = '2.66'; our $XS_VERSION = $VERSION; $VERSION = eval $VERSION; @ISA = qw(Exporter DynaLoader); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @EXPORT = qw( gdBrushed gdDashSize gdMaxColors gdStyled gdStyledBrushed gdTiled gdTransparent gdAntiAliased gdArc gdChord gdPie gdNoFill gdEdged gdTinyFont gdSmallFont gdMediumBoldFont gdLargeFont gdGiantFont gdAlphaMax gdAlphaOpaque gdAlphaTransparent ); @EXPORT_OK = qw ( GD_CMP_IMAGE GD_CMP_NUM_COLORS GD_CMP_COLOR GD_CMP_SIZE_X GD_CMP_SIZE_Y GD_CMP_TRANSPARENT GD_CMP_BACKGROUND GD_CMP_INTERLACE GD_CMP_TRUECOLOR ); %EXPORT_TAGS = ('cmp' => [ @EXPORT_OK ] ); # documentation error *GD::Polygon::delete = \&GD::Polygon::deletePt; sub AUTOLOAD { # This AUTOLOAD is used to 'autoload' constants from the constant() # XS function. If a constant is not found then control is passed # to the AUTOLOAD in AutoLoader. my($constname); ($constname = $AUTOLOAD) =~ s/.*:://; undef $!; my $val = constant($constname); if ($! != 0) { if ($! =~ /Invalid/) { $AutoLoader::AUTOLOAD = $AUTOLOAD; goto &AutoLoader::AUTOLOAD; } else { my($pack,$file,$line) = caller; die "Your vendor has not defined GD macro $pack\:\:$constname, used at $file line $line $!.\n"; } } eval "sub $AUTOLOAD { $val }"; goto &$AUTOLOAD; } bootstrap GD; # Preloaded methods go here. sub GD::gdSmallFont { return GD::Font->Small; } sub GD::gdLargeFont { return GD::Font->Large; } sub GD::gdMediumBoldFont { return GD::Font->MediumBold; } sub GD::gdTinyFont { return GD::Font->Tiny; } sub GD::gdGiantFont { return GD::Font->Giant; } sub GD::Image::startGroup { } # does nothing - used by GD::SVG sub GD::Image::endGroup { } # does nothing - used by GD::SVG sub GD::Image::newGroup { my $self = shift; GD::Group->new($self,$self->startGroup); } =head1 NAME GD.pm - Interface to Gd Graphics Library =head1 SYNOPSIS use GD; # create a new image $im = new GD::Image(100,100); # allocate some colors $white = $im->colorAllocate(255,255,255); $black = $im->colorAllocate(0,0,0); $red = $im->colorAllocate(255,0,0); $blue = $im->colorAllocate(0,0,255); # make the background transparent and interlaced $im->transparent($white); $im->interlaced('true'); # Put a black frame around the picture $im->rectangle(0,0,99,99,$black); # Draw a blue oval $im->arc(50,50,95,75,0,360,$blue); # And fill it with red $im->fill(50,50,$red); # make sure we are writing to a binary stream binmode STDOUT; # Convert the image to PNG and print it on standard output print $im->png; =head1 DESCRIPTION B is a Perl interface to Thomas Boutell's gd graphics library (version 2.01 or higher; see below). GD allows you to create color drawings using a large number of graphics primitives, and emit the drawings as PNG files. GD defines the following four classes: =over 5 =item C An image class, which holds the image data and accepts graphic primitive method calls. =item C A font class, which holds static font information and used for text rendering. =item C A simple polygon object, used for storing lists of vertices prior to rendering a polygon into an image. =item C A "simple" class that simplifies the GD::Image API and then adds a set of object-oriented drawing methods using turtle graphics, simplified font handling, ability to work in polar coordinates, HSV color spaces, and human-readable color names like "lightblue". Please see L for a description of these methods. =back A Simple Example: #!/usr/bin/perl use GD; # create a new image $im = new GD::Image(100,100); # allocate some colors $white = $im->colorAllocate(255,255,255); $black = $im->colorAllocate(0,0,0); $red = $im->colorAllocate(255,0,0); $blue = $im->colorAllocate(0,0,255); # make the background transparent and interlaced $im->transparent($white); $im->interlaced('true'); # Put a black frame around the picture $im->rectangle(0,0,99,99,$black); # Draw a blue oval $im->arc(50,50,95,75,0,360,$blue); # And fill it with red $im->fill(50,50,$red); # make sure we are writing to a binary stream binmode STDOUT; # Convert the image to PNG and print it on standard output print $im->png; Notes: =over 5 =item 1. To create a new, empty image, send a new() message to GD::Image, passing it the width and height of the image you want to create. An image object will be returned. Other class methods allow you to initialize an image from a preexisting JPG, PNG, GD, GD2 or XBM file. =item 2. Next you will ordinarily add colors to the image's color table. colors are added using a colorAllocate() method call. The three parameters in each call are the red, green and blue (rgb) triples for the desired color. The method returns the index of that color in the image's color table. You should store these indexes for later use. =item 3. Now you can do some drawing! The various graphics primitives are described below. In this example, we do some text drawing, create an oval, and create and draw a polygon. =item 4. Polygons are created with a new() message to GD::Polygon. You can add points to the returned polygon one at a time using the addPt() method. The polygon can then be passed to an image for rendering. =item 5. When you're done drawing, you can convert the image into PNG format by sending it a png() message. It will return a (potentially large) scalar value containing the binary data for the image. Ordinarily you will print it out at this point or write it to a file. To ensure portability to platforms that differentiate between text and binary files, be sure to call C on the file you are writing the image to. =back =head1 Object Constructors: Creating Images The following class methods allow you to create new GD::Image objects. =over 4 =item B<$image = GD::Image-Enew([$width,$height],[$truecolor])> =item B<$image = GD::Image-Enew(*FILEHANDLE)> =item B<$image = GD::Image-Enew($filename)> =item B<$image = GD::Image-Enew($data)> The new() method is the main constructor for the GD::Image class. Called with two integer arguments, it creates a new blank image of the specified width and height. For example: $myImage = new GD::Image(100,100) || die; This will create an image that is 100 x 100 pixels wide. If you don't specify the dimensions, a default of 64 x 64 will be chosen. The optional third argument, $truecolor, tells new() to create a truecolor GD::Image object. Truecolor images have 24 bits of color data (eight bits each in the red, green and blue channels respectively), allowing for precise photograph-quality color usage. If not specified, the image will use an 8-bit palette for compatibility with older versions of libgd. Alternatively, you may create a GD::Image object based on an existing image by providing an open filehandle, a filename, or the image data itself. The image formats automatically recognized and accepted are: PNG, JPEG, XPM and GD2. Other formats, including WBMP, and GD version 1, cannot be recognized automatically at this time. If something goes wrong (e.g. insufficient memory), this call will return undef. =item B<$image = GD::Image-EtrueColor([0,1])> For backwards compatibility with scripts previous versions of GD, new images created from scratch (width, height) are palette based by default. To change this default to create true color images use: GD::Image->trueColor(1); before creating new images. To switch back to palette based by default, use: GD::Image->trueColor(0); =item B<$image = GD::Image-EnewPalette([$width,$height])> =item B<$image = GD::Image-EnewTrueColor([$width,$height])> The newPalette() and newTrueColor() methods can be used to explicitly create an palette based or true color image regardless of the current setting of trueColor(). =item B<$image = GD::Image-EnewFromPng($file, [$truecolor])> =item B<$image = GD::Image-EnewFromPngData($data, [$truecolor])> The newFromPng() method will create an image from a PNG file read in through the provided filehandle or file path. The filehandle must previously have been opened on a valid PNG file or pipe. If successful, this call will return an initialized image which you can then manipulate as you please. If it fails, which usually happens if the thing at the other end of the filehandle is not a valid PNG file, the call returns undef. Notice that the call doesn't automatically close the filehandle for you. But it does call C for you, on platforms where this matters. You may use any of the following as the argument: 1) a simple filehandle, such as STDIN 2) a filehandle glob, such as *PNG 3) a reference to a glob, such as \*PNG 4) an IO::Handle object 5) the pathname of a file In the latter case, newFromPng() will attempt to open the file for you and read the PNG information from it. Example1: open (PNG,"barnswallow.png") || die; $myImage = newFromPng GD::Image(\*PNG) || die; close PNG; Example2: $myImage = newFromPng GD::Image('barnswallow.png'); To get information about the size and color usage of the information, you can call the image query methods described below. Images created by reading PNG images will be truecolor if the image file itself is truecolor. To force the image to be palette-based, pass a value of 0 in the optional $truecolor argument. The newFromPngData() method will create a new GD::Image initialized with the PNG format B contained in C<$data>. =item B<$image = GD::Image-EnewFromJpeg($file, [$truecolor])> =item B<$image = GD::Image-EnewFromJpegData($data, [$truecolor])> These methods will create an image from a JPEG file. They work just like newFromPng() and newFromPngData(), and will accept the same filehandle and pathname arguments. Images created by reading JPEG images will always be truecolor. To force the image to be palette-based, pass a value of 0 in the optional $truecolor argument. =item B<$image = GD::Image-EnewFromGif($file, [$truecolor])> =item B<$image = GD::Image-EnewFromGifData($data)> These methods will create an image from a GIF file. They work just like newFromPng() and newFromPngData(), and will accept the same filehandle and pathname arguments. Images created from GIFs are always 8-bit palette images. To convert to truecolor, you must create a truecolor image and then perform a copy. =item B<$image = GD::Image-EnewFromXbm($file, [$truecolor])> This works in exactly the same way as C, but reads the contents of an X Bitmap (black & white) file: open (XBM,"coredump.xbm") || die; $myImage = newFromXbm GD::Image(\*XBM) || die; close XBM; There is no newFromXbmData() function, because there is no corresponding function in the gd library. =item B<$image = GD::Image-EnewFromWBMP($file, [$truecolor])> This works in exactly the same way as C, but reads the contents of an Windows BMP Bitmap file: open (BMP,"coredump.bmp") || die; $myImage = newFromWBMP GD::Image(\*BMP) || die; close BMP; There is no newFromWBMPData() function, because there is no corresponding function in the gd library. =item B<$image = GD::Image-EnewFromGd($file)> =item B<$image = GD::Image-EnewFromGdData($data)> These methods initialize a GD::Image from a Gd file, filehandle, or data. Gd is Tom Boutell's disk-based storage format, intended for the rare case when you need to read and write the image to disk quickly. It's not intended for regular use, because, unlike PNG or JPEG, no image compression is performed and these files can become B. $myImage = newFromGd GD::Image("godzilla.gd") || die; close GDF; =item B<$image = GD::Image-EnewFromGd2($file)> =item B<$image = GD::Image-EnewFromGd2Data($data)> This works in exactly the same way as C and newFromGdData, but use the new compressed GD2 image format. =item B<$image = GD::Image-EnewFromGd2Part($file,srcX,srcY,width,height)> This class method allows you to read in just a portion of a GD2 image file. In addition to a filehandle, it accepts the top-left corner and dimensions (width,height) of the region of the image to read. For example: open (GDF,"godzilla.gd2") || die; $myImage = GD::Image->newFromGd2Part(\*GDF,10,20,100,100) || die; close GDF; This reads a 100x100 square portion of the image starting from position (10,20). =item B<$image = GD::Image-EnewFromXpm($filename)> This creates a new GD::Image object starting from a B. This is unlike the other newFrom() functions because it does not take a filehandle. This difference comes from an inconsistency in the underlying gd library. $myImage = newFromXpm GD::Image('earth.xpm') || die; This function is only available if libgd was compiled with XPM support. NOTE: The libgd library is unable to read certain XPM files, returning an all-black image instead. =back =head1 GD::Image Methods Once a GD::Image object is created, you can draw with it, copy it, and merge two images. When you are finished manipulating the object, you can convert it into a standard image file format to output or save to a file. =head2 Image Data Output Methods The following methods convert the internal drawing format into standard output file formats. =over =item B<$pngdata = $image-Epng([$compression_level])> This returns the image data in PNG format. You can then print it, pipe it to a display program, or write it to a file. Example: $png_data = $myImage->png; open (DISPLAY,"| display -") || die; binmode DISPLAY; print DISPLAY $png_data; close DISPLAY; Note the use of C. This is crucial for portability to DOSish platforms. The optional $compression_level argument controls the amount of compression to apply to the output PNG image. Values range from 0-9, where 0 means no compression (largest files, highest quality) and 9 means maximum compression (smallest files, worst quality). A compression level of -1 uses the default compression level selected when zlib was compiled on your system, and is the same as calling png() with no argument. Be careful not to confuse this argument with the jpeg() quality argument, which ranges from 0-100 and has the opposite meaning from compression (higher numbers give higher quality). =item B<$gifdata = $image-Egifanimbegin([$GlobalCM [, $Loops]])> For libgd version 2.0.33 and higher, this call begins an animated GIF by returning the data that comprises animated gif image file header. After you call this method, call gifanimadd() one or more times to add the frames of the image. Then call gifanimend(). Each frame must be the same width and height. A typical sequence will look like this: my $gifdata = $image->gifanimbegin; $gifdata .= $image->gifanimadd; # first frame for (1..100) { # make a frame of right size my $frame = GD::Image->new($image->getBounds); add_frame_data($frame); # add the data for this frame $gifdata .= $frame->gifanimadd; # add frame } $gifdata .= $image->gifanimend; # finish the animated GIF print $gifdata; # write animated gif to STDOUT If you do not wish to store the data in memory, you can print it to stdout or a file. The image that you call gifanimbegin on is used to set the image size, color resolution and color map. If argument $GlobalCM is 1, the image color map becomes the GIF89a global color map. If $Loops is given and >= 0, the NETSCAPE2.0 application extension is created, with looping count. Looping count 0 means forever. =item B<$gifdata = $image-Egifanimadd([$LocalCM [, $LeftOfs [, $TopOfs [, $Delay [, $Disposal [, $previm]]]]]])> Returns the data that comprises one animated gif image frame. You can then print it, pipe it to a display program, or write it to a file. With $LeftOfs and $TopOfs you can place this frame in different offset than (0,0) inside the image screen. Delay between the previous frame and this frame is in 1/100s units. Disposal is usually and by default 1. Compression is activated by giving the previous image as a parameter. This function then compares the images and only writes the changed pixels to the new frame in animation. The Disposal parameter for optimized animations must be set to 1, also for the first frame. $LeftOfs and $TopOfs parameters are ignored for optimized frames. =item B<$gifdata = $image-Egifanimend()> Returns the data for end segment of animated gif file. It always returns string ';'. This string must be printed to an animated gif file after all image frames to properly terminate it according to GIF file syntax. Image object is not used at all in this method. =item B<$jpegdata = $image-Ejpeg([$quality])> This returns the image data in JPEG format. You can then print it, pipe it to a display program, or write it to a file. You may pass an optional quality score to jpeg() in order to control the JPEG quality. This should be an integer between 0 and 100. Higher quality scores give larger files and better image quality. If you don't specify the quality, jpeg() will choose a good default. =item B<$gifdata = $image-Egif()>. This returns the image data in GIF format. You can then print it, pipe it to a display program, or write it to a file. =item B<$gddata = $image-Egd> This returns the image data in GD format. You can then print it, pipe it to a display program, or write it to a file. Example: binmode MYOUTFILE; print MYOUTFILE $myImage->gd; =item B<$gd2data = $image-Egd2> Same as gd(), except that it returns the data in compressed GD2 format. =item B<$wbmpdata = $image-Ewbmp([$foreground])> This returns the image data in WBMP format, which is a black-and-white image format. Provide the index of the color to become the foreground color. All other pixels will be considered background. =back =head2 Color Control These methods allow you to control and manipulate the GD::Image color table for palette, non-truecolor images. =over 4 =item B<$index = $image-EcolorAllocate(red,green,blue)> This allocates a color with the specified red, green and blue components and returns its index in the color table, if specified. The first color allocated in this way becomes the image's background color. (255,255,255) is white (all pixels on). (0,0,0) is black (all pixels off). (255,0,0) is fully saturated red. (127,127,127) is 50% gray. You can find plenty of examples in /usr/X11/lib/X11/rgb.txt. If no colors are allocated, then this function returns -1. Example: $black = $myImage->colorAllocate(0,0,0); #background color $white = $myImage->colorAllocate(255,255,255); $peachpuff = $myImage->colorAllocate(255,218,185); =item B<$index = $image-EcolorAllocateAlpha(reg,green,blue,alpha)> This allocates a color with the specified red, green, and blue components, plus the specified alpha channel. The alpha value may range from 0 (opaque) to 127 (transparent). The C function changes the way this alpha channel affects the resulting image. =item B<$image-EcolorDeallocate(colorIndex)> This marks the color at the specified index as being ripe for reallocation. The next time colorAllocate is used, this entry will be replaced. You can call this method several times to deallocate multiple colors. There's no function result from this call. Example: $myImage->colorDeallocate($peachpuff); $peachy = $myImage->colorAllocate(255,210,185); =item B<$index = $image-EcolorClosest(red,green,blue)> This returns the index of the color closest in the color table to the red green and blue components specified. If no colors have yet been allocated, then this call returns -1. Example: $apricot = $myImage->colorClosest(255,200,180); =item B<$index = $image-EcolorClosestAlpha(red,green,blue,alpha)> This returns the index of the color closest in the color table to the red green blue and alpha components specified. If no colors have yet been allocated, then this call returns -1. Example: $apricot = $myImage->colorClosestAlpha(255,200,180,0); =item B<$index = $image-EcolorClosestHWB(red,green,blue)> This also attempts to return the color closest in the color table to the red green and blue components specified. It uses a Hue/White/Black color representation to make the selected color more likely to match human perceptions of similar colors. If no colors have yet been allocated, then this call returns -1. Example: $mostred = $myImage->colorClosestHWB(255,0,0); =item B<$index = $image-EcolorExact(red,green,blue)> This returns the index of a color that exactly matches the specified red green and blue components. If such a color is not in the color table, this call returns -1. $rosey = $myImage->colorExact(255,100,80); warn "Everything's coming up roses.\n" if $rosey >= 0; =item B<$index = $image-EcolorExactAlpha(red,green,blue,alpha)> This returns the index of a color that exactly matches the specified red green blue and alpha components. If such a color is not in the color table, this call returns -1. $rosey = $myImage->colorExactAlpha(255,100,80,0); warn "Everything's coming up roses.\n" if $rosey >= 0; =item B<$index = $image-EcolorResolve(red,green,blue)> This returns the index of a color that exactly matches the specified red green and blue components. If such a color is not in the color table and there is room, then this method allocates the color in the color table and returns its index. $rosey = $myImage->colorResolve(255,100,80); warn "Everything's coming up roses.\n" if $rosey >= 0; =item B<$index = $image-EcolorResolveAlpha(red,green,blue,alpha)> This returns the index of a color that exactly matches the specified red green blue and alpha components. If such a color is not in the color table and there is room, then this method allocates the color in the color table and returns its index. $rosey = $myImage->colorResolveAlpha(255,100,80,0); warn "Everything's coming up roses.\n" if $rosey >= 0; =item B<$colorsTotal = $image-EcolorsTotal> I This returns the total number of colors allocated in the object. $maxColors = $myImage->colorsTotal; In the case of a TrueColor image, this call will return undef. =item B<$index = $image-EgetPixel(x,y)> I This returns the color table index underneath the specified point. It can be combined with rgb() to obtain the rgb color underneath the pixel. Example: $index = $myImage->getPixel(20,100); ($r,$g,$b) = $myImage->rgb($index); =item B<($red,$green,$blue) = $image-Ergb($index)> This returns a list containing the red, green and blue components of the specified color index. Example: @RGB = $myImage->rgb($peachy); =item B<($alpha) = $image-Ealpha($index)> This returns an item containing the alpha component of the specified color index. Example: @RGB = $myImage->rgb($peachy); =item B<$image-Etransparent($colorIndex)> This marks the color at the specified index as being transparent. Portions of the image drawn in this color will be invisible. This is useful for creating paintbrushes of odd shapes, as well as for making PNG backgrounds transparent for displaying on the Web. Only one color can be transparent at any time. To disable transparency, specify -1 for the index. If you call this method without any parameters, it will return the current index of the transparent color, or -1 if none. Example: open(PNG,"test.png"); $im = newFromPng GD::Image(PNG); $white = $im->colorClosest(255,255,255); # find white $im->transparent($white); binmode STDOUT; print $im->png; =back =head2 Special Colors GD implements a number of special colors that can be used to achieve special effects. They are constants defined in the GD:: namespace, but automatically exported into your namespace when the GD module is loaded. =over 4 =item B<$image-EsetBrush($image)> You can draw lines and shapes using a brush pattern. Brushes are just images that you can create and manipulate in the usual way. When you draw with them, their contents are used for the color and shape of the lines. To make a brushed line, you must create or load the brush first, then assign it to the image using setBrush(). You can then draw in that with that brush using the B special color. It's often useful to set the background of the brush to transparent so that the non-colored parts don't overwrite other parts of your image. Example: # Create a brush at an angle $diagonal_brush = new GD::Image(5,5); $white = $diagonal_brush->colorAllocate(255,255,255); $black = $diagonal_brush->colorAllocate(0,0,0); $diagonal_brush->transparent($white); $diagonal_brush->line(0,4,4,0,$black); # NE diagonal # Set the brush $myImage->setBrush($diagonal_brush); # Draw a circle using the brush $myImage->arc(50,50,25,25,0,360,gdBrushed); =item B<$image-EsetThickness($thickness)> Lines drawn with line(), rectangle(), arc(), and so forth are 1 pixel thick by default. Call setThickness() to change the line drawing width. =item B<$image-EsetStyle(@colors)> Styled lines consist of an arbitrary series of repeated colors and are useful for generating dotted and dashed lines. To create a styled line, use setStyle() to specify a repeating series of colors. It accepts an array consisting of one or more color indexes. Then draw using the B special color. Another special color, B can be used to introduce holes in the line, as the example shows. Example: # Set a style consisting of 4 pixels of yellow, # 4 pixels of blue, and a 2 pixel gap $myImage->setStyle($yellow,$yellow,$yellow,$yellow, $blue,$blue,$blue,$blue, gdTransparent,gdTransparent); $myImage->arc(50,50,25,25,0,360,gdStyled); To combine the C and C behaviors, you can specify C. In this case, a pixel from the current brush pattern is rendered wherever the color specified in setStyle() is neither gdTransparent nor 0. =item B Draw filled shapes and flood fills using a pattern. The pattern is just another image. The image will be tiled multiple times in order to fill the required space, creating wallpaper effects. You must call C in order to define the particular tile pattern you'll use for drawing when you specify the gdTiled color. details. =item B The gdStyled color is used for creating dashed and dotted lines. A styled line can contain any series of colors and is created using the setStyled() command. =item B The C color is used for drawing lines with antialiasing turned on. Antialiasing will blend the jagged edges of lines with the background, creating a smoother look. The actual color drawn is set with setAntiAliased(). =item B<$image-EsetAntiAliased($color)> "Antialiasing" is a process by which jagged edges associated with line drawing can be reduced by blending the foreground color with an appropriate percentage of the background, depending on how much of the pixel in question is actually within the boundaries of the line being drawn. All line-drawing methods, such as line() and polygon, will draw antialiased lines if the special "color" B is used when calling them. setAntiAliased() is used to specify the actual foreground color to be used when drawing antialiased lines. You may set any color to be the foreground, however as of libgd version 2.0.12 an alpha channel component is not supported. Antialiased lines can be drawn on both truecolor and palette-based images. However, attempts to draw antialiased lines on highly complex palette-based backgrounds may not give satisfactory results, due to the limited number of colors available in the palette. Antialiased line-drawing on simple backgrounds should work well with palette-based images; otherwise create or fetch a truecolor image instead. When using palette-based images, be sure to allocate a broad spectrum of colors in order to have sufficient colors for the antialiasing to use. =item B<$image-EsetAntiAliasedDontBlend($color,[$flag])> Normally, when drawing lines with the special B "color," blending with the background to reduce jagged edges is the desired behavior. However, when it is desired that lines not be blended with one particular color when it is encountered in the background, the setAntiAliasedDontBlend() method can be used to indicate the special color that the foreground should stand out more clearly against. Once turned on, you can turn this feature off by calling setAntiAliasedDontBlend() with a second argument of 0: $image->setAntiAliasedDontBlend($color,0); =back =head2 Drawing Commands These methods allow you to draw lines, rectangles, and ellipses, as well as to perform various special operations like flood-fill. =over 4 =item B<$image-EsetPixel($x,$y,$color)> This sets the pixel at (x,y) to the specified color index. No value is returned from this method. The coordinate system starts at the upper left at (0,0) and gets larger as you go down and to the right. You can use a real color, or one of the special colors gdBrushed, gdStyled and gdStyledBrushed can be specified. Example: # This assumes $peach already allocated $myImage->setPixel(50,50,$peach); =item B<$image-Eline($x1,$y1,$x2,$y2,$color)> This draws a line from (x1,y1) to (x2,y2) of the specified color. You can use a real color, or one of the special colors gdBrushed, gdStyled and gdStyledBrushed. Example: # Draw a diagonal line using the currently defined # paintbrush pattern. $myImage->line(0,0,150,150,gdBrushed); =item B<$image-EdashedLine($x1,$y1,$x2,$y2,$color)> DEPRECATED: The libgd library provides this method solely for backward compatibility with libgd version 1.0, and there have been reports that it no longer works as expected. Please use the setStyle() and gdStyled methods as described below. This draws a dashed line from (x1,y1) to (x2,y2) in the specified color. A more powerful way to generate arbitrary dashed and dotted lines is to use the setStyle() method described below and to draw with the special color gdStyled. Example: $myImage->dashedLine(0,0,150,150,$blue); =item B<$image-Erectangle($x1,$y1,$x2,$y2,$color)> This draws a rectangle with the specified color. (x1,y1) and (x2,y2) are the upper left and lower right corners respectively. Both real color indexes and the special colors gdBrushed, gdStyled and gdStyledBrushed are accepted. Example: $myImage->rectangle(10,10,100,100,$rose); =item B<$image-EfilledRectangle($x1,$y1,$x2,$y2,$color)> =item B<$image-EsetTile($otherimage)> This draws a rectangle filled with the specified color. You can use a real color, or the special fill color gdTiled to fill the polygon with a pattern. Example: # read in a fill pattern and set it $tile = newFromPng GD::Image('happyface.png'); $myImage->setTile($tile); # draw the rectangle, filling it with the pattern $myImage->filledRectangle(10,10,150,200,gdTiled); =item B<$image-EopenPolygon($polygon,$color)> This draws a polygon with the specified color. The polygon must be created first (see below). The polygon must have at least three vertices. If the last vertex doesn't close the polygon, the method will close it for you. Both real color indexes and the special colors gdBrushed, gdStyled and gdStyledBrushed can be specified. Example: $poly = new GD::Polygon; $poly->addPt(50,0); $poly->addPt(99,99); $poly->addPt(0,99); $myImage->openPolygon($poly,$blue); =item B<$image-EunclosedPolygon($polygon,$color)> This draws a sequence of connected lines with the specified color, without connecting the first and last point to a closed polygon. The polygon must be created first (see below). The polygon must have at least three vertices. Both real color indexes and the special colors gdBrushed, gdStyled and gdStyledBrushed can be specified. You need libgd 2.0.33 or higher to use this feature. Example: $poly = new GD::Polygon; $poly->addPt(50,0); $poly->addPt(99,99); $poly->addPt(0,99); $myImage->unclosedPolygon($poly,$blue); =item B<$image-EfilledPolygon($poly,$color)> This draws a polygon filled with the specified color. You can use a real color, or the special fill color gdTiled to fill the polygon with a pattern. Example: # make a polygon $poly = new GD::Polygon; $poly->addPt(50,0); $poly->addPt(99,99); $poly->addPt(0,99); # draw the polygon, filling it with a color $myImage->filledPolygon($poly,$peachpuff); =item B<$image-Eellipse($cx,$cy,$width,$height,$color)> =item B<$image-EfilledEllipse($cx,$cy,$width,$height,$color)> These methods() draw ellipses. ($cx,$cy) is the center of the arc, and ($width,$height) specify the ellipse width and height, respectively. filledEllipse() is like Ellipse() except that the former produces filled versions of the ellipse. =item B<$image-Earc($cx,$cy,$width,$height,$start,$end,$color)> This draws arcs and ellipses. (cx,cy) are the center of the arc, and (width,height) specify the width and height, respectively. The portion of the ellipse covered by the arc are controlled by start and end, both of which are given in degrees from 0 to 360. Zero is at the top of the ellipse, and angles increase clockwise. To specify a complete ellipse, use 0 and 360 as the starting and ending angles. To draw a circle, use the same value for width and height. You can specify a normal color or one of the special colors B, B, or B. Example: # draw a semicircle centered at 100,100 $myImage->arc(100,100,50,50,0,180,$blue); =item B<$image-EfilledArc($cx,$cy,$width,$height,$start,$end,$color [,$arc_style])> This method is like arc() except that it colors in the pie wedge with the selected color. $arc_style is optional. If present it is a bitwise OR of the following constants: gdArc connect start & end points of arc with a rounded edge gdChord connect start & end points of arc with a straight line gdPie synonym for gdChord gdNoFill outline the arc or chord gdEdged connect beginning and ending of the arc to the center gdArc and gdChord are mutually exclusive. gdChord just connects the starting and ending angles with a straight line, while gdArc produces a rounded edge. gdPie is a synonym for gdArc. gdNoFill indicates that the arc or chord should be outlined, not filled. gdEdged, used together with gdNoFill, indicates that the beginning and ending angles should be connected to the center; this is a good way to outline (rather than fill) a "pie slice." Example: $image->filledArc(100,100,50,50,0,90,$blue,gdEdged|gdNoFill); =item B<$image-Efill($x,$y,$color)> This method flood-fills regions with the specified color. The color will spread through the image, starting at point (x,y), until it is stopped by a pixel of a different color from the starting pixel (this is similar to the "paintbucket" in many popular drawing toys). You can specify a normal color, or the special color gdTiled, to flood-fill with patterns. Example: # Draw a rectangle, and then make its interior blue $myImage->rectangle(10,10,100,100,$black); $myImage->fill(50,50,$blue); =item B<$image-EfillToBorder($x,$y,$bordercolor,$color)> Like C, this method flood-fills regions with the specified color, starting at position (x,y). However, instead of stopping when it hits a pixel of a different color than the starting pixel, flooding will only stop when it hits the color specified by bordercolor. You must specify a normal indexed color for the bordercolor. However, you are free to use the gdTiled color for the fill. Example: # This has the same effect as the previous example $myImage->rectangle(10,10,100,100,$black); $myImage->fillToBorder(50,50,$black,$blue); =back =head2 Image Copying Commands Two methods are provided for copying a rectangular region from one image to another. One method copies a region without resizing it. The other allows you to stretch the region during the copy operation. With either of these methods it is important to know that the routines will attempt to flesh out the destination image's color table to match the colors that are being copied from the source. If the destination's color table is already full, then the routines will attempt to find the best match, with varying results. =over 4 =item B<$image-Ecopy($sourceImage,$dstX,$dstY,$srcX,$srcY,$width,$height)> This is the simplest of the several copy operations, copying the specified region from the source image to the destination image (the one performing the method call). (srcX,srcY) specify the upper left corner of a rectangle in the source image, and (width,height) give the width and height of the region to copy. (dstX,dstY) control where in the destination image to stamp the copy. You can use the same image for both the source and the destination, but the source and destination regions must not overlap or strange things will happen. Example: $myImage = new GD::Image(100,100); ... various drawing stuff ... $srcImage = new GD::Image(50,50); ... more drawing stuff ... # copy a 25x25 pixel region from $srcImage to # the rectangle starting at (10,10) in $myImage $myImage->copy($srcImage,10,10,0,0,25,25); =item B<$image-Eclone()> Make a copy of the image and return it as a new object. The new image will look identical. However, it may differ in the size of the color palette and other nonessential details. Example: $myImage = new GD::Image(100,100); ... various drawing stuff ... $copy = $myImage->clone; =item B<$image-EcopyMerge($sourceImage,$dstX,$dstY,> B< $srcX,$srcY,$width,$height,$percent)> This copies the indicated rectangle from the source image to the destination image, merging the colors to the extent specified by percent (an integer between 0 and 100). Specifying 100% has the same effect as copy() -- replacing the destination pixels with the source image. This is most useful for highlighting an area by merging in a solid rectangle. Example: $myImage = new GD::Image(100,100); ... various drawing stuff ... $redImage = new GD::Image(50,50); ... more drawing stuff ... # copy a 25x25 pixel region from $srcImage to # the rectangle starting at (10,10) in $myImage, merging 50% $myImage->copyMerge($srcImage,10,10,0,0,25,25,50); =item B<$image-EcopyMergeGray($sourceImage,$dstX,$dstY,> B< $srcX,$srcY,$width,$height,$percent)> This is identical to copyMerge() except that it preserves the hue of the source by converting all the pixels of the destination rectangle to grayscale before merging. =item B<$image-EcopyResized($sourceImage,$dstX,$dstY,> B< $srcX,$srcY,$destW,$destH,$srcW,$srcH)> This method is similar to copy() but allows you to choose different sizes for the source and destination rectangles. The source and destination rectangle's are specified independently by (srcW,srcH) and (destW,destH) respectively. copyResized() will stretch or shrink the image to accommodate the size requirements. Example: $myImage = new GD::Image(100,100); ... various drawing stuff ... $srcImage = new GD::Image(50,50); ... more drawing stuff ... # copy a 25x25 pixel region from $srcImage to # a larger rectangle starting at (10,10) in $myImage $myImage->copyResized($srcImage,10,10,0,0,50,50,25,25); =item B<$image-EcopyResampled($sourceImage,$dstX,$dstY,> B< $srcX,$srcY,$destW,$destH,$srcW,$srcH)> This method is similar to copyResized() but provides "smooth" copying from a large image to a smaller one, using a weighted average of the pixels of the source area rather than selecting one representative pixel. This method is identical to copyResized() when the destination image is a palette image. =item B<$image-EcopyRotated($sourceImage,$dstX,$dstY,> B< $srcX,$srcY,$width,$height,$angle)> Like copyResized() but the $angle argument specifies an arbitrary amount to rotate the image clockwise (in degrees). In addition, $dstX and $dstY species the B
of the destination image, and not the top left corner. =item B<$image-EtrueColorToPalette([$dither], [$colors])> This method converts a truecolor image to a palette image. The code for this function was originally drawn from the Independent JPEG Group library code, which is excellent. The code has been modified to preserve as much alpha channel information as possible in the resulting palette, in addition to preserving colors as well as possible. This does not work as well as might be hoped. It is usually best to simply produce a truecolor output image instead, which guarantees the highest output quality. Both the dithering (0/1, default=0) and maximum number of colors used (<=256, default = gdMaxColors) can be specified. =item B<$image = $sourceImage-EcreatePaletteFromTrueColor([$dither], [$colors])> Creates a new palette image from a truecolor image. Same as above, but returns a new image. Don't use these function -- write real truecolor PNGs and JPEGs. The disk space gain of conversion to palette is not great (for small images it can be negative) and the quality loss is ugly. =item B<$error = $image-EcolorMatch($otherimage)> Bring the palette colors in $otherimage to be closer to truecolor $image. A negative return value is a failure. -1 image must be True Color -2 otherimage must be indexed -3 the images are meant to be the same dimensions -4 At least 1 color in otherimage must be allocated This method is only available with libgd >= 2.1.0 =item B<$image = $sourceImage-EneuQuant($maxcolor=256,$samplefactor=5)> Creates a new palette image from a truecolor image. samplefactor The quantization precision between 1 (highest quality) and 10 (fastest). maxcolor The number of desired palette entries. This is the same as createPaletteFromTrueColor with the quantization method GD_QUANT_NEUQUANT. This does not support dithering. This method is only available with libgd >= 2.1.0 =back =head2 Image Transformation Commands Gd provides these simple image transformations, non-interpolated. =over 4 =item B<$image = $sourceImage-EcopyRotate90()> =item B<$image = $sourceImage-EcopyRotate180()> =item B<$image = $sourceImage-EcopyRotate270()> =item B<$image = $sourceImage-EcopyFlipHorizontal()> =item B<$image = $sourceImage-EcopyFlipVertical()> =item B<$image = $sourceImage-EcopyTranspose()> =item B<$image = $sourceImage-EcopyReverseTranspose()> These methods can be used to rotate, flip, or transpose an image. The result of the method is a copy of the image. =item B<$image-Erotate180()> =item B<$image-EflipHorizontal()> =item B<$image-EflipVertical()> These methods are similar to the copy* versions, but instead modify the image in place. =back =head2 Image Interpolation Methods Since libgd 2.1.0 there are better transformation methods, with these interpolation methods: GD_BELL - Bell GD_BESSEL - Bessel GD_BILINEAR_FIXED - fixed point bilinear GD_BICUBIC - Bicubic GD_BICUBIC_FIXED - fixed point bicubic integer GD_BLACKMAN - Blackman GD_BOX - Box GD_BSPLINE - BSpline GD_CATMULLROM - Catmullrom GD_GAUSSIAN - Gaussian GD_GENERALIZED_CUBIC - Generalized cubic GD_HERMITE - Hermite GD_HAMMING - Hamming GD_HANNING - Hannig GD_MITCHELL - Mitchell GD_NEAREST_NEIGHBOUR - Nearest neighbour interpolation GD_POWER - Power GD_QUADRATIC - Quadratic GD_SINC - Sinc GD_TRIANGLE - Triangle GD_WEIGHTED4 - 4 pixels weighted bilinear interpolation GD_LINEAR - bilinear interpolation =over 4 =item B<$image-EinterpolationMethod( [$method] )> Gets or sets the interpolation methods for all subsequent interpolations. See above for the valid values. Only available since libgd 2.2.0 =item B<$image-EcopyScaleInterpolated( width, height )> Returns a copy, using interpolation. =item B<$image-EcopyRotateInterpolated( angle, bgcolor )> Returns a copy, using interpolation. =back =head2 Image Filter Commands Gd also provides some common image filters, they modify the image in place and return TRUE if modified or FALSE if not. Most of them need libgd >= 2.1.0, with older versions those functions are undefined. =over 4 =item B<$ok = $image-Escatter($sub, $plus)> if $sub and $plus are 0, nothing is changed, TRUE is returned. if $sub >= $plus, nothing is changed, FALSE is returned. else random pixels are changed. =item B<$ok = $image-EscatterColor($sub, $plus, @colors)> Similar to scatter, but using the given array of colors, i.e. palette indices. =item B<$ok = $image-Epixelate($blocksize, $mode)> if $blocksize <= 0, nothing is changed, FALSE is returned. if $blocksize == 1, nothing is changed, TRUE is returned. else the following modes are observed: GD_PIXELATE_UPPERLEFT GD_PIXELATE_AVERAGE =item B<$ok = $image-Enegate()> =item B<$ok = $image-Egrayscale()> =item B<$ok = $image-Ebrightness($add)> $add: -255..255 =item B<$ok = $image-Econtrast($contrast)> $contrast: a double value. The contrast adjustment value. Negative values increase, postive values decrease the contrast. The larger the absolute value, the stronger the effect. =item B<$ok = $image-Ecolor($red,$green,$blue,$alpha)> Change channel values of an image. $red - The value to add to the red channel of all pixels. $green - The value to add to the green channel of all pixels. $blue - The value to add to the blue channel of all pixels. $alpha - The value to add to the alpha channel of all pixels. =item B<$ok = $image-EselectiveBlur()> =item B<$ok = $image-EedgeDetectQuick()> =item B<$ok = $image-EgaussianBlur()> =item B<$ok = $image-Eemboss()> =item B<$ok = $image-EmeanRemoval()> =item B<$ok = $image-Esmooth($weight)> =item B<$image = $sourceImage-EcopyGaussianBlurred($radius, $sigma)> $radius: int, the blur radius (*not* diameter--range is 2*radius + 1) a radius, not a diameter so a radius of 2 (for example) will blur across a region 5 pixels across (2 to the center, 1 for the center itself and another 2 to the other edge). $sigma: the sigma value or a value <= 0.0 to use the computed default. represents the "fatness" of the curve (lower == fatter). The result is always truecolor. =back =head2 Character and String Drawing GD allows you to draw characters and strings, either in normal horizontal orientation or rotated 90 degrees. These routines use a GD::Font object, described in more detail below. There are four built-in monospaced fonts, available in the global variables B, B, B, B and B. In addition, you can use the load() method to load GD-formatted bitmap font files at runtime. You can create these bitmap files from X11 BDF-format files using the bdf2gd.pl script, which should have been installed with GD (see the bdf_scripts directory if it wasn't). The format happens to be identical to the old-style MSDOS bitmap ".fnt" files, so you can use one of those directly if you happen to have one. For writing proportional scaleable fonts, GD offers the stringFT() method, which allows you to load and render any TrueType font on your system. =over 4 =item B<$image-Estring($font,$x,$y,$string,$color)> This method draws a string starting at position (x,y) in the specified font and color. Your choices of fonts are gdSmallFont, gdMediumBoldFont, gdTinyFont, gdLargeFont and gdGiantFont. Example: $myImage->string(gdSmallFont,2,10,"Peachy Keen",$peach); =item B<$image-EstringUp($font,$x,$y,$string,$color)> Just like the previous call, but draws the text rotated counterclockwise 90 degrees. =item B<$image-Echar($font,$x,$y,$char,$color)> =item B<$image-EcharUp($font,$x,$y,$char,$color)> These methods draw single characters at position (x,y) in the specified font and color. They're carry-overs from the C interface, where there is a distinction between characters and strings. Perl is insensible to such subtle distinctions. =item $font = Bload($fontfilepath)> This method dynamically loads a font file, returning a font that you can use in subsequent calls to drawing methods. For example: my $courier = GD::Font->load('./courierR12.fnt') or die "Can't load font"; $image->string($courier,2,10,"Peachy Keen",$peach); Font files must be in GD binary format, as described above. =item B<@bounds = $image-EstringFT($fgcolor,$fontname,$ptsize,$angle,$x,$y,$string)> =item B<@bounds = GD::Image-EstringFT($fgcolor,$fontname,$ptsize,$angle,$x,$y,$string)> =item B<@bounds = $image-EstringFT($fgcolor,$fontname,$ptsize,$angle,$x,$y,$string,\%options)> This method uses TrueType to draw a scaled, antialiased string using the TrueType vector font of your choice. It requires that libgd to have been compiled with TrueType support, and for the appropriate TrueType font to be installed on your system. The arguments are as follows: fgcolor Color index to draw the string in fontname A path to the TrueType (.ttf) font file or a font pattern. ptsize The desired point size (may be fractional) angle The rotation angle, in radians (positive values rotate counter clockwise) x,y X and Y coordinates to start drawing the string string The string itself If successful, the method returns an eight-element list giving the boundaries of the rendered string: @bounds[0,1] Lower left corner (x,y) @bounds[2,3] Lower right corner (x,y) @bounds[4,5] Upper right corner (x,y) @bounds[6,7] Upper left corner (x,y) In case of an error (such as the font not being available, or FT support not being available), the method returns an empty list and sets $@ to the error message. The string may contain UTF-8 sequences like: "À" You may also call this method from the GD::Image class name, in which case it doesn't do any actual drawing, but returns the bounding box using an inexpensive operation. You can use this to perform layout operations prior to drawing. Using a negative color index will disable antialiasing, as described in the libgd manual page at L. An optional 8th argument allows you to pass a hashref of options to stringFT(). Several hashkeys are recognized: B, B, B, and B. The value of B is supposed to be a multiple of the character height, so setting linespacing to 2.0 will result in double-spaced lines of text. However the current version of libgd (2.0.12) does not do this. Instead the linespacing seems to be double what is provided in this argument. So use a spacing of 0.5 to get separation of exactly one line of text. In practice, a spacing of 0.6 seems to give nice results. Another thing to watch out for is that successive lines of text should be separated by the "\r\n" characters, not just "\n". The value of B is one of "Unicode", "Shift_JIS" and "Big5". The interaction between Perl, Unicode and libgd is not clear to me, and you should experiment a bit if you want to use this feature. The value of B is the vertical and horizontal resolution, in DPI, in the format "hdpi,vdpi". If present, the resolution will be passed to the Freetype rendering engine as a hint to improve the appearance of the rendered font. The value of B is a flag. Set it to false to turn off the default kerning of text. Example: $gd->stringFT($black,'/dosc/windows/Fonts/pala.ttf',40,0,20,90, "hi there\r\nbye now", {linespacing=>0.6, charmap => 'Unicode', }); If GD was compiled with fontconfig support, and the fontconfig library is available on your system, then you can use a font name pattern instead of a path. Patterns are described in L and will look something like this "Times:italic". For backward compatibility, this feature is disabled by default. You must enable it by calling useFontConfig(1) prior to the stringFT() call. $image->useFontConfig(1); For backward compatibility with older versions of the FreeType library, the alias stringTTF() is also recognized. =item B<$hasfontconfig = $image-EuseFontConfig($flag)> Call useFontConfig() with a value of 1 in order to enable support for fontconfig font patterns (see stringFT). Regardless of the value of $flag, this method will return a true value if the fontconfig library is present, or false otherwise. This method can also be called as a class method of GD::Image; =item B<$result = $image-EstringFTCircle($cx,$cy,$radius,$textRadius,$fillPortion,$font,$points,$top,$bottom,$fgcolor)> This draws text in a circle. Currently (libgd 2.0.33) this function does not work for me, but the interface is provided for completeness. The call signature is somewhat complex. Here is an excerpt from the libgd manual page: Draws the text strings specified by top and bottom on the image, curved along the edge of a circle of radius radius, with its center at cx and cy. top is written clockwise along the top; bottom is written counterclockwise along the bottom. textRadius determines the "height" of each character; if textRadius is 1/2 of radius, characters extend halfway from the edge to the center. fillPortion varies from 0 to 1.0, with useful values from about 0.4 to 0.9, and determines how much of the 180 degrees of arc assigned to each section of text is actually occupied by text; 0.9 looks better than 1.0 which is rather crowded. font is a freetype font; see gdImageStringFT. points is passed to the freetype engine and has an effect on hinting; although the size of the text is determined by radius, textRadius, and fillPortion, you should pass a point size that "hints" appropriately -- if you know the text will be large, pass a large point size such as 24.0 to get the best results. fgcolor can be any color, and may have an alpha component, do blending, etc. Returns a true value on success. =back =head2 Alpha channels The alpha channel methods allow you to control the way drawings are processed according to the alpha channel. When true color is turned on, colors are encoded as four bytes, in which the last three bytes are the RGB color values, and the first byte is the alpha channel. Therefore the hexadecimal representation of a non transparent RGB color will be: C=0x00(rr)(bb)(bb) When alpha blending is turned on, you can use the first byte of the color to control the transparency, meaning that a rectangle painted with color 0x00(rr)(bb)(bb) will be opaque, and another one painted with 0x7f(rr)(gg)(bb) will be transparent. The Alpha value must be >= 0 and <= 0x7f. =over 4 =item B<$image-EalphaBlending($integer)> The alphaBlending() method allows for two different modes of drawing on truecolor images. In blending mode, which is on by default (libgd 2.0.2 and above), the alpha channel component of the color supplied to all drawing functions, such as C, determines how much of the underlying color should be allowed to shine through. As a result, GD automatically blends the existing color at that point with the drawing color, and stores the result in the image. The resulting pixel is opaque. In non-blending mode, the drawing color is copied literally with its alpha channel information, replacing the destination pixel. Blending mode is not available when drawing on palette images. Pass a value of 1 for blending mode, and 0 for non-blending mode. =item B<$image-EsaveAlpha($saveAlpha)> By default, GD (libgd 2.0.2 and above) does not attempt to save full alpha channel information (as opposed to single-color transparency) when saving PNG images. (PNG is currently the only output format supported by gd which can accommodate alpha channel information.) This saves space in the output file. If you wish to create an image with alpha channel information for use with tools that support it, call C to turn on saving of such information, and call C to turn off alpha blending within the library so that alpha channel information is actually stored in the image rather than being composited immediately at the time that drawing functions are invoked. =back =head2 Miscellaneous Image Methods These are various utility methods that are useful in some circumstances. =over 4 =item B<$image-Einterlaced([$flag])> This method sets or queries the image's interlaced setting. Interlace produces a cool venetian blinds effect on certain viewers. Provide a true parameter to set the interlace attribute. Provide undef to disable it. Call the method without parameters to find out the current setting. =item B<($width,$height) = $image-EgetBounds()> This method will return a two-member list containing the width and height of the image. You query but not change the size of the image once it's created. =item B<$width = $image-Ewidth> =item B<$height = $image-Eheight> Return the width and height of the image, respectively. =item B<$is_truecolor = $image-EisTrueColor()> This method will return a Boolean representing whether the image is true color or not. =item B<$flag = $image1-Ecompare($image2)> Compare two images and return a bitmap describing the differences found, if any. The return value must be logically AND'ed with one or more constants in order to determine the differences. The following constants are available: GD_CMP_IMAGE The two images look different GD_CMP_NUM_COLORS The two images have different numbers of colors GD_CMP_COLOR The two images' palettes differ GD_CMP_SIZE_X The two images differ in the horizontal dimension GD_CMP_SIZE_Y The two images differ in the vertical dimension GD_CMP_TRANSPARENT The two images have different transparency GD_CMP_BACKGROUND The two images have different background colors GD_CMP_INTERLACE The two images differ in their interlace GD_CMP_TRUECOLOR The two images are not both true color The most important of these is GD_CMP_IMAGE, which will tell you whether the two images will look different, ignoring differences in the order of colors in the color palette and other invisible changes. The constants are not imported by default, but must be imported individually or by importing the :cmp tag. Example: use GD qw(:DEFAULT :cmp); # get $image1 from somewhere # get $image2 from somewhere if ($image1->compare($image2) & GD_CMP_IMAGE) { warn "images differ!"; } =item B<$image-Eclip($x1,$y1,$x2,$y2)> =item B<($x1,$y1,$x2,$y2) = $image-Eclip> Set or get the clipping rectangle. When the clipping rectangle is set, all drawing will be clipped to occur within this rectangle. The clipping rectangle is initially set to be equal to the boundaries of the whole image. Change it by calling clip() with the coordinates of the new clipping rectangle. Calling clip() without any arguments will return the current clipping rectangle. =item B<$flag = $image-EboundsSafe($x,$y)> The boundsSafe() method will return true if the point indicated by ($x,$y) is within the clipping rectangle, or false if it is not. If the clipping rectangle has not been set, then it will return true if the point lies within the image boundaries. =back =head2 Grouping Methods GD does not support grouping of objects, but GD::SVG does. In that subclass, the following methods declare new groups of graphical objects: =over 4 =item $image-EstartGroup([$id,\%style]) =item $image-EendGroup() =item $group = $image-EnewGroup See L for information. =back =head1 Polygons A few primitive polygon creation and manipulation methods are provided. They aren't part of the Gd library, but I thought they might be handy to have around (they're borrowed from my qd.pl Quickdraw library). Also see L. =over 3 =item B<$poly = GD::Polygon-Enew> Create an empty polygon with no vertices. $poly = new GD::Polygon; =item B<$poly-EaddPt($x,$y)> Add point (x,y) to the polygon. $poly->addPt(0,0); $poly->addPt(0,50); $poly->addPt(25,25); $myImage->fillPoly($poly,$blue); =item B<($x,$y) = $poly-EgetPt($index)> Retrieve the point at the specified vertex. ($x,$y) = $poly->getPt(2); =item B<$poly-EsetPt($index,$x,$y)> Change the value of an already existing vertex. It is an error to set a vertex that isn't already defined. $poly->setPt(2,100,100); =item B<($x,$y) = $poly-EdeletePt($index)> Delete the specified vertex, returning its value. ($x,$y) = $poly->deletePt(1); =item B<$poly-Eclear()> Delete all vertices, restoring the polygon to its initial empty state. =item B<$poly-EtoPt($dx,$dy)> Draw from current vertex to a new vertex, using relative (dx,dy) coordinates. If this is the first point, act like addPt(). $poly->addPt(0,0); $poly->toPt(0,50); $poly->toPt(25,-25); $myImage->fillPoly($poly,$blue); =item B<$vertex_count = $poly-Elength> Return the number of vertices in the polygon. $points = $poly->length; =item B<@vertices = $poly-Evertices> Return a list of all the vertices in the polygon object. Each member of the list is a reference to an (x,y) array. @vertices = $poly->vertices; foreach $v (@vertices) print join(",",@$v),"\n"; } =item B<@rect = $poly-Ebounds> Return the smallest rectangle that completely encloses the polygon. The return value is an array containing the (left,top,right,bottom) of the rectangle. ($left,$top,$right,$bottom) = $poly->bounds; =item B<$poly-Eoffset($dx,$dy)> Offset all the vertices of the polygon by the specified horizontal (dh) and vertical (dy) amounts. Positive numbers move the polygon down and to the right. $poly->offset(10,30); =item B<$poly-Emap($srcL,$srcT,$srcR,$srcB,$destL,$dstT,$dstR,$dstB)> Map the polygon from a source rectangle to an equivalent position in a destination rectangle, moving it and resizing it as necessary. See polys.pl for an example of how this works. Both the source and destination rectangles are given in (left,top,right,bottom) coordinates. For convenience, you can use the polygon's own bounding box as the source rectangle. # Make the polygon really tall $poly->map($poly->bounds,0,0,50,200); =item B<$poly-Escale($sx,$sy)> Scale each vertex of the polygon by the X and Y factors indicated by sx and sy. For example scale(2,2) will make the polygon twice as large. For best results, move the center of the polygon to position (0,0) before you scale, then move it back to its previous position. =item B<$poly-Etransform($sx,$rx,$sy,$ry,$tx,$ty)> Run each vertex of the polygon through a transformation matrix, where sx and sy are the X and Y scaling factors, rx and ry are the X and Y rotation factors, and tx and ty are X and Y offsets. See the Adobe PostScript Reference, page 154 for a full explanation, or experiment. =back =head2 GD::Polyline Please see L for information on creating open polygons and splines. =head1 Font Utilities The libgd library (used by the Perl GD library) has built-in support for about half a dozen fonts, which were converted from public-domain X Windows fonts. For more fonts, compile libgd with TrueType support and use the stringFT() call. If you wish to add more built-in fonts, the directory bdf_scripts contains two contributed utilities that may help you convert X-Windows BDF-format fonts into the format that libgd uses internally. However these scripts were written for earlier versions of GD which included its own mini-gd library. These scripts will have to be adapted for use with libgd, and the libgd library itself will have to be recompiled and linked! Please do not contact me for help with these scripts: they are unsupported. Each of these fonts is available both as an imported global (e.g. B) and as a package method (e.g. BSmall>). =over 5 =item B =item BSmall> This is the basic small font, "borrowed" from a well known public domain 6x12 font. =item B =item BLarge> This is the basic large font, "borrowed" from a well known public domain 8x16 font. =item B =item BMediumBold> This is a bold font intermediate in size between the small and large fonts, borrowed from a public domain 7x13 font; =item B =item BTiny> This is a tiny, almost unreadable font, 5x8 pixels wide. =item B =item BGiant> This is a 9x15 bold font converted by Jan Pazdziora from a sans serif X11 font. =item B<$font-Enchars> This returns the number of characters in the font. print "The large font contains ",gdLargeFont->nchars," characters\n"; =item B<$font-Eoffset> This returns the ASCII value of the first character in the font =item B<$width = $font-Ewidth> =item B<$height = $font-Eheight> =item C These return the width and height of the font. ($w,$h) = (gdLargeFont->width,gdLargeFont->height); =back =head1 Helper Functions =over =item GD::LIBGD_VERSION Returns a number of the libgd VERSION, like 2.0204, 2.0033 or 2.01. =item GD::VERSION_STRING Returns the string of the libgd VERSION, like "2.2.4". =item GD::constant =back =head1 Obtaining the C-language version of gd libgd, the C-language version of gd, can be obtained at URL http://libgd.org/ Directions for installing and using it can be found at that site. Please do not contact me for help with libgd. =head1 AUTHOR The GD.pm interface is copyright 1995-2010, Lincoln D. Stein. This package and its accompanying libraries is free software; you can redistribute it and/or modify it under the terms of the GPL (either version 1, or at your option, any later version) or the Artistic License 2.0. Refer to LICENSE for the full license text. package for details. The latest versions of GD.pm are available at https://github.com/lstein/Perl-GD =head1 SEE ALSO L, L, L, L =cut 1; __END__ GD-2.66/LICENSE0000644000076500001200000000053013076515043012106 0ustar rurbanadminThe GD.pm interface is copyright 1995-2010, Lincoln D. Stein. This package and its accompanying libraries is free software; you can redistribute it and/or modify it under the terms of the GPL (either version 1, or at your option, any later version) or the Artistic License 2.0. Refer to LICENSE for the full license text. package for details. GD-2.66/Makefile.PL0000644000076500001200000004444313077114266013071 0ustar rurbanadminuse ExtUtils::MakeMaker qw(prompt WriteMakefile); use ExtUtils::Constant 'WriteConstants'; use Config; use strict; require 5.6.0; unless (@ARGV) { warn < PATHS: CHECK AND ADJUST <===== my (@INC,@LIBPATH,@LIBS,$LIBGD_VERSION); my $AUTOCONFIG = 0; # global set by try_to_autoconfigure() below my ($options,$lib_gd_path,$lib_ft_path,$lib_png_path,$lib_jpeg_path,$lib_xpm_path, $lib_zlib_path,$lib_fontconfig_path,$force,$FCGI,$gdlib_config_path); use Getopt::Long; my $result = GetOptions("ignore_missing_gd" => \$force, "options=s" => \$options, "lib_gd_path=s" => \$lib_gd_path, "lib_ft_path=s" => \$lib_ft_path, "lib_png_path=s" => \$lib_png_path, "lib_jpeg_path=s" => \$lib_jpeg_path, "lib_xpm_path=s" => \$lib_xpm_path, "lib_zlib_path=s" => \$lib_zlib_path, "lib_fontconfig_path=s" => \$lib_fontconfig_path, "gdlib_config_path=s" => \$gdlib_config_path, "fcgi" => \$FCGI, ); unless (try_to_autoconfigure() || $force) { die <.config.cache"; print F $DEFINES,"\n"; close F; my $CCFLAGS = $Config{ccflags}; $CCFLAGS .= " -Wall -Wextra -Wformat=0" if $Config{gccversion} and $] > 5.020; my %WriteMakefileArgs = ( 'NAME' => 'GD', 'ABSTRACT' => 'Perl interface to the gd2 graphics library', 'VERSION_FROM' => 'lib/GD.pm', 'PREREQ_PM' => { 'Math::Trig' => 0, }, 'CONFIGURE_REQUIRES' => { 'ExtUtils::Constant' => 0.22, 'ExtUtils::PkgConfig' => 0, }, 'PL_FILES' => {'bdf_scripts/bdf2gdfont_pl.PL' => 'bdf_scripts/bdf2gdfont.pl', 'lib/GD/Image_pm.PL' => 'lib/GD/Image.pm'}, 'LIBS' => [join(' ',$ENV{'GD_LIBS'},@LIBPATH,@LIBS)], 'INC' => join(' ',$ENV{'GD_INC'},@INC), 'CCFLAGS' => $CCFLAGS, 'EXE_FILES' => ['bdf_scripts/bdf2gdfont.pl'], 'AUTHOR' => 'Lincoln Stein ', $CAPI ? ('CAPI' => 'TRUE') : (), 'DEFINE' => $DEFINES, 'clean' => { FILES => '.config.cache cover_db MANIFEST.git *.gcov GD.gcda GD.gcno' .' META.yml META.json' }, 'LICENSE' => 'perl_5', 'META_MERGE' => { recommends => { 'ExtUtils::Constant'=> '0.23', 'Test::More' => '0.88', 'Test::Kwalitee' => 0, 'Class::XSAccessor' => 0, 'Text::CSV_XS' => 0, 'List::MoreUtils' => 0, 'Pod::Spell::CommonMistakes' => 0, 'Test::Pod' => '1.00', }, resources => { repository => 'http://github.com/lstein/Perl-GD', license => 'http://dev.perl.org/licenses/', }, }, SIGN => 1, ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) { my $br = delete $WriteMakefileArgs{BUILD_REQUIRES}; my $pp = $WriteMakefileArgs{PREREQ_PM}; for my $mod ( keys %$br ) { if ( exists $pp->{$mod} ) { $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod}; } else { $pp->{$mod} = $br->{$mod}; } } } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; delete $WriteMakefileArgs{META_MERGE} unless eval { ExtUtils::MakeMaker->VERSION(6.46) }; WriteMakefile(%WriteMakefileArgs); my @constants_iv = qw( GD_CMP_IMAGE GD_CMP_NUM_COLORS GD_CMP_COLOR GD_CMP_SIZE_X GD_CMP_SIZE_Y GD_CMP_TRANSPARENT GD_CMP_BACKGROUND GD_CMP_INTERLACE GD_CMP_TRUECOLOR GD_PIXELATE_UPPERLEFT GD_PIXELATE_AVERAGE gdBrushed gdDashSize gdMaxColors gdStyled gdStyledBrushed gdTiled gdTransparent gdAntiAliased gdArc gdPie gdChord gdNoFill gdEdged gdEffectReplace gdEffectAlphaBlend gdEffectNormal gdEffectOverlay gdEffectMultiply gdAlphaMax gdAlphaOpaque gdAlphaTransparent gdRedMax gdGreenMax gdBlueMax GD_MAJOR_VERSION GD_MINOR_VERSION GD_RELEASE_VERSION GD_FLIP_HORINZONTAL GD_FLIP_VERTICAL GD_FLIP_BOTH GD_RESOLUTION GD_DEFAULT GD_BELL GD_BESSEL GD_BILINEAR_FIXED GD_BICUBIC GD_BICUBIC_FIXED GD_BLACKMAN GD_BOX GD_BSPLINE GD_CATMULLROM GD_GAUSSIAN GD_GENERALIZED_CUBIC GD_HERMITE GD_HAMMING GD_HANNING GD_MITCHELL GD_NEAREST_NEIGHBOUR GD_POWER GD_QUADRATIC GD_SINC GD_TRIANGLE GD_WEIGHTED4 GD_LINEAR GD_METHOD_COUNT GD_AFFINE_TRANSLATE GD_AFFINE_SCALE GD_AFFINE_ROTATE GD_AFFINE_SHEAR_HORIZONTAL GD_AFFINE_SHEAR_VERTICAL ); # Note that ExtUtils::Constant::ProxySubs creates code incompatible # with <5.14. Only 0.23_04 has that fixed. if (!-e 'const-xs.inc' or !-e"const-c.inc") { WriteConstants( #PROXYSUBS => {autoload => 1}, NAME => 'GD', NAMES => \@constants_iv, DEFAULT_TYPE => 'IV'); } exit 0; sub try_to_autoconfigure { #my ($options,$lib_gd_path,$INC,$LIBPATH,$LIBS) = @_; my ($version, $cflags, $ldflags, $libs, $libdir, $features, $includedir); # perl Makefile.PL --lib_gd_path /opt/libgd/2.1.1/lib my ($prefix) = $lib_gd_path ? ($lib_gd_path =~ m|(^.*)/lib|) : ""; my $bindir = $prefix ? "$prefix/bin/" : $lib_gd_path ? "$lib_gd_path/bin/" : ""; my $config = `${bindir}gdlib-config --all` if -e "${bindir}gdlib-config"; if (!$config and !-e "$prefix/lib/pkgconfig/gdlib.pc" and !-e "/usr/lib/pkgconfig/gdlib.pc") { $gdlib_config_path = "gdlib-config" unless defined($gdlib_config_path); $config = `$gdlib_config_path --all`; } unless ($config) { my %config; require ExtUtils::PkgConfig; %config = ExtUtils::PkgConfig->find ("$prefix/lib/pkgconfig/gdlib.pc") if $prefix; %config = ExtUtils::PkgConfig->find ("gdlib") unless %config; return unless %config; $version = $config{modversion}; warn "Configuring for libgd version $version.\n"; $cflags = $config{cflags}; $libs = $config{libs}; ($libdir, $libs) = $libs =~ m/-L(.*) (-lgd.*)/; # Libs.private: -L/opt/local/lib -lz -L/opt/local/lib -lpng16 -L/opt/local/lib -lfreetype -L/opt/local/lib -lfontconfig -lfreetype -ljpeg -L/opt/local/lib -lXpm -lX11 -L/opt/local/lib -ltiff -lwebp # not in the hash! $features = 'GD_GIF GD_OPENPOLYGON GD_ZLIB GD_PNG GD_FREETYPE GD_FONTCONFIG GD_JPEG GD_XPM GD_TIFF GD_WEBP'; $AUTOCONFIG++; } else { $AUTOCONFIG++; ($version) = $config =~ /^GD library\s+(\S+)/m; warn "Configuring for libgd version $version.\n"; ($includedir) = $config =~ /^includedir:\s*(.+)$/m; ($cflags) = $config =~ /^cflags:\s*(.+)$/m; ($ldflags) = $config =~ /^ldflags:\s*(.+)$/m; ($libs) = $config =~ /^libs:\s*(.+)$/m; ($libdir) = $config =~ /^libdir:\s*(.+)$/m; ($features) = $config =~ /^features:\s*(.+)$/m; ($includedir) = $config =~ /^includedir:\s*(.+)$/m; } $LIBGD_VERSION = $version; @INC = map {s/^-I// && "-I$_"} split /\s+/,$cflags; @LIBS = split /\s+/,$libs; if ($libdir) { if ($config) { @LIBPATH = map {s/^-L// && "-L$_"} split /\s+/,$ldflags; ($lib_gd_path = $libdir) =~ s!/[^/]+$!!; } else { $lib_gd_path = $libdir; } push @LIBPATH,"-L$libdir"; } push @LIBS,"-lgd" unless $libs =~ /-lgd/; $options = $features; my ($release, $major, $minor) = $version =~ /^(\d+)\.(\d+)\.(\d+)/; $options .= " GD_UNCLOSEDPOLY GD_ANIMGIF GD_FTCIRCLE VERSION_33" if defined($minor) && ($release > 2 || ($release == 2 && $major > 0) || ($release == 2 && $major == 0 && $minor >= 33)); if ($config) { my @correct_inc = map {s/^-I// && $_} split /\s+/,$cflags; check_for_stray_headers($includedir,@correct_inc); } return 1; } sub check_for_stray_headers { my @official_libraries = @_; my %official_libraries = map {$_=>1} @official_libraries; print STDERR "Checking for stray libgd header files..."; my $cc = $Config{'cc'}; my $data = `$cc -print-search-dirs 2>/dev/null`; $data ||= ''; my ($libraries) = $data =~ /^libraries: =(.+)/m; my @cc_libs = split /:/,$libraries; foreach (@cc_libs) { s/\/$//; } my %libraries = map {$_=>1} (@cc_libs,'/include','/usr/include', '/usr/local/include','/opt/include', '/usr/X11R6/include'); my $problems; my $o = $official_libraries[0]; foreach (keys %libraries) { s/\blib\b/include/; next if $official_libraries{$_}; next unless -e "$_/gd.h"; if (-l "$_/gd.h" or -l "$o/gd.h") { next if (stat("$_/gd.h"))[1] == (stat("$o/gd.h"))[1]; } warn "\n\n** WARNING: found gd.h header file in ${_}/gd.h, but it is expected at $official_libraries[0]/gd.h. This may cause compile errors! **\n"; $problems++; } print STDERR $problems ? "** Possible problems found **\n" : "none found.\n"; print STDERR "\n"; } sub MY::postamble { my $postamble = <<'END'; html: lib/GD.pm pod2html --outfile=GD.html lib/GD.pm END $postamble; } package MY; # Ignore templates sub libscan { return 0 if $_[1] =~ /_p[ml].PL$/; return $_[1]; } sub processPL { my $inherited = shift->SUPER::processPL(@_); $inherited =~ s/(:: lib\/GD\/Image_pm\.PL)/$1 .config.cache/; $inherited; } sub depend { " release : dist git tag release_\$(VERSION_SYM) cpan-upload \$(DISTVNAME).tar\$(SUFFIX) git push git push --tags const-c.inc const-xs.inc : Makefile.PL GCOV = gcov test_cover :: pure_all \$(RM_RF) cover_db +\$(PERLRUNINST) -S cover -test test_coveralls :: pure_all +\$(PERLRUNINST) -S cover -test -report coveralls gcov : \$(BASEEXT).c.gcov \$(BASEEXT).gcov cover_db/\$(BASEEXT)-xs.html \$(BASEEXT).c.gcov \$(BASEEXT).xs.gcov : \$(BASEEXT).xs \$(MAKE) CCFLAGS=\"\$(CCFLAGS) -fprofile-arcs -ftest-coverage\" LDDLFLAGS=\"\$(LDDLFLAGS) -fprofile-arcs -ftest-coverage\" \$(GCOV) \$(BASEEXT).c \$(BASEEXT).xs cover_db/\$(BASEEXT)-xs.html : \$(BASEEXT).xs.gcov PERL5OPT=-MDevel::Cover make test -$^X -S gcov2perl \$(BASEEXT).c.gcov \$(BASEEXT).xs.gcov $^X -S cover gprof : \$(MAKE) CCFLAGS=\"\$(CCFLAGS) -pg\" LDDLFLAGS=\"\$(LDDLFLAGS) -pg\" " } GD-2.66/MANIFEST0000644000076500001200000000432613077123433012240 0ustar rurbanadminChangeLog GD.xs LICENSE MANIFEST MANIFEST.SKIP Makefile.PL README README.QUICKDRAW bdf_scripts/README bdf_scripts/bdf2gdfont_pl.PL bdf_scripts/bdftogd bdf_scripts/cvtbdf.pl const-c.inc const-xs.inc demos/brushes.pl demos/copies.pl demos/draw_colors.pl demos/fills.pl demos/font_list.png demos/fonttest demos/gd_example.cgi demos/polyline.pl demos/polys.pl demos/shapes.pl demos/tile.png demos/transform.pl demos/truetype_test demos/ttf.pl lib/GD.pm lib/GD/Group.pm lib/GD/Image.pm lib/GD/Image_pm.PL lib/GD/Polygon.pm lib/GD/Polyline.pm lib/GD/Simple.pm t/GD.t t/HSV.t t/Polyline.t t/test_data/Generic.ttf t/test_data/frog.jpg t/test_data/frog.xpm t/test_data/images/corrupt.png t/test_data/images/t1/1-00.gd t/test_data/images/t1/1-00.gd2 t/test_data/images/t1/1-00.gif t/test_data/images/t1/1-00.jpeg t/test_data/images/t1/1-00.png t/test_data/images/t2/2-00.gd t/test_data/images/t2/2-00.gd2 t/test_data/images/t2/2-00.gif t/test_data/images/t2/2-00.jpeg t/test_data/images/t2/2-00.png t/test_data/images/t3/3-00.gd t/test_data/images/t3/3-00.gd2 t/test_data/images/t3/3-00.gif t/test_data/images/t3/3-00.jpeg t/test_data/images/t3/3-00.png t/test_data/images/t4/4-00.gd t/test_data/images/t4/4-00.gd2 t/test_data/images/t4/4-00.gif t/test_data/images/t4/4-00.jpeg t/test_data/images/t4/4-00.png t/test_data/images/t5/5-00.gd t/test_data/images/t5/5-00.gd2 t/test_data/images/t5/5-00.gif t/test_data/images/t5/5-00.jpeg t/test_data/images/t5/5-00.png t/test_data/images/t6/6-00.gd t/test_data/images/t6/6-00.gd2 t/test_data/images/t6/6-00.gif t/test_data/images/t6/6-00.jpeg t/test_data/images/t6/6-00.png t/test_data/images/t7/7-00.gd t/test_data/images/t7/7-00.gd2 t/test_data/images/t7/7-00.gif t/test_data/images/t7/7-00.jpeg t/test_data/images/t7/7-00.png t/test_data/images/t7/7-01.gd2 t/test_data/palettemap.png t/test_data/tile.gd t/test_data/tile.gd2 t/test_data/tile.gif t/test_data/tile.jpeg t/test_data/tile.png t/transp.t t/z_kwalitee.t t/z_manifest.t t/z_pod-spell-mistakes.t t/z_pod.t typemap META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) SIGNATURE Public-key signature (added by MakeMaker) GD-2.66/MANIFEST.SKIP0000644000076500001200000000022713076515043013002 0ustar rurbanadmin^\.travis\.yml ^\.appveyor\.yml ^\.config \bGD-\d+ \bGD\.c$ ^MYMETA\.yml$ ^MYMETA\.json$ \.git ~$ \.bak$ \b# lib/GD/Image.pm bdf_scripts/bdf2gdfont.pl GD-2.66/META.json0000644000076500001200000000275113077123433012530 0ustar rurbanadmin{ "abstract" : "Perl interface to the gd2 graphics library", "author" : [ "Lincoln Stein " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "GD", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::Constant" : "0.22", "ExtUtils::PkgConfig" : "0" } }, "runtime" : { "recommends" : { "Class::XSAccessor" : "0", "ExtUtils::Constant" : "0.23", "List::MoreUtils" : "0", "Pod::Spell::CommonMistakes" : "0", "Test::Kwalitee" : "0", "Test::More" : "0.88", "Test::Pod" : "1.00", "Text::CSV_XS" : "0" }, "requires" : { "Math::Trig" : "0" } } }, "release_status" : "stable", "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "http://github.com/lstein/Perl-GD" } }, "version" : "2.66", "x_serialization_backend" : "JSON::PP version 2.27300_01" } GD-2.66/META.yml0000644000076500001200000000160513077123433012355 0ustar rurbanadmin--- abstract: 'Perl interface to the gd2 graphics library' author: - 'Lincoln Stein ' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::Constant: '0.22' ExtUtils::PkgConfig: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: GD no_index: directory: - t - inc recommends: Class::XSAccessor: '0' ExtUtils::Constant: '0.23' List::MoreUtils: '0' Pod::Spell::CommonMistakes: '0' Test::Kwalitee: '0' Test::More: '0.88' Test::Pod: '1.00' Text::CSV_XS: '0' requires: Math::Trig: '0' resources: license: http://dev.perl.org/licenses/ repository: http://github.com/lstein/Perl-GD version: '2.66' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' GD-2.66/README0000644000076500001200000003231013076515043011762 0ustar rurbanadminGD.pm -- A perl5 interface to Thomas Boutell's gd library. ABSTRACT: This is a autoloadable interface module for libgd, a popular library for creating and manipulating PNG files. With this library you can create PNG images on the fly or modify existing files. Features include: a. lines, polygons, rectangles and arcs, both filled and unfilled b. flood fills c. the use of arbitrary images as brushes and as tiled fill patterns d. line styling (dashed lines and the like) e. horizontal and vertical text rendering f. support for transparency and interlacing g. support for TrueType font rendering, via libfreetype. h. support for spline curves, via GD::Polyline i. support for symbolic font names, such as "helvetica:italic" j. support for symbolic color names, such as "green", via GD::Simple k. produces output in png, gif, jpeg and xbm format l. produces output in svg format via GD::SVG. For full information on usage, see the accompanying man and html documentation. Also check the FAQ at the bottom of this document. INSTALLATION: 1. Windows users can find a binary PPM package in the repositories at these sites: http://trouchelle.com/perl/ppmrepview.pl http://www.bribes.org/perl/ppmdir.html These packages are not always updated to the most recent version, but GD is pretty stable and you usually won't miss the bleeding edge version. For MacOSX/Unix users and those who have a developer's kit installed on Windows (e.g. cygwin): 2. Make sure you have downloaded and installed the following packages: a. Perl 5.6.0 or higher: http://www.perl.com/ b. The gd graphics library: http://libgd.org c. The PNG graphics library: http://www.libpng.org/pub/png/libpng.html d. The zlib compression library: http://www.gzip.org/zlib/ (OPTIONAL) e. The FreeType font rendering library for TrueType fonts: http://www.freetype.org/ f. The JPEG library, version 6b or later: ftp://ftp.uu.net/graphics/jpeg/ g. The XPM library, a standard part of modern X Windows distributions. If you don't have a modern version of X, don't try to get XPM working. 3. On MacOSX, you can use these package managers to resolve dependencies and build libgd: i. MacPorts http://www.macports.org/ ii. Homebrew http://mxcl.github.io/homebrew/ If this module fails to compile and link, you are probably using an older version of libgd. Symptoms of this problem include errors about functions not being recognized in the gd.h header file, and undefined symbols from the linker. If you are having this type of error, please REMOVE all versions of libgd, gd.h from your system and reinstall libgd 2.0.28 or higher. Do not contact Lincoln for help until you have done this. Use GD 1.41 for libgd versions 1.8.4 and lower. 3. Unpack the tar file: zcat GD-2.XX.tar.gz | tar xvf - (Where "XX" is the most recent revision number.) This will create the directory GD-2.XX. 4. To compile GD.pm: a. cd GD-2.XX b. perl Makefile.PL c. make d. make test f. sudo make install This will create GD.pm and install it into the system-wide Perl library directory. You'll need root privileges to do the install step. If you don't have them, see below. During step (b), Makefile.PL will look for the program gdlib-config or gdlib.pc that newer versions of libgd install for you. If this program is not present, the Makefile.PL script will ask you whether to build support for JPEG, FreeType and/or XPM image formats. Please answer "y" (the default) if libgd was built with the feature, and "n" if it was not. Failure to answer correctly will lead to link errors. If, during step (b) you see notes about missing libraries, then this module will probably not link correctly, even though the warning may say "probably harmless". 5. Before you install GD, you will want to run the regression tests. You can do this after the "make" step by typing: make test 6. There are some demos you can run in ext/GD/demos. They print PNG files to standard output. To view the files, pipe their output to "display" or "xv" in this way: a. cd GD-2.XX/demos b perl shapes.pl | display - You will need a graphics program that can read and display PNG format. I recommend Image::Magick's display program, available from ftp://ftp.wizards.dupont.com/pub/ImageMagick/ If you don't have any display programs handy, you can save to a temporary file and display with recent versions of Netscape or Internet Explorer. 7. A program named fonttest is included in this package under demos. This generates an image showing all the built-in fonts available. If you have built libgd with TrueType support, and you have a directory containing some TrueType fonts, you can create a simple font listing by running the program truetype_test, also located in demos. 8. See demos/gd_example.cgi for an example of how to use GD to create a picture dynamically with a CGI script. It's intended to be run under a Web server. To see it work, install it in your server's cgi-bin/ directory and invoke it from a browser by fetching a URL like: http://your.site/cgi-bin/gd_example.cgi IF YOU RUN INTO PROBLEMS If the make and install all seem to go well but you get errors like "Fatal error: can't load module GD.so", or "Fatal error: unknown symbol gdFontSmall" when you try to run a script that uses GD, you may have problems with dynamic linking. Check whether other dynamically-linked Perl modules such as POSIX and DB_File run correctly. If not, then you'll have to link Perl statically, as described above. Other problems may be fixed by compiling libgd as a shared library, as described in step (2) of the installation instructions. If you are trying to compile and link GD on a Windows or Macintosh machine and fail, please verify that you are able to build the Perl distribution from source code. If you can't do that, then you don't have the compiler/linker/make tools required for building Perl modules. You may not even need to do this, as ActiveState and MacPerl both include precompiled versions of GD. If you have problems and can't solve it on your own, post a message to the newsgroup "comp.lang.perl.modules". There are some systems that require obscure compiler and linker options in order to compile correctly, and unfortunately I have a limited number of systems at my disposal. You're much more likely to get correct answers from the gurus on the newsgroup than from myself. THE GD::SIMPLE LIBRARY GD::Simple is a simplified API for GD. It supports turtle graphics, a unified interface for drawing text, and symbolic color names (like "green"). Run "perldoc GD::Simple" for information on using it. The GD::SVG LIBRARY GD::SVG, which is available separately on CPAN, provides a subset of GD method calls. For this subset, you can create images in SVG (scaleable vector graphics) format. THE QUICKDRAW LIBRARY This is no longer supported. FREQUENTLY ASKED QUESTIONS 1. I get a warning about prerequisite Math::Trig not being found The version of Math::Trig that comes with Perl version 5.6.0 and lower has a bug in it that causes it not to be found even when it is installed. Try running perl -MMath::Trig -e0 from the command line. If you get no errors, go ahead and install GD. If you get an error, install Math::Trig from CPAN. 2. Why do I get errors about functions not being found when building this module? You need libgd (the C library that does all the work) version 2.0.28 or higher. Older versions will give you errors during GD installation. Get the latest version from http://libgd.org and install it. Sometimes just installing the new version of libgd is not enough: you must remove the old library first. Find the gd.h include file and all libgd files and remove them from your system. 3. Why do I get errors about symbols being undefined when building this module? See (1). 4. The %&#&#! thing doesn't compile at all! I'm getting lots of compile errors! Does "make" fail with messages like these? GD.xs: In function 'newDynamicCtx': GD.xs:440: error: 'gdIOCtx' has no member named 'gd_free' GD.xs: In function 'gd_cloneDim': GD.xs:460: error: 'struct gdImageStruct' has no member named 'alpha' GD.xs:460: error: 'struct gdImageStruct' has no member named 'alpha' GD.xs:466: error: 'struct gdImageStruct' has no member named 'thick' GD.xs:466: error: 'struct gdImageStruct' has no member named 'thick' If so, then you may have an old gd.h include file located somewhere in your system include path. Please find it and remove it. A typical location is /usr/include/gd.h. The way to make sure you are removing the correct gd.h is to run "gdlib-config --cflags" to find out where the current gd.h lives: % gdlib-config --cflags -I/usr/local/include This tells you that /usr/local/include/gd.h is the correct gd.h. Please find and remove any other gd.h. 5. My scripts fail with "Can't locate object method 'png' via package "GD::Image". libgd can now be built with support for one or more of the PNG, GIF, XPM or JPEG formats. If one or more of these formats are not supported by libgd, then the corresponding GD::Image methods will be unavailable. Unfortunately, many older scripts assume that the png() method will always be present. You can work around this issue with code like the following: my $image = $gd->can('png') ? $gd->png : $gd->gif; or if you prefer eval {} my $image = eval {$gd->png} || $gd->gif; As of libgd 2.0.33, GIF support is always compiled in, so (for the time being!) this is a safe fallback. 6. Is there a utility to convert X Windows BDF fonts into GD fonts. Yes. See the utility bdf2gdfont.pl. Run "bdf2gdfont.pl -h" to get help on using this. 7. Does GD run with Macintosh OS X? Yes. GD compiles just fine under OSX. However, you may need to remove old versions of libgd, libpng, and libz and reinstall the current versions before you try to install GD. 8. Does GD run with Win32 Perl? The latest ActiveState binaries for Win32 systems come with GD already compiled in and ready to go. I don't own any Win32 systems, and cannot provide you with help in compiling GD from scratch on such systems. 9. GD won't compile on system XX. Because libgd relies on multiple external libraries, GD does as well. Unfortunately, different systems place their libraries in different places and sometimes are picky about the order in which libraries are linked. The best thing to do is to install the latest version of libgd. Recent versions of libgd contain a gdlib-config utility, which GD will use to determine which libraries are necessary and in which order to link them. Another thing to be aware of is that some Unix distributions provide a faulty precompiled version of Perl which is unable to build and load new C-based modules (like this one). If you are getting errors like this: /arch/auto/GD/GD.so: undefined symbol: SetCPerlObj at .... then you may have such a faulty version of Perl. The most reliable thing to do is to recompile Perl from source code, thereby ensuring that it is complete. 10. When I try to load an XPM file, all I get is blackness! The libgd createFromXpm() function works with some XPM files, and not with others. The problem is buried deep in the libXpm library somewhere. 11. The stringFTCircle() method doesn't work! I know. I think this might be a problem in libgd because I have never gotten it to work as a C program. If you have any insight into this problem let me know. 12. Test XX fails The regression tests for GD involve generating images, saving them as PNG, JPEG or GIF files, and then comparing the files bit-for-bit to known "correct" files. Sometimes one of the underlying C libraries such as libz, libpng or libgd is updated, causing GD to generate an image that is subtly different. These differences are usually insignificant, such as a reordering of colors in the color table, but they will call isolated tests to fail. If you are seeing the great majority of GD tests pass, but one or two fail, then you are probably seeing the effect of a new library. Just go ahead and install GD and drop me a note about the problem. BUG REPORTS Please report bugs, feature requests and propose code changes using the GitHub repository at https://github.com/lstein/Perl-GD. We do not check the CPAN RT bug system with any frequency. ACKNOWLEDGEMENTS: I'd like to thank Jan Pazdziora, Geoff Baysinger, and David Kilzer for their contributions to the library, as well as Thomas Boutell who wrote libgd. SOURCE CODE AND UPDATES: The current version of GD can be found in CPAN. The development version can be found on GitHub at https://github.com/lstein/Perl-GD. AUTHOR and LICENSE Copyright 1995-2014 Lincoln Stein Maintainance taken over by Reini Urban 2017. This package and its accompanying libraries is free software; you can redistribute it and/or modify it under the terms of the GPL (either version 1, or at your option, any later version) or the Artistic License 2.0. Refer to LICENSE for the full license text. package for details. GD-2.66/README.QUICKDRAW0000644000076500001200000000012313076515043013310 0ustar rurbanadminSupport for the archaic Quickdraw format was withdrawn from GD as of version 2.55. GD-2.66/SIGNATURE0000644000076500001200000001551713077123434012400 0ustar rurbanadminThis file contains message digests of all files listed in MANIFEST, signed via the Module::Signature module, version 0.81. To verify the content in this distribution, first make sure you have Module::Signature installed, then type: % cpansign -v It will check each file's integrity, as well as the signature's validity. If "==> Signature verified OK! <==" is not displayed, the distribution may already have been compromised, and you should not run its Makefile.PL or Build.PL. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 SHA1 1d572bfeefa1b826622da362e4ed79a592c1030e ChangeLog SHA1 e1cb4dfc7c6c38a2f4d99b7c201244e8eff24681 GD.xs SHA1 a670a0f6bf54244e98000dac01027a0cf9c01ee2 LICENSE SHA1 52c88e9f516768523969cd0f352ef44e7c63a006 MANIFEST SHA1 2c9e59c832fe8cc31ddf5068e39864a46c14b650 MANIFEST.SKIP SHA1 a1c39fb29c86695c033b0ad37eaf9671f21545d3 META.json SHA1 0190f19745a5c811a0ea5e8cc8c6f2de6a1db6a4 META.yml SHA1 63da3ad869e307278d63ac02fdf873a28684bd1d Makefile.PL SHA1 ad9ca326a04f1a01344003aa19a79b9089d490bb README SHA1 a4130024c229f17921f4168266a372adc3d50c1f README.QUICKDRAW SHA1 66754814e77c9cac2656dbf87688df8a19f68344 bdf_scripts/README SHA1 52e86e8d8ed01862508f4ba745e267cec8ccc946 bdf_scripts/bdf2gdfont_pl.PL SHA1 7a1e000010ffa47da5b833bdd625fff71c043946 bdf_scripts/bdftogd SHA1 a03838f0190c18be02eaa05773ae94cc7a1b4648 bdf_scripts/cvtbdf.pl SHA1 92e02d229d6db40a60d43e8d8d93c0cbbbd5c529 const-c.inc SHA1 1aa0bf16c21c1e7a9b12c52e263fc5d1c45e72d8 const-xs.inc SHA1 e8bce4b6054ca1a61e21a78cab05a4fa2bc4a59e demos/brushes.pl SHA1 3ab28c2445db04a53c0ef3e1de2536ba446e7906 demos/copies.pl SHA1 5312907b8bb1841ab12b301a1cb271cebba3ba90 demos/draw_colors.pl SHA1 26b0d6a63be5962fad04273441b852d14d9464d9 demos/fills.pl SHA1 0f3f3fd8738cc2a9aba8c19503c7caf0c3f87a43 demos/font_list.png SHA1 cc5a1f736a6fbcef31b39a328b69c65633af929d demos/fonttest SHA1 43d60bafe52999200a37ae5e9114fbdd206511d7 demos/gd_example.cgi SHA1 55a8028dce35b9834b10a1f7bc9f5f846c6a8795 demos/polyline.pl SHA1 c42ef9c321fb7ad9bc24bc21c0a7fbea71837f7d demos/polys.pl SHA1 011fc9605c1d58b1215e6015bed5faeb8c555459 demos/shapes.pl SHA1 f8a82028ff9be72100fecdc88550a0dad616a5c2 demos/tile.png SHA1 09eca663f2a408bf9c3129f332c6c56493670a61 demos/transform.pl SHA1 0af9d18d9ff540323a7fb1a2dd55e7e8bb36e08b demos/truetype_test SHA1 34b58832de0d82e724f58d910ff7049d30a9a895 demos/ttf.pl SHA1 d91a95f545335a2c0b69d324d95d94283ecafbf7 lib/GD.pm SHA1 8f3d2799bccc9ad37fbd28ce3321693840ba33bc lib/GD/Group.pm SHA1 b55eb75938c985125395fee9c024f2070f0694d2 lib/GD/Image.pm SHA1 eb63a3bc5f5f20e314449825c5aaaf7c241cf63d lib/GD/Image_pm.PL SHA1 e1d9add14f7e7445f521f1c7a6b7bb13c8c940ed lib/GD/Polygon.pm SHA1 a3cd1d6b349b2202172ec46e66f41b9cdb695cc9 lib/GD/Polyline.pm SHA1 49e2a672738e156dc2c5691f956991e6599476b2 lib/GD/Simple.pm SHA1 1fa5072bb1b044eddc4a3a4ffb7a9db267d0be7d t/GD.t SHA1 9e9a794a7c72ecc3d20034746ea756d7ccc58cc7 t/HSV.t SHA1 e7a8a36560240d801eb9dc900ef4ba0cee4f3170 t/Polyline.t SHA1 e9b05fc79ae66119c6ffbeb7cf851a82a8af3f0b t/test_data/Generic.ttf SHA1 5de16754ef5ec122c7a1e3306a16c11195d218cc t/test_data/frog.jpg SHA1 c71435c69b13cd19b56b839a0334bf58a3a4152f t/test_data/frog.xpm SHA1 edff2bad6104140721ef4e47938c668450eb9a2f t/test_data/images/corrupt.png SHA1 5c87ae5d91010beea33b94c12cd2f64318cb6dcf t/test_data/images/t1/1-00.gd SHA1 13fcf6c434c412404bd89064dd0ad42592f2038b t/test_data/images/t1/1-00.gd2 SHA1 332d6d54430c6e78e672612b0a0cbd5cc2dbe0ae t/test_data/images/t1/1-00.gif SHA1 2e492d69810db736718f68354458cf2bd638bb1c t/test_data/images/t1/1-00.jpeg SHA1 11582bd38a3ea26e5a166e4afaa4e5c4ea85f2b8 t/test_data/images/t1/1-00.png SHA1 79a7a49dca7278710598515d080e26f7cf12e0d0 t/test_data/images/t2/2-00.gd SHA1 d6f1eb2c14fcaaad4e4aa6f6c9af62797a19a6e2 t/test_data/images/t2/2-00.gd2 SHA1 ead01cb00d6c5f171844dbfad09d763cb2f4c9a3 t/test_data/images/t2/2-00.gif SHA1 05e1772b9ec6e4b3252ea3a4225099d2e0540396 t/test_data/images/t2/2-00.jpeg SHA1 c7f6ff2d7933c7f84096a21dae0c116f975e2fce t/test_data/images/t2/2-00.png SHA1 28eeb2ac09c60b7959d40b761cf33ce71b434e1c t/test_data/images/t3/3-00.gd SHA1 6ebbe178ecebe95d61b1612bfc600f81b8f238be t/test_data/images/t3/3-00.gd2 SHA1 12bad62842a18691b5631946cbd2eedc35a02561 t/test_data/images/t3/3-00.gif SHA1 18bc99a9ea585938a7de42e753c1802a97b5c7b2 t/test_data/images/t3/3-00.jpeg SHA1 cd818368377040876e9997f7781098d86ffe58f2 t/test_data/images/t3/3-00.png SHA1 3d3bfc53aba0b6ba976128f394e808240458f799 t/test_data/images/t4/4-00.gd SHA1 64e99869cfaa3cd76d78336ff75117e1757bbf95 t/test_data/images/t4/4-00.gd2 SHA1 f6d9d0e63f420f7a2d7029a82efbe4e4b3be6523 t/test_data/images/t4/4-00.gif SHA1 8f5ac097ea31269743fba0bab2acc13e9e35a991 t/test_data/images/t4/4-00.jpeg SHA1 2b3b0896a6f1e22c2e8f56d899385a4f4c06b089 t/test_data/images/t4/4-00.png SHA1 31c63fcd9f74bebabb9aad08e114196371fcf135 t/test_data/images/t5/5-00.gd SHA1 8b7a085d0c9d94c8a8f6965787fd8626e48ad775 t/test_data/images/t5/5-00.gd2 SHA1 cd428b1bc7eb8f93b1129315aeb9aeb3fa01db72 t/test_data/images/t5/5-00.gif SHA1 b4448bfa0472a44fc64983deeb775dd4599b0a3a t/test_data/images/t5/5-00.jpeg SHA1 5d3dbe5703e7e71597dc9ac7e9a8c257cb3b975b t/test_data/images/t5/5-00.png SHA1 b4cc666813ea7476995e73b6ba0b7a0f790daef4 t/test_data/images/t6/6-00.gd SHA1 e0a9b2ff9a44234f4d3ce1590a5ac6c505afe2e2 t/test_data/images/t6/6-00.gd2 SHA1 d1bad53c6f8e5949497e8550e661dcd1f652c8c1 t/test_data/images/t6/6-00.gif SHA1 7dd604d83e9938049a4e73f6ebed93c7ad38a60f t/test_data/images/t6/6-00.jpeg SHA1 5ae76eeba4682f09dc5f3daabaa89e44d9758960 t/test_data/images/t6/6-00.png SHA1 0a9e033829bd8b3d156c87e2039ede27377570d0 t/test_data/images/t7/7-00.gd SHA1 29153fdb58db4c7cb5b98bfe0033562e2603e09d t/test_data/images/t7/7-00.gd2 SHA1 2fd38d1308251d82fb77c8403d7e0ff82be71d7b t/test_data/images/t7/7-00.gif SHA1 61038e512beed1acfdb7608716982946e79c5b7a t/test_data/images/t7/7-00.jpeg SHA1 161b55a07901e8dcbd5699592dc9d524f80402fa t/test_data/images/t7/7-00.png SHA1 e3d849dbe2731ba175e3c35b9e06cf1e5a64d554 t/test_data/images/t7/7-01.gd2 SHA1 e79b51c344514410f58bc18a66372c2a269fa6da t/test_data/palettemap.png SHA1 94b1ff6e1a950524ba251260655f73953e30d335 t/test_data/tile.gd SHA1 47cf4c2e969b5f3f9f8f5bdfddff85b3ae6eda23 t/test_data/tile.gd2 SHA1 e1d2dd1fe9f6502ce44b27a860f208536d96d1c3 t/test_data/tile.gif SHA1 81a4b73a2aca1592555b9b3a926aeed1ed395cf7 t/test_data/tile.jpeg SHA1 f8a82028ff9be72100fecdc88550a0dad616a5c2 t/test_data/tile.png SHA1 32117e631ae6f5fbcf30cc09d2ae609e663df467 t/transp.t SHA1 a9d3b7db55ac95e11798c409ba566d3a53a4097b t/z_kwalitee.t SHA1 c6bbbe8c1a0fa2803be5a83ffdfea9b65c601a34 t/z_manifest.t SHA1 c562193b547edb1824e7466fa9f2133eee1e2109 t/z_pod-spell-mistakes.t SHA1 5f435a91dcba00ff9c4f4f434ff80451de71a474 t/z_pod.t SHA1 b557ea8c70773b80a9e6118e7f4e0597bb94af74 typemap -----BEGIN PGP SIGNATURE----- iF0EARECAB0WIQRZHhhUcL58V8z0UW2abZJij/3JQgUCWPynGwAKCRCabZJij/3J Qhd6AJ9lb30J1480tnMd91apiNJWT54l2QCgkdWkkku9ErAHpZmqWAcD1HcBThQ= =We2a -----END PGP SIGNATURE----- GD-2.66/t/0000755000076500001200000000000013077123433011345 5ustar rurbanadminGD-2.66/t/GD.t0000644000076500001200000002126213076515043012030 0ustar rurbanadmin#!/usr/bin/perl use strict; use warnings; use FileHandle; use FindBin qw($Bin); use lib "$Bin/../blib/lib","$Bin/../blib/arch","$Bin/../lib"; use constant FONT=>"$Bin/test_data/Generic.ttf"; use constant IMAGE_TESTS => 7; use Test::More tests => 13; use IO::Dir; use_ok('GD',':DEFAULT',':cmp'); use_ok('GD::Simple'); chdir $Bin || die "Couldn't change to 't' directory: $!"; my $images = './test_data/images'; my $arg = shift; write_regression_tests() if (defined $arg && $arg eq '--write'); run_image_regression_tests(); run_round_trip_test(); catch_libgd_error(); exit 0; sub write_regression_tests { warn "Writing regression files..."; for my $suffix ('gd2','gd','png','gif','jpeg') { my $op = ucfirst $suffix; unless (GD::Image->can("newFrom$op")) { print "# not writing $op regression test: not supported\n"; next; } for my $t (1..IMAGE_TESTS) { my $data = eval "test${t}('$suffix')" or die $@; write_regression_test($data,$t,$suffix); } } } sub write_regression_test { my ($data,$test,$suffix) = @_; my $base = "$images/t${test}"; mkdir $base unless -d $base; my $count = 0; my $filename = sprintf ("$base/$test-%02d.$suffix",$count); while (-e $filename) { $count++; $filename = sprintf ("$base/$test-%02d.$suffix",$count); } open my $fh,'>',$filename or die "$filename: $!"; binmode($fh); print $fh $data->$suffix; close $fh or die "$filename: $!"; } sub compare { my ($data,$test,$suffix) = @_; my @files_to_match = glob("$images/t${test}/*.$suffix"); my $matched; for my $file (@files_to_match) { $matched ||= compare_image($data,$file,$suffix); } return $matched; } sub compare_image { my ($data1,$file,$suffix) = @_; my $op = ucfirst($suffix); my $method = "newFrom${op}"; my $data2 = eval {GD::Image->$method($file)} or die $@; return ! $data1->compare($data2) & GD_CMP_IMAGE(); } sub test1 { my $suffix = shift; my $im = new GD::Image(300,300); my($white) = $im->colorAllocate(255, 255, 255); my($black) = $im->colorAllocate(0, 0, 0); my($red) = $im->colorAllocate(255, 0, 0); my($green) = $im->colorAllocate(0,255,0); my($yellow) = $im->colorAllocate(255,250,205); my $fn = "./test_data/tile.$suffix"; my $op = ucfirst($suffix); my $tile = eval "GD::Image->newFrom${op}('$fn')" or die $@; return unless $tile; $im->setBrush($tile); $im->arc(100,100,100,150,0,360,gdBrushed()); $im->setTile($tile); $im->filledRectangle(150,150,250,250,gdTiled()); $im->rectangle(150,150,250,250,$black); $im->setStyle($green,$green,$green,gdTransparent(),$red,$red,$red,gdTransparent()); $im->line(0,280,300,280,gdStyled()); return $im; } sub test2 { my($im) = new GD::Image(300,300); my($white,$black,$red,$blue,$yellow) = ( $im->colorAllocate(255, 255, 255), $im->colorAllocate(0, 0, 0), $im->colorAllocate(255, 0, 0), $im->colorAllocate(0,0,255), $im->colorAllocate(255,250,205) ); my($brush) = new GD::Image(10,10); $brush->colorAllocate(255,255,255); # white $brush->colorAllocate(0,0,0); # black $brush->transparent($white); # white is transparent $brush->filledRectangle(0,0,5,2,$black); # a black rectangle $im->setBrush($brush); $im->arc(100,100,100,150,0,360,gdBrushed()); my($poly) = new GD::Polygon; $poly->addPt(30,30); $poly->addPt(100,10); $poly->addPt(190,290); $poly->addPt(30,290); $im->polygon($poly,gdBrushed()); $im->fill(132,62,$blue); $im->fill(100,70,$red); $im->fill(40,40,$yellow); $im->copy($im,150,150,20,20,50,50); $im->copyResized($im,10,200,20,20,100,100,50,50); return $im; } sub test3 { my($im) = new GD::Image(100,50); my($black,$white,$red,$blue) = ( $im->colorAllocate(0, 0, 0), $im->colorAllocate(255, 255, 255), $im->colorAllocate(255, 0, 0), $im->colorAllocate(0,0,255) ); $im->arc(50, 25, 98, 48, 0, 360, $white); $im->fill(50, 21, $red); return $im; } sub test4 { my($im) = new GD::Image(225,180); my($black,$white,$red,$blue,$yellow) = ($im->colorAllocate(0, 0, 0), $im->colorAllocate(255, 255, 255), $im->colorAllocate(255, 0, 0), $im->colorAllocate(0,0,255), $im->colorAllocate(255,250,205) ); my($poly) = new GD::Polygon; $poly->addPt(0,50); $poly->addPt(25,25); $poly->addPt(50,50); $im->filledPolygon($poly,$blue); $poly->offset(100,100); $im->filledPolygon($poly,$red); $poly->map(50,50,100,100,10,10,110,60); $im->filledPolygon($poly,$yellow); $poly->map($poly->bounds,50,20,80,160); $im->filledPolygon($poly,$white); return $im; } sub test5 { my($im) = new GD::Image(300,300); my($white,$black,$red,$blue,$yellow) = ( $im->colorAllocate(255, 255, 255), $im->colorAllocate(0, 0, 0), $im->colorAllocate(255, 0, 0), $im->colorAllocate(0,0,255), $im->colorAllocate(255,250,205) ); $im->transparent($white); my($brush) = new GD::Image(10,10); $brush->colorAllocate(255,255,255); $brush->colorAllocate(0,0,0); $brush->transparent($white); $brush->filledRectangle(0,0,5,2,$black); $im->string(gdLargeFont(),150,10,"Hello world!",$red); $im->string(gdSmallFont(),150,28,"Goodbye cruel world!",$blue); $im->stringUp(gdTinyFont(),280,250,"I'm climbing the wall!",$black); $im->charUp(gdMediumBoldFont(),280,280,"Q",$black); $im->setBrush($brush); $im->arc(100,100,100,150,0,360,gdBrushed()); my $poly = new GD::Polygon; $poly->addPt(30,30); $poly->addPt(100,10); $poly->addPt(190,290); $poly->addPt(30,290); $im->polygon($poly,gdBrushed()); $im->fill(132,62,$blue); $im->fill(100,70,$red); $im->fill(40,40,$yellow); return $im; } sub test6 { my $dtor = 0.0174533; my $pi = 3.141592654; my $xsize = 500; my $ysize = 500; my $scale = 1; my $x_offset = $xsize/2; my $y_offset = $ysize/2; my $im = new GD::Image($xsize,$ysize); my $poly = new GD::Polygon; my $col_bg = $im->colorAllocate(0,0,0); my $col_fg = $im->colorAllocate(255,255,0); my $col_fill = $im->colorAllocate(255,0,0); my $r_0 = 100; my $theta_0 = 20; my $spring_factor = 30; for(my $theta=0;$theta<=360;$theta++) { my $r = $r_0 + $spring_factor*sin(2*$pi*$theta/$theta_0); my $x = int($r * cos($theta*$dtor))*$scale+$x_offset; my $y = int($r * sin($theta*$dtor))*$scale+$y_offset; $poly->addPt($x,$y); } $im->filledPolygon($poly,$col_fill); # Call gdImageFilledPolygon() return $im; } sub test7 { my $im = GD::Image->new(400,250); if (!$im) { printf("Test7: no image");}; my($white,$black,$red,$blue,$yellow) = ( $im->colorAllocate(255, 255, 255), $im->colorAllocate(0, 0, 0), $im->colorAllocate(255, 0, 0), $im->colorAllocate(0,0,255), $im->colorAllocate(255,250,205) ); # Some TTFs $im->stringFT($black,FONT,12.0,0.0,20,20,"Hello world!") || warn $@; $im->stringFT($red,FONT,14.0,0.0,20,80,"Hello world!") || warn $@; $im->stringFT($blue,FONT,30.0,-0.5,60,100,"Goodbye cruel world!") || warn $@; return $im; } sub run_image_regression_tests { my $suffix = $ENV{GDIMAGETYPE} || 'gd2'; print STDERR "# Testing gd ".GD::VERSION_STRING()." using $suffix support.\n"; for my $t (1..IMAGE_TESTS) { my $gd = eval "test${t}('$suffix')"; if (!$gd) { fail("unable to generate comparison image for test $t: $@"); } else { my $ok = compare($gd,$t,$suffix); unless ($ok) { if (($suffix ne 'gd2') or ($t == 7)) { ok(1, "TODO image comparison test $t $suffix failed (regen with --write)"); } else { ok($ok, "image comparison test $t $suffix"); } diag("gd: ",GD::VERSION_STRING(), ", files: ",join(" ",glob("$images/t${t}/*.$suffix"))); } else { ok($ok, "image comparison test $t $suffix"); } } } } sub run_round_trip_test { my $image = GD::Image->new(300,300); $image->colorAllocate(255,255,255); $image->colorAllocate(0,0,0); $image->colorAllocate(255,0,0); $image->rectangle(0,0,300,300,0); $image->filledRectangle(10,10,50,50,2); my $gd = $image->gd; my $image2 = GD::Image->newFromGdData($gd); ok(!$image->compare($image2) & GD_CMP_IMAGE(),'round trip gd'); my $gd2 = $image->gd2; $image2 = GD::Image->newFromGd2Data($gd2); ok(!$image->compare($image2) & GD_CMP_IMAGE(),'round trip gd2'); } sub catch_libgd_error { diag("ignore corrupt png error messages..."); my $image = eval { GD::Image->newFromPng("test_data/images/corrupt.png") }; is($image, undef); ok($@, 'caught corrupt png'); } GD-2.66/t/HSV.t0000644000076500001200000000211613076515043012173 0ustar rurbanadmin#!/usr/bin/perl # -*- encoding: utf-8; indent-tabs-mode: nil -*- # See https://rt.cpan.org/Ticket/Display.html?id=120572 # checks 5832 RGB triples, executes a # round trip RGB -> HSV -> RGB and compares the initial and final # RGB triples. Of course, there will be rounding errors, so the # final RGB triple will be a little different from the initial. # So I compare the Manhattan distance between the two triples and # compare it with a fuzz value. use Test::More tests => 1; use strict; use warnings; use GD::Simple; my $fmt = " %3d" x 10; my $step = 15; my $fuzz = 3; my $neg_fix = 0; for (my $r0 = 0; $r0 <= 255; $r0 += $step) { for (my $g0 = 0; $g0 <= 255; $g0 += $step) { for (my $b0 = 0; $b0 <= 255; $b0 += $step) { my ($h, $s, $v) = GD::Simple->RGBtoHSV($r0, $g0, $b0); my ($r1, $g1, $b1) = GD::Simple->HSVtoRGB($h, $s, $v); my $delta = abs($r1 - $r0) + abs($g1 - $g0) + abs($b1 - $b0); if ($delta > $fuzz) { diag(sprintf $fmt, $h, $s, $v, $r0, $g0, $b0, $r1, $g1, $b1, $delta); fail(); exit; } } } } pass(); GD-2.66/t/Polyline.t0000644000076500001200000000075413075665245013345 0ustar rurbanadmin# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test; BEGIN { plan tests => 1 }; use GD::Polyline; ok(1); # If we made it this far, we're ok. ######################### # Insert your test code below, the Test module is use()ed here so read # its man page ( perldoc Test ) for help writing this test script. GD-2.66/t/test_data/0000755000076500001200000000000013077123433013315 5ustar rurbanadminGD-2.66/t/test_data/frog.jpg0000644000076500001200000000302313076515043014753 0ustar rurbanadminJFIFC    $.' ",#(7),01444'9=82<.342C  2!!2222222222222222222222222222222222222222222222222200"-!1"Q2AqB#3Ra/!1QAaq"#$2 ?Y5Ɗ:h҅2j|Қ{:T mA]{ϟkĩYkjrJaG 1:Ag%GfTI#pVg}w.x0F_r4ƹ,ݭ \b A9cz5m:+k1#|M{ebZdJQ,eRC$ddL$yQÿY|Vآ6T7ZeEpg$#C[D(*o=BڊAd x:m[Pz.<4 "1c*Kvxy(m f"˷p ;S]9Y q<IO`2HeaCsݐzzQ 0[;q20+:GBk IhxxIpӕL{64rCl(wFOrwPTT$"H BRJJn2 >5ZR $-T`ȪKc8>ՅKKeAdaT=yypԴ}0 ;X4lݧ-{UUHeNFꝺJi- m=2J 'v S~N%E0ƱDApzP`;=t݋RFGD-2.66/t/test_data/frog.xpm0000644000076500001200000002445413076515043015012 0ustar rurbanadmin/* XPM */ static char *magick[] = { /* columns rows colors chars-per-pixel */ "48 48 256 2", " c #060604040606", ". c #080888884040", "X c #9c9c9e9e4c4c", "o c #1f1fc7c73c3c", "O c #47478a8a5151", "+ c #4747c4c43939", "@ c #747448482828", "# c #4747a5a53131", "$ c #2020d8d8b8b8", "% c #a4a4c6c66c6c", "& c #71716a6a4444", "* c #0c0ca6a61414", "= c #4848aeae7474", "- c #c8c896960808", "; c #040446460c0c", ": c #4848d8d8a0a0", "> c #0505e9e9e5e5", ", c #a4a443431111", "< c #d4d4a6a67c7c", "1 c #d0d0a8a82424", "2 c #6464a2a24444", "3 c #2929ededd9d9", "4 c #242484845c5c", "5 c #4848b3b33737", "6 c #040427270606", "7 c #6767c7c75757", "8 c #a2a254541a1a", "9 c #eaeaaaaa1414", "0 c #4747d9d95454", "q c #4646c2c27878", "w c #2e2eaaaa2c2c", "e c #0808f6f6dede", "r c #4a4ab4b44f4f", "t c #282805050505", "y c #4747cfcf3d3d", "u c #e9e9adad4545", "i c #2828d6d63636", "p c #272787872f2f", "a c #4949e9e9c7c7", "s c #2626fafaf6f6", "d c #3737b5b52929", "f c #717155552727", "g c #4c4c60604040", "h c #040418180505", "j c #e4e48e8e0707", "k c #a3a353533333", "l c #3838c6c62828", "z c #5656c6c63c3c", "x c #6767adad7373", "c c #fafab4b41212", "v c #68688c8c4848", "b c #292993935959", "n c #a8a868680808", "m c #5959b5b55252", "M c #3c3cb5b55555", "N c #3333c7c75555", "B c #b5b54a4a2626", "V c #26269a9a1c1c", "C c #e4e49a9a5c5c", "Z c #4646a9a95454", "A c #484894943434", "S c #1818f9f9e9e9", "D c #e4e4caca4c4c", "F c #040434340808", "G c #fafaa9a90606", "H c #e8e89c9c0606", "J c #909054541717", "K c #4747c6c65252", "L c #a7a745452e2e", "P c #2929edededed", "I c #3c3ccece1c1c", "U c #f9f99a9a0707", "Y c #1c1ce9e9e9e9", "T c #36368b8b6666", "R c #6161e6e6d1d1", "E c #4646bbbb7474", "W c #b7b755551111", "Q c #3737b4b43d3d", "! c #414175754040", "~ c #181805050404", "^ c #9494c2c28484", "/ c #3939d2d2cfcf", "( c #10107e7e3030", ") c #6464cecec9c9", "_ c #161615150404", "` c #5656aaaa5a5a", "' c #ccccdededcdc", "] c #929263633737", "[ c #8c8c52522f2f", "{ c #a3a35c5c1717", "} c #4949bcbc5454", "| c #b6b658583939", " . c #2c2c6e6e2c2c", ".. c #565685856666", "X. c #3838fbfbf3f3", "o. c #e7e7fdfdf9f9", "O. c #c4c4bebe1414", "+. c #5757baba3737", "@. c #373788884444", "#. c #04041b1b2424", "$. c #3737c5c53b3b", "%. c #040428282222", "&. c #fbfba9a92020", "*. c #a2a24c4c2b2b", "=. c #09099a9a3737", "-. c #8484b2b26868", ";. c #4646caca3b3b", ":. c #8a8a44441c1c", ">. c #6666b9b96c6c", ",. c #5757bcbc5b5b", "<. c #3535bbbb3c3c", "1. c #45458b8b6c6c", "2. c #6666b6b65b5b", "3. c #26268b8b7e7e", "4. c #0606fcfcfafa", "5. c #a4a45b5b3838", "6. c #c9c967671919", "7. c #fafaa0a00808", "8. c #5757b8b87474", "9. c #59597a7a3737", "0. c #0707f1f1f2f2", "q. c #1515fbfbfbfb", "w. c #34346e6e5c5c", "e. c #8f8f43433737", "r. c #05050c0c0505", "t. c #4848dbdbdcdc", "y. c #3939ebebd4d4", "u. c #4747e6e6e4e4", "i. c #373798985959", "p. c #9191fefefcfc", "a. c #a4a49a9a1c1c", "s. c #6464e2e26c6c", "d. c #b8b8b8b83434", "f. c #2121b9b92525", "g. c #c4c4a2a24444", "h. c #ccccc2c29494", "j. c #acacc2c28484", "k. c #d3d3fefefbfb", "l. c #b4b4fefefcfc", "z. c #a4a4aeae5454", "x. c #717177773f3f", "c. c #6f6f9b9b4949", "v. c #efefbbbb3737", "b. c #8c8c78785050", "n. c #464696967070", "m. c #6060e8e8ecec", "M. c #6868dcdcb8b8", "N. c #c6c6a8a84646", "B. c #a9a964644545", "V. c #3939d8d83d3d", "C. c #7474cccc7272", "Z. c #2020a8a84343", "A. c #7c7cb2b2acac", "S. c #262699994040", "D. c #aeaeb9b95f5f", "F. c #24241a1a0404", "G. c #dcdcb2b2c4c4", "H. c #3939a6a65757", "J. c #2424bebe6464", "K. c #b8b8b7b7bcbc", "L. c #b4b4dede8c8c", "P. c #3737dfdfd4d4", "I. c #1010dddddcdc", "U. c #646465653a3a", "Y. c #69699e9e6c6c", "T. c #bcbca8a83c3c", "R. c #d4d4b9b94141", "E. c #4444f2f2cccc", "W. c #6c6c92927c7c", "Q. c #6161f3f3c4c4", "!. c #dada9d9d1414", "~. c #f4f4a2a24040", "^. c #09097d7d5151", "/. c #6565abab5959", "(. c #2a2a97977a7a", "). c #5959dede6767", "_. c #5757c8c86c6c", "`. c #f8f8aaaa4444", "'. c #5c5c9c9c5c5c", "]. c #5050f3f3ecec", "[. c #7878ceceb8b8", "{. c #2f2f7c7c5050", "}. c #bcbc72722c2c", "|. c #3434e4e44848", " X c #8484aeae4444", ".X c #5c5caeae4444", "XX c #717155554444", "oX c #424279795f5f", "OX c #94946d6d5151", "+X c #dcdc9c9c5454", "@X c #747478786060", "#X c #191999994040", "$X c #5757dbdbdada", "%X c #5c5cf2f2e8e8", "&X c #3c3ccfcf6464", "*X c #91914d4d1c1c", "=X c #2c2c7c7c6969", "-X c #1c1c8d8d4242", ";X c #808066664444", ":X c #7777aeae6f6f", ">X c #3939ecece8e8", ",X c #f8f8fcfcfafa", " q.q.UXs s p.l.k.k.,Xo.,Xo.k.k.o.k.k.k.l.p.t.P q.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.", "4.4.4.q.> q.I.>Xl.k.o.o.,X,Xk.o.o.o.,Xk.k.l.l.p.P 4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.> 4.4.", "0.4.4.4.4.q.S S P ].l.k.k.l.l.k.k.l.l.l.p.X.I.0.4.4.4.4.4.4.4.S 4.4.4.4.4.4.4.4.q.4.4.4.4.4.4.4.", "4.4.4.0.q.e s 0.e q.>Xp.m.m./ u.$Xt.t.>Xs q.4.4.4.4.4.4.4.4.0.q.4.4.4.4.4.4.4.4.UXS s q.e 4.4.0.", "4.0.4.q.X.>X0Xs S 0.> Y P Y P s Y s s 0.0.0.q.q.4.4.4.4.4.4.4.4.UXq.0.4.4.4.4.4.s P.t./ s 4.4.4.", "4.4.Y P %.%.eXy.3 S q.q.0.q.4.4.4.0.4.4.4.q.0.4.4.4.4.4.4.4.4.0.UXq.4.4.4.4.S y.P.eX#.%.u.UXq.4.", "4.UX].6 (.4 4 6 #.$X>XS q.0.4.4.4.4.0.4.4.0.4.4.4.4.4.4.4.0.q.0.4.4.4.4.4.S P.%.6 3.3.3.#.t.S 4.", "e X.h =XT H.sX@.gX6 / X.> q.4.4.4.0.X.0XP X.UXUXs UXX.0X0XX.UXq.0.4.4.4.S X.6 3.T T 3.zX=XeX$ S ", "y.F cXn.( -XbX-XE (.F t.S 4.4.4.4.S P.#.#.#.%.%X/ m.#.#.#.#.>XS 4.0.4.e y.%.T oX=X4 T =X=X3.%.y.", "R 6 4 4 8.#X#X=.=.bX^.eXs > 4.4.S 3 %.o.,X,Xk.#.M.h o.,X,Xk.6 E.0.4.q.X.%.=Xw.O {.Z sXi.cX3.%.SX", "r.n.(.bX4 1X#XN J.uX(.F y.S 4.s >X6 k.,Xt ~ ,X,Xh k.o. ,X,X#.s e S P.6 1.oX@.# -X( -XH.4 =Xh ", "r.w.3.= @.@.* N N &XE . F y.s I.$Xh ,X~ G.,X ,Xr.o. ' o. ,Xr.0Xs >X%.gX{.dXp LXQ s.#X. cXKXr.", "h x VX@.-XM K $.BXf.0 uXcX%.u.].) #.k. K.K.r.,Xr.,Xr.K.K. ,X#.>XP %.(.zX4 sX} HXZXo o &X-Xw. ", "h VXlXO S.N l y I BXIXAX= 6 6X6 6 h k.o.r.r.k.o.h o.,X ,Xo.6 a y.%.=Xi.i.Q ZX5 AX* i =.q lXr.", "6 VXT @.Z.f.l l I I o 0 Z 6 F uXM ,.h o.,Xo.k.h '.h o.,X,Xo.6 M 6 6 1.1.p z V + PXAXi i BXS.{.h ", "h n.9X1XJ.0 l I + IX&XQ F ,.5 $.y K .Xh h h 6 8.,.m h r.h 6 FXK K C.6 dX7 PXPX+ ;.d i 5Xi <.x h ", "F VX4 #XZ.N + PXjX} F 6 ,.5 + l BXIXd hX5 jX<.<.$.$.} m LXr AXIXl f.$.F LXLXz + IXV.|.5Xo &XZ h ", "A.#.bXbXZ.N r F 6 F r ,.} 5 <.;.uX} 5 7 5 LX).uXuX} FX7 7 # jXK l y <.).F 6 F F IX|.f.5X|.J.6 [.", "[.eX^.q = r 6 m z <.BXQ } ,.8.h 6 6 r.r.r.h h h 6 h h r.r.h h h h .X>.Z uXK jXFX6 F $.|.f.N F R ", ") %.4 -XF 6 2.6 LXjXjX} 6 h h r.r. ~ r. ~ r.r.h h h ,.Z m 6 9XE F <.$.&XF / ", "6X6 T 6 M jXdX6 h h h r. ~ ~ h ~ t qXt t ~ ~ t qXt t ~ r.r. ~ r.h #.h r.h 8.H.} ; 5 uXF GX", "GX6 sXh jXQ ,.h r.r. r.~ t r.~ < C u +XiXqX:.~.C u N.h ~ ~ r. r.h ` 7 LXF + uXF GX", "Y eX=XF r Q ,.Z h h h r. r. < +X~.~.!.n J J ~.v.u g.h. ~ ~ h h xX+.z PXF $.J.eXP ", "q.P h h m +._.r x r.h F r.h h h r.r. ~ 4XtXD d.R.R.1 1 T.F. r.r.r.h h 6 h X.%.oX6 6 6 m x :X:XO 2.9Xh h h h h h h h h h h 6 h h 6 h h 6 6 PXK K + IXPX+..X6 h _.E F X.UX", "q.P %.3.x dXm F 6 6 h F 6 m x >.2.7 LX,.jXr ,.,.2.Z Z ,.r m C.LX<.0 Q uXBX;.l ; F Z 8.gXq F 0Xs ", "q.I.y.F b HX5 PX+ ;.Q M ` 6 h h ` Z uXBX$.$.0 d ;.+ IX0 $.Q Z m + } ,.'.kX6 F IXd AXq q F a E.$ ", "a Q.Q.a F #Xw V l BX&XK Z h ! O 6 F K <.N + y PXd ;.;.uXuX} ,.,.5 6 h h h .X+ l BX$.H.6 6X6XCXCX", "N.D.C.: E.; ^._.-XK <._.h .i.r r jXF 6 6 6 6 F F 6 6 6 h 6 6 F F i.oXoX1XuXBXl $.LX6 L.% NXd.O.", "7.v.D.C.Q.: F 4 b p } H.F O -XZ.K 5 5 2.x {.O {.r 2.>.KX1.sXHXd r ,.h h @.} IXBXjXh % z.R.9 9 c ", "G 9 u T.pX% h 6 h F @.'.:Xh i.M o BXz # 6 @.b E r jXm 6 i.-X$.i ;.FXHX/.2.2.6 6 h h D.R.!.&.G 7.", "9 !.u tXt r.9.! /.` h 6 h h @.i.N BXl z 6 sXb -X&XV C.6 @.E BXo $.+ 6 6 h h kXKX2 -.6 r.1 v.j 7.", "9 u ~ h 9.O ` 1Xr LXK ,.m 6 r.lX= } + +.F 1XsX,.jXjXm 6 H.S.IXy uXjXF H.@.1X9X/.>.` A .6 z FX2.h U. dX-XQ z 6 @.9XO '.2.m 6 -XM y <.m 8.h zX{.T 6 nX@.6 >.h 2 c.h d.", "t ;X@Xr...oXh Y.Y.h Y.-.r.U.OX {.#XAXQ F h yXr. h h h S.#X;.PX2 h h r.W.g r.9.v 6 nX! 6 9.X _ ", "XX~ ~ & _ & U.r. & f ;XU.6 E Q + ` ^ XX;X lXT -XK w hXh & & U._ pX~ _ z.h h D.~ ~ N.", ";XmX[ 5.rX:.MXvXMXvX5.[ [ ;Xb.! @.-XZ.F .Xc. OXMX yX{.F M jX# h T.tXv.DX9 v.1 9 2X- 2X!.9 9 9 ", "vX@ B.7XL 7X3XJ J { *.k iX[ x.lXh /.2.h r.OX[ MXf _ h ! x h Xa.qXH G G 7.7.c 9 H c 7.7.G U &.", "8 { 7X*.| *.*.8 k 3XiX*XMXOX@ t t f ~ ~ f MXMXMX5.iX] vX~ ~ @ qXqX!.c G G 7.G G G G 7.7.7.7.U 7.", "7XW 5.*.:.rXk aX*XJ J iX[ 5.rXe.e.B.:.e.B.rX*.k { J *X3X8 8 }.J DXv.7.7.G 7.U U G 7.7.7.7.U 7.7.", "L L *.k B.B.*X:.5.8 iXiX[ rXL | | k rX| 5.e.rX[ J n n DX`.H fXfXc &.H G c 7.G G 7.G G G G G 7.&.", "B k | [ *X*X*.aX5.*.*.k k L L L k e.k , e.aX{ { { 9 fX7.c 7.9 c U 7.&.&.7.7.G 7.7.G G G 9 9 G G ", "e.L L *.7Xk B 7XB B L B B B B 7Xk iX3X, 6.~.fX7.!.c &.7.7.c 9 H G 7.G 7.H G G 7.G 7.G 9 9 G 9 G ", "aX8 7X6.JXJX6., B B B B , W W { 8 { 7XW j &.U G G 7.7.7.7.7.c 7.G wX7.7.7.c G G 7.G G G G G c G ", "H 7.H U 7.7.7.7.7.&.&.7.fX7.9 9 &.fX7.7.G c 7.c G U 7.G 7.7.G c G U G G G 7.H 7.G 7.7.G 7.G G G ", "c c G G G G G G G G 9 9 c c 9 9 H 7.G G G G G G G U 7.7.7.G G 7.G 7.G U G c 7.&.&.7.7.7.7.7.7.G " }; GD-2.66/t/test_data/Generic.ttf0000644000076500001200000005420413076515043015416 0ustar rurbanadminpOS/2O7X4NPCLT=ͺ <6cmap9 Xcvt ;Tfpgmahglyf tJhead Y@6hhea X$hmtxSiVhkernCxlocaTmaxpVW name:P post x DprepsT=  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a>z "   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUV[WYZ\]`a^_X $4U !JfP hP!wohB+'ym/+)fZ?+'oj=7^`T) omb!@ ,C b#BfV-,*CTx+X9Y+Xf  H  n * (D* "6, F !"##$f%b&f'B((()x**+,-R--./0l1.124556v78 9T:@:;8?4@@ABCxDtEEGDGGH.HIXJJJ@$i Uiii4 <++{b  "$%&'()*+,-./0123456789:;<=?BDEFGHIJKLMNOPQRSTUVWXYZ[\](7>F F F  V 4b    ArtBrushMediumFontMonger:ArtBrush MediumArtBrush Medium001.001ArtBrushArtBrushMediumFontMonger:ArtBrush MediumArtBrush Medium001.001ArtBrush!ArtBrush Medium7@"@33  +1+0!!'!!B!B!!@   ^ #+1?*04722632.1".5467632#"UP $& .5+w!?@ Y V;wZ )G J.@gLl' H!@ a #+1?*0>7#"'>6%>7#"'>6o5%,.>xL!S<,.=xM !!(N \JYz.BlC'A `HVy,Cld@X  //    D!+1????++073737#7#''#'IHőFC–îǏgb`^`3bwV[fqG@=hg`\H@86/  n k khgd`\YVRMJFC@:64/,)#! 8<s+1???*0263267632.547&#"#.#"507#"'&54>732763.5>7>746>74&'7257 IAT+/QU 1܏!; -HVOp,ņD PGf+69`lc Ck5*:W9?/g:@5bN&Ej7 J1K[o+@#e^UL8-"D cZQ4) n?q++??*0#"&567>724>3#"'&&#"'.'&54>72"327>543267654'"#"3V! R_K2\UDon'#+< hMI7uD LVFly-.= `*G :Y n%` $UFI՗B p'-=|d}-LEwr32##"'&54>7&54>7632#&54673267 32>7&54654P&GI2 IwЌY]ZN{(7#"'>6o5%,.>xL!!(N \JYz.Bl@  | ++?.0#.547721nV-+P9>o/S)٥?CC%?e& '@ |++?.0>54&'&5463"&5>6=1V-9(wH8*Ut٤P>V0'=C_ޯȺ& ÃFOR@DJBA76.*&#"N K I / !   JICBA<:765.-("! _>Q+1???????*0#"&'74&#"&57>54'&5467'>54637327632732%%'.#" T    % z!   P    " s     '  "    7!0,@%0-)  0&"! X2+1*0%.#"#"&'>54'&5467%>7>323267P !*& # L==& +% + & F+ /  &''@  i+1..0.547>3#"'4>54V:A'4? {X6Y2? )&./(4Yz2D55\@ ` +1..065>5%4&'4\& V   o ' {N@ f +1..07&5467632#"&3 :038&? 9219&=J1_!"1]!"@ R +1*06332632"#"'66V?ϱ(  {!By@?O/*`3)3@*( (+   $ |$p+++1++07.5467632 #" 3274.#"h#_Yw97M(2f "E.30栓I*$t'%شs~<`%00iL! @   V#+1??*0.'.5>72>76322632:" 8+U*'6l-=}<~u 7 ON+C l,=M6@.B F+'#KF@=60-+'#!@ 4O+1*+0>7632>32.'&5465.507>$7654&'&#".54'&&5ZtL:0G`67!e/L @@11  6q;I /1El= Am'oA64\y=]M1uߺF  !  &  93@;G2" $WU@KT/,'"K1 OK 1&  TQOCA>;," 5/ s GIo5*'$/Y++1?++0>7632#"'&54>732>74.#&54674&547>54'&#"&5465.&xd`563A^ffg?/o2A=HOK2]Y#pkcW 4 42I [g"6/'   ED>;/'& C1I+1????*0>763226323".'#>&546.547627>7 . gR! ",B A@F ?_wQQ_    4  '  '&K: 0IN@F/(%!;1 H =E0;1)  H=86% t6E(-r%!K+++++02632#"2#"&5>72332>54'.#".54'.56727:uFB8ܒՋvj>sE^5d O"-@X[*YQ[0 u, !  D K_]H4Q=K$5! N:#<9 !0$=3@*5)'7 0.'+ 7   < {3!?++??++06$763232632#"'&5466&#"#"'32>74De  #0 .Ą(cVfOiyT0Zrb?D 2LGA VR[)'#i@ WikvP{Q#('2=@NRQ. 50"@'&  /,)'& N2+1??..0>7632".'.527667&5465.54%]hU@0 )#] ) "IDXr    -cXT U`&5.  ^ 7ENL@@A-* N8 J ,    ?,6= KNJF j%D82|H6=/P+++????*+0672>7&'#"'.547.5432654%.'fQN^J!!N4  !77U" $U' (=6kpqn@1}Oi\d BFmD{M74_A, ( #E#,C7Qj9*.g4Ma)g\c+[k84FcR!8+@"/-'(7  % 3:++??.+0&54>7632.'#"&&3267632>54'&#" kݠ-Zl{mlt( UHeD~<RAF,Q0&<h_ۼ. `[ "${oX #$+k)852 %H%=P'5X$@#! c&+1*07&5467632#"&5467632#"3 ;/09'> 811;Rd 9/47T 900:Ts0b!!1^!1b=1_!X+@*!% h -+1*07.54763#"'4>54&5467632#"bFu5= KyC,h,3 9/47T 900:T+:#)i0,2BsF*T/91b=1_!?`.&@**)$"  Z -0+1*065>5%4&'465>5%4&'4++' n  ' o    PO;@00 E3C C3.+ oI+?=85 e Q++1??*+07&54>7632#"#".'&547>7>7654&'&#"&54654.547>7632\ 1!5:V# :e7654.'>7>7>72+9- OU@li+ @3j 8] ;3rK M'JfX6z 8 0o{>7o " [DBu7%9G_M@D\TPHB>=: FX 2.F( NK)&X# "  VPK>5.)} Bl\a++??++0>7632#"'.'.'.5667.54>&6$65.#">322>5.&𞰰4$B`NVw|);񥗌 7 #_"4oGB Pb/p8I)*c'9#uf(RTL4$:W5L<]{NBY[HMp?4P-" %}{~/*  5(feU.Xrh+7 # Al33!B4@(=7"9 )    3/, =o?D++????..+0%2367.'>732>76323#".'&5466z;!u$ -0L|+)1.. 8\*D,'/B5{u RL.SB&J.k-)R{`z0  6\Y6 \ڨKBQ@L^*  <,!.Z7632!&'&%6$>7654&(BhP0.ґN/~$& r&ZZ1`Z"SzcVT ?Q;id}D1@''"-   B>:74-,)"> /F+1???*0>72%#>32&'>7.'>7>7.'&&Ru*  `%f)CH5 *f;hNR18Tp ##Ju  ** )'%%% >+IAh|}:"eAvȥc 59A>.@%>; '  >;86'&%#  =*@+1??*0>7.'.'6$>32%.5>7>7>54'>3NTS ' HBC Պ )/*>n $-!'   P,,*I:) ! " #! 6`/.Oema$%>Xj>5<>-9G1@)D?"'A 85/,( 5,&DmFI++?*+06$763233.'6732>54'6$32.#"#"&'&54+ZE d. T7'=2"'#_d>^%-[FgW1#sS  /#O>C9X?a2C=B@3:P> =R"aaWs`@R_J  %59+"̈v"7YKW uG9@)$F -      ?<9-($ 74I+1????????..0>32%>7632>32.'.'>7".'.'>7.'>7>7>32+21&(9= L-6_A -S\k)2 OC;N**H!_U%  %Q0 XxDQ' MwNk*V@   [ +1????06332632.'>69@ LH;3:Q)5W -E\x%"@ A$+1?*067632 #"&'&54>7>6o3;/JE-Na%Z!J;%)!87S3Ao@t7'*@     : $)+1???*067632 .'.'6ŇE`*6/;Yaa*3]"9HI .w%-322>3#"'&'67>7>6*x0ʧOy#)  PC< 4 .2# ;1@%2 - * %   72/-*# 5 =+1?????*06;>32"&' .'>67.'>667632263>7>6):CH7-  =#SQ KP> "BE!  Mbk,LB@1UiF  31*KR{-Zx$*](\_] Bcw#@ #   < %+1???*0>72"&'. '&'.'>7>3h!`K0, K T-=->5r$)ra#9J ZT1!H$k)kF, 5*&@)! !  &g,++?+0%.54$7632 #"3267.#"7-/'Wp<ݑI4*4iŀ &60#.ۙQ;% QW($ֲ@f9@oC@*><@3+=5 != 1.5  51.)&# 9@++??++0>7632#"'".'.'7&54654&545>36$65.#"KkEP_)'%)*R-?0">8DqQ')-5$qՏUVb h '  & "Ha#!gH#G1 b(D=@3:70" C :7?- u ?42q-'F++1?.+0>7632.'#"&'&54327&54672>54'&#"uD;Ud3\d.0%i]26jiI'p$@8641(cB%;.,E[;-ߊ/") (J@2  qHZ^4CO 71",/#Y]Y(31@(&#1 *  *&#"~ /5++??*+0>7632&'.'66>7&#"ZiOUwyj :M EYqV ȲM lF550hMC4.'uC * 1 &ND`88MlB9L<,@$2" * 840-*  ? &>+1*+046$%632.547 #"'&54>7327>7.&-YEQb%)/@e 2l9f@{WU=X 9sV]S& S`Ko +$%2Q6&6"^w`Tp!>pDl aAHHwN0N~ * @!  !F ),+1??..0,%2.'.5.54.540b ~U B?jC]8Q"[ AC* ,()6Fۍ@ ('7y'#@ % 'l)++??.+0327632#"'$467>32632T#6^ }-+ߕPbpD 2QE_$5e '!#-Q0j ! @   = !+1??..0>7632.'.'47>7>32P$P *8! =1="V11Bc 2>  9^35/@%(%  5   520('   4 7+1???*0 632"&'.'&'676322>32>766767263 @:P *}zcddtF VC* >% V B }&  {pcrEk  #|a7+ J>/@$$< %  <830$ 6 ,@+1????*06$>722#"&'"#.'".'.'65&'>7>35!y%` ^dhz 5C' ^ "0 H*T A."$9  '+pu  hY^}+| 2s~" -f-8&  7-+@+(%   -(# I/+1?????*0>7632631.'>7.'6323>32B׃+2 $S+JPL;V2JO 29Q L%?OCVB<,[Li ##/*@")(" .,)('" ;%1+1?*0>7632>32 #.547467"54]Ǝ[h<za00  ()gA3'$+bb$ S(A   N%jJ65#@ R +1*0" '&&'>323#"&#"{>!AyA 6  (GǒO_*h@1 G+1+015!hh3#(36@*-' )  '  )z-!5++???+..+0>722#".'#"547#".'&54676$32>76m$:&'  ; ;7'X? F[_#1z:mbJ8 "  $a'a !<"%+Gi;dgV"0<@2.( .( ,& u,y&2++1?++0>7632632#"'&546632$7&#"քQ+ D t6,r`nG6\8S$kI ?D(: uxBTD]y#8Uɾ3a,| 39,@#(.8 +   41- w$;++??*+07&54>$76326322&#'.5>73267#"N &5V "Fx(),#o'1d6 yU%V\,0 : u 42: _1s .VNVh .*@!' ! ! u%0++??.+0>7632".'"'>7#"'&54$32>766 *-! 9  k5 `^0~_&F   #&%!3v;.a'bnE$3-@$%# ,' 2/,)% U 5+1?*+07&546$33267#"&#">7>54##n_r%>Z|7.h= -f8%1h?!.bom7Xr YF?bD4[A2 xn9'US-'xc3%Q" +B6@+41.) A    =:41.) K&D+1????*0>3".'7"2.'.'>7027#&5.'>76632+5@14E6#%P?]9 @v" |)&C)  R7L ,aB1V^M)7P< +%;u;q{3/5/c94G<@0' ;# D2 / ,  @ w9'I++?????.+02632 #".54763267>7#".'46$7226722>54'&#"C Ŷ?f(.>CZ1:Q!VJ!;)EK$A3>"#l! "M՜+͂!-$h.ც"Oy8;%eWnGpSQo!J;EK( Q#ܽ. qF1@#&D@+  B32".'.'>7>7".'.'>76>7>32326$y\.GD'.n +* @% 6/1yu9) . eX@ "R^   $V *m \*9"6(Vf? $PLr_h8n  CLj>Fx  h -"@% ( "  *r/++???*0&546?#"#"&'&567>76322632B3!T3P%!39AMS-pB & , RcN%7=jN*^@KT1.&1Ug!` +$@!( (D &-+1?*0&5467632 632>32 #"'.547B7!)(6JqA =w‡V#Kp&#I+'^04y* :tHF˺;//%#>klYF8@+=8+ D , &   B=:8+&#  M3H+1??????*0>32>7>7#.'".'>6724>7632{E 6e/CO"#$s{u57'n32.'.547>7V 0 8 8']: +k +#%b<X 4b((   FYUw\7@)R0V L I F 8 #   ZRN?0+~^++????????*0>32"&'.'&54665 ".'.5>65".'7676323>32>32VQk=z( RMMsT,VO 7 Q " 3  1ed+?'R*|1F%Q^,մ-  A#/#`B   ;5BQ7'$W@` E B.5(?/@$1& 6 , )  81.)!  S:A+1????*0%"&'.5>67".'.5>7>76323>32>32R 2L= ;tnE3|d0 YJQe3 / 6  JHI":7?=B) '=?4VuVA2% 3f ' %.61''1[oZ/&,@$   " t %{(+1++07&54>7632 #"&#"267>54Ns=@DpGepPB67H%TS9"O^ͬ8Jw9pbNSCAw}/-0H&5.@%+ 3"  )$q17++??*+067632#"'.'&#"#"52763232>7654#"+1!]W/UxCU_J- " i e`%3*yD=u%i\D@O/6 ^ 1Gy@_@F 1!/-@"', .   ,|'1++???..+0>7272&'.5>7#"'&54627654#"j9d:/\FF[7.'.5>763632>32:?  .F'/ 5 L@2# ?!L6" " P[n=tU. 3xH ) B'DK@B@;75$ = ',=**   n$@7k,v;/F++??++0467632#&547>7&#"#"'.547>3232674.&(6:qS . 5Mg<' !V!PJ\)Wd gBT7(^l Kf-Y@39\[ho, (8 A5='D& <*8LzbHM3"$hL$()L3[31`64@haXsD.@%'%>  A>;41/,)'% P F+1??*0"67 #".'&#"'>7""5465.547>7>7>7>72V?  j#Qc ))/UktS bP E D@; JMX  %   %8 lʚ 5) 0x,y &` 60@!05 & #    0-%t8++????????..07&5476322632>63232632".'.5467#"] - 0 [. D 71  8?' e`9fw(8p7p j! =!  1wbRE^%(@#   O *+1??..0747632>76;2632#"&'&&^," 9  շ$A8 u * '-:M]  !);[3  7GI@8D63'  A > ; /       DC63/'$"  98I+1??????????*06323632>676323>32"&'""'"547".'""'63212632> #Td}# :&P ' A.'H0%?&   $A i !u8H - 78cE3O!K92@&4  1 . !  61,'!  J&;+1?????*0>7632327632#"'&'.5.'6323>32s6r51 >#); . Z   Z4 7 O66$ B (X-Gdr $1Qnb6*@ 30-)  32$"!  E8+1???*0#4>7632.'&547&47>3232632>6Y`D1?  2.7 @8# (9 ' eenvT  C4F9 # ͤ®XR&;G-@$C@$ 0 C@520/+(&  L9I+1??*0.547>76322>32&5>5.5>7>7"=4 7@c$ 4-f!# pGN3=)MU!'G'/NJ /   + # c9>  * 1 )8"C##RDO(@"HE?862  H;32 # K)Q++*047>7'>5.'&54>746?632#4&'&&632 DYgcL# l/9O.0>Y}VL p"   %/' &s:  $"LN8o82%0H&E;:"L!]P.4vT77@ ]+1..0#".54>763238WP?sR46AoN_QiVi##[W@LWTJ@=<9+L 20-1 O2LZ1D 5 WTQOJD@=<90+ H 5H&]++1??++0".54>3232>54.#"&54>7632632.#'.5>73267#"hPmP@uPronqTr@(T[ ' "=H  :X 1orB]OgRkQs>nqqo@p),rtZ  B=  |1 W8  @V @  d "+1??..0&54>7632#"&#"267654VNCzI!#6$WJ% 1N;,9-3'b@#$:MɐpSA 2CP?@ Y +1..065>5%4&'4P' V   o )'h@ B +1..065>5%4&'4' n   )hN3-@"(2! &i2i!-5++1??..0#".547>72#".547>72 #0d,AxI ?5u#0d,AxI ?5u(!@2O+Fs@8&1i("=2O+Fs@8&1o73)@!+"2 %h'2- h 5++1*0.547>3#"'4>54%.547>3#"'4>54'V=5? }W6Z0'V=5? }W6Z0="):./*2Zy2F3="):./*2Zy2F3)N@ i+1?.0#".547>72B#0d,AxI ?5u("=2O+Fs@8&157@  i+1..0.547>3#"'4>549B&5? {X6Y2? (&./(4Zz2D55'FR;3'f' +7d'sF P'FPR9^ -%R F 7!7##DhPD{+qPB\T3H\X3^ {7DTqf5br d%bPqqf @ &k#GD-2.66/t/test_data/images/0000755000076500001200000000000013077123433014562 5ustar rurbanadminGD-2.66/t/test_data/images/corrupt.png0000644000076500001200000000236613076515043016776 0ustar rurbanadminPNG  IHDR.,SFPLTEܸ L$}IDATxڽn@`R5q EԜիo7{g490$%!Mp8Sv܆)˴m4mQ#Q\U._U+T_+\vq+R1b\c*j S+.ڐJT >qa*R+.|\ ڸr[V(kǕ K/1~\`e̥₶5F5 kU.֠2ӏNN\,R`2,Z\ -JXӈ,ѡ]EXNÜXɰhVkaɸ`ZqXaMq[X,HXS\XѰƸ˕ӡhQƸȲ7>"rua q鰒aqYZ,r!bth`6{:ºX?,R\Vji2:ZڬE=du˳\dZr;u:d:v_Xټ!,?#Y'gyF"tYpKYded},:miec?'uez J 2vx27~sV`%Y;b5v۫U)S2{o&K!vZU X{Ed%KVaCn{)vvz$+٢ZY;/W VEZ`V4.,w1VzVEW>kX.xJ`;ldZ"Xru3 %° %| m-?z8oэK իd\^Xfen?z?'_XErTk˪ѩ \EenS8Vy2k z i< 55ĺbc,Ea]p̸31WeX{_7O=-0| Z=`=_GK tf=-C|!@I_+`§Ha>>s~32> { 7@GC@~>a+/B /yu秾-'1bǾ~>1ߜ}뿁?}>~MLJh,Vs]}Xח<}OGxA0C7Q-}[Tʲ,˲,&M/@p 8@p (8 (8 (8Ƈ||&GV>l/=`7 >`o+9`7ǟ>X?/q>QN?"o?\sy#_x㏏zIgz]߿&Sx  Omx0 \{ݹFa<ӌ{Fg/;_DQ,'دcF   0^':xiVzw葏+6xkg{=tk-0`;xkz=0߆PL_ iނn~go v c8+xZ0wP#O?U@'8~Gh~h `AqX!B!B!B!Bx[>++++++kw}oT?O?>>~m.|BM_lKgp;x1 ep>M_lKgp;xc``쀙(zQ@!{UGD-2.66/t/test_data/images/t1/1-00.gif0000644000076500001200000000553313076515043016161 0ustar rurbanadminGIF87a,,ܸ ,,,0I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzxLannzNixn{Dm-1> Nۢ"dJ ( dKֶˀjV;/S#'/pz2[%k 2!2+Dj&+ 39;DokH/mҾP,sƸ RrV4]K\8[|mk, G&M|3p8s9񠽾S^9@:i;ӓ+y=k7=X~7"ȓ!H F"h0 P!{h£Q+ o.p|Z%=VZAmRN3Mھε+pڏ浬 <ڎ&tu}fZVv{ >{`jT v-n[Mv3 bp[p3n's;ַӝ[[v뱭x+'8yL\eF#~q~C'2'g?;vnn:֬nKo;6[r[f}rK5ҍr.z+K[t\::؝u0G>{]aoq}|/??}I]ٞ[诺3?=n~R}oywg ؀WwN瀵p 8o HhWzyxz!&ȁ%Hq#{+xzg1Wx7x7ԃo@B8DXFxHJL؄NPR8TXVxXZ\؅^`b8dXf li8k؆ojȆu8xhpz(w}(tȇy8xh~Hhx38Xx؊8Xx ;GD-2.66/t/test_data/images/t1/1-00.jpeg0000644000076500001200000003141413076515043016336 0ustar rurbanadminJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222,," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( ( ( +/Q&-i3X&+2qy5^_y%#Ld!E*z%|Jw:khOt$!ՈJjxEnm;( Hb@_+ d;0م z&";f o_zg|y+iwqg>TpG=kĺ/TKb*RџY^}|3}+#z0 1ےS`Et򖟨%q^Lhsۡ~!tA=U\CѽG8C'/6Fְ~GoEWaAEPEPEPEPEPEPEPEPEPEPEPEP'|Oc  !ϴ.ׂrH냁x8umSƞ(Ԯe& =I<𽸔[Y(`p 2 54Ap;(3W^ ,D91ivAxrH%p$/{(zI&_Ӵ&>^58gnAkT`(j1]OJ2&QUg`I5 Lkdl~9Һ (L #z}=ZYysM}g*OTqڗT2 T|T. KfNhWh-rP+Ȍ(ea#xZWYZ]NraE{XlٴWK9q92Gz)¢ 朇Qȁ$Cz}:ruZ^-)2J? 'Y:][ӟ@F=9?8`mcz(Zily$fK[{Y'Yba x>o _5֜u=?1_5~9Rx:ߪO|!h|Q%bK[P I ?Z?{ cld <ZWC]gzbaU_/(Š((((((((((/i~qŘxi>}[2^=.R%ڧ}=x+ Ww[- *C>ჸWك=wr '󽣩ٛJvMۤ덣#+𝪥L;$s{WE_-὎-~]?31S杻Q^QEQExI椱F}s /=x }L³\yLٰ2@l$A_Vamcw+0k(TG֩KFu4mbc|~ עQ҈~A瑸3Wx:f[ˈ@Z08k4F%*gWoџYOz>+?8 ( ( ( ( ( ( ( ( ( ( T ݿ\ӻЊ6`&mn.%yy$3I{ׯ~G(4t>%w+83>xj4}T)e9]i5R ʊæA#?ξ;kJ>u/nU;oiʃr8csVzpPvZ-݅QV ((+xfw2rFT_x};wP(Yxܠi_۪|+oב»Tdy$ܢNWDŽ?'7p??Z<05UXzy#x&7TQYI3,$g ;bPIkJD~}RpQE2(((((((((b%۷yQ{c5|,rC#*2HU ׷yOs_|+Wo'ªqv`F{kr3oup! $l'}$IRu0PEWQ@Q@Q@x' & +. l$#5uu*^%} HϘv| q20ЊJܵ68 i楹 6jv_fGõy0?<5kgN2KndӏN+VU1kKuR8 +ɂ((((((((((suټP.Udw f.HS={pֹ Z\7 INSw91 Oy٥/ik|7Nʁ"%1 y2$h89XRD9FE|\q0%⍸f5)R}u5F~ Zߤ8&*nӏ-_w++QL3 \{]?GQQ|$ʮ^NN01Jtft+ T5pe_QE0QEQ\'?_ _؅Q`dbA]ps@2@m3.c} IId"kAk_!c5YK}w8,NDk'"ݟKX W{y/v? n 46gev@2N+mkBH'xԈA tkkWEuw~Sxa}_E!EPEPEPEPEPEPEPEPEPEPTu2-gGӦ;Vt`;QN2qjKt)EI8mͼRN%r.A2=uMaO?z;FZMU47P(0P1' \xZ;#-kpq8z:9Ֆ_{7oFvXa=+ٮ18b$I pq2=z eX4?^3 ,gy^24*8XKFzW|Me0]Zr76#Wnbt`p08;+ؼ/L>gx~ǩ>cp7WFjͲ f5=;Z(<;w{YP0Tհ YgGoi~յixU^^W=v8 8|S}jy8 X*MOz]_ȁBG @ '$N=bV>m\=o*ƶ">#$p4`1L:ץW2]RbE>Re~W}?u֫Ij4`01/) ޠ^;XpFb/rO'_j,"[֝wUG#@1ǥq8k?:H"K?!>|xž%]&8/Ӄ== 2Jtcg~}T{[O2̱NKM[Ls/?UoZ]c'/!WWBOS.n]{ɜ8_o/3X%^u- ơ"vF_P\j83^ jˡ搳1ӓUoY]*"/0|,XT+{;k:⣀۔ok}]?|9OjOMO[E%yUXyi'^ .? ?µkW~W9lFR#ؤ(㪶tT|O 4qE_0x: ^q$?VKZ.T-:緰U'Wӥ뽾G-W~|G)fRU$?W]ԼM *,ڼoF_UU'FsbqwW|3*mEe.? ]N L[y!e}+"zKjĭzԚ3^hWNżsTZQirۿdXb*4.ǢQEyEPEPEPEPEPvL7*u&7+GמGC^ i>=Q4-rFAЂ5]s-𕿉l.o\C1_w\_yyĿZ~+1gqry5\^h2= 5iZz88K:zo(a{twdvu7-ڏzOӼ3I^UomFa!_2۠f䞨ܿ8*u5x >{ &#y@u㓞> igzI6zyw~Gv$BOC۞? ޯ>?ƽfqjizeU\c44q$1EDF)/ Vc$B(y<А=?Ʀ2ܯt#{KY?ta _>NZnQYG0Q˱$EE mC]=E t#J: csLutG7F7V6}y-`~?nk/}_i3qW^͟E^[j "UNXCm}^e6y5%yzxB?_ʯϛ*αOkH<7+cO6L~v~ _Kyw>l!4'l&T¯l\]?װN2"G5j]m}Y^űXglDӡ!Fy&f<% B)m:?]f!*φ91^|4H?k/<>wrڷ.lԼ6v0y ڎqM׽ =F.4:IU5\Sbjwϧ#—i$ qj/riNk)R骜9@s-_ T-yXZyZ=4zξ/J5v ($((((((|3x Q$P 6G>הk^ 3\ľsFIf_UNGWxk.sz7!i<8J[|)# t<+ğ"o>kt 'o/G5s¾5ƌ19kM&yL ɷ˧&?kͫ-GynK/fx#L#SyU}җ꿻{|E.\|!e>[8&ƗuO^ ^? ›i7l{V?Q: d(((((((((((,"C#\ZR2L\W^ !^x{Wa'Vn*KY6G5`|g]t:|Mhr[_GtTzV>6¼'MxZߕ 鏍y?/y' y\!l?^[__;/cnKgxcKΖ`LLG8#޹frٹhxK~m` ;NskVrE|쯩.1NK= PҴۯb<K}s·5cK? mfƸIFqz6պ9~c.h:]-elHdĽ|78!qFFFE^Y9]z7:nw~fwg 򰐨*>ý1_'gQW?&OV 2Kce~s~[+>_¾y|⼾ӗ%oÚmY\K+~;U_:iQar~?uo.;'fq uQڸ ?յݗi>l*U)SqቅZRQ}XKi+R7uW3?%s(m6K=`1ҷ-x~ǛoZp,|ǧ[ž'WJ<${W m-5q#L_2y'urD 2e,'s^srח}UQRckmb}J).#ʪNA?JIuiE;N XMq]2:?i–ѿ;vfў-|ϑ&Q}~"N|?=O$դVˮN9+ng ^\4yЌcU5_iŮG{:u ~m,BdR\ʯoxXU_HYOy%z$ V_:$мRkGR7Xo3?%FFJm s}HJ$]bK-V=&%[Z#'5?fu|̀3xj-(45Toƺ Nuŕ\鐶⊘UF0cC JJ: ~ 0d[&>Q]QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEU#iecٖȉsq/r=FBM-6^8?(zJϷ#ӛ yhGFBM-6^8?(zJfZ"&m̼p~Q^}?.[̻ER:6Z:mḧ12G#zPtm,,t2?0.cn>eGve*Ѵбl@dD9҃iecٖȉsq/r=oG7˵.TfZ"&m̼p~QK- 6̴DL ۏx=(~?=9~]vtm,,t2?0.cn>eGYhXe2"`\|AEn˴U#iecٖȉsq/r=FBM-6^8?(zJ/>ߏNokw-]K- 6̴DL ۏx=(:6Z:mḧ12G#zQyzs|[o2HYhXe2"`\|AAѴбl@dD9ҋϷ#ӛ yhGFBM-6^8?(zJfZ"&m̼p~Q^}?.[̻ER:6Z:mḧ12G#zPtm,,t2?0.cn>eGve*Ѵбl@dD9҃iecٖȉsq/r=oG7˵.TfZ"&m̼p~QK- 6̴DL ۏx=(~?=9~]vtm,,t2?0.cn>eGYhXe2"`\|AEn˴U#iecٖȉsq/r=FBM-6^8?(zJ/>ߏNokw-]K- 6̴DL ۏx=(:6Z:mḧ12G#zQyzs|[o2HYhXe2"`\|AAѴбl@dD9ҋϷ#ӛ yhGFBM-6^8?(zJfZ"&m̼p~Q^}?.[̻ER:6Z:mḧ12G#zU-BG POӗU}%*QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEGD-2.66/t/test_data/images/t1/1-00.png0000644000076500001200000000236613076515043016201 0ustar rurbanadminPNG  IHDR,,SFPLTEܸ L$}IDATxڽn@`R5q EԜիo7{g490$%!Mp8Sv܆)˴m4mQ#Q\U._U+T_+\vq+R1b\c*j S+.ڐJT >qa*R+.|\ ڸr[V(kǕ K/1~\`e̥₶5F5 kU.֠2ӏNN\,R`2,Z\ -JXӈ,ѡ]EXNÜXɰhVkaɸ`ZqXaMq[X,HXS\XѰƸ˕ӡhQƸȲ7>"rua q鰒aqYZ,r!bth`6{:ºX?,R\Vji2:ZڬE=du˳\dZr;u:d:v_Xټ!,?#Y'gyF"tYpKYded},:miec?'uez J 2vx27~sV`%Y;b5v۫U)S2{o&K!vZU X{Ed%KVaCn{)vvz$+٢ZY;/W VEZ`V4.,w1VzVEW>kX.xJ`;ldZ"Xru3 %° %| m-?z8oэK իd\^Xfen?z?'_XErTk˪ѩ \EenS8Vy2k z i< 55ĺbc,Ea]p̸31WeX{Wi}~OwVcsç]Zu۸ /׷޾lcCG*^Fճt<WM/~U$&q*?Hh3/`I@ ~%*ȗ_!g8}1Pa9yvo/oy|3םSbygHxnԾRV />· ַb]|Wwm|q~q.>') /|GBb|O|~O(}~OÏi# ? ̇HX}T?Nf#xA P*L^ 8뺮뺮뺮{}8 p@  8`K|*`{p'>$>`x|D>r?`O2gޏ ~~O}7#mü~]AG?~?<?8Q/ *x  Omx0DQlZh vegu)OLSe8/0sE>1O 3\>?>+O 0ƀ~`)O,>!&5$3fo bkłu}!$<N 4jA3K{t P~V6dlWP| #ZCioe4#_|˗/_|d\_>}ܻn?\>[qcuGK˧EkE[=oty/~G@c5 xێ еUt%`,g`עbl]{?:_O7@"RYRE_>Or?n—ڧgk6ncJ_m/_?K~3uKLҲ/M }'_})lˀO볭/Z|_ |V||2s='˿~>~ 4>2> p/@ P>*>0>(@Z# !BF|D>! +`̷G0 1 "&||@3eX}Mx  OmxA DQj݂u%SϪYQo;X3/HW:?GWiZ~E1x 1 ka+$9j}Xgui>}c|է tȀH<>wB},֚lxc``Q0 F@GD-2.66/t/test_data/images/t2/2-00.gif0000644000076500001200000000561613076515043016165 0ustar rurbanadminGIF87a,,,,,0I8ͻ`(dihlp,tmx|pH$q)L:PsڌZX u[z^GzȮ4mK{}we d{DhV@C;xRb+› \ѓ} b}b[LSOߔ{D=* CoBk1A\P#%|=NHG%M&BR%-Q5S~ْNB1}ZP"JhSK*5UVv| W7_k֜fϚIko-۶Bn+7LO%k_D2ܔpaz|er2%l3ϼ*Ɗ9sB z5!5ڶ]޳?.unyc!G<5Sױ]Q}sy7Q}wSi iSHP"!c נQGFn]\hÃD;E/'[+؂lc~6Rx[d Chd)YbN8m*(>*kjj뤔º箩Iʨ^OjN8F+ʚj鵼>#♧JP R˒:K*Bn+CR0 Wo{oYW,mz_ȶJc/pr8 21O1, LW RRlHvzfO|sT\r@cLDb.o-C[-,O}0mh+ wt\ ݷvs т^7y(.C3SSM&8;^s>難py{:d-~+ /^)޵3|Ռs7?c_ޯOO!G&׃o>λpGK}' P{a_py. DU?eP3!jP$8A!~[ BNw2 kh bF ;RK 7djm$TH$ojEJQz!FE耱NJ\4`ZqMغ91v, 8.@ $H>EϏWb$G #r#Y$"B2,-7fg(Ir"(xJN`]Lܥ-I=J+ "0]X_ &+WeLIA3&5(2rN|3wtBB/\Dl)jf,f[nzLd Z@ ~F̔BLB/$NBR4EJH{*ZRQJ-JE4I%4SxiKEhHԧiCqjO:[rN*541QSӈTC5iQ-XkXźSALh'V g\sŮr[ٱ׫֯]a)fM$ _JNmլ]ݨFjIuc=M(eDGkXTuw]l+Y.浳iQ[T nB:WLo۟&Z.mT\Z=-f{N""wK^;0oy{^Ln{@],#{_7uo_OnQ'8 $`FpzOni9DI)jdLI]џؗ11D;fGm(c8q䥦ثd*9L.`<,k62u#k<w|f unDhH+iASZ̛==P+%e~OhzaEud^ k(upo\z<`5-G2djH{k5vbXC=Pkn j@{;s{NJfuyso[ߎPCgv:>qEi }nG3'׻n;=/O1>r@<杅t'=:K6Pa#>Dխ>jK]M/G׽3}c'clݽx=;}gn$nkt{>xT~p/|oZS[P˝xz#K.DgzԧDz<9{{;a~D{#'~no)a~z~7>S.=׻mk~Om}|o;[E57~gk2|~~z\  Ȁ 2VG~~8xe{_WE؂x)_Te'X7xi9 ({~(:SWWeH J؁vG7|FXA|"8xZ_^*8N\d=hQ+jhg88w7rXhhw@XDŽwiZ8'ElqXG>MZ򈖘~І$fL}'M&$ƈbA%`$A":Et"JEfπ抣ȋR!l⋛t(H؇mF ;GD-2.66/t/test_data/images/t2/2-00.jpeg0000644000076500001200000002303013076515043016333 0ustar rurbanadminJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222,," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( (=>3kZťV5˰y>7(hih}ެy~)\|=3;:3%4niBWirr1Kp>xmm常8` $Q@$i6!̻'v# "WQ_+I,Fs, 2s]3ZEǟ-֤_LP@!rx!K<7ms"kJlXIUÒ[c^_Mqm+O@ Uo9 Ak ;(((((((((((((*9[cHU I9I_;|cү5 ֞fc/eP J#[mOC6wvN#8'G^+?hm_Urҷî<'\gq'n*yn ZB ub]&="(QEQEQEQEQEQEQEQEQEQEQEN Tz(P׶nsw'mmM3'j(%'zU㷏Rυ4l9E)q/'r WNr7cRrCByO2Lp[Q?4"=2=Ïʷ΅g`)?ux=\Ew ~ù*b}EoQEqV6Hh'GR=A= wJQlbԖpٔC?,~uXP՚Z!?itg@ 2jtOY"xIv91oaG~' IՕ[ݒ Qzv5_p/}z_? Az"@Ou?c⋿O>-uFۏd I#3+>Wʸ'k)ʜ;W J8->'TV~m{Lռ'֑\[lށ83Z'HQEQEQEQEQEQEQEQEQEQEW'j۪?o83cWR袳F%]G%צd7Dh*r89HbHaBd+!!|kތC8CBvQE}QEQEFe0~Klkc]5gn?x#\+ZqܸI%o~ȸ|l꣨I? oq@> Z9MIH~Ϛæӝ4۹"X7f v^_6~͚xYc.,ñph*1[['^ ^')F*JȬ8TGpHlVIeDyY.r6V8=Χ#WgS=;U@r]Us>]5r_;YMҘQE{EPEP7vwi, HrFp{{uشa\9G +*Y@sׯ {6.X|BwM?ϋ=bMf:2b l*>zZ2_?0ٝ?ސK"$:J_% 7*|ybxm-/<ą@AfG=H~&zAEPEPEPEPEPEPEPEPEPEP_n _uJ[0>:eouQhIi,@ẘv/?I5a:ƍ^͞]5rQ3+\g?OᦞYNS (Ot((+6[$<`~uP^x0ZQ%E#2k Ru8>LFOC&U.W=F`XɯxkI F7>n#Y^`77}=|KJoO%}_EPEPEPEPEPEPEPEPEPEP_n _uJ[0>\j^-#.nl'h(rGZעMQ9_һJ]+S[_&+KCn%dBykVWPA |}5}l4=S(낊(((]65I<>YAi=3kx}7J96k3fb=99jo⍗gA>q[7u=nZǛXt&G>Wy^Do{^v>kZK}jWgdCڼg9t1^^iQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@|~pgƯ+?5)lފ(0&Enkwn-4 8J'$F{-q鑯H@_L|Axy&#-C e0 awc*Gk=SgG~'kEW~QEQEQEW3[eԅ x? "IGjYI'Ws -2WLǾ}?qVfmg'uk*M kNe6?> xqĖϷ)=-'H)IiiRp3rFNryP:5n,F+` 5rŠ((((((((((?o83cWWꔶ`}oEWjNΝJB&||ijG^~ޏi HMqː@`pAWN|~h۔1?{Zg$|OU";؎7.r:iڌ: 8t'?\ج?#{9XjgQ\gQ@#2f 2I8R)vKGI$=ӮhʬQY,RעʚƹomK 4 dqһ_ "G_*|Ӿ$&cA["b2y{noqg?ľR1}iZִj9⒰QE!EPEPEPEPEPEP_n _uJ[0>+5 (2%k)v»6$1TyҊTqt4Z]>6ӼM˼ qeu Xdrf/kb-g12Ə*ʸrkodwNñM1 sCYOJz(C=?*k`P9c~zW_a7K_Z;Mp#?< I${?r] %Ψ+@i&I9! `Sn°_C𵡵4,oP`7967dg׮4-5d|#[SW3ࢊ+3 h?xH#n8#I@`p1%OT6Z,>3x+Qd." ^<9'*?-z4ڳ=O7`_XZ襭4 (G/- o%G8Przv 6>+|Vik'Ht.G*xoZ-#qy{'$ҵԛq~$ҾJ1n+uU(T(֒etVQEl`QEQEQEQEQEQEN Tz(P((((((D3O ;fPJ6ҹ_Cdv$wh(zѲ_3PGe?D=O7`_XZ襭찯>1xnPI]1][62FYʪddWп[o/5m|g( #n;V%a0ݿ ֛PpWo'KSl87# L<OPON )%Q^aEPEPEPEPEPEP_n )5u`+Q^qxm=Γ{||?*h<̰h0 <;=e>.K?@#j|W>'񷈼c_Ce8︣9ڽ}+;EujiZU/gŽSv,yb֗խ9试_~1l,ww7$|&NH9Mjݟo[y8!ݜ6r#vzxjw邏vqǧoNQEQEQE:?+;J`lpꋵ<t,)%u&?0x:lLͿ?R|:ET-Gb,Y`ғ{c;^cqv6pe*XR<#v̬d?*u04zYNe!pvߣ>L袖 oog_|/-QEuQEQEQEQEQEQE._›S8#GJ_P uZ}fegU,Dr-뽢ɽŠ(EPEPEPEPEP|4R@Iy^h2C: AE}[qo,sA*H2AG9?h,5tH;Slw&囎~W~\p_9>iM?>>21sԘH$=rfos*QEQEQEQEQEQEQEQE|M̭oF[x}EWjQEQEQEPֵ?úDq{(6g۹y t|r.nSP}춙Ww[0*LӠ?<}} *NP8U-AW [K EϮh,((: k o%vOuEVU&CP#g8~"6ziqB<DPfV#E>n巸&T)$r(eu#x  >*FҴ) J,*Q#ĉ# (I ( ( ( ( ( ( ( (>V^^M̭oF>+5 ( ( 㧏 {'ʿڷ,rrO翥zoů)>Ǩ}Z?sn"yT±޼s_#WNL@_/˧x8_3)ˈ9y懡7#W?:9"kgOX S}OrG[Y[ܗ/.ko(>\((+A[k1**jvd1f,)blhO_|=Kآsʷ*Rc?,U\>J27? YY3[DlHOE 2p1{8+ٳ_aqrF B '1`r>SӿuQ@Q@Q@Q@Q@Q@Q@Q@?_+ѯV^@{QE嚅Q@V|K߲}_1=;Pݐ2Z&-z[\}>^ѧCu: 3t>I2Ea!Ti69n븸PnO_EﭖgMoo +5IN{_G3觮V?E=xQm7S0a% ~L( ((VsawmsC2n#r0!G#zU( ?^K5k:E+(c,G}_,~ i:WU#TV.̤y =_:/̺/\2?c3c'\φ-<ߏ#q{Wa\{XJRKyhz맘WUG3觮V=+O smmz@ܥ ua޸i#?*ϥ#'?_v?e>GQ^G k/;G4O߈}+|#@oEhO]Ey4O߈>v~"{) ?$#F*٣$p>_P+l>/P$$XoUcG.,5Ky8a ԩ#2J_hK5uBWTt:)(٢d}EVąQ@Q@Q@Q@Q@Q@Q@?_+ѯV^@{QE嚅Q@eZ~W7/uec3˖6~@9i_?hׂWuh-οM\ϟ8Kv$'=ZTr~ǗV N}z+g% K)뒮-/觧CD5/ɟCQE'EPEPEPEPEPEPEPEPEPEPEPGD-2.66/t/test_data/images/t2/2-00.png0000644000076500001200000000313213076515043016173 0ustar rurbanadminPNG  IHDR,,SFPLTE1tRNS@fIDATxۑ MUf3ʖoQyNuƒlo!,)?D_i,)d-r]0̹k#4 u X;祺M4ԛU!\1T k1Qke-F>\u5 XP̼ՁEopJj.*)+tV TB.xQ%\`9P7˅To2Yn-z6Xz]֤6F K /\do.P,'+WekEh,XG劲:YrEYb,W*֙yX(,S\:Gq-W}JQ]\XYb)b顚yL,OUQX(bd97-3󐭫G(B!Cm]顶CX取>p DKE@,dPuV.Q P|. P*pŽbRYÊ "xYw+-(Ɗ "vy,ؙ`VAw=AIXvYr,QE!-}\p; KVe%bݴKTe%CQ,?bjpH:`%b3_S\/g%fCV j#_LE.^j}fYնSjJ袬z.-OVY0]Q,B=,d=4lcZqVk ]\{=pC)*ϊm]{Q/ k6X?+.(..,Q-?+Xq嚕,0@ԎUgy˥>zZf[5ۨoքaO;UXg$eP~cMVfk7rΧi,e R๫yMRwlaU{ dYO5~VXCY*WTx/ײ&eysMEb{lHj(`YYr`XE`Y"EeJcX`eX9rFݳ2H.G.VNgM J{jU \ OjUfݬ\ӭTa1H..U*2gkXEv b+1;\yaJb+rX+vXQ`EkU`YB?(3\b*kSQp}KXQxJc>YQbY'd,RT+\w,NXWs,Ngi(9H#\"H,FE(+?\,=5TaXQIJEdYQJVvi,K1CYeH,(YBcX"\$j%6XM`X`c_B(Y(IENDB`GD-2.66/t/test_data/images/t3/0000755000076500001200000000000013077123433015110 5ustar rurbanadminGD-2.66/t/test_data/images/t3/3-00.gd0000644000076500001200000001362513076515043016013 0ustar rurbanadmind2GD-2.66/t/test_data/images/t3/3-00.gd20000644000076500001200000000232513076515043016070 0ustar rurbanadmingd2d2!x E?H5MmfBߛeܢe:sՙ8,0؄.UqB uŝx"Q"#" q"@%D}jGD-2.66/t/test_data/images/t3/3-00.gif0000644000076500001200000000044713076515043016164 0ustar rurbanadminGIF87ad2,d2TF@(ʶh~rL_( E,M*Vg튝Lg*1ۺt%ҮF~ӧhx3xPxxH(Y0gC 8yiJz"ʈ+kHk+I[[j6LlL\ |< yXM(m-\ o"oLc/?~ˮ_'s$PEX#;GD-2.66/t/test_data/images/t3/3-00.jpeg0000644000076500001200000000411013076515043016333 0ustar rurbanadminJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality C    $.' ",#(7),01444'9=82<.342C  2!!222222222222222222222222222222222222222222222222222d" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?iWoi\\>ȢNdxpz=xMa1o'BְYb.HaSZФ&vrF:߲8}3lVs]mrYd*<88l pxM%4gv+FЀv-RWkB[?4 :x Jjf^|Dܟ!hs$:-x}XB&7R"(w!`/lD%HQ!l]])#qo,y98ÿ)iyRo+.H_*v.c<7JFAdY;85qtcLebSk"yc*ܞ25Ek uU_0?xz;w?ԴKF[}SO:u DrF@`2ϱukW 2(5 0<Ԑrr6B'smw"O"K%m!#0sw zqpχ8|Pz8:( 㺷1y <ҋ9@6up$y XoỴ`T/, M2I$sUI;J2n[`+(((X_iN\ےE<WdJӵk[qBVŖHmU$ ~P+ƾ ѦѴQi~#JLXW,gn ~1!  K|S.-5O$JsXu#V>cu1++rLu|t?>Y4m˶hx+Wfqmvggu4]ފ S϶M(IENDB`GD-2.66/t/test_data/images/t4/0000755000076500001200000000000013077123433015111 5ustar rurbanadminGD-2.66/t/test_data/images/t4/4-00.gd0000644000076500001200000012110113076515043016002 0ustar rurbanadminGD-2.66/t/test_data/images/t4/4-00.gd20000644000076500001200000000326113076515043016072 0ustar rurbanadmingd29Q[VxQ0 Q\gF|&Z ǃ1c>y=M{2` ⻧v Bw_ ^_6OLwY?J ~ /~O;f$i 6@/M_?j 7 [߬6(~Ï#*J?ҏ#*s~he}aGH'hxֱ CAg7cnz ><8<.q;?@6sO3^^^^^^^> ׇb~KW/K^n ?xOyy?UY!/l?RJ)tdxֱ @NMORZ g-8r-` -` -` -@\@Z@XXQa'Zkڏ]&)GD-2.66/t/test_data/images/t4/4-00.gif0000644000076500001200000000161213076515043016161 0ustar rurbanadminGIF87a,0I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.ύz}R"7|ޑ;:p{U-zN,Q+)KJ(FmE&A%<#9q>!ƺ74u2/,*y+A  0ȰBB$JbA%Te#-?bhOMFA2 ˖'IŒr&6̹R&O)(S4TP"E:I ӦJBE"u*ѠVT:d+W EK~e Ilضnv.vu͋Y+x  *܅9č Hv, ɘ%3|%g͹8SL)ĉ^mBXn5ٸiӱ$oox+M8G+7^9Йq$u_;;>5lӓb 5>}_~7'Q7Àx2$蠂Hރx'T!>' w(Ha~c`,I6cȣ;B F@I>dĔ2HNi70֓6W\Y-Y$ ciLzS)ÛtB%' tԝ.R|C jf 6'4*iNlTi`L0j¨d* Ҫ"*I "歸r+k,DZZZ*lFKгDkm?n`dke@~:nFrczKޫ,l' 7 ;GD-2.66/t/test_data/images/t4/4-00.jpeg0000644000076500001200000000747313076515043016354 0ustar rurbanadminJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?((((((((((((((((٧oDMXw0@}k֡e}oc7R*\EWhQEhk:gEvwvݸIv'g3JϯX,XEeigJ) a"=UGP: z((((((((((*{kfu4[[4胩UUE tBWM;­^]નT`+E(Y#wi2F>nYT7fH}k­~{>믮ݑZa|Uiw "{{ $dCYu|+?(xz]wg]Ҿ =#QNjq ?a^_GҚgVk57nxǓcݱQEQEQEQEQEQEQEQEQEQEioE _ EzαJ1D{8v-hK/S?U(/eſ ?%~Gjnf?aIrzOm6kw4a,-渔19*PŅ3du,RLdy,eA=!Xi6RNrݚ%ch-6kF&%W'%Hhu"q?C}PQk"ē $r$yUc9*(((((((((((((+f_kWWC²訨(Osyۏ/ŷ9VslOM/hڣ4~EőE bx1*ǧp(eg-Z,HP`˹ :w>hknͮy" s$gתKᧀlƺ%ZH9}ۂ WYxmZXk;!E$Am"Q<_ޟgWoKVd}SG+,m4D<"p'N|#CN?9 :' "⫖NrܥdoXGTstOET7N|#CN?9 :' "}۞n巸&T)$r(eu#x 1 >m߇ɽl1ޱ\Ӣ/*N|#CNa;3> )iu 0HRv69 W9_i/[oqMh%BG%,` `;W]gͻM&OkwonǒTeraZIJ*ˢi-Ս2Vk+7\e'pl3T+((((}?6E$5;w*XY1PI=&ۯ> ^пI䯯n$Ӽ;~gG>WpF:#WWO4 (((W,H>zRU4JYrSo*QEŠ(((((((((` F_Oϟ4ljn(ȒXXUIJ Huw҈+7?|H4ˇ X)`=>$(459r~w9Kc|>&I^L4"MNl_϶Xa@QD0o k*([_QEQEQEQEQEQEQEQElXĚevv m-c`4\N OV?; z f⫟:NaC^?; z f⫟$y%I$Y$I'tQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@GD-2.66/t/test_data/images/t4/4-00.png0000644000076500001200000000117513076515043016204 0ustar rurbanadminPNG  IHDRV PLTE͠?[;)IDATxIn0 ᤹@}'( tWi}~OwVcsç]Zu۸ /׷޾lcCG*^Fճt<WM/~U$&q*?Hh3/`I@ ~%*ȗ_!g8}1Pa9yvo/oy|3םSbygHxnԾRV />· ַb]|Wwm|q~q.>') /|GBb|O|~O(}~OÏi# ? ̇HX}T?Nf#x[r0 PK3vt;Hm!1FGdLp>nϗU ~~3v~+>-ߥ8s;(m/YmI>F]X;w?eu` uUc_~H]H1>^&433;QRz=ݟksHw,Wk_ p"~A8'|5 hv^2\mf,__n0}szfoU bb\oYoX/A Y(U0Q8{\o[ojP ` >XンO`#侭O'm}jA W!"Gx 0s |΀Evjۼz6{FLx 0ns6Q6;d |<:)\ē>0S`>J@>0OLCi?03 yOd| R~~6 0 ~* ????? p`Y/_@S/ j:_ X^a )9iU36w{ {{wMD9xY0QlόH$6r|WrgqܤZ$W.~=駽ߟZ^t#rk6|)w_H`'\iy?CΏ.W`|G*p }Ǿ&WpK,}g" p L}>[_4O.}8ؗ pξb d0>>>`TPƇ >P'>8O| 0SL:>38 P_P'_P_P_?q5xQ C_z8v06Ť6vq!l;n`#@o0'csɾ-}D<{\d yYҒ kxͱ 0,MQ׶~s~>j//-x 1 ka+$9j}Xgui>}c|է tȀH<>wB},֚lxc`` 0#JAP A qjwo`*!%GD-2.66/t/test_data/images/t5/5-00.gif0000644000076500001200000000615413076515043016171 0ustar rurbanadminGIF89a,,!,,,0I8ͻ`(dihlp,tmx|pH$q)L:PsڌZX u[z^GzȮ4mK{}we6 3-d5 1 )D7/"ǺȫǫŔڠ4ӻC츚{B6zXJm@/ !'rNTFVD%,&AD\jO#O.;3cGz7*魢F!\h9)Yժo8iOWm_~sI-1gqQv.nNtEk 8>D10ƍ?Ld-{e9`ΝC}ZtMoF}c0 xNص*ctC1D hm\ؒʙܜCuف>pyzڱc~GDw|^xDGB5~g߄> ^X߆iw!w *`{`3uh!"@e&Xr ע0d/r}NhcLGe#GF')ݓ_MF#(%UNCUdGIfmdߠIߏ7P-_/CggrH"um⥞m*lZuʨ]iliz`ʒ6֩ i+hKk2 rmZY`V"be^Fn(E- /P;缪|-[*V+/+Kq gk`D|'r3mJ:ۯS{,׿7]?;T<*X\{S;OO}wV~7?o_>ֻ|?zQj?ˁ|&@ ˠ=yp3D6vh9a|GC-/~b. Qy| X|0=lah+bE`$K2 a!tmэ*9HG1wxԂG5nym 2BT =ҐD" %A#7I3R5hcXJkE\%+K+ `y咓^$( Y0YhL`z}4b&GVF e)Il~2Ԥ oBa7iNtJ3K$9Lw4%ӖJmnl=99Q%f F&td$9iiҙ/hQ1'Qi˖u,&HخiU*cXwBֳ Zhcfs=jD+=e$*V]nh2EgbF}-l]6=:{3|mfyWҺ].^zGCj_h_b|΋W[6#A\pKC8rT`{pt dktK˻']+Iڔ%sa,ּu 6#ɶnw6'?y~޹ pZoypJ-8=k\ϋ +vKnr} Y([~mb)|箎~\nD/:+P+ӟS0TW uO=Fs/':Y=f`.;u#Z{=tkz߻*/ނ`xG<ToCݒ\/5^\|3v}Is|ؓj]~}6;z=}/^yӽJO~YOkW{_+޾1nbzY|W|+P}܇Hr|̶~}|?7w*m/lȀ$3~8z)жg@XsBx,\2xFyc#S=cG(*ȅ_q$ׄN%8헆OgnxpֆuvI,fZxdhqh&FVH`2syqvtLj\'3RSa>~([x'({(,x({؅v*h}h苷sɨ(؂t؊،x즍cm)a(YȍȎ(H&(#Y"눍aw9h:8|8 ,F@^xeɏ6pKI,ْI[H`hy}?u.w=vHJILPR)lN9VyX#\ٕ^`b9dYfyhjlI] ;GD-2.66/t/test_data/images/t5/5-00.jpeg0000644000076500001200000002462413076515043016353 0ustar rurbanadminJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222,," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( (=>3kZťV5˰y>7(hih}ެy~)\|=3;:3%4niBWirr1Kp>xmm常8` $Q@$i6!̻'v# "WQ_+I,Fs, 2s]3ZEǟ-֤_LP@!rx!K<7ms"kJlXIUÒ[c^_Mqm+O@ Uo9 Ak ;(((zvu}2Em Xg=iAbU١e |!@sҺ-BM].ESM]N\2#h۹YHꧡ4_[ tȷEToS) H9vVGd`v:M[;\$-QE ( *~HeF˷r;#OBiyjPXo6hdH(P~r9)8[Ur^;hCs*qV)}I\[Q@(((xmm常8` $Q@$ԕcG;*Pi!f2U 5><};sa~qd3r~nu[aO -+y^{=`0zE"ϖRp/ TP=i=[} ;hV5-2B39,J< = O5=F}>qtJ Ļ@8޸qםqӒvM;"*mnpqӞ=UG3;YQ2K*y#`\`tOT,tM2RԮR7+Q'$ɯuU 6qX1LL [rFUELa*~H?|CŦA +J?2%rg.򵾕I8BcI#=qkt ;2^#ry}>Ǒod.ʣ${j0{>Dyfֿw=]-}9UrWf㐪':y-~ѥe` ;“Fld~尖:QIY5~]#8˥r|N.ϻo;8,.໵;&A"6  88 ¬W>6V;&դq0E02H _K|7nS:sFwrp⧐ ५Z*PV-5ўbi(f_" jI,S*" kT'FI9$M؄$t㩞xyHK$Q@$2QKnmɠ:6*eGs5s.tRQӽյ9Gky=KC,ZhsYyCę `כA3̲ʌQԨ* .O c5PO{im$q]C}Œ@e^:/ՔwIJ󧭺w北7~mA%fI%hʳ<23I]v9t}5ŴrګZ?/!w'zJ)*{yw沷5ۦ2KTm!fTbL!TO@ m5rK @E#H kD7|2?sO<1)y$($wZ\d m}|9.n'YCy kփ͂Kv̒Jѕg *xѸ2v4ss*K 9#`FApAJ^OS||^[gh%ǰӻtqqZ4T7^Oڮϕa͐/#tEV881zE''7Ԟi@Je@B$;*G*;$U`J6`2z{ӳ$)QEQEW'j۪?o83cWR袊 B^}ܞ]M4ϴ8V+?mKS>guIļs9'g#( ]89ݎS=K. Y=<1lgF@"4rp>w*Қs:A{s6_}QE}X#IxeJ+Yr3b:ppk+ERY;fPrOקb%BwVkj|5]oq==}>;Idphzm'nqjFPTڱ 2_Sӑ_Yv/2GD\_0cl +B|#cxwXtۙ-|3!B8 A ;~,u4ܤȧ *p3ШTVks4? }L1<KXԳl9 p2N0$ $umBie}6yl#>v@H B)WyEmGnO˲qy֟_۾m/7WgXwZӤ.-vaɥL(Xar\)NRP_OO.' 8{I]>iu8]>8#hY݄e3j"|?mIZ"Kgs xVG!Vg)P ?sޗm=卵֭IWh IS9Qj1ի_Wep2GI>na|Gvݿ6/~66+Qլ pE0ig;)vnHC,W5,KTVGQsWOV]VH Qj (,E-!-Lrjh5e7֍auLl +x:|[_n]..0<,3C,60$sѺ VXQko:LʆRnSEYVUySGpǚz춖qMCxlĬ%;.M;6I>P1Wmt!W#Gg*nx~@g*;eQZ(]|]pzƴj8l^`V6ddJ$9^km^Recs|[BH휂NT;[K~_ :((((+?5}_nKfQEy'5DŽ5Me۳E+2H^p\ר_iPɫfkZg,$sI=y]V7m3V|IQEQEQEQEQEQEQEQEQEQEN Tz(j3h;uFk@JD,-MO{~%kQn5!91099ʪx8$DP=+ö~!Jĥoc$1Щ]d__QEp`QEQEq~$>dQC.z'9G?ZEMY`rOW;?#ֿDw.!R{I[_.(_;lz1OCvq3ϵ}u-VSvgx<6H4?8x{H׬W͟f4^*tX!pA7 sbVNIGxQEQEQEQEQEQEQEQEQEQEW'j۪?o83cWR< ׂWD2+;$+><0'ՒYQg"V` ;U`OjH|(s6NUP;`WU\τWM\t?NᨥSkQErQEQE ݺKc)\k-WNv2?JAl-y P$^MO3FGYu' Oޣ(V6gO:y$Rȉ2Nvzʧ}w_|oz ,q!yP3PYuQr;}_QEQEQEQEQEQEQEQEQEQEW'j۪?o83cWRξ8[|+f=ZKls"E OMsΧWgWM\A-D{ +wiSŠ(S ( ( M; 0<noTj )..֔gQH̰ZTiN+O(ѓsɫg&˕FkQ*<2kŪzRz?#ѴMσ6}W aCǣ*|s}_ |__hQEQEQEQEQEQEQEQEQEQEW'j۪?o83cWR#vW H˛ 76 2xֵ1;jj|C᩼aSn|dzҹoi_AVɊ m=P^y2eaA"yMuGp# :xŢ+ࢊ(((m62ROLZ*o Ҏcmzd?ZLٶXf}k86[e%`~Vz==cn$~?ɑD*1ב^⾗OVdڕ.6e?LWWyEPEPEPEPEPEPEPEPEPEP_n _uJ[0>+5>q4 G[ۋyd&d$1@\~zzdk#`=C~|4,FymɈhuL3p?)<|#57oy}xkJkTGE䟩Q@Q@Q@u!rpv?+kipgbpI7LCqnO\Uƙ_ZʓBAASzz|ϸt"c%~ hxKI @ZZG@4F kb::΍c[w Fp}M\@(((((((mwGMFM9[glnHʪseEPEP_n _uJ[0>+5 {㇁'mzgNեg!U>pr>bY#/?P oG{_kO \e 08 >I\M\?CmJ?֭`z {'Z*}G9ARtFJ͋:ʟlVg=]5BW^yr(3邊(QK3U$)ku;u뤒Z4eV\,ʖQwMJ\㷶VDBN2I8]įx#VK5gGmS 럔91ø.KkGAvG’,Bt7u"%vkrТ2iPEpePs؞GZ}`!?'W*]#Լ.\2U`| uf'Ky2;\>x,V2˲U<H>h؎=sQ@Q@Q@Q@Q@Q@Q@ssj/iioՈ, yb01228$m=%yޱm[xN_t5"m`i.]Gt%6K((+?5}_nKfQEyEPG|5DIՠ-Yxxtt=g ^5a/Ҷy.Wf"d3ʜ98ZQW :nRGwwa~3+ A %z]%\4X|YW3NMq-9]C,>.Iv)1=a! pqk)OXSEb#'Tԭl3c!,ïJ>gV=nXV1Þ6H﮳/$z;緦0z牎 GPgݿuRtgidpB~gǁ2I8dugZ\[k!dh$9'$;sV ~6&m^LF9f㌓qZ妬bkbj{JQEfb|wfGŻ-a-HU,&01P@B_b_[zueI4/8<:vGj Yvxrs.O#;E+euJmc?4lGU\tѧ.hfՙQEX((((((hwڇ|?ir \EL߽E_8mv:_;]_]7i%"63J m%s (((N U|~pgƯ-[EQ@Q@Q@Q@Q@Q@KVH˘MX|#빀)z>'=k]O#UeyO GdwMW'8?Y%դe&VX)PyuaI>Тxn⸷9$l]H #ԕ@QEQEQEQEQEQEWK@bví\BLK*GV6H7&ĹqX&oũ]$ 'vXp{e-p0EPEP_n _uJ[0>+5 ( ( ( ( ( ( ٵ3ň6ӔH3󈻁U_W_k.Sг<Ԙ$t4.Y5׾X#O;X2qNA%|:ET-Gb,Y`ғ{3 ( ( ( ( ( ( xoL|s`M|֘,(DYI3v 1ۅzpqw.Yfy=]X#*DnضeQEQEW'j۪?o83cWR袊 B(((((((/#iQ%:4¼d2u ?:2 ặXTeu# 8 s_4~Z?|Yj$w֦&0$M7$^s__|2қt~}}eEe c 1dIz4yEU(((((+GirxH\Omr-q*EpA #p7PPķ/꺦. GKx ۴(D EhR_vZ;( ( _u_`W'j۪RفQ^aQEQEQEQEQEQEQEt~4J>|LݞFp9z:|TiS^X2U G?= uᥣGQEtQEQEQEQEQE^ZꉦZKi<~Z?3,N>TeM)monQXw%cʂYy]DHKsF#1 f;nQEQEW'j۪?o83cWR袊 B(((((((i}nVL3ib– ƌ t-^e?d-:\r!3ȠUOO4.YKc{E5FD(P' P#|5χ$i 2 *RI =rs#=;^QEQEQEQEQEW/oag}& O]Iߕa}a$E86TBnA-`mW<;wy{1oQEQEW'j۪?o83cWR袊 B(((((((Y[Z}ͅ~eM ɸ V(<+|*ZI{$,M-av|@h-x-]URX22v~"{) (#'?_ve>tz>v~"DG.\'?_vh;[=?WPDnV#ݕSђ8/6kmHчW(Vz`b,zx^iyo%0 Ty/}nmn4^c%P:v|ޡX*:utl2>ˢ+bB((((ƞ14Z%̒wXDIӿV~hߕX9n38=r |YxNԓJm[xflo/H@S)GqUl,8- ;!1.I' 8$ƬPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPGD-2.66/t/test_data/images/t5/5-00.png0000644000076500001200000000356113076515043016207 0ustar rurbanadminPNG  IHDR,,SFPLTEogtRNSv8 IDATxn0`{$U~Wـ 3X%ishJ ߣ BbƂ%IUB=X wR=_4mA3=şV+=O*f1%u,ugvyY2 ׆5w|_:5ܞ܉PqP @b^sE HbEA4Pͬ?ܿ\(M5zJsOa'FKWM7z*ɦR%5z]k|^Jd^r)2,c 7Vo 6u]O?Mi'bϓsXVd+7=&X OV'`*֚y\CﻅOOrkc2Lrb:@Xb-hKsm{#6F9Ybm%DQ#?xtX6y9ВةBp\ZQg9Pɼb 2T2XJ+fC5h| +1ׇ|'cO{E6nVb+V">cCPG!~'h?0aۧ>#M%Z$H}1[> `Ƭ~@csĜ4 )Qg,>[_Y0 V~U/*%[ .}o[ X7ྦྷ/`}uk/2~9{?s?Ogo*߿J]/oHҀ;VIxInC1 @?t7]XzhX?g~~~}7뻏__S'kR$槍[RTǔǍkx؇OƇOYCV5I&Zc{d[H;|6nˏ0ggX𬏦,ѐ'}w,oiWx/>_]|n3Oy@/o_^ZK~b;g[k׻?F>w3ş wxu>0^3'Cm|]77< 9J|"I "4 B /?1x1 Om x2:x 1C;?},pZ"<?Y^xn0 РahHdRB.z5:t լ^z'9g|"u:+㾯.oo?!AZcwi5yTO>ч7U[O?W|*y9I:x?9|}5b*]G><_ós˼S%>>;>>mSo-?1c7{k}N>[U3zW<ЃKU3ztp|SW=7emZ3~OT!!?GnPGH>Ț~%هxQ}I}V}.I>7 G4UmSmDk>^m}M >ܧ_>d`}d;};t Ib7بu~~NaNGzꩧ?xv0CQ}%Kɓ,g<B}oY }q^v\7_ 0_(0r T`}s*D@ R>Z󱂤D}  đѷ>۽O;?&|dӗKW.jX2ӿ'E^3O |2:`<.S0~$|CupCO-Cnp 6~*b+:۷\j>Ӫ>PP/.ŀ~?O=,K϶o9.oݾlnma[_>ߚMN 9ox1 Om x2:x1 Om x2:x1 Om x2:x1 Om x2:xàS_U|4GD-2.66/t/test_data/images/t6/6-00.gif0000644000076500001200000000473513076515043016176 0ustar rurbanadminGIF87a,ڋ޼H扦ʶ L ĢL*̦ JԪjܮ N (8HXhx)9IYiy *:JZjz +;K[k{ ,N^n~/?O_o0 <0… :|1ĉ+Z1;z2ȑ$K<2ʕ,[| 3̙4kڼ3Ν<{ 4СD=4ҥL:} 5ԩTZ5֭\z 65Kٵi%=[)53 w[bn_ю;8La! 'ncǏD!re˗'S<0˘9t- N~0_ܺݶW,Aqo,4g^t͝ӆt*c]vݽK};+O~+/[xqEhW}`!\lAp-`>aN%6qg.aZbчH7ژ@-'3G"yC2$Qzi@2Rch%i" &|@&hk&9gZN&R#zV&wX`깡y@ yxZ ?b藁)TiY (f~z jRjP)ZiH먶SjdK'S ƊyJ5-%>[-e}J-v5vnU:. ʮmUKaҦɯo< +o;yS[. o5/ +KZ 8*d u.,q,r-3Ϭv9o1LE\tӸ hAܬVI۴WMWQ͵邍,rP]vGNM*wdMj 8w/4܁ m6V⹊x|E.o>8әw1 s%pN&I8벇r${kk{сs Ὗd5',} <_͠{4t>}~wo7O'@9n(g*p[aWJd56mWRJf 3} A|pC q H!qz 'PR۪8`q.R!3фj$ ۈF"c}gG(0<c?Z&! y!T\$"H$Y$% K:В|d;)FEz%iPN-2t"+[W&rD!kE3rr_14"1%c<])gBS{fޮh$$79oN&dK9])PɤelFFP9% l CiЇI%[^Y;m 6w?}ԗ+7ICnh yOLiOgҒxyNKB>:/aFHդ7m+bT;dA.5QCG2hTJQvԊGU*Ql)\&X8W]md`͟uYE [o|=)CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((+kúb^4bFoOp=>**qrgV S^4)Vt{v!m#?CV*U#R<;W]ЫQEQWn4[E꾄.QM&5BHPj:-JTQEQQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEe_۴*wyT$Hd)*280Ev B4sJѷc^zƵU{\ 5asMWӧs+><+Ks#3W]äZA7>uJ>)c'>]i7.w$c2 ^mukCn 1Vy}M;x $:sfŠ(AR3k=x~=Aq~t+mrv|uOWVc x;~9_b6t*1Ī{;^qoռJ2>Zi, ppr nx=|e]b)v{Ky z O=Bi\SAW~e|Q&F Ĭ$ +SŐwBLߥr]#sev٧9|+kkF+~Wu[ m"A1z~mNZV| a==MiVg?sЅi'YJ@@=F :X}ϓYuX㨢FycooO3}zt5w)y$'zEo]=v)Rvv6qʞ .+cu=8y}^Y[yż7QdCهOq}跸99G\ooK^&~gXw8mWFNczQh_c !ma]JV +<>֊6 (?^(bX:sL`][_WQTt :9X|?ǃ%8Э VJt_8t6 ɧZ)VXPF8bnp{ N8_V~v*u$R#8==TӺ7#8KgSM[ \z@*Q)964B8ӂJ+Ӭ5y]Q_$nϯӽtQ1tU:1.JՒ)G%><=kq ߿Sk [1x1zՊxp0>D/=ԫ^\Ϯ/躼*=^^qCwXm#5TM%4^G9,j:hRPQ?5q_J^((((((((((((((((( EbKm _ ( s?Ns\dr<2p]G&E\:_<x\L;z6OTEѮXĀOnF1%Ƌ[@hqߎwW-֞!j`}Kb>g]EW}PE$I %PbdQE ( ( ( oç6?Ө)YHPTzUj2NJөVҗ,];Kn/(0da~i|E-'%Z]pe.y3(]r;1 .v/e5!)˖(bidzd8{"S4\LLsƉfg/#5{|? :~_fy**T5y3 FŢ(/g?.# e؏ȚxKk>KY8^c>VK1SN?W=:柅M7{]{Wic>VK2Ssj<+5Ru\kvڎT?'9֝W[ 4`i#U87x+#0qƟ.&JRQPuQ@Q@Q@Q@Q@Q@Q@T7vy1F\m9曲&B[XCh8GX:rNg1.r/_ֺ}>noo\ol7gi?1:ur2ɔ_v;Q]԰4ᬵ>WBV$M!y]VciQ]Ͷۻ (Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@oi~#kHR#$H0^l J5,׃WT%gն܎'62V_Oִݶ{f1ê+^ϫ񄖘_?EqSI4 0,o|Uv=Xqf_%w̽W6vW3 w8_ƭl):pXO Y}e6i#ni}m|҉7X4VHU6}V(EQ@Q@Q@Q@Q@Q@Q@j'!x \3;f,rI9$ץrhE :3},lir%p\]GQ욿_$yˤi(Vs.T 1nTFB)LgEu[³./w >?2v?ÙrszjkiԮ:SOTxdŠ(HQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEKoo5Ԣ(#iQzMʌe6vȨo ]J3q*@>f~m>1)᎟r҆~"Q_-u-i뎃zkY u:8;Pn>=UTPUF Z⩏/C|'g]}_ĩe.  X?Nn+RrwljTт8DQE#@((((((f!f1$d!m \RmQ\&ԡ𣎪֙ U[k5O|SfvW U[hy[-4X?֬Š*V#x)#~MQ'Yww*e 0AW+[K[[bs$k'9϶sӶ= 5NX5Ok:0Yҗ4>cTQEw(QEQEQEQEQEQEQEQEQEQEQEQEQEQEQWt{]J)T=;MhSJʛJ慄ao%RS?:mᵈEk:ST !Q ?_ ¼ZX> ZH'ߙ_﹧Ec]:-Isbc* +2Uϛu!vS0šb8OJI_I$p^WTA՘ lS:TA(i]ƣ0XԬy#_>Ycn@QԞ}Og^)ivv9'0nOizOEW1Q@Q@Q@Q@Q@Q@Q@/t[qҹGwlLÿoƊޖ&-dLrnm.?3S-?xrNJӈ'E9RϯzqPϱgb ɮh2WO̥EWIQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ohkKRr?n \4E7цv$N2zӢ3O>$dŧH};xVP$h0TQ^cw՟s$VV-7uF^q{V%/*푐\cE\1RkFsRPVTiؖ(:((((( nkhc dWh9~sZk_ uFx@롮7]ўVf$OOۆUף>g;x3 6Kv]uvױ﷙d::ŤX) [~$ M5u2-`r`T9_u_2VPEc}>F!؆3ӏ;{{ 'igGj*Jq>*^W0O ,¹$}>9\+#e*pA ץfGۖU)ÿ'Wfjm熩NZ[~(X(((((((((((((((((+д/'m~q>ўѐF,yOW^>qx_O]*+mb2"ƃW=⟽~kA*Bu_f\iY{s@c\;ص^nz{fg/#4C ,0y(R4yⱲt{zY|OzjjKFyT"<é=k,R+t9ϩ:EgVwl- oE(fTRUFI' Ȱ?uy!b"$9sϰ?LNRM_JNoޛ_Cb(:B()$k"#:|Ryluǭm-QE ̸#ՖvD O֝`c[βt}q0i- }XokINQ53 d?+_*9d4C4wиxd0+Tϣ*C48M_K}2.ɓv>uz-7={YI=l`0g [N ^w//ֵ:9$@;#ShSiKhEE'"7R"YV~Ɵ_0+C(((((((((((((((((z(UuU"Tnt\NLƤyTWK\Mu)yG=ڢI%dxܤWQ8,fOXsV{ylgw?zq1$H0Tz\8ܱ[˕j5o_Ek`kQ>tʤb}/K I֬^#I&+^Jg'r*NO+fgbřI'$|1oifR2 ` uׄhWSrM\9UmvVZ~TsʰA$ XԱy)_C)IE9={ #Ÿ9t549Ko,8;^]*]x%?My't܂Ha*:32B6I\ϋx?/vqk,m鷫cÁه_E[?7g6؎ooOʻ M/eQ.?H܊;y ep}RF8ãaEzUq~$>dQC.zN_Rpx_ JZ??[L4"<poU]:Ԭn>=س1fcI&4\LLsƣ_AQHE-aAD'μyH #8HL_ OZ֪e MɊ;pH36O^ߙoW s c_ԚS窟mOkqWJ)?w >f]z O=@f}سp$ @{9*;s_iW3sW3sŃ<~I"fQ:igZ_g1g½LUk 7G9qI\]5gn?x#[u,I E*H1^5)MKV? Xii~=?'HXѱRGL;~7(Y+e9kL/cWnޟsVu(¢ق18)Pnz\Ǵ=8>%E4hƒj&g[0jVI4Š(8(((((((((((((((((((*H%h'el 棢'GI'd1-&`:KirXtVTӧ+Nz%+QZ*7VT"UoWW []y^Gy[KnYK`d^tř3NI5X˃\tirÙ՞Sv7Ͼ^*ޣہϮ5S++w;F;~Go)فדh`&osNG&7,ڍA~wS>D| G%lh3=f%x|dD}L}<A ~@W8rܨ7';H[dwabGݍ#L'z&"#1{GKֻA=8~TGOakN>6uM>]c/œV XO$w+C䂢 -x[map{ R?ѩ { , ~8thrkW\j 5Ov罃Oz{Mى-.f݀w'=xh7B=W0t62b-QovW{h;o#qptN?PEdoA/}&{clzkI3Cm@]v;tKSWCnG7RKiZ՛G _zcT uw]WnrwtՎf_\i^f=W9ir~KNݨN5,ˢVk.A]'v.kIKP}$׫k4v*>_"&W,} w7|-B+-kL= dp]KVv{nj_즋I]OYvv?۰KulSV˛j;N/{*b? of%rʮV4Kھ٥% .I yCtʼnr$^/_o=mpy=O\פnV?2&۷kbWx]ˊ3',=/e߯ھU{3Xg?"ras=({m:ꃽlj{j{wK5nti?>|g6/".>n͛cnqX`W+.\`˖ ɦR;!B!B!B!B!B!B!B!vRdT3^IENDB`GD-2.66/t/test_data/images/t7/0000755000076500001200000000000013077123433015114 5ustar rurbanadminGD-2.66/t/test_data/images/t7/7-00.gd0000644000076500001200000030525513076515043016026 0ustar rurbanadmin/___???GGG///oooSSS??__SS//ccwwOO77__??//ww                                                                                                           !"#$%&&&%%#'"$(&''&%$###%%""%&#'($#(%"%%%%""&"(('"'"(%&(&$""($"$"&$#$(&'&&$''"#(#$&'%(&""""%#$##%(%"$'&"%(""#$%()%$&"&#'*(%%&(%&#''#%#$($'("%'$(#"#(''%"&("%%"($%#""""$&(&%'##&%#%(%"&%"(&"%("($&"%%(""$(%'((%%&(%&&($$($'(""%%'"&"$(#"'(&#(#'%"&(%##(&#($%#"'(("'##'"##&%"$%(&%'$%"$&&%"(&#&($'&##$($&$((&"'("(""$(%'(($'"'(%"%$%&&($$%"'(##(%""&"%%"$&""&&"#(#%(''($$&'#(&#$%"%(''((#'##'""%#&&""%(#$("$($#(&&((&$"%(''#%(('"&'$&"#("$$(&%%("'&&$$('&(%'""""'&"&(#$("&"&#&$$$%%(('$('"&"'&'#%"(""$#&%#("'%$#"%&""#%($(#$&"#("(&#('"$(%""(&$"$%#&#%(((&%$'"(""$($$#"%&'(('&%'""'""#''&$+#&(%'&((($"%('"&#$(&&(#'&&'"&&#"#'&%""(&'#''&&#&&$'"""'&''&%"$"'&($"("$($"&''''$&((#&%"'#"'####'%($"$"%&'%%#'""#%'"#$$$$#'&"'%%#(('#(%#%(($""&(&("""'(($'"%#'%'%''&""&(('&($%%#%%$&"$((%#''(("(&$%""''''"("&("(%'("$(#%$""(#"""'%('"&(&%%%%%&&(("#&"($""#"#(%'(&"#&$#%&&&$"'$$(##('$($"(&"#($""'$"&$"#&&"(##$"#($'"$%""$(('#(''%&""%#&$$""#%('""'""%(%"#&(%'##"%('"("$(&&(##(%'((%#%%"&&#"#"&%"'"$(#"(&'#'$%"'&"&&$'"""'&''((#&$$"$&"'('("$($'($'''$&((#$(''#"'####'"&%"$"##%%#'""#%'"&&"&"#(%#(('%$(&'#%(($"'('%&""#('$%$("'&%(""(("$&&'"$(&"&&%#"%&'"(%#%"%'"$"&'%#"(("'&%&$&((($(#$"'$%#'(###'%(&'"(&''%"$(&"""'(%'"&'&%,%(%"(($""((""$(&-%("'%'&$%%.%%%&#'((%%&(#%"$($'(""&&#$(#"$%"'%"&("&#($%#'"##&%%%#%%&%"(&'(("#(%($&$%""''''""&%(""$(%"&("$%"%&&($'("'((#"&"$"$&"#(#"&(&%%%%%&&((.($#(&#"($"$('"%%''##'"'(&""&%'(&'$##%##('"&&""'(("(&"#(%"$%(&%'$%'$%$#&($'&#"%%"(#'('$((&"#%"'"#(''(($'"'(%%'$("$%"'(#"&('%("%%"$&""(&"$&%(''($"($&&$%"%('"(('"(%"%#&&""(%""$$("$($&#%(''#%(('&("$&"$%"$'#'&&$$('"(("""'&"$%&#&#(('#$##%&$%%#"($&"""GD-2.66/t/test_data/images/t7/7-00.gd20000644000076500001200000001041013076515043016072 0ustar rurbanadmingd2Y7 W' ~ ` ;0/___???GGG///oooSSS??__SS//ccwwOO77__??//wwxX6Drqp8$9@$͋fVR겞asE/$"y)EQ 1f=-cށQIE"O[HővJ R4̲V?R+LϺ_`4"I^Њ0fq1 Q"UPIsSgq&}S!l2+nV|OscȅDI"M"(a! *qrk@ÒE^Y,2BAy[!~ \<~Ne?mQ=SZS.KKQ N#( uG5sPTFV%!iQUp*Z-L)2ba~9S)4PqC|"+Sߟel#НվWk}FQVGmJ6NafUle&ۺԼ+ꦒ|>hi ȳr%{#v7M`E!s¦uG`yw,Phs.+&G+()H) ޢk %5,Rf׊r?8uΌRwdsTsMqARd#E܉WHQUPSD5XZlmؑV[CŠ[3j+}xE?<4,/ ~MXfG<0Lt{c'`͡Xck~az q~=ԛQj:>ߔZ0EkP<[} u?ݟ?yӇd5x2392}翟]/D2~yXao`5nr;u!:Cgr.^~ zȧjΓVw?Ӏf q>_: ?y>&.gDq~iby@ާ5b>1 ,Xa91 ю,82mDp1 :|>ߞG(4 |6p; ˿\Ӏ/KA=ø 2'ɿ:#[z߿)ѾBv/[_z ix1 DHlORl94UP {=_[J){ʡԲ:7fm<1Vc׾?~! $9e]99vz(wh-L;wxJhx۹k^Wy|x1 Om @xc``Q0 FHx A$w‘! [ R!!_ʌGRX%{יۿ.bxZK D&؀w=>BG݋IF\N[k4[o`)_]#ħz{ټ`2"W}QwvzC5 J3BZM>illhɋE'Jf$?և(M|ΏsSCg8N>lj,y0d.f@8B~^l!)Yt|g©8gqfcd>h?rsqA$ ;a'(9%gEPv@BOEHӞρ_>AAC>&Hed2* ߜy!T-saJ *!{BbJE^6T&TFbP+UO"Gƒp|y&(Hܰhldw1Arvםl!ڸM(?N> Gd9 F.#ʢ*ͬC.SoWE'G>,dk[!6l SozNDt=쒫k[2t$Uog +;"V.ԛ3٨O%?5O0}r&Οڅa- 3ʺ)̝ $OVne/ U?ϐ_ύzr<ϐЊ HRfI4Ci[byn/BbJ̐8)[3$$ 9ʥx!qEzs!)V0͐ZBMW`7QK/i!lhQD-k/P%Put3z._7nh888888888888888888888 dxY[#! D&?v[L'3V.1FP( BP( BP( b-[k ѻos5xBaMzH能j=sasA2}y\)[kٻSnO"v}hSi&_l p&nH~: { bHfGẗ́E-Ÿ*6 h\>Лt ޖ~ DXCi}EѷY)͝/-eX@>喙\6QJsJZ՜-:A^ $)j'Oc[~yhSzޏrzP8tYm29|^s_\ӳp8w}b׶a-ؽ!U(_pOxc``Q0 F`GD-2.66/t/test_data/images/t7/7-00.gif0000644000076500001200000000664013076515043016175 0ustar rurbanadminGIF87a___???GGG///oooSSS??__SS//ccwwOO77__??//ww,@pH,Ȥrl:ШtJZجvzxL.zn|N~dG BB G BaC  E`CB GŠ OٙԱ w Ǩ Iv~xkzGqV(,Y4fNj BGd \;M20*=e W8Z0/F6Y TP9ɵkCx5AhrJC67l1'+’Dx.ђh̘r yBd,Bj3ŧ<o=pwZUU;FB,Rj";IA~}Ͽ(h& 6F(Vhfv ($h(,0(4h8<@)DiH&L6PF)TViXf\v`)difD`pPɕL0HDoamZ M *H\P'᨝C9n AIf 'tf F4B(xYJgk~Y+*Rj:V@`' 'zA Zl kti.Nֻhժ먚j`-E A ƹ\ Hɯ2iq⩮0Lrj ̣'/CB*P*,,(4~="뮜J ]_Zb1ʫp,Npmض` Gc*8i^t *OL!,yބ33Ѿ5Jiޢ.ΦNS.W-?yv8r: a,.?0oI^0AZloGTkfi(Ko# A L@`'߅D@ M@B& K@x$j#0 @PA#`aK B#p/< Chp&!D =!"JMP`ԐM,\^"F @d,c"`U\t ~g! R8 m$ JE8q"HdEC>?#G@'r5H14%1BБE+&HOJR'PA$Q`@1 ]! OpJjБ4" (Q3; %G#Jw:fW@Ai$B#Hg 4K m(Es&bgG!s2dH BLD6X{ _N";$`!dNq`BPBz~ DHMT4W_:{J$>;jhڔ~CQN$JЩ(Zb"<I.B2%O&"d>meLYP#$+xE>psCE f(XJDF%DHCԟn,$ !)T"h=kF;<" ْ:Q(VXZ=k۪z_DCB&=jёBV']JeڽB=I*Z׾Uh,bg7‘Ԭ [y"Dp" 5"R\{;`Nkێ&➒d1Ob(8 +G;xD-?#"5CkhO"y5/oP7OC]"xe]2WHoW  yt$DoJУK Y$&[Ǹ 8./9ʼn|ORt-z RԀ'X>ծ^ya%kϹîO:J9n&F$O54GP=jV&L@oaa9 @DG0 Y8 ;%}> (0䎖{ ֣=., =iJA\cm8`mnPD\ 89r,+\2gbk *nO] ,lkNrJ; c;@$ Hm~~2[nagh;!n;k] $`dRwWOMco큧W ó3cP փ3+Z <~[|V-s 5Rȏ}-'w!L=q߿יvySo)0H%y^6? 5_9F)QCP WzE@zUB7D`3Aۘw~kIu񮈧z+I|v'whYm&me?U| lN6o}_5sDIrDtX`o*Ep'~*HgbCXT$1XpTCn}_&X`RdW\eKSpWOI'@)HH F:OePє~\N.[Ie~7xSQ@ ؆,ugǂhhNI6^wƇYS@mTeqU*$^d(d]dmdex;5aLJh1Ha, ^BUx@s8U8H凯X.'E&\QF^BUbRTւU6eBPSDjktGm4&tUD\MuaC@zØ|Cwa|VHcMCx}uE@4D~>wHG5aFVtXH8Y#FI>xe|74dvHȌ v].EopUHG4|7gU䈀 ~VRqU`T!8xN5g@xJ%@nc%6,LBƷyQUHt^y}1Y\X؉B{.Y{JXCuIm9*9ireh{w'ia=\EGgHyZi\@*dH{G}☎FDL<8^KIS8zǘrȗNڦIU`F)>VUO988EAYdb4)9S i1u))Yy)&A;GD-2.66/t/test_data/images/t7/7-00.jpeg0000644000076500001200000002120613076515043016350 0ustar rurbanadminJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( +#"uwA|ąUV {Wj?uãHc,5bcsswtE +l. $} Eyt?gKc] d6rܙv 2 su=oN]ۓjf9乘/tW|gˍz(/h٨O2m&EU[0vƽYϥq&gA+khRg$$@Zgsp8z~{mcFߺ}OAuv E|8̂rN9^S0ڭŹ@6\>xJ mFH oZ놷) t_j77zEfyΩL[ʁ\"!Fx%ȟ_;VQEZzu)ϗ{xUn`M\Kh\95VsfO|vqq3\7a|AmصX]ou:Aa*1$a`9倌zNs؝Ib4Bm1@͖v=?S+'Q{_K'{[PxHy JV#;6cՀ}'e4Z/!?#>۸`"\ƿ<ޤp8{I woIΟ嶫4DqRB=:r^j\M0^'Y5I^{-]׫]]gRPKV˻[sT.uڲ<3i aeݥM!wǐ? ׮I$f!S)B6_aEVQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEV/:[Dފ&bcX{EmmI#`>׿Pޫ;+"H⸋~2efҭ-'޽{ W?E5:`#ye* Ҿ;:uk5~U{GڿǝU(>"[ijgiq=鍕}Xӭ^7/Ʈ X(7i$ zqr;/7U[#!T9<)þ)q=B5̛~Rx'OI5o[#JWVzQ^QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEVOoH|1"_)h+ud Vt*sS|;-um V<"".@Qu 95Gl!]Z ʸxTLu^:v׻>t/$jU!e(K{dǒ=wsjl,-요=$6oG}k+R/ڦ+;FUb QkwZCJIMÁPx<׻ZX(2I%.U}~C<xBu5{vޒ3JҪ:_*[F69^_2i W萮ۂbi-@rnj`|KWQsXu"3qx mW7ki6jEG;AnQ+xzr)I_$EۿӰo5{hK[PcI=؜{Vome"fGf9ְ7E$ý6(\bkе> cךxC ףӬMk*w=+zi+R7Q>} 7zG_.5uK!eru s^\??x w![~Q1 * r?N5s̡8(8htхQ^qaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP'<)WQ*`oqp=yOXlt-:ݭ @\t.q^QW03Ē AK/̧ ތoe}5Ȝ9Gi_% ,<5|1JFd|}e,XBh![9k v(s^kO2HEl0+KO xfbuibmoP$ڽz9Ԩ^&[k]#NYu % 2*@Iɯ 4ո.]Luڈ$I98MַǨV;y Lx8SWU*Qv97v^vpʛGҺ_G;7b/9AkW>K8Zb.;n.TWo|JYh>6ЗOeH.mtlIRnK(UpRK4yD#hԺ(#P(((((((((((((((((((((/g}:/6)^Mw6ݢKҼ]r#Llg J7:[Un|&pY UH6G\Vχ84>scKIq`#Ԋ1:4Ѹ#S;* {n0ʲ2b,EO^M;3P)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE:_|@|O5H1lK3lwrtT+PeMҸ2$z Pm{Dү0]Dcn9\a<5Uzi%ͭ׳iu%gUox: Ŕ+Hk̽늽~όme2[AS鸑W_zOtŲf|%>{:|Ys{ 0^+0 7z=;pkգVV8,KWdF^=8w>ObHyr^jܙz2%j]cse.)$n~ӉUiTV~1=χ+c]Zqi}*Ktc[kd1¢]!'3|':5)tqM2Cj((((((((((((((((((((((_Hv/q ۼ`A ꨭhWBIKMY/ٰ־R]\LPLu"Z? z8?gwInicǞ :tyMd+G# ryZC7=nןd%wϞ/>skoi:\"rS^:`gi .4i`OVYTxIgU?J4/];OS<({tO|%Ix = Z٢p3OxIJT4](P/u /Rxwm`ڽ88cku_g@g$ҿ |;785ڧ~5k&6Z ϕz{g|7}'šhmDHy/)fAc*ZN/ ,vwԤ,Ԃ3cj?x䌌 uwUbWMVsJ%bˠQEPQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWxM%D7Vw?  4I[ I汻yTCen>rH'wW[?$С]N2뷀7)48$`7<sx/ŷIhj$, (D^X$ zK ioH1_{}A`6d ]$IYaR[[O0_3i5-R 86dqz 79 終!>꫚Éux߾ymmc+<o|C>\\"U7D?0r +`j`(MtkTc%%tQEqQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEfM*M7TϵvV+9#KhNmi:ugyHoV?ZѢ=|_VW6|n-p)S!]+VyxʆAX6&2`JIxtl7ܠ& >I?;棫hZr@}u$2HJWq*<%)(](_kCI+ٜW4_x7waf -)~O'-v^ZzvBg|x䌷 }zՏ#?Q?\Io?10/bSWߓ^yx!Ӵ[XI @H,ezJU툏cվJMi1+GeAgUuUKOz|^n|=Ʈ兏&$oBG,}W;_iY!@ CZIʂ3򎼎k+MoMqoW=\ur%*^Nvwɭw=G@/h.5:=>^IVa K,HFr>7<$dU{yٵ*2REWAEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPHJH- ^'o(oe3^ѝwGpln@zz'l+]W&PRVgz>cm2>׸pr :0+~|8_^Z꺚Yc*SϽt^%A2}ms1_H\)y]Jo]̆E#<\?OGRTZPWG)un[I8.{~"9]:Kk)~VDǘܻtE*JIQmQ?JnTB~Z|4y=RS弾QH:qSxG᥶ɮ듍W_C+\8"b`;̨a)Z:TV5w:d#߳HΜ=+m`$qª 35W- (Š((((((((((((((((((((((;Ngi1:}[ey%w'8һ(*iՓm++IlQEb0(((GD-2.66/t/test_data/images/t7/7-00.png0000644000076500001200000000645213076515043016215 0ustar rurbanadminPNG  IHDRyvPLTE___???GGG///oooSSS??__SS//ccwwOO77__??//ww XIDATx ma1K&mӦd],xKAG\ xKٵULʆv>6 %Pݷ.ϝ7=< )H Pz[UWSLCnW1_vص `4~ekSvMmIc@֍.ꖅҜ2w3HAMo^\؟͏M;|1NF&(ȹ'ece.>6Ms=}V=XAKGb9_T^A~hذ]ađm]|%i>S_Ù|ɕg|;#ģO?+˥狯MSDG6jh^#isxd =Ϳq<լM~vg'y\_ϱtԐK>Hz3u^ieqtƁ 1 _?r<ٺ?ы^Dr%]|m~C"B: iFL7h{%i. ќi1X8lbCu և$Г:;G/臯6 |zփuh:þ;;ITp׹oH_AIzG4/4W?Wr4/7|9 ]H$[z|AH5Rb*}+~!LBo7 녰k,{S/pj 'U^G5x})yW/`CGN ~Nu"G ^' RkBG G O^(§ZF Z2='&% !" '!Դ!o.0S὆Dr1$b?JJ,£tYZL ʭ8S_0aW6Q U6qV"ؖ9!8r b&QǮ J4j4dE4 %"w3"ِoK\K1,^Bң [+grH$7hC'5y$+F mP>hKo,.XgEؕ(#oE""yL~tq0H~C)J *JVD HK086zU6bbRwrwrzTny œP{9юy$֣#5T Ä֫2k!-Bݽ f/L[}4DtӐ3wv!_JdؓZ"ڷ]_X ,%X Nǎ(OHk@.t1~sġö,qYc8%79LLq;Lȅb[jEPkCAX/ BМL$[~o5e*;H$n^xüqcVVVBB|# .픱cΕm㮊S/6K%{ndI8NrT2>DWi)Ɉ4eA 8W ^ҥ4c9m6^@2""s;o+R\XdDzowĂo.%ۿxTrcע8/?0b[s%X22-͕fq3ѩKq>\X1ЧXvâ>+7G:>E<ܲr>)l>קC)' qb8d>Ez!}"$ /k}xUInJ٫S\}P!t́΅EJ!B}Z KVaʏ؜]i c)s2C)[XDNK-CH>3 T zrj{zi "䎝ň,T0^bqXd0j OV|G. 3Ʉ/4en%':=<2\+ ېHy /~`ÙIgJs#eB^  g-_^dV0YT0  #QwH$7"Qkyz&><^];d X9QOmkM4`exqn_I>m4RT hFH_ЀAe&klkx8>Z9dnQ1Lں7Ww?66`E'4YQ(MF烬ܮVEX(t`R%ؚ(U*v0Wඪ)%UiF0W\ a|܃x+)ˆE̒LDH^b΄U#O7^5sqey쾱H1`iJ#&x.XY \WŸ'bNi^P|h}CKXBZpC\iQH|N9=Ҫ\S\$_'OJIq0&¾@Г0z.e)jAvTn ""] +O} 21C=Oc2.NuA H$ЮtӒ4JH~RY>tĜ)}WS=sN Sʒ/t> C*4ǧT DIF!Beߐ x K_ ǿ?)RAԍ,MC0 KY*ja;X]׍"+VFaOywfZFB0R,G#GæZɶ-VJ+" Vf{ K2ZZ=#ۨcڦ? H&HɋP*ɐ4SA?S8J>` E  Ft܊|5-D] D m"nN:וj~F~_4fV5:lIW0ZG V>xJY@4toM`K--bDѧQ>qB3 .:IQAR~i봐\E [dtU *Ix *.T3pi!e~ݢ>NE44K}.{L[K/#>{> ]-ػѰ[΄bpBoϛyegE0hc#銪sz.#k;zobߓ1q>; >&-q=}˨x +sٲzc9הY,ol-1@c%t ΫI0oCoWxGok'F?ѵ>ևіi8>~Aw(P|s {9ltܕ΄rn@LE^`:&d[;۳dnpnѓnu'b?%?]7t+ki^7Nޏti 'W짿!|,G<v~Oo+fԭ?W緕[{g+C8% /Ӱf9?| Boxx1!,(ṲHUn}Sr14k&C>YZ F5[h~؉}^=5-D׵w] M_6N}l$K羅ev{j7;sw$WjX7ހ+߿qSx1 Om @xc``Q0 FHx @&ED?!$ JhzNg12 #GוEeUWaz+ѪxYK0t΂{K' CO$Ij>9<:KVHtO3l?Ayo}cwtP}1!6v_^8^>?eڇTc1ϕPxݟcU~I`$><1exI*τ@ PJ:q/gz%[򷿏IJIzלذJeAgז${II_S?4Ps5^/ TlG6D5F?57&eANڛ‚WYڔFтy442(>n:| 9NvkKvJvk18]F0zFHHq)8:f!gkb^R/.?1)BWvj g%odbdP/ V9biЬ=.&Z>COŨO˲ή(k@܋.4.q:z\uu TB6Gk/l\_n,R=}"ًK8vH77,|,,!z$1ƀCxvH).wH85P}O;6Eh)JC&?wH] eurY-f%nwH,b_V=y!qݬ'O;~ fյ}od8OK&Π&o^f5`FSAuS4| 5|Z OjWK:㽍 qkxY[0`3ƀ_IkC+Q_Pe0 `0 `0 0gKwtrG c8IOt21znt.?W eכ(̾^*ϡCTjH4a>tsTƒb$q0cֹ/pG %\h&ܥ_m(3' 7i-=d^G\>=7=@6XԯB:G=8^4KױFZnCk0 eB+!\`Nˢws"ȓWُOJN՚j[eP|+"Hto~Ud`vɲ#T{JW%/kT_8}Ua̠u_"3z|vzSp|{WYBzj Em(%\bj7dAL4meڌ "L t񩖾hBb.m~P1}A)ޚoTo:GP9`oupH4b~w'|wϬe آ~2XB-k !e\qCl+6j^^3W ¸d:?"8I]vmx 9c쟼QvoPUrxc``Q0 F`GD-2.66/t/test_data/palettemap.png0000644000076500001200000000416613076515043016167 0ustar rurbanadminPNG  IHDR?1=IDATxOuGC-@J,DP$es:u2qVnYaԡJ3-3)Dc)(Hx^rlPD͒ 7k:imOdw-,}ޑs/mekKҾ(iƹe~piHx ``````````````->t`li{$izi,&iRi_ݿ@ڧrB5yig Ǥ}v}`JZia4i#^{H{FFFFFFFFFFFFFF|xtfViy{?iIzi?iǘҾ:1PgnUm{}LoϿ_(oh kkkkkkkkkkkkkkkEӥ [W[j_J?Z{ixϹ&7/G7I*^X+wʗ\```````````````-P:pt\ڟ~oNHS[^kt,/珘(GHvJ/H)񇚥=WX#X#X#X#X#X#X#X#X#X#X#X#X#X#X .,}[:.1ilܜOKIoI&I mIQ~riNUi=!Kڟ9Oگh-Zp8@aҾ}Ya"Qg7[}ɚv' ikai?SҾjF^0Q־Ҟ+Iʏ&"HW'GkGڷ}+lFw!nƭ'C1M>G ``````````````-wҁg%㊴ϳey~}T}j+T (J_eyד/I;=WX#X#X#X#X#X#X#X#X#X#X#X#X#X#X E$H/hG=DڏXiݏ^.7T}/G f79Y/S*/S Ñ}FFFFFFFFFFFFFF,.@:P$+Q>ҾU~h io~iFk?YߍC=}j<Ƴ޿H^\```````````````-$KWռ}ZAimri?Zڿ;VisYWJ@ DJѾ#"v~]ZiB)ҁo}}QҾ.s!Q?tz߫~SL{i঱ҾwwMXO{i!F{>+Z]?"x|Liv?yji)4$-9+-O J;JP}EM>eh\}TXiւ6L:Ei?iU!/5H.]}o'(iY%פJKMfI[k7J>umҞ+2I)>o~ˮRi.;oFIڟHG׽$ "}C~mפŀ%Ҟ+r9+{IENDB`GD-2.66/t/test_data/tile.gd0000644000076500001200000000273313076515043014574 0ustar rurbanadminܸ GD-2.66/t/test_data/tile.gd20000644000076500001200000000207213076515043014652 0ustar rurbanadmingd2!ܸ xc`&`vO FGD-2.66/t/test_data/tile.gif0000644000076500001200000000015413076515043014742 0ustar rurbanadminGIF89aܸ !,=˂I2zQ+yqcz C@׶z݃jAW!,B$;GD-2.66/t/test_data/tile.jpeg0000644000076500001200000000067113076515043015126 0ustar rurbanadminJFIFHHC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222"* "1S!56as( a!145AQqr ?ROBqQhxZKhv;DtIM=k1mtK[ zt~, [T?+2tNJ~rS%dy ՟*>B8x+lGGD-2.66/t/test_data/tile.png0000644000076500001200000000043013076515043014756 0ustar rurbanadminPNG  IHDRR? PLTEܸ [ѧ:bKGDHIDATxc``Z:CCC?bBFCtEXtSoftware@(#)ImageMagick 4.1.0 98/09/08 cristy@mystic.es.dupont.comeB*tEXtSignature7a52b1cac1657d1b4f8ef32b4198eabc{;\tEXtPage21x22+0+0IENDB`GD-2.66/t/transp.t0000644000076500001200000000341113077111044013033 0ustar rurbanadminuse strict; use warnings; # This is a feature: adding transparency changes the palette # https://rt.cpan.org/Ticket/Display.html?id=40525 use Test::More tests => 12; use_ok('GD'); my $gif = "t/test_data/tile.gif"; my $jpeg = "t/test_data/tile.jpeg"; my $frog = "t/test_data/frog.jpg"; my $im = GD::Image->newFromGif($gif); $im->transparent( -1 ); is($im->transparent, -1, 'image is not transparent'); my $closest = $im->colorClosest( 24, 53, 62 ); $im->transparent( $im->colorClosest( 24, 53, 62 ) ); is( $im->transparent, $closest, "transparency preserves RGB before $closest" ); is( $im->transparent, $im->colorClosest( 24, 53, 62 ), 'transparency preserves RGB after' ); $im = GD::Image->newFromJpeg($jpeg); $im->transparent( -1 ); is($im->transparent, -1, 'image is not transparent'); $closest = $im->colorClosest( 24, 53, 62 ); $im->transparent( $closest ); is( $im->transparent, $closest, 'transparency preserves RGB before' ); my ($t, $c) = ($im->transparent, $im->colorClosest( 24, 53, 62 )); if ($t == $c) { TODO: { local $TODO = 'colorClosest ignores alpha'; isnt( $t, $c, "Closest" ); } } else { isnt( $t, $c, "Closest" ); } is( $im->transparent, $im->colorClosestAlpha( 24, 53, 62, 255 ), "ClosestAlpha" ); $im = GD::Image->newFromJpeg($frog); $im->transparent( -1 ); is($im->transparent, -1, 'image is not transparent'); $closest = $im->colorClosest( 24, 53, 62 ); $im->transparent( $closest ); is( $im->transparent, $closest, 'transparency preserves RGB before' ); ($t, $c) = ($im->transparent, $im->colorClosest( 24, 53, 62 )); if ($t == $c) { TODO: { local $TODO = 'colorClosest ignores alpha'; isnt( $t, $c, "Closest" ); } } else { isnt( $t, $c, "Closest" ); } is( $im->transparent, $im->colorClosestAlpha( 24, 53, 62, 255 ), "ClosestAlpha" ); GD-2.66/t/z_kwalitee.t0000644000076500001200000000172313077061577013705 0ustar rurbanadmin# -*- perl -*- use strict; use warnings; use Test::More; use Config; plan skip_all => 'requires Test::More 0.88' if Test::More->VERSION < 0.88; plan skip_all => 'No RELEASE_TESTING' unless -d '.git' || $ENV{RELEASE_TESTING}; # Missing XS dependencies are usually not caught by EUMM # And they are usually only XS-loaded by the importer, not require. # But even the most basic deps are missing mostly. for (qw( Class::XSAccessor Text::CSV_XS List::MoreUtils Algorithm::Diff )) { eval "use $_;"; plan skip_all => "$_ required for Test::Kwalitee" if $@; } eval "require Test::Kwalitee;"; plan skip_all => "Test::Kwalitee required" if $@; if (!-e 'META.yml') { require File::Copy; File::Copy::cp('MYMETA.yml','META.yml'); File::Copy::cp('MYMETA.json','META.json'); } #plan skip_all => 'Test::Kwalitee fails with clang -faddress-sanitizer' # if $Config{ccflags} =~ /-faddress-sanitizer/; Test::Kwalitee->import( tests => [ qw( -has_test_pod_coverage ) ] ); GD-2.66/t/z_manifest.t0000644000076500001200000000102313076515043013666 0ustar rurbanadmin# -*- perl -*- use Test::More; if (!-d ".git" or $^O != /^(linux|.*bsd|darwin|solaris|sunos)$/) { plan skip_all => "requires a git checkout and a unix for git and diff"; } plan tests => 1; system("git ls-tree -r --name-only HEAD |" ." egrep -v '(.gitignore|.appveyor.yml|.travis.yml)' >MANIFEST.git"); if (-e "MANIFEST.git") { #diag "MANIFEST.git created with git ls-tree"; is(`diff -bu MANIFEST.git MANIFEST`, "", "MANIFEST.git compared to MANIFEST") and unlink "MANIFEST.git"; } else { ok(1, "skip no git"); } GD-2.66/t/z_pod-spell-mistakes.t0000644000076500001200000000117513076515043015605 0ustar rurbanadmin# -*- perl -*- use strict; use Test::More; plan skip_all => 'No RELEASE_TESTING' unless -d '.git' || $ENV{RELEASE_TESTING}; eval "use Pod::Spell::CommonMistakes;"; plan skip_all => "Pod::Spell::CommonMistakes required" if $@; my @docs = qw( lib/GD.pm lib/GD/Group.pm lib/GD/Image.pm lib/GD/Polygon.pm lib/GD/Polyline.pm lib/GD/Simple.pm ); plan tests => scalar @docs; for my $f (@docs) { my $r = Pod::Spell::CommonMistakes::check_pod($f); if ( keys %$r == 0 ) { ok(1, "$f"); } else { ok(0, "$f"); foreach my $k ( keys %$r ) { diag " Found: '$k' - Possible spelling: '$r->{$k}'?"; } } } GD-2.66/t/z_pod.t0000644000076500001200000000036113076515043012646 0ustar rurbanadmin# -*- perl -*- use strict; use Test::More; plan skip_all => 'No RELEASE_TESTING' unless -d '.git' || $ENV{RELEASE_TESTING}; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); GD-2.66/typemap0000644000076500001200000000010213075665176012512 0ustar rurbanadminTYPEMAP GD::Image T_PTROBJ GD::Font T_PTROBJ GD::Polygon T_PTROBJ