- extra concept index entries
- Imager::Draw - align_string()'s valign parameter was invalid in the
synopsis
+- start of external Imager API access:
+ - rename headers to avoid conflicts:
+ - image.h to imager.h
+ - imagei.h to imageri.h
+ - datatypes.h to imdatatypes.h
+ - config.h to imconfig.h (created by Makefile.PL)
+ - moved all public types defined in imager.h to imdatatypes.h
+ - supply the PM parameter to WriteMakefile(), to install headers
+ under Imager/include, and the Imager typemap in Imager/typemap.
+ We scan the MANIFEST for files to add to PM.
+ - add "i_" prefix on some functions useful as public at the C level.
+ - moved the typedefs that support the typemap from Imager.xs to
+ imperl.h
+ - set the global callbacks hook in the Imager.xs BOOT section
+ - API cleanup:
+ - define i_tags_set(), i_tags_setn() - we might not allow multiple
+ values for a tag in the future
+ - i_copy() now returns a new image instead of doing horrible inplace
+ things to an existing image
+ - provide actual functions for all of the macros we define in imager.h
+ so we can put them in the global callbacks structure
+ - define global functions structure (imexttypes.h)
+ and initialize it (imext.c)
+ - add API include header with macros to setup the define and
+ initialize the local callbacks pointer, and macros to call the API
+ functions.
+ - build Imager::APIRef from C sources, including updating the sources
+ to include documentation for each API function.
+ - convert dyntest and mandelbrot dynfilts into XS modules (too easy)
+ - simple Imager::CountColor example
+- support Inline::C :
+ - typemap changes to accept Imager or Imager::ImgRaw objects as
+ image parameters
+ - define Imager output type for trivial cases of returning an i_img as
+ a full Imager object
+ - Inline WITH hook to filter Imager XS types into types Inline::C can
+ accept, supply appropriate headers and initialization.
+ - test script t/t82inline.t
+- try to use XSLoader instead of DynaLoader (but fallback if necessary)
+- paste() can now paste a subset of the source image.
+- paste() now has better tests
+- paste() should now be faster for larger pastes
=================================================================
--- /dev/null
+package Imager::CountColor;
+use strict;
+use Imager;
+use vars qw($VERSION @ISA @EXPORT_OK);
+require Exporter;
+@EXPORT_OK = 'count_color';
+
+BEGIN {
+ $VERSION = "0.01";
+ @ISA = qw(Exporter);
+
+ eval {
+ require XSLoader;
+ XSLoader::load('Imager::CountColor', $VERSION);
+ 1;
+ } or do {
+ require DynaLoader;
+ push @ISA, 'DynaLoader';
+ bootstrap Imager::CountColor $VERSION;
+ };
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Imager::CountColor - demonstrates writing a simple function using Imager.
+
+=head1 SYNOPSIS
+
+ use Imager;
+ use Imager::CountColor;
+ my $im = Imager->new(...); # some Imager image
+ ...; # some sort of manipulation
+ print count_color($im, $color_object);
+
+=head1 DESCRIPTION
+
+This module is a simple demonstration of how to create an XS module
+that works with Imager objects.
+
+You may want to copy the source for this module as a start.
+
+=head1 SEE ALSO
+
+Imager, Imager::Filter::DynTest
+
+=head1 AUTHOR
+
+Tony Cook <tony@imager.perl.org>
+
+=cut
+
+
+
--- /dev/null
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "ppport.h"
+#ifdef __cplusplus
+}
+#endif
+
+#include "imext.h"
+#include "imperl.h"
+
+DEFINE_IMAGER_CALLBACKS;
+
+int
+count_color(i_img *im, i_color *color) {
+ int x, y, chan;
+ i_color c;
+ int count = 0;
+
+ for (x = 0; x < im->xsize; ++x) {
+ for (y = 0; y < im->ysize; ++y) {
+ i_gpix(im, x, y, &c);
+ int match = 1;
+ for (chan = 0; chan < im->channels; ++chan) {
+ if (c.channel[chan] != color->channel[chan]) {
+ match = 0;
+ break;
+ }
+ }
+ if (match) ++count;
+ }
+ }
+
+ return count;
+}
+
+MODULE = Imager::CountColor PACKAGE = Imager::CountColor
+
+PROTOTYPES: ENABLE
+
+int
+count_color(im, color)
+ Imager::ImgRaw im
+ Imager::Color color
+
+BOOT:
+ PERL_INITIALIZE_IMAGER_CALLBACKS;
+
--- /dev/null
+use ExtUtils::MakeMaker;
+require "../metafile.pl";
+
+my %opts =
+ (
+ NAME => 'Imager::CountColor',
+ VERSION_FROM => 'CountColor.pm',
+ OBJECT => 'CountColor.o',
+ INC => '-I..',
+ );
+if ($ExtUtils::MakeMaker::VERSION > 6.06) {
+ $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>';
+ $opts{ABSTRACT} = 'Color Count an Imager image';
+}
+
+WriteMakefile(%opts);
+
+
--- /dev/null
+#!perl -w
+use strict;
+use blib;
+use lib '../t';
+use Imager;
+use Test::More tests => 9;
+
+BEGIN { use_ok('Imager::CountColor' => 'count_color') }
+
+my $black = Imager::Color->new(0, 0, 0);
+my $blue = Imager::Color->new(0, 0, 255);
+my $red = Imager::Color->new(255, 0, 0);
+my $im = Imager->new(xsize=>50, ysize=>50);
+is(count_color($im, $black), 2500, "check black vs black image");
+is(count_color($im, $red), 0, "check red vs black image");
+$im->box(filled=>1, color=>$blue, xmin=>25);
+is(count_color($im, $black), 1250, "check black vs black/blue image");
+is(count_color($im, $red), 0, "check red vs black/blue image");
+is(count_color($im, $blue), 1250, "check blue vs black/blue image");
+$im->box(filled=>1, color=>$red, ymin=>25);
+is(count_color($im, $black), 625, "check black vs black/blue/red image");
+is(count_color($im, $blue), 625, "check black vs black/blue/red image");
+is(count_color($im, $red), 1250, "check black vs black/blue/red image");
--- /dev/null
+package Imager::Filter::DynTest;
+use strict;
+use Imager;
+use vars qw($VERSION @ISA);
+
+BEGIN {
+ $VERSION = "0.01";
+
+ eval {
+ require XSLoader;
+ XSLoader::load('Imager::Filter::DynTest', $VERSION);
+ 1;
+ } or do {
+ require DynaLoader;
+ push @ISA, 'DynaLoader';
+ bootstrap Imager::Filter::DynTest $VERSION;
+ };
+}
+
+
+sub _lin_stretch {
+ my %hsh = @_;
+
+ lin_stretch($hsh{image}, $hsh{a}, $hsh{b});
+}
+
+Imager->register_filter(type=>'lin_stretch',
+ callsub => \&_lin_stretch,
+ defaults => { a => 0, b => 255 },
+ callseq => [ qw/image a b/ ]);
+
+1;
--- /dev/null
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "ppport.h"
+#ifdef __cplusplus
+}
+#endif
+
+#include "imext.h"
+#include "imperl.h"
+
+extern void lin_stretch(i_img *, int, int);
+
+DEFINE_IMAGER_CALLBACKS;
+
+MODULE = Imager::Filter::DynTest PACKAGE = Imager::Filter::DynTest
+
+void
+lin_stretch(im, a, b)
+ Imager::ImgRaw im
+ int a
+ int b
+
+BOOT:
+ PERL_INITIALIZE_IMAGER_CALLBACKS;
+
--- /dev/null
+use ExtUtils::MakeMaker;
+require "../metafile.pl";
+
+my %opts =
+ (
+ NAME => 'Imager::Filter::DynTest',
+ VERSION_FROM => 'DynTest.pm',
+ OBJECT => 'DynTest.o linstretch.o',
+ INC => '-I..'
+ );
+if ($ExtUtils::MakeMaker::VERSION > 6.06) {
+ $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>';
+ $opts{ABSTRACT} = 'Demo Imager filter extension';
+}
+
+WriteMakefile(%opts);
+
+
--- /dev/null
+#include "imext.h"
+
+char evalstr[]="Description string of plugin dyntest - kind of like";
+
+void null_plug(void *ptr) { }
+
+/* Example dynamic filter - level stretch (linear) - note it only stretches and doesn't compress */
+
+/* input parameters
+ a: the current black
+ b: the current white
+
+ 0 <= a < b <= 255;
+
+ output pixel value calculated by: o=((i-a)*255)/(b-a);
+
+ note that since we do not have the needed functions to manipulate the data structures *** YET ***
+*/
+
+
+unsigned char
+static
+saturate(int in) {
+ if (in>255) { return 255; }
+ else if (in>0) return in;
+ return 0;
+}
+
+void lin_stretch(i_img *im, int a, int b) {
+
+ i_color rcolor;
+ int i,bytes,x,y;
+ int info[4];
+
+
+ /* fprintf(stderr,"parameters: (im 0x%x,a %d,b %d)\n",im,a,b);*/
+ bytes=im->bytes;
+
+ i_img_info(im,info);
+
+ for(y=0;y<im->ysize;y++) for(x=0;x<im->xsize;x++) {
+ i_gpix(im,x,y,&rcolor);
+ for(i=0;i<im->channels;i++) rcolor.channel[i]=saturate((255*(rcolor.channel[i]-a))/(b-a));
+ i_ppix(im,x,y,&rcolor);
+ }
+
+}
+
+
--- /dev/null
+#!perl -w
+use strict;
+use blib;
+use lib '../t';
+use Imager;
+use Test::More tests => 4;
+
+BEGIN { use_ok('Imager::Filter::DynTest') }
+
+my $im = Imager->new;
+SKIP:
+{
+ ok($im->read(file => '../testout/t104.ppm'), "load source image")
+ or skip("couldn't load work image", 2);
+ ok($im->filter(type=>'lin_stretch', a => 50, b => 200),
+ "try filter")
+ or print "# ", $im->errstr, "\n";
+ ok($im->write(file => '../testout/t00dyntest.ppm'),
+ "save result");
+}
BEGIN {
require Exporter;
- require DynaLoader;
-
+ @ISA = qw(Exporter);
$VERSION = '0.47';
- @ISA = qw(Exporter DynaLoader);
- bootstrap Imager $VERSION;
+ eval {
+ require XSLoader;
+ XSLoader::load(Imager => $VERSION);
+ 1;
+ } or do {
+ require DynaLoader;
+ push @ISA, 'DynaLoader';
+ bootstrap Imager $VERSION;
+ }
}
BEGIN {
}
my $newcopy=Imager->new();
- $newcopy->{IMG}=i_img_new();
- i_copy($newcopy->{IMG},$self->{IMG});
+ $newcopy->{IMG} = i_copy($self->{IMG});
return $newcopy;
}
sub paste {
my $self = shift;
- unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
- my %input=(left=>0, top=>0, @_);
- unless($input{img}) {
- $self->{ERRSTR}="no source image";
+
+ unless ($self->{IMG}) {
+ $self->_set_error('empty input image');
+ return;
+ }
+ my %input=(left=>0, top=>0, src_minx => 0, src_miny => 0, @_);
+ my $src = $input{img} || $input{src};
+ unless($src) {
+ $self->_set_error("no source image");
return;
}
$input{left}=0 if $input{left} <= 0;
$input{top}=0 if $input{top} <= 0;
- my $src=$input{img};
+
my($r,$b)=i_img_info($src->{IMG});
+ my ($src_left, $src_top) = @input{qw/src_minx src_miny/};
+ my ($src_right, $src_bottom);
+ if ($input{src_coords}) {
+ ($src_left, $src_top, $src_right, $src_bottom) = @{$input{src_coords}}
+ }
+ else {
+ if (defined $input{src_maxx}) {
+ $src_right = $input{src_maxx};
+ }
+ elsif (defined $input{width}) {
+ if ($input{width} <= 0) {
+ $self->_set_error("paste: width must me positive");
+ return;
+ }
+ $src_right = $src_left + $input{width};
+ }
+ else {
+ $src_right = $r;
+ }
+ if (defined $input{src_maxx}) {
+ $src_bottom = $input{src_maxy};
+ }
+ elsif (defined $input{height}) {
+ if ($input{height} < 0) {
+ $self->_set_error("paste: height must be positive");
+ return;
+ }
+ $src_bottom = $src_top + $input{height};
+ }
+ else {
+ $src_bottom = $b;
+ }
+ }
+
+ $src_right > $r and $src_right = $r;
+ $src_bottom > $r and $src_bottom = $b;
+
+ if ($src_right <= $src_left
+ || $src_bottom < $src_top) {
+ $self->_set_error("nothing to paste");
+ return;
+ }
i_copyto($self->{IMG}, $src->{IMG},
- 0,0, $r, $b, $input{left}, $input{top});
+ $src_left, $src_top, $src_right, $src_bottom,
+ $input{left}, $input{top});
+
return $self; # What should go here??
}
return $self;
}
+sub register_filter {
+ my $class = shift;
+ my %hsh = ( defaults => {}, @_ );
+
+ defined $hsh{type}
+ or die "register_filter() with no type\n";
+ defined $hsh{callsub}
+ or die "register_filter() with no callsub\n";
+ defined $hsh{callseq}
+ or die "register_filter() with no callseq\n";
+
+ exists $filters{$hsh{type}}
+ and return;
+
+ $filters{$hsh{type}} = \%hsh;
+
+ return 1;
+}
+
# Scale an image to requested size and return the scaled version
sub scale {
return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
}
-# Autoload methods go after =cut, and are processed by the autosplit program.
+sub Inline {
+ my ($lang) = @_;
+
+ $lang eq 'C'
+ or die "Only C language supported";
+
+ require Imager::ExtUtils;
+ return Imager::ExtUtils->inline_config;
+}
1;
__END__
L<Imager::Fountain> - Helper for making gradient profiles.
+=item *
+
+L<Imager::API> - using Imager's C API
+
+=item *
+
+L<Imager::APIRef> - API function reference
+
+=item *
+
+L<Imager::Inline> - using Imager's C API from Inline::C
+
+=item *
+
+L<Imager::ExtUtils> - tools to get access to Imager's C API.
+
=back
=head2 Basic Overview
#include "XSUB.h"
#include "ppport.h"
#ifdef __cplusplus
-
+}
#endif
#define i_int_hlines_testing() 1
-#include "image.h"
+#include "imager.h"
#include "feat.h"
#include "dynaload.h"
#include "regmach.h"
-
-#if i_int_hlines_testing()
-#include "imagei.h"
-#endif
+#include "imextdef.h"
typedef io_glue* Imager__IO;
-typedef i_color* Imager__Color;
-typedef i_fcolor* Imager__Color__Float;
-typedef i_img* Imager__ImgRaw;
-typedef int undef_neg_int;
-#ifdef HAVE_LIBTT
-typedef TT_Fonthandle* Imager__Font__TT;
+#if i_int_hlines_testing()
+#include "imageri.h"
#endif
-#ifdef HAVE_FT2
-typedef FT2_Fonthandle* Imager__Font__FT2;
-#endif
+#include "imperl.h"
/* These functions are all shared - then comes platform dependant code */
static int getstr(void *hv_t,char *key,char **store) {
#define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
#define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
-/* for the fill objects
- Since a fill object may later have dependent images, (or fills!)
- we need perl wrappers - oh well
-*/
-#define IFILL_DESTROY(fill) i_fill_destroy(fill);
-typedef i_fill_t* Imager__FillHandle;
/* the m_init_log() function was called init_log(), renamed to reduce
potential naming conflicts */
int ty
Imager::Color trans
-void
-i_copy(im,src)
- Imager::ImgRaw im
+Imager::ImgRaw
+i_copy(src)
Imager::ImgRaw src
Imager::Internal::Hlines hlines
#endif
+
+BOOT:
+ PERL_SET_GLOBAL_CALLBACKS;
Changes
+CountColor/CountColor.pm sample XS access to API
+CountColor/CountColor.xs
+CountColor/Makefile.PL
+CountColor/t/t00countcolor.t
+DynTest/DynTest.pm simple conversion of the dyntest sample from dynfilt/
+DynTest/DynTest.xs
+DynTest/Makefile.PL
+DynTest/linstretch.c
+DynTest/t/t00dyntest.t
Imager.pm
Imager.xs
MANIFEST
+MANIFEST.SKIP
META.yml Module meta-data
+Mandelbrot/Makefile.PL more complex filter
+Mandelbrot/Mandelbrot.pm
+Mandelbrot/Mandelbrot.xs
+Mandelbrot/mandel.c
+Mandelbrot/t/t00mandel.t
Makefile.PL
README
+apidocs.perl Build lib/Imager/APIRef.pm
bigtest.perl Library selection tester
bmp.c Reading and writing Windows BMP files
color.c Color translation and handling
conv.c
convert.c
-datatypes.c
-datatypes.h
doco.perl
+datatypes.c
draw.c
draw.h
dynaload.c
gif.c
hlines.c Manage sets of horizontal line segments
image.c
-image.h
-imagei.h
+imager.h
+imageri.h
+imdatatypes.h
+imext.c Defines the function table
+imext.h Included by external modules for API access
+imextdef.h
+imexttypes.h Define API function table type
imexif.c Experimental JPEG EXIF decoding
imexif.h
img16.c
imgdouble.c Implements double/sample images
imio.h
+imperl.h
io.c
iolayer.c
iolayer.h
jpeg.c
+lib/Imager/API.pm
+lib/Imager/APIRef.pm API function reference
lib/Imager/Color.pm
lib/Imager/Color/Float.pm
lib/Imager/Color/Table.pm
lib/Imager/Cookbook.pod
lib/Imager/Draw.pod
lib/Imager/Engines.pod
+lib/Imager/ExtUtils.pm
lib/Imager/Expr.pm
lib/Imager/Expr/Assem.pm
lib/Imager/Files.pod
lib/Imager/Font/Wrap.pm
lib/Imager/Fountain.pm
lib/Imager/ImageTypes.pod
+lib/Imager/Inline.pod Using Imager with Inline::C
lib/Imager/Matrix2d.pm
lib/Imager/Regops.pm
lib/Imager/Transform.pm
log.h
map.c
maskimg.c
+metafile.pl Common META.yml generation
palimg.c
plug.h
png.c
t/t75polyaa.t
t/t80texttools.t Test text wrapping
t/t81hlines.t Test hlines.c
+t/t82inline.t Test Inline::C integration
t/t90cc.t
t/t91pod.t Test POD with Test::Pod
t/testtools.pl
--- /dev/null
+# svn work files'
+^\.svn\b
+/\.svn\b
+
+# editor trash
+~$
+
+# stuff we don't distribute
+^TODO$
+^STATUS$
+^\.cvsignore$
+/\.cvsignore$
+^announce/
+^bench/
+^design/
+^fileformatdocs/
+^extraimages/
+^fontfiles/.*\.sfd$
+
+# might distribute one day
+^tools/imager$
+
+# trash left by Inline::C
+^_Inline/
+
+# build trash
+Makefile$
+Makefile\.old
+\bpm_to_blib$
+\.o$
+^testimg/
+^blib/
+^Imager\.c$
+^Mandelbrot/Mandelbrot\.c$
+^CountColor/CountColor\.c$
+^DynTest/DynTest\.c$
+^dynfilt/.*\.(so|dll)$
+\.bs$
+^meta\.tmp$
+/meta\.tmp$
+^imconfig\.h$
use Config;
use File::Spec;
use Getopt::Long;
+use vars qw(%Recommends);
+require "metafile.pl";
+use ExtUtils::Manifest qw(maniread);
#
# IM_INCPATH colon seperated list of paths to extra include paths
filters.o dynaload.o stackmach.o datatypes.o
regmach.o trans2.o quant.o error.o convert.o
map.o tags.o palimg.o maskimg.o img16.o rotate.o
- bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o);
+ bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
+ imext.o);
+
+$Recommends{Imager} =
+ { 'Parse::RecDescent' => 0 };
%opts=(
'NAME' => 'Imager',
'INC' => "$lib_cflags $DFLAGS $F_INC",
'OBJECT' => join(' ', @objs, $F_OBJECT),
clean => { FILES=>'testout meta.tmp' },
+ PM => gen_PM(),
);
if ($ExtUtils::MakeMaker::VERSION > 6.06) {
lib/Imager/Regops.pm : regmach.h regops.perl
$(PERL) regops.perl regmach.h lib/Imager/Regops.pm
-imconfig.h: Makefile.PL
+imconfig.h : Makefile.PL
$(ECHO) "imconfig.h out-of-date with respect to $?"
$(PERLRUN) Makefile.PL
$(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
+
+lib/Imager/APIRef.pm : $(C_FILES) apidocs.perl
+ $(PERLRUN) apidocs.perl lib/Imager/APIRef.pm
+
';
-}
-sub MY::metafile {
- my ($self) = @_;
-
- my $meta = <<YAML;
---- #YAML:1.0
-name: Imager
-version: $self->{VERSION}
-version_from: $self->{VERSION_FROM}
-author: $self->{AUTHOR}
-abstract: $self->{ABSTRACT}
-installdirs: $self->{INSTALLDIRS}
-recommends:
- Parse::RecDescent: 0
-license: perl
-dynamic_config: 1
-distribution_type: module
-generated_by: Imager version $self->{VERSION}
-YAML
- open META, "> meta.tmp" or die "Cannot create meta.tmp: $!";
- print META $meta;
- close META;
-
- return sprintf "metafile :\n\t\$(CP) meta.tmp META.yml\n";
}
# manual configuration of helper libraries
exit 1;
}
+
+# generate the PM MM argument
+# I'd prefer to modify the public version, but there doesn't seem to be
+# a public API to do that
+sub gen_PM {
+ my %pm;
+ my $instbase = '$(INST_LIBDIR)';
+
+ # first the basics, .pm and .pod files
+ $pm{"Imager.pm"} = "$instbase/Imager.pm";
+
+ my $mani = maniread();
+
+ for my $filename (keys %$mani) {
+ if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
+ (my $work = $filename) =~ s/^lib//;
+ $pm{$filename} = $instbase . $work;
+ }
+ }
+
+ # need the typemap
+ $pm{typemap} = $instbase . '/Imager/typemap';
+
+ # and the core headers
+ for my $filename (keys %$mani) {
+ if ($filename =~ /^\w+\.h$/) {
+ $pm{$filename} = $instbase . '/Imager/include/' . $filename;
+ }
+ }
+
+ # and the generated header
+ $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
+
+ \%pm;
+}
--- /dev/null
+use ExtUtils::MakeMaker;
+require "../metafile.pl";
+
+my %opts =
+ (
+ NAME => 'Imager::Filter::Mandelbrot',
+ VERSION_FROM => 'Mandelbrot.pm',
+ OBJECT => 'Mandelbrot.o mandel.o',
+ INC => '-I..'
+ );
+if ($ExtUtils::MakeMaker::VERSION > 6.06) {
+ $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>';
+ $opts{ABSTRACT} = 'Mandelbrot Imager filter extension';
+}
+
+WriteMakefile(%opts);
+
+
--- /dev/null
+package Imager::Filter::Mandelbrot;
+use strict;
+use Imager;
+use vars qw($VERSION @ISA);
+
+BEGIN {
+ $VERSION = "0.01";
+
+ eval {
+ require XSLoader;
+ XSLoader::load('Imager::Filter::Mandelbrot', $VERSION);
+ 1;
+ } or do {
+ require DynaLoader;
+ push @ISA, 'DynaLoader';
+ bootstrap Imager::Filter::Mandelbrot $VERSION;
+ };
+}
+
+sub _mandelbrot {
+ my %hsh = @_;
+
+ mandelbrot($hsh{image}, $hsh{minx}, $hsh{miny}, $hsh{maxx}, $hsh{maxy}, $hsh{maxiter});
+}
+
+my %defaults =
+ (
+ minx => -2.5,
+ maxx => 1.5,
+ miny => -1.5,
+ maxy => 1.5,
+ maxiter => 256,
+ );
+
+my @callseq = qw/image minx miny maxx maxy maxiter/;
+
+Imager->register_filter(type=>'mandelbrot',
+ callsub => \&_mandelbrot,
+ defaults => \%defaults,
+ callseq => \@callseq);
+
+1;
--- /dev/null
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "ppport.h"
+#ifdef __cplusplus
+}
+#endif
+
+#include "imext.h"
+#include "imperl.h"
+
+void
+mandelbrot(i_img *im, double minx, double miny, double maxx, double maxy, int max_iter);
+
+DEFINE_IMAGER_CALLBACKS;
+
+MODULE = Imager::Filter::Mandelbrot PACKAGE = Imager::Filter::Mandelbrot
+
+void
+mandelbrot(im, minx=-2.5, miny=-2.0, maxx=2.5, maxy=-2.0, max_iter=256)
+ Imager::ImgRaw im
+ double minx
+ double miny
+ double maxx
+ double maxy
+ int max_iter
+
+BOOT:
+ PERL_INITIALIZE_IMAGER_CALLBACKS;
+
--- /dev/null
+#include "imext.h"
+#include <stdlib.h>
+
+char evalstr[]="Mandlebrot renderer";
+
+/* Example Mandlebrot generator */
+
+/* input parameters
+ image is the image object.
+*/
+
+
+static
+int
+mandel(double x, double y, int max_iter) {
+ double xn, yn;
+ double xo, yo;
+ double dist;
+ int iter = 1;
+ /* Z(n+1) = Z(n) ^2 + c */
+
+ /* printf("(%.2f, %.2f) -> \n", x,y); */
+
+ xo = x;
+ yo = y;
+
+ while( xo*xo+yo*yo <= 10 && iter < max_iter) {
+ xn = xo*xo-yo*yo + x;
+ yn = 2*xo*yo + y;
+ xo=xn;
+ yo=yn;
+ iter++;
+ }
+ return (iter == max_iter)?0:iter;
+}
+
+void
+mandelbrot(i_img *im, double minx, double miny, double maxx, double maxy, int max_iter) {
+
+ i_color vl;
+ int i,bytes,x,y;
+ int idx;
+ double divx, divy;
+
+ i_color icl[256];
+ srand(12235);
+ for(i=1;i<256; i++) {
+ icl[i].rgb.r = 100+(int) (155.0*rand()/(RAND_MAX+1.0));
+ icl[i].rgb.g = 100+(int) (155.0*rand()/(RAND_MAX+1.0));
+ icl[i].rgb.g = 100+(int) (155.0*rand()/(RAND_MAX+1.0));
+ }
+
+ icl[0].rgb.r = 0;
+ icl[0].rgb.g = 0;
+ icl[0].rgb.g = 0;
+
+ if (maxx <= minx)
+ maxx = minx + 1.0;
+ if (maxy <= miny)
+ maxy = miny + 1.0;
+
+ divx = (maxx - minx) / im->xsize;
+ divy = (maxy - miny) / im->ysize;
+
+ for(y = 0; y < im->ysize; y ++) {
+ for(x = 0; x < im->xsize; x ++ ) {
+ idx = mandel(minx + x*divx , miny + y*divy, max_iter);
+ idx = idx % 256;
+ i_ppix(im,x,y,&icl[idx]);
+ }
+ }
+}
--- /dev/null
+#!perl -w
+use strict;
+use blib;
+use lib '../t';
+use Imager;
+use Test::More tests => 3;
+
+BEGIN { use_ok('Imager::Filter::Mandelbrot') }
+
+my $im = Imager->new(xsize=>100, ysize=>100);
+SKIP:
+{
+ ok($im->filter(type=>'mandelbrot'),
+ "try filter")
+ or print "# ", $im->errstr, "\n";
+ ok($im->write(file => '../testout/t00mandel.ppm'),
+ "save result");
+}
--- /dev/null
+#!perl -w
+use strict;
+
+my $outname = shift || '-';
+
+
+my @funcs = make_func_list();
+my %funcs = map { $_ => 1 } @funcs;
+
+# look for files to parse
+
+my @files = grep $_ ne 'Imager.xs', glob '*.c';
+
+# scan each file for =item <func>\b
+my $func;
+my $start;
+my %alldocs;
+my @funcdocs;
+my %from;
+my $category;
+my %funccats;
+my %cats;
+my $synopsis = '';
+my %funcsyns;
+for my $file (@files) {
+ open SRC, "< $file"
+ or die "Cannot open $file for documentation: $!\n";
+ while (<SRC>) {
+ if (/^=item (\w+)\b/ && $funcs{$1}) {
+ $func = $1;
+ $start = $.;
+ @funcdocs = $_;
+ }
+ elsif ($func && /^=(cut|head)/) {
+ if ($funcs{$func}) { # only save the API functions
+ $alldocs{$func} = [ @funcdocs ];
+ $from{$func} = "Line $start in $file";
+ if ($category) {
+ $funccats{$func} = $category;
+ push @{$cats{$category}}, $func;
+ }
+ if ($synopsis) {
+ $funcsyns{$func} = $synopsis;
+ }
+ }
+ undef $func;
+ undef $category;
+ $synopsis = '';
+ }
+ elsif ($func) {
+ if (/^=category (.*)/) {
+ $category = $1;
+ }
+ elsif (/^=synopsis (.*)/) {
+ $synopsis .= "$1\n";
+ }
+ else {
+ push @funcdocs, $_;
+ }
+ }
+ }
+ $func and
+ die "Documentation for $func not followed by =cut or =head in $file\n";
+
+ close SRC;
+}
+
+open OUT, "> $outname"
+ or die "Cannot open $outname: $!";
+
+print OUT <<'EOS';
+Do not edit this file, it is generated automatically by apidocs.perl
+from Imager's source files.
+
+Each function description has a comment listing the source file and
+line number where you can find the documentation.
+
+=head1 NAME
+
+Imager::APIRef - Imager's C API.
+
+=head1 SYNOPSIS
+
+ i_color color;
+ color.rgba.red = 255; color.rgba.green = 0; color.rgba.blue = 255;
+ i_fill_t *fill = i_new_fill_...(...);
+
+EOS
+
+for my $cat (sort { lc $a cmp lc $b } keys %cats) {
+ print OUT "\n # $cat\n";
+ for my $func (grep $funcsyns{$_}, sort @{$cats{$cat}}) {
+ my $syn = $funcsyns{$func};
+ $syn =~ s/^/ /gm;
+ print OUT $syn;
+ }
+}
+
+print OUT <<'EOS';
+
+ i_fill_destroy(fill);
+
+=head1 DESCRIPTION
+
+EOS
+
+my %undoc = %funcs;
+
+for my $cat (sort { lc $a cmp lc $b } keys %cats) {
+ print OUT "=head2 $cat\n\n=over\n\n";
+ for my $func (sort @{$cats{$cat}}) {
+ print OUT @{$alldocs{$func}}, "\n";
+ print OUT "=for comment\nFrom: $from{$func}\n\n";
+ delete $undoc{$func};
+ }
+ print OUT "\n=back\n\n";
+}
+
+# see if we have an uncategorized section
+if (grep $alldocs{$_}, keys %undoc) {
+ print OUT "=head2 Uncategorized functions\n\n=over\n\n";
+ for my $func (sort @funcs) {
+ if ($undoc{$func} && $alldocs{$func}) {
+ print OUT @{$alldocs{$func}}, "\n";
+ print OUT "=for comment\nFrom: $from{$func}\n\n";
+ delete $undoc{$func};
+ }
+ }
+ print OUT "\n\n=back\n\n";
+}
+
+if (keys %undoc) {
+ print OUT <<'EOS';
+
+=head1 UNDOCUMENTED
+
+The following API functions are undocumented so far, hopefully this
+will change:
+
+=over
+
+EOS
+
+ print OUT "=item *\n\nB<$_>\n\n" for sort keys %undoc;
+
+ print OUT "\n\n=back\n\n";
+}
+
+print OUT <<'EOS';
+
+=head1 AUTHOR
+
+Tony Cook <tony@imager.perl.org>
+
+=head1 SEE ALSO
+
+Imager, Imager::ExtUtils, Imager::Inline
+
+=cut
+EOS
+
+close OUT;
+
+
+sub make_func_list {
+ my $funcs;
+ open FUNCS, "< imexttypes.h"
+ or die "Cannot open imexttypes.h: $!\n";
+ my $in_struct;
+ while (<FUNCS>) {
+ /^typedef struct/ && ++$in_struct;
+ if ($in_struct && /\(\*f_(i_\w+)/) {
+ push @funcs, $1;
+ }
+ if (/^\} im_ext_funcs;$/) {
+ $in_struct
+ or die "Found end of functions structure but not the start";
+
+ close FUNCS;
+ return @funcs;
+ }
+ }
+ if ($in_struct) {
+ die "Found start of the functions structure but not the end\n";
+ }
+ else {
+ die "Found neither the start nor end of the functions structure\n";
+ }
+}
#include <stdarg.h>
-#include "imagei.h"
+#include "imageri.h"
/*
=head1 NAME
-#include "image.h"
+#include "imager.h"
#include <math.h>
/*
-#include "image.h"
+#include "imager.h"
/*
General convolution for 2d decoupled filters
=cut
*/
-#include "image.h"
+#include "imager.h"
/*
#include "imio.h"
-#include "datatypes.h"
+#include "imdatatypes.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+++ /dev/null
-#ifndef _DATATYPES_H_
-#define _DATATYPES_H_
-
-#include "imio.h"
-
-#define MAXCHANNELS 4
-
-/* used for palette indices in some internal code (which might be
- exposed at some point
-*/
-typedef unsigned char i_palidx;
-
-/* We handle 2 types of sample, this is hopefully the most common, and the
- smaller of the ones we support */
-typedef unsigned char i_sample_t;
-
-typedef struct { i_sample_t gray_color; } gray_color;
-typedef struct { i_sample_t r,g,b; } rgb_color;
-typedef struct { i_sample_t r,g,b,a; } rgba_color;
-typedef struct { i_sample_t c,m,y,k; } cmyk_color;
-
-typedef int undef_int; /* special value to put in typemaps to retun undef on 0 and 1 on 1 */
-
-typedef union {
- gray_color gray;
- rgb_color rgb;
- rgba_color rgba;
- cmyk_color cmyk;
- i_sample_t channel[MAXCHANNELS];
- unsigned int ui;
-} i_color;
-
-/* this is the larger sample type, it should be able to accurately represent
- any sample size we use */
-typedef double i_fsample_t;
-
-typedef struct { i_fsample_t gray_color; } i_fgray_color_t;
-typedef struct { i_fsample_t r, g, b; } i_frgb_color_t;
-typedef struct { i_fsample_t r, g, b, a; } i_frgba_color_t;
-typedef struct { i_fsample_t c, m, y, k; } i_fcmyk_color_t;
-
-typedef union {
- i_fgray_color_t gray;
- i_frgb_color_t rgb;
- i_frgba_color_t rgba;
- i_fcmyk_color_t cmyk;
- i_fsample_t channel[MAXCHANNELS];
-} i_fcolor;
-
-typedef enum {
- i_direct_type, /* direct colour, keeps RGB values per pixel */
- i_palette_type /* keeps a palette index per pixel */
-} i_img_type_t;
-
-typedef enum {
- /* bits per sample, not per pixel */
- /* a paletted image might have one bit per sample */
- i_8_bits = 8,
- i_16_bits = 16,
- i_double_bits = sizeof(double) * 8
-} i_img_bits_t;
-
-typedef struct {
- char *name; /* name of a given tag, might be NULL */
- int code; /* number of a given tag, -1 if it has no meaning */
- char *data; /* value of a given tag if it's not an int, may be NULL */
- int size; /* size of the data */
- int idata; /* value of a given tag if data is NULL */
-} i_img_tag;
-
-typedef struct {
- int count; /* how many tags have been set */
- int alloc; /* how many tags have been allocated for */
- i_img_tag *tags;
-} i_img_tags;
-
-typedef struct i_img_ i_img;
-typedef int (*i_f_ppix_t)(i_img *im, int x, int y, i_color *pix);
-typedef int (*i_f_ppixf_t)(i_img *im, int x, int y, i_fcolor *pix);
-typedef int (*i_f_plin_t)(i_img *im, int x, int r, int y, i_color *vals);
-typedef int (*i_f_plinf_t)(i_img *im, int x, int r, int y, i_fcolor *vals);
-typedef int (*i_f_gpix_t)(i_img *im, int x, int y, i_color *pix);
-typedef int (*i_f_gpixf_t)(i_img *im, int x, int y, i_fcolor *pix);
-typedef int (*i_f_glin_t)(i_img *im, int x, int r, int y, i_color *vals);
-typedef int (*i_f_glinf_t)(i_img *im, int x, int r, int y, i_fcolor *vals);
-
-typedef int (*i_f_gsamp_t)(i_img *im, int x, int r, int y, i_sample_t *samp,
- const int *chans, int chan_count);
-typedef int (*i_f_gsampf_t)(i_img *im, int x, int r, int y, i_fsample_t *samp,
- const int *chan, int chan_count);
-
-typedef int (*i_f_gpal_t)(i_img *im, int x, int r, int y, i_palidx *vals);
-typedef int (*i_f_ppal_t)(i_img *im, int x, int r, int y, i_palidx *vals);
-typedef int (*i_f_addcolors_t)(i_img *im, i_color *colors, int count);
-typedef int (*i_f_getcolors_t)(i_img *im, int i, i_color *, int count);
-typedef int (*i_f_colorcount_t)(i_img *im);
-typedef int (*i_f_maxcolors_t)(i_img *im);
-typedef int (*i_f_findcolor_t)(i_img *im, i_color *color, i_palidx *entry);
-typedef int (*i_f_setcolors_t)(i_img *im, int index, i_color *colors,
- int count);
-
-typedef void (*i_f_destroy_t)(i_img *im);
-
-struct i_img_ {
- int channels;
- int xsize,ysize,bytes;
- unsigned int ch_mask;
- i_img_bits_t bits;
- i_img_type_t type;
- int virtual; /* image might not keep any data, must use functions */
- unsigned char *idata; /* renamed to force inspection of existing code */
- /* can be NULL if virtual is non-zero */
- i_img_tags tags;
-
- void *ext_data;
-
- /* interface functions */
- i_f_ppix_t i_f_ppix;
- i_f_ppixf_t i_f_ppixf;
- i_f_plin_t i_f_plin;
- i_f_plinf_t i_f_plinf;
- i_f_gpix_t i_f_gpix;
- i_f_gpixf_t i_f_gpixf;
- i_f_glin_t i_f_glin;
- i_f_glinf_t i_f_glinf;
- i_f_gsamp_t i_f_gsamp;
- i_f_gsampf_t i_f_gsampf;
-
- /* only valid for type == i_palette_type */
- i_f_gpal_t i_f_gpal;
- i_f_ppal_t i_f_ppal;
- i_f_addcolors_t i_f_addcolors;
- i_f_getcolors_t i_f_getcolors;
- i_f_colorcount_t i_f_colorcount;
- i_f_maxcolors_t i_f_maxcolors;
- i_f_findcolor_t i_f_findcolor;
- i_f_setcolors_t i_f_setcolors;
-
- i_f_destroy_t i_f_destroy;
-};
-
-/* ext_data for paletted images
- */
-typedef struct {
- int count; /* amount of space used in palette (in entries) */
- int alloc; /* amount of space allocated for palette (in entries) */
- i_color *pal;
- int last_found;
-} i_img_pal_ext;
-
-/* Helper datatypes
- The types in here so far are:
-
- doubly linked bucket list - pretty efficient
- octtree - no idea about goodness
-
- needed: hashes.
-
-*/
-
-
-
-
-
-/* bitmap mask */
-
-struct i_bitmap {
- int xsize,ysize;
- char *data;
-};
-
-struct i_bitmap* btm_new(int xsize,int ysize);
-void btm_destroy(struct i_bitmap *btm);
-int btm_test(struct i_bitmap *btm,int x,int y);
-void btm_set(struct i_bitmap *btm,int x,int y);
-
-
-
-
-
-
-
-
-/* Stack/Linked list */
-
-struct llink {
- struct llink *p,*n;
- void *data;
- int fill; /* Number used in this link */
-};
-
-struct llist {
- struct llink *h,*t;
- int multip; /* # of copies in a single chain */
- int ssize; /* size of each small element */
- int count; /* number of elements on the list */
-};
-
-
-/* Links */
-
-struct llink *llink_new( struct llink* p,int size );
-int llist_llink_push( struct llist *lst, struct llink *lnk, void *data );
-
-/* Lists */
-
-struct llist *llist_new( int multip, int ssize );
-void llist_destroy( struct llist *l );
-void llist_push( struct llist *l, void *data );
-void llist_dump( struct llist *l );
-int llist_pop( struct llist *l,void *data );
-
-
-
-
-/* Octtree */
-
-struct octt {
- struct octt *t[8];
- int cnt;
-};
-
-struct octt *octt_new(void);
-int octt_add(struct octt *ct,unsigned char r,unsigned char g,unsigned char b);
-void octt_dump(struct octt *ct);
-void octt_count(struct octt *ct,int *tot,int max,int *overflow);
-void octt_delete(struct octt *ct);
-
-/* font bounding box results */
-enum bounding_box_index_t {
- BBOX_NEG_WIDTH,
- BBOX_GLOBAL_DESCENT,
- BBOX_POS_WIDTH,
- BBOX_GLOBAL_ASCENT,
- BBOX_DESCENT,
- BBOX_ASCENT,
- BBOX_ADVANCE_WIDTH,
- BBOX_RIGHT_BEARING,
- BOUNDING_BOX_COUNT
-};
-
-#endif
-
-#include "image.h"
+#include "imager.h"
#include "draw.h"
#include "log.h"
-#include "imagei.h"
+#include "imageri.h"
#include <limits.h>
}
}
+/*
+=item i_arc(im, x, y, rad, d1, d2, color)
+
+=category Drawing
+=synopsis i_arc(im, 50, 50, 20, 45, 135, &color);
+
+Fills an arc centered at (x,y) with radius I<rad> covering the range
+of angles in degrees from d1 to d2, with the color.
+
+=cut
+*/
+
void
i_arc(i_img *im,int x,int y,float rad,float d1,float d2,i_color *val) {
i_int_hlines hlines;
i_int_hlines_destroy(&hlines);
}
+/*
+=item i_arc_cfill(im, x, y, rad, d1, d2, fill)
+
+=category Drawing
+=synopsis i_arc_cfill(im, 50, 50, 35, 90, 135, fill);
+
+Fills an arc centered at (x,y) with radius I<rad> covering the range
+of angles in degrees from d1 to d2, with the fill object.
+
+=cut
+*/
+
#define MIN_CIRCLE_STEPS 8
#define MAX_CIRCLE_STEPS 360
++*count;
}
+/*
+=item i_arc_aa(im, x, y, rad, d1, d2, color)
+
+=category Drawing
+=synopsis i_arc_aa(im, 50, 50, 35, 90, 135, &color);
+
+Antialias fills an arc centered at (x,y) with radius I<rad> covering
+the range of angles in degrees from d1 to d2, with the color.
+
+=cut
+*/
+
void
i_arc_aa(i_img *im, double x, double y, double rad, double d1, double d2,
i_color *val) {
myfree(yvals);
}
+/*
+=item i_arc_aa_cfill(im, x, y, rad, d1, d2, fill)
+
+=category Drawing
+=synopsis i_arc_aa_cfill(im, 50, 50, 35, 90, 135, fill);
+
+Antialias fills an arc centered at (x,y) with radius I<rad> covering
+the range of angles in degrees from d1 to d2, with the fill object.
+
+=cut
+*/
+
void
i_arc_aa_cfill(i_img *im, double x, double y, double rad, double d1, double d2,
i_fill_t *fill) {
return cnt;
}
+/*
+=item i_circle_aa(im, x, y, rad, color)
+
+=category Drawing
+=synopsis i_circle_aa(im, 50, 50, 45, &color);
+
+Antialias fills a circle centered at (x,y) for radius I<rad> with
+color.
+
+=cut
+*/
void
i_circle_aa(i_img *im, float x, float y, float rad, i_color *val) {
i_mmarray dot;
i_mmarray_dst(&dot);
}
+/*
+=item i_box(im, x1, y1, x2, y2, color)
+=category Drawing
+=synopsis i_box(im, 0, 0, im->xsize-1, im->ysize-1, &color).
+Outlines the box from (x1,y1) to (x2,y2) inclusive with I<color>.
-
+=cut
+*/
void
i_box(i_img *im,int x1,int y1,int x2,int y2,i_color *val) {
}
}
+/*
+=item i_box_filled(im, x1, y1, x2, y2, color)
+
+=category Drawing
+=synopsis i_box_filled(im, 0, 0, im->xsize-1, im->ysize-1, &color);
+
+Fills the box from (x1,y1) to (x2,y2) inclusive with color.
+
+=cut
+*/
+
void
i_box_filled(i_img *im,int x1,int y1,int x2,int y2,i_color *val) {
int x,y;
for(x=x1;x<x2+1;x++) for (y=y1;y<y2+1;y++) i_ppix(im,x,y,val);
}
+/*
+=item i_box_cfill(im, x1, y1, x2, y2, fill)
+
+=category Drawing
+=synopsis i_box_cfill(im, 0, 0, im->xsize-1, im->ysize-1, fill);
+
+Fills the box from (x1,y1) to (x2,y2) inclusive with fill.
+
+=cut
+*/
+
void
i_box_cfill(i_img *im,int x1,int y1,int x2,int y2,i_fill_t *fill) {
mm_log((1,"i_box_cfill(im* 0x%x,x1 %d,y1 %d,x2 %d,y2 %d,fill 0x%x)\n",im,x1,y1,x2,y2,fill));
/*
=item i_line(im, x1, y1, x2, y2, val, endp)
+=category Drawing
+
Draw a line to image using bresenhams linedrawing algorithm
im - image to draw to
}
+/*
+=item i_line_aa(im, x1, x2, y1, y2, color, endp)
+
+=category Drawing
+
+Antialias draws a line from (x1,y1) to (x2, y2) in color.
+The point (x2, y2) is drawn only if endp is set.
+
+=cut
+*/
void
i_line_aa(i_img *im, int x1, int y1, int x2, int y2, i_color *val, int endp) {
return btm;
}
+/*
+=item i_flood_fill(im, seedx, seedy, color)
+
+=category Drawing
+=synopsis i_flood_fill(im, 50, 50, &color);
+Flood fills the 4-connected region starting from the point (seedx,
+seedy) with I<color>.
+Returns false if (seedx, seedy) are outside the image.
+
+=cut
+*/
undef_int
i_flood_fill(i_img *im, int seedx, int seedy, i_color *dcol) {
return 1;
}
+/*
+=item i_flood_cfill(im, seedx, seedy, fill)
+
+=category Drawing
+=synopsis i_flood_cfill(im, 50, 50, fill);
+Flood fills the 4-connected region starting from the point (seedx,
+seedy) with I<fill>.
+
+Returns false if (seedx, seedy) are outside the image.
+
+=cut
+*/
undef_int
i_flood_cfill(i_img *im, int seedx, int seedy, i_fill_t *fill) {
-#include "image.h"
+#include "imager.h"
typedef struct {
int min,max;
-#include "image.h"
+#include "imager.h"
#include "dynaload.h"
/* #include "XSUB.h" so we can compile on threaded perls */
-#include "imagei.h"
+#include "imageri.h"
static symbol_table_t symbol_table={i_has_format,ICL_set_internal,ICL_info,
i_img_new,i_img_empty,i_img_empty_ch,i_img_exorcise,
=cut
*/
-#include "image.h"
+#include "imager.h"
#include <stdio.h>
#include <stdlib.h>
=item i_clear_error()
+=category Error handling
+
+Clears the error stack.
+
Called by any imager function before doing any other processing.
-=cut */
+=cut
+*/
void i_clear_error() {
#ifdef IMAGER_DEBUG_MALLOC
int i;
/*
=item i_push_error(int code, char const *msg)
+=category Error handling
+
Called by an imager function to push an error message onto the stack.
No message is pushed if the stack is full (since this means someone
/*
=item i_push_errorvf(int code, char const *fmt, va_list ap)
+=category Error handling
+
Intended for use by higher level functions, takes a varargs pointer
and a format to produce the finally pushed error message.
/*
=item i_push_errorf(int code, char const *fmt, ...)
+=category Error handling
+
A version of i_push_error() that does printf() like formating.
=cut
-#include "image.h"
+#include "imager.h"
#ifndef IMAGER_EXT_H
#define IMAGER_EXT_H
-#include "image.h"
+#include "imager.h"
static char *i_format_list[]={
#ifdef HAVE_LIBJPEG
-#include "image.h"
-#include "imagei.h"
+#include "imager.h"
+#include "imageri.h"
/*
=head1 NAME
/*
=item i_fill_destroy(fill)
+=category Fills
+
Call to destroy any fill object.
=cut
/*
=item i_new_fill_solidf(color, combine)
+=category Fills
+
Create a solid fill based on a float color.
If combine is non-zero then alpha values will be combined.
/*
=item i_new_fill_solid(color, combine)
-Create a solid fill based.
+=category Fills
+
+Create a solid fill based on an 8-bit color.
If combine is non-zero then alpha values will be combined.
/*
=item i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
+=category Fills
+
Creates a new hatched fill with the fg color used for the 1 bits in
the hatch and bg for the 0 bits. If combine is non-zero alpha values
will be combined.
/*
=item i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
+=category Fills
+
Creates a new hatched fill with the fg color used for the 1 bits in
the hatch and bg for the 0 bits. If combine is non-zero alpha values
will be combined.
/*
=item i_new_fill_image(im, matrix, xoff, yoff, combine)
+=category Fills
+
Create an image based fill.
+matrix is an array of 9 doubles representing a transformation matrix.
+
+xoff and yoff are the offset into the image to start filling from.
+
=cut
*/
i_fill_t *
-#include "image.h"
-#include "imagei.h"
+#include "imager.h"
+#include "imageri.h"
#include <stdlib.h>
#include <math.h>
int x, y;
unsigned char ch;
- i_color rcolor;
+ i_color *row, *entry;
- mm_log((1,"i_hardinvert(im %p)\n", im));
+ mm_log((1,"i_hardinvert(im %p)\n", im));
+
+ row = mymalloc(sizeof(i_color) * im->xsize);
for(y = 0; y < im->ysize; y++) {
+ i_glin(im, 0, im->xsize, y, row);
+ entry = row;
for(x = 0; x < im->xsize; x++) {
- i_gpix(im, x, y, &rcolor);
-
for(ch = 0; ch < im->channels; ch++) {
- rcolor.channel[ch] = 255 - rcolor.channel[ch];
+ entry->channel[ch] = 255 - entry->channel[ch];
}
-
- i_ppix(im, x, y, &rcolor);
+ ++entry;
}
+ i_plin(im, 0, im->xsize, y, row);
}
+ myfree(row);
}
=cut
*/
void i_unsharp_mask(i_img *im, double stddev, double scale) {
- i_img copy;
+ i_img *copy;
int x, y, ch;
if (scale < 0)
if (scale > 100)
scale = 100;
- i_copy(©, im);
- i_gaussian(©, stddev);
+ copy = i_copy(im);
+ i_gaussian(copy, stddev);
if (im->bits == i_8_bits) {
i_color *blur = mymalloc(im->xsize * sizeof(i_color) * 2);
i_color *out = blur + im->xsize;
for (y = 0; y < im->ysize; ++y) {
- i_glin(©, 0, copy.xsize, y, blur);
+ i_glin(copy, 0, copy->xsize, y, blur);
i_glin(im, 0, im->xsize, y, out);
for (x = 0; x < im->xsize; ++x) {
for (ch = 0; ch < im->channels; ++ch) {
i_fcolor *out = blur + im->xsize;
for (y = 0; y < im->ysize; ++y) {
- i_glinf(©, 0, copy.xsize, y, blur);
+ i_glinf(copy, 0, copy->xsize, y, blur);
i_glinf(im, 0, im->xsize, y, out);
for (x = 0; x < im->xsize; ++x) {
for (ch = 0; ch < im->channels; ++ch) {
myfree(blur);
}
- i_img_exorcise(©);
+ i_img_destroy(copy);
}
/*
fount_fill_destroy(i_fill_t *fill);
/*
-=item i_new_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, count, segs)
+=item i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, count, segs)
+
+=category Fills
+=synopsis fill = i_new_fill_fount(0, 0, 100, 100, i_ft_linear, i_ft_linear,
+=synopsis i_fr_triangle, 0, i_fts_grid, 9, 1, segs);
+
Creates a new general fill which fills with a fountain fill.
-#include "image.h"
+#include "imager.h"
#include <sys/types.h>
#include <sys/stat.h>
bit->size = bit->rows * bit->cols; /* number of bytes in buffer */
}
+ /* rows can be 0 for some glyphs, for example ' ' */
if (bit->rows && bit->size / bit->rows != bit->cols) {
m_fatal(0, "Integer overflow calculating bitmap size (%d, %d)\n",
bit->width, bit->rows);
=cut
*/
-#include "image.h"
+#include "imager.h"
#include <stdio.h>
#include <ft2build.h>
#include FT_FREETYPE_H
-#include "image.h"
+#include "imager.h"
static float
gauss(int x,float std) {
-#include "imagei.h"
+#include "imageri.h"
#include <gif_lib.h>
#ifdef _MSCVER
#include <io.h>
}
else {
glob_paletted = 0;
- quant_makemap(quant, glob_imgs, glob_img_count);
+ i_quant_makemap(quant, glob_imgs, glob_img_count);
}
glob_color_count = quant->mc_count;
quant->mc_colors = orig_colors;
}
else {
colors_paletted = 0;
- quant_makemap(quant, imgs, 1);
+ i_quant_makemap(quant, imgs, 1);
}
}
if ((map = make_gif_map(quant, imgs[0], want_trans)) == NULL) {
}
else {
colors_paletted = 0;
- quant_makemap(quant, imgs, 1);
+ i_quant_makemap(quant, imgs, 1);
}
if ((map = make_gif_map(quant, imgs[0], want_trans)) == NULL) {
i_mempool_destroy(&mp);
if (colors_paletted)
result = quant_paletted(quant, imgs[0]);
else
- result = quant_translate(quant, imgs[0]);
+ result = i_quant_translate(quant, imgs[0]);
if (!result) {
i_mempool_destroy(&mp);
quant->mc_colors = orig_colors;
return 0;
}
if (want_trans) {
- quant_transparent(quant, result, imgs[0], quant->mc_count);
+ i_quant_transparent(quant, result, imgs[0], quant->mc_count);
trans_index = quant->mc_count;
}
result = quant_paletted(quant, imgs[imgn]);
}
else {
- quant_makemap(quant, imgs+imgn, 1);
- result = quant_translate(quant, imgs[imgn]);
+ i_quant_makemap(quant, imgs+imgn, 1);
+ result = i_quant_translate(quant, imgs[imgn]);
}
if (!result) {
i_mempool_destroy(&mp);
quant->mc_colors = orig_colors;
EGifCloseFile(gf);
- mm_log((1, "error in quant_translate()"));
+ mm_log((1, "error in i_quant_translate()"));
return 0;
}
if (want_trans) {
- quant_transparent(quant, result, imgs[imgn], quant->mc_count);
+ i_quant_transparent(quant, result, imgs[imgn], quant->mc_count);
trans_index = quant->mc_count;
}
if (glob_paletted)
result = quant_paletted(quant, imgs[imgn]);
else
- result = quant_translate(quant, imgs[imgn]);
+ result = i_quant_translate(quant, imgs[imgn]);
want_trans = glob_want_trans && imgs[imgn]->channels == 4;
if (want_trans) {
- quant_transparent(quant, result, imgs[imgn], quant->mc_count);
+ i_quant_transparent(quant, result, imgs[imgn], quant->mc_count);
trans_index = quant->mc_count;
}
map = NULL;
-#include "imagei.h"
+#include "imageri.h"
#include <stdlib.h>
#define OVERLAPPED(start1, end1, start2, end2) \
-#include "image.h"
-#include "imagei.h"
+#include "imager.h"
+#include "imageri.h"
/*
=head1 NAME
/*
=item IIM_new(x, y, ch)
-Creates a new image object I<x> pixels wide, and I<y> pixels high with I<ch> channels.
+=item i_img_8_new(x, y, ch)
+
+=category Image creation
+
+Creates a new image object I<x> pixels wide, and I<y> pixels high with
+I<ch> channels.
=cut
*/
/* myfree(cl); */
}
-
-
/*
=item i_img_new()
/*
=item i_img_destroy(im)
+=category Image
+
Destroy image and free data via exorcise.
im - Image pointer
/*
=item i_img_info(im, info)
+=category Image
+
Return image information
im - Image pointer
/*
=item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
+=category Image
+
(x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
(tx,ty) specifies the upper left corner for the target image.
pass NULL in trans for non transparent i_colors.
/*
=item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
+=category Image
+
Copies image data from the area (x1,y1)-[x2,y2] in the source image to
a rectangle the same size with it's top-left corner at (tx,ty) in the
destination image.
if (x2<x1) { t=x1; x1=x2; x2=t; }
if (y2<y1) { t=y1; y1=y2; y2=t; }
-
+ if (tx < 0) {
+ /* adjust everything equally */
+ x1 += -tx;
+ x2 += -tx;
+ tx = 0;
+ }
+ if (ty < 0) {
+ y1 += -ty;
+ y2 += -ty;
+ ty = 0;
+ }
+ if (x1 >= src->xsize || y1 >= src->ysize)
+ return; /* nothing to do */
+ if (x2 > src->xsize)
+ x2 = src->xsize;
+ if (y2 > src->ysize)
+ y2 = src->ysize;
+ if (x1 == x2 || y1 == y2)
+ return; /* nothing to do */
+
mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
im, src, x1, y1, x2, y2, tx, ty));
if (im->bits == i_8_bits) {
- i_color pv;
+ i_color *row = mymalloc(sizeof(i_color) * (x2-x1));
tty = ty;
for(y=y1; y<y2; y++) {
ttx = tx;
- for(x=x1; x<x2; x++) {
- i_gpix(src, x, y, &pv);
- i_ppix(im, ttx, tty, &pv);
- ttx++;
- }
+ i_glin(src, x1, x2, y, row);
+ i_plin(im, tx, tx+x2-x1, tty, row);
tty++;
}
+ myfree(row);
}
else {
i_fcolor pv;
}
/*
-=item i_copy(im, src)
+=item i_copy(src)
+
+=category Image
+
+Creates a new image that is a copy of src.
+
+Tags are not copied, only the image data.
-Copies the contents of the image I<src> over the image I<im>.
+Returns: i_img *
=cut
*/
-void
-i_copy(i_img *im, i_img *src) {
+i_img *
+i_copy(i_img *src) {
int y, y1, x1;
+ i_img *im = i_sametype(src, src->xsize, src->ysize);
+
+ mm_log((1,"i_copy(src %p)\n", src));
- mm_log((1,"i_copy(im* %p,src %p)\n", im, src));
+ if (!im)
+ return NULL;
x1 = src->xsize;
y1 = src->ysize;
if (src->type == i_direct_type) {
if (src->bits == i_8_bits) {
i_color *pv;
- i_img_empty_ch(im, x1, y1, src->channels);
pv = mymalloc(sizeof(i_color) * x1);
for (y = 0; y < y1; ++y) {
}
else {
i_fcolor *pv;
- if (src->bits == i_16_bits)
- i_img_16_new_low(im, x1, y1, src->channels);
- else if (src->bits == i_double_bits)
- i_img_double_new_low(im, x1, y1, src->channels);
- else {
- fprintf(stderr, "i_copy(): Unknown image bit size %d\n", src->bits);
- return; /* I dunno */
- }
pv = mymalloc(sizeof(i_fcolor) * x1);
for (y = 0; y < y1; ++y) {
}
myfree(vals);
}
+
+ return im;
}
/*
=item i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy )
+=category Image
+
Takes the sub image I<src[src_minx, src_maxx)[src_miny, src_maxy)> and
overlays it at (I<tx>,I<ty>) on the image object.
/*
=item i_sametype(i_img *im, int xsize, int ysize)
+=category Image creation
+
Returns an image of the same type (sample size, channels, paletted/direct).
For paletted images the palette is copied from the source.
/*
=item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
+=category Image creation
+
Returns an image of the same type (sample size).
For paletted images the equivalent direct type is returned.
+++ /dev/null
-#ifndef _IMAGE_H_
-#define _IMAGE_H_
-
-#include "imconfig.h"
-#include "imio.h"
-#include "iolayer.h"
-#include "log.h"
-#include "stackmach.h"
-
-
-#ifndef _MSC_VER
-#include <unistd.h>
-#endif
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include <stdlib.h>
-
-#ifdef SUNOS
-#include <strings.h>
-#endif
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-#ifndef MAXINT
-#define MAXINT 2147483647
-#endif
-
-#include "datatypes.h"
-
-undef_int i_has_format(char *frmt);
-
-/* constructors and destructors */
-
-i_color *ICL_new_internal( unsigned char r,unsigned char g,unsigned char b,unsigned char a);
-i_color *ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a);
-void ICL_info (i_color *cl);
-void ICL_DESTROY (i_color *cl);
-void ICL_add (i_color *dst, i_color *src, int ch);
-
-extern i_fcolor *i_fcolor_new(double r, double g, double b, double a);
-extern void i_fcolor_destroy(i_fcolor *cl);
-
-extern void i_rgb_to_hsvf(i_fcolor *color);
-extern void i_hsv_to_rgbf(i_fcolor *color);
-extern void i_rgb_to_hsv(i_color *color);
-extern void i_hsv_to_rgb(i_color *color);
-
-i_img *IIM_new(int x,int y,int ch);
-void IIM_DESTROY(i_img *im);
-i_img *i_img_new( void );
-i_img *i_img_empty(i_img *im,int x,int y);
-i_img *i_img_empty_ch(i_img *im,int x,int y,int ch);
-void i_img_exorcise(i_img *im);
-void i_img_destroy(i_img *im);
-
-void i_img_info(i_img *im,int *info);
-
-extern i_img *i_sametype(i_img *im, int xsize, int ysize);
-extern i_img *i_sametype_chans(i_img *im, int xsize, int ysize, int channels);
-
-i_img *i_img_pal_new(int x, int y, int ch, int maxpal);
-
-/* Image feature settings */
-
-void i_img_setmask (i_img *im,int ch_mask);
-int i_img_getmask (i_img *im);
-int i_img_getchannels(i_img *im);
-
-/* Base functions */
-
-#if 0
-int i_ppix(i_img *im,int x,int y,i_color *val);
-int i_gpix(i_img *im,int x,int y,i_color *val);
-int i_ppixf(i_img *im,int x,int y,i_color *val);
-int i_gpixf(i_img *im,int x,int y,i_color *val);
-#endif
-
-#define i_ppix(im, x, y, val) (((im)->i_f_ppix)((im), (x), (y), (val)))
-#define i_gpix(im, x, y, val) (((im)->i_f_gpix)((im), (x), (y), (val)))
-#define i_ppixf(im, x, y, val) (((im)->i_f_ppixf)((im), (x), (y), (val)))
-#define i_gpixf(im, x, y, val) (((im)->i_f_gpixf)((im), (x), (y), (val)))
-
-#if 0
-int i_ppix_d(i_img *im,int x,int y,i_color *val);
-int i_gpix_d(i_img *im,int x,int y,i_color *val);
-int i_plin_d(i_img *im,int l, int r, int y, i_color *val);
-int i_glin_d(i_img *im,int l, int r, int y, i_color *val);
-#endif
-
-#define i_plin(im, l, r, y, val) (((im)->i_f_plin)(im, l, r, y, val))
-#define i_glin(im, l, r, y, val) (((im)->i_f_glin)(im, l, r, y, val))
-#define i_plinf(im, l, r, y, val) (((im)->i_f_plinf)(im, l, r, y, val))
-#define i_glinf(im, l, r, y, val) (((im)->i_f_glinf)(im, l, r, y, val))
-
-#define i_gsamp(im, l, r, y, samps, chans, count) \
- (((im)->i_f_gsamp)((im), (l), (r), (y), (samps), (chans), (count)))
-#define i_gsampf(im, l, r, y, samps, chans, count) \
- (((im)->i_f_gsampf)((im), (l), (r), (y), (samps), (chans), (count)))
-
-#define i_psamp(im, l, r, y, samps, chans, count) \
- (((im)->i_f_gsamp)((im), (l), (r), (y), (samps), (chans), (count)))
-#define i_psampf(im, l, r, y, samps, chans, count) \
- (((im)->i_f_gsampf)((im), (l), (r), (y), (samps), (chans), (count)))
-
-
-
-
-#define i_findcolor(im, color, entry) \
- (((im)->i_f_findcolor) ? ((im)->i_f_findcolor)((im), (color), (entry)) : 0)
-
-#define i_gpal(im, l, r, y, vals) \
- (((im)->i_f_gpal) ? ((im)->i_f_gpal)((im), (l), (r), (y), (vals)) : 0)
-#define i_ppal(im, l, r, y, vals) \
- (((im)->i_f_ppal) ? ((im)->i_f_ppal)((im), (l), (r), (y), (vals)) : 0)
-#define i_addcolors(im, colors, count) \
- (((im)->i_f_addcolors) ? ((im)->i_f_addcolors)((im), (colors), (count)) : -1)
-#define i_getcolors(im, index, color, count) \
- (((im)->i_f_getcolors) ? \
- ((im)->i_f_getcolors)((im), (index), (color), (count)) : 0)
-#define i_setcolors(im, index, color, count) \
- (((im)->i_f_setcolors) ? \
- ((im)->i_f_setcolors)((im), (index), (color), (count)) : 0)
-#define i_colorcount(im) \
- (((im)->i_f_colorcount) ? ((im)->i_f_colorcount)(im) : -1)
-#define i_maxcolors(im) \
- (((im)->i_f_maxcolors) ? ((im)->i_f_maxcolors)(im) : -1)
-#define i_findcolor(im, color, entry) \
- (((im)->i_f_findcolor) ? ((im)->i_f_findcolor)((im), (color), (entry)) : 0)
-
-#define i_img_virtual(im) ((im)->virtual)
-#define i_img_type(im) ((im)->type)
-#define i_img_bits(im) ((im)->bits)
-
-/* Generic fills */
-struct i_fill_tag;
-
-typedef void (*i_fill_with_color_f)
- (struct i_fill_tag *fill, int x, int y, int width, int channels,
- i_color *data);
-typedef void (*i_fill_with_fcolor_f)
- (struct i_fill_tag *fill, int x, int y, int width, int channels,
- i_fcolor *data);
-typedef void (*i_fill_destroy_f)(struct i_fill_tag *fill);
-typedef void (*i_fill_combine_f)(i_color *out, i_color *in, int channels,
- int count);
-typedef void (*i_fill_combinef_f)(i_fcolor *out, i_fcolor *in, int channels,
- int count);
-
-
-typedef struct i_fill_tag
-{
- /* called for 8-bit/sample image (and maybe lower) */
- /* this may be NULL, if so call fill_with_fcolor */
- i_fill_with_color_f fill_with_color;
-
- /* called for other sample sizes */
- /* this must be non-NULL */
- i_fill_with_fcolor_f fill_with_fcolor;
-
- /* called if non-NULL to release any extra resources */
- i_fill_destroy_f destroy;
-
- /* if non-zero the caller will fill data with the original data
- from the image */
- i_fill_combine_f combine;
- i_fill_combinef_f combinef;
-} i_fill_t;
-
-typedef enum {
- ic_none,
- ic_normal,
- ic_multiply,
- ic_dissolve,
- ic_add,
- ic_subtract,
- ic_diff,
- ic_lighten,
- ic_darken,
- ic_hue,
- ic_sat,
- ic_value,
- ic_color
-} i_combine_t;
-
-extern i_fill_t *i_new_fill_solidf(i_fcolor *c, int combine);
-extern i_fill_t *i_new_fill_solid(i_color *c, int combine);
-extern i_fill_t *
-i_new_fill_hatch(i_color *fg, i_color *bg, int combine, int hatch,
- unsigned char *cust_hatch, int dx, int dy);
-extern i_fill_t *
-i_new_fill_hatchf(i_fcolor *fg, i_fcolor *bg, int combine, int hatch,
- unsigned char *cust_hatch, int dx, int dy);
-extern i_fill_t *
-i_new_fill_image(i_img *im, double *matrix, int xoff, int yoff, int combine);
-extern void i_fill_destroy(i_fill_t *fill);
-
-float i_gpix_pch(i_img *im,int x,int y,int ch);
-
-/* functions for drawing primitives */
-
-void i_box (i_img *im,int x1,int y1,int x2,int y2,i_color *val);
-void i_box_filled (i_img *im,int x1,int y1,int x2,int y2,i_color *val);
-void i_box_cfill(i_img *im, int x1, int y1, int x2, int y2, i_fill_t *fill);
-void i_line (i_img *im,int x1,int y1,int x2,int y2,i_color *val, int endp);
-void i_line_aa (i_img *im,int x1,int y1,int x2,int y2,i_color *val, int endp);
-void i_arc (i_img *im,int x,int y,float rad,float d1,float d2,i_color *val);
-void i_arc_aa (i_img *im, double x, double y, double rad, double d1, double d2,i_color *val);
-void i_arc_cfill(i_img *im,int x,int y,float rad,float d1,float d2,i_fill_t *fill);
-void i_arc_aa_cfill(i_img *im,double x,double y,double rad,double d1,double d2,i_fill_t *fill);
-void i_circle_aa (i_img *im,float x, float y,float rad,i_color *val);
-void i_copyto (i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty);
-void i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,i_color *trans);
-void i_copy (i_img *im,i_img *src);
-int i_rubthru (i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny, int src_maxx, int src_maxy);
-
-
-undef_int i_flipxy (i_img *im, int direction);
-extern i_img *i_rotate90(i_img *im, int degrees);
-extern i_img *i_rotate_exact(i_img *im, double amount);
-extern i_img *i_rotate_exact_bg(i_img *im, double amount, i_color *backp, i_fcolor *fbackp);
-extern i_img *i_matrix_transform(i_img *im, int xsize, int ysize, double *matrix);
-extern i_img *i_matrix_transform_bg(i_img *im, int xsize, int ysize, double *matrix, i_color *backp, i_fcolor *fbackp);
-
-void i_bezier_multi(i_img *im,int l,double *x,double *y,i_color *val);
-void i_poly_aa (i_img *im,int l,double *x,double *y,i_color *val);
-void i_poly_aa_cfill(i_img *im,int l,double *x,double *y,i_fill_t *fill);
-
-undef_int i_flood_fill (i_img *im,int seedx,int seedy,i_color *dcol);
-undef_int i_flood_cfill(i_img *im, int seedx, int seedy, i_fill_t *fill);
-
-
-/* image processing functions */
-
-void i_gaussian (i_img *im,float stdev);
-void i_conv (i_img *im,float *coeff,int len);
-void i_unsharp_mask(i_img *im, double stddev, double scale);
-
-/* colour manipulation */
-extern int i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan);
-extern void i_map(i_img *im, unsigned char (*maps)[256], unsigned int mask);
-
-float i_img_diff (i_img *im1,i_img *im2);
-
-/* font routines */
-
-undef_int i_init_fonts( int t1log );
-
-/*
- describes an axis of a MM font.
- Modelled on FT2's FT_MM_Axis.
- It would be nice to have a default entry too, but FT2
- doesn't support it.
-*/
-typedef struct i_font_mm_axis_tag {
- char const *name;
- int minimum;
- int maximum;
-} i_font_mm_axis;
-
-#define IM_FONT_MM_MAX_AXES 4
-
-/*
- multiple master information for a font, if any
- modelled on FT2's FT_Multi_Master.
-*/
-typedef struct i_font_mm_tag {
- int num_axis;
- int num_designs; /* provided but not necessarily useful */
- i_font_mm_axis axis[IM_FONT_MM_MAX_AXES];
-} i_font_mm;
-
-#ifdef HAVE_LIBT1
-
-undef_int i_init_t1( int t1log );
-int i_t1_new( char *pfb, char *afm );
-int i_t1_destroy( int font_id );
-undef_int i_t1_cp( i_img *im, int xb, int yb, int channel, int fontnum, float points, char* str, int len, int align, int utf8, char const *flags );
-undef_int i_t1_text( i_img *im, int xb, int yb, i_color *cl, int fontnum, float points, char* str, int len, int align, int utf8, char const *flags );
-int i_t1_bbox( int fontnum, float point, char *str, int len, int cords[6], int utf8, char const *flags );
-void i_t1_set_aa( int st );
-void close_t1( void );
-int i_t1_has_chars(int font_num, char const *text, int len, int utf8, char *out);
-extern int i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size);
-extern int i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf,
- size_t name_buf_size);
-#endif
-
-#ifdef HAVE_LIBTT
-
-struct TT_Fonthandle_;
-
-typedef struct TT_Fonthandle_ TT_Fonthandle;
-
-undef_int i_init_tt( void );
-TT_Fonthandle* i_tt_new(char *fontname);
-void i_tt_destroy( TT_Fonthandle *handle );
-undef_int i_tt_cp( TT_Fonthandle *handle,i_img *im,int xb,int yb,int channel,float points,char const* txt,int len,int smooth, int utf8, int align);
-undef_int i_tt_text( TT_Fonthandle *handle, i_img *im, int xb, int yb, i_color *cl, float points, char const* txt, int len, int smooth, int utf8, int align);
-undef_int i_tt_bbox( TT_Fonthandle *handle, float points,char *txt,int len,int cords[6], int utf8);
-int i_tt_has_chars(TT_Fonthandle *handle, char const *text, int len, int utf8, char *out);
-void i_tt_dump_names(TT_Fonthandle *handle);
-int i_tt_face_name(TT_Fonthandle *handle, char *name_buf,
- size_t name_buf_size);
-int i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf,
- size_t name_buf_size);
-
-#endif /* End of freetype headers */
-
-#ifdef HAVE_FT2
-
-typedef struct FT2_Fonthandle FT2_Fonthandle;
-extern int i_ft2_init(void);
-extern FT2_Fonthandle * i_ft2_new(char *name, int index);
-extern void i_ft2_destroy(FT2_Fonthandle *handle);
-extern int i_ft2_setdpi(FT2_Fonthandle *handle, int xdpi, int ydpi);
-extern int i_ft2_getdpi(FT2_Fonthandle *handle, int *xdpi, int *ydpi);
-extern int i_ft2_settransform(FT2_Fonthandle *handle, double *matrix);
-extern int i_ft2_sethinting(FT2_Fonthandle *handle, int hinting);
-extern int i_ft2_bbox(FT2_Fonthandle *handle, double cheight, double cwidth,
- char const *text, int len, int *bbox, int utf8);
-extern int i_ft2_bbox_r(FT2_Fonthandle *handle, double cheight, double cwidth,
- char const *text, int len, int vlayout, int utf8, int *bbox);
-extern int i_ft2_text(FT2_Fonthandle *handle, i_img *im, int tx, int ty,
- i_color *cl, double cheight, double cwidth,
- char const *text, int len, int align, int aa,
- int vlayout, int utf8);
-extern int i_ft2_cp(FT2_Fonthandle *handle, i_img *im, int tx, int ty,
- int channel, double cheight, double cwidth,
- char const *text, int len, int align, int aa, int vlayout,
- int utf8);
-extern int i_ft2_has_chars(FT2_Fonthandle *handle, char const *text, int len,
- int utf8, char *work);
-extern int i_ft2_face_name(FT2_Fonthandle *handle, char *name_buf,
- size_t name_buf_size);
-extern int i_ft2_can_face_name(void);
-extern int i_ft2_glyph_name(FT2_Fonthandle *handle, unsigned long ch,
- char *name_buf, size_t name_buf_size,
- int reliable_only);
-extern int i_ft2_can_do_glyph_names(void);
-extern int i_ft2_face_has_glyph_names(FT2_Fonthandle *handle);
-
-extern int i_ft2_get_multiple_masters(FT2_Fonthandle *handle,
- i_font_mm *mm);
-extern int
-i_ft2_is_multiple_master(FT2_Fonthandle *handle);
-extern int
-i_ft2_set_mm_coords(FT2_Fonthandle *handle, int coord_count, long *coords);
-#endif
-
-#ifdef WIN32
-
-extern int i_wf_bbox(char *face, int size, char *text, int length, int *bbox);
-extern int i_wf_text(char *face, i_img *im, int tx, int ty, i_color *cl,
- int size, char *text, int len, int align, int aa);
-extern int i_wf_cp(char *face, i_img *im, int tx, int ty, int channel,
- int size, char *text, int len, int align, int aa);
-extern int i_wf_addfont(char const *file);
-
-#endif
-
-/* functions for reading and writing formats */
-
-/* general reader callback
- userdata - data the user passed into the reader
- buffer - the buffer to fill with data
- need - the amount of data needed
- want - the amount of space we have to store data
- fill buffer and return the number of bytes read, 0 for eof, -1 for error
-*/
-
-typedef int (*i_read_callback_t)(char *userdata, char *buffer, int need,
- int want);
-
-/* i_gen_reader() translates the low-level requests from whatever library
- into buffered requests.
- but the called function can always bypass buffering by only ever
- reading I<need> bytes.
-*/
-#define CBBUFSIZ 4096
-
-typedef struct {
- i_read_callback_t cb;
- char *userdata;
- char buffer[CBBUFSIZ];
- int length;
- int cpos;
-} i_gen_read_data;
-
-extern int i_gen_reader(i_gen_read_data *info, char *buffer, int need);
-extern i_gen_read_data *i_gen_read_data_new(i_read_callback_t cb, char *userdata);
-extern void i_free_gen_read_data(i_gen_read_data *);
-
-/* general writer callback
- userdata - the data the user passed into the writer
- data - the data to write
- data_size - the number of bytes to write
- write the data, return non-zero on success, zero on failure.
-*/
-typedef int (*i_write_callback_t)(char *userdata, char const *data, int size);
-
-typedef struct {
- i_write_callback_t cb;
- char *userdata;
- char buffer[CBBUFSIZ];
- int maxlength;
- int filledto;
-} i_gen_write_data;
-
-extern int i_gen_writer(i_gen_write_data *info, char const *data, int size);
-extern i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb, char *userdata, int maxlength);
-extern int i_free_gen_write_data(i_gen_write_data *, int flush);
-
-/* transparency handling for quantized output */
-typedef enum i_transp_tag {
- tr_none, /* ignore any alpha channel */
- tr_threshold, /* threshold the transparency - uses tr_threshold */
- tr_errdiff, /* error diffusion */
- tr_ordered /* an ordered dither */
-} i_transp;
-
-/* controls how we build the colour map */
-typedef enum i_make_colors_tag {
- mc_none, /* user supplied colour map only */
- mc_web_map, /* Use the 216 colour web colour map */
- mc_addi, /* Addi's algorithm */
- mc_median_cut, /* median cut - similar to giflib, hopefully */
- mc_mask = 0xFF /* (mask for generator) */
-} i_make_colors;
-
-/* controls how we translate the colours */
-typedef enum i_translate_tag {
- pt_giflib, /* get gif lib to do it (ignores make_colours) */
- pt_closest, /* just use the closest match within the hashbox */
- pt_perturb, /* randomly perturb the data - uses perturb_size*/
- pt_errdiff /* error diffusion dither - uses errdiff */
-} i_translate;
-
-/* Which error diffusion map to use */
-typedef enum i_errdiff_tag {
- ed_floyd, /* floyd-steinberg */
- ed_jarvis, /* Jarvis, Judice and Ninke */
- ed_stucki, /* Stucki */
- ed_custom, /* the map found in ed_map|width|height|orig */
- ed_mask = 0xFF, /* mask to get the map */
- ed_bidir = 0x100 /* change direction for each row */
-} i_errdiff;
-
-/* which ordered dither map to use
- currently only available for transparency
- I don't know of a way to do ordered dither of an image against some
- general palette
- */
-typedef enum i_ord_dith_tag
-{
- od_random, /* sort of random */
- od_dot8, /* large dot */
- od_dot4,
- od_hline,
- od_vline,
- od_slashline, /* / line dither */
- od_backline, /* \ line dither */
- od_tiny, /* small checkerbox */
- od_custom /* custom 8x8 map */
-} i_ord_dith;
-
-typedef struct i_gif_pos_tag {
- int x, y;
-} i_gif_pos;
-
-/* passed into i_writegif_gen() to control quantization */
-typedef struct i_quantize_tag {
- /* how to handle transparency */
- i_transp transp;
- /* the threshold at which to make pixels opaque */
- int tr_threshold;
- i_errdiff tr_errdiff;
- i_ord_dith tr_orddith;
- unsigned char tr_custom[64];
-
- /* how to make the colour map */
- i_make_colors make_colors;
-
- /* any existing colours
- mc_existing is an existing colour table
- mc_count is the number of existing colours
- mc_size is the total size of the array that mc_existing points
- at - this must be at least 256
- */
- i_color *mc_colors;
- int mc_size;
- int mc_count;
-
- /* how we translate the colours */
- i_translate translate;
-
- /* the error diffusion map to use if translate is mc_errdiff */
- i_errdiff errdiff;
- /* the following define the error diffusion values to use if
- errdiff is ed_custom. ed_orig is the column on the top row that
- represents the current
- */
- int *ed_map;
- int ed_width, ed_height, ed_orig;
-
- /* the amount of perturbation to use for translate is mc_perturb */
- int perturb;
-} i_quantize;
-
-typedef struct i_gif_opts {
- /* each image has a local color map */
- int each_palette;
-
- /* images are interlaced */
- int interlace;
-
- /* time for which image is displayed
- (in 1/100 seconds)
- default: 0
- */
- int delay_count;
- int *delays;
-
- /* user input flags
- default: 0
- */
- int user_input_count;
- char *user_input_flags;
-
- /* disposal
- default: 0 */
- int disposal_count;
- char *disposal;
-
- /* this is added to the color table when we make an image transparent */
- i_color tran_color;
-
- /* image positions */
- int position_count;
- i_gif_pos *positions;
-
- /* Netscape loop extension - number of loops */
- int loop_count;
-
- /* should be eliminate unused colors? */
- int eliminate_unused;
-} i_gif_opts;
-
-extern void quant_makemap(i_quantize *quant, i_img **imgs, int count);
-extern i_palidx *quant_translate(i_quantize *quant, i_img *img);
-extern void quant_transparent(i_quantize *quant, i_palidx *indices, i_img *img, i_palidx trans_index);
-
-extern i_img *i_img_pal_new(int x, int y, int channels, int maxpal);
-extern i_img *i_img_pal_new_low(i_img *im, int x, int y, int channels, int maxpal);
-extern i_img *i_img_to_pal(i_img *src, i_quantize *quant);
-extern i_img *i_img_to_rgb(i_img *src);
-extern i_img *i_img_masked_new(i_img *targ, i_img *mask, int x, int y,
- int w, int h);
-extern i_img *i_img_16_new(int x, int y, int ch);
-extern i_img *i_img_16_new_low(i_img *im, int x, int y, int ch);
-extern i_img *i_img_double_new(int x, int y, int ch);
-extern i_img *i_img_double_new_low(i_img *im, int x, int y, int ch);
-
-
-char * i_test_format_probe(io_glue *data, int length);
-
-
-#ifdef HAVE_LIBJPEG
-i_img *
-i_readjpeg_wiol(io_glue *ig, int length, char** iptc_itext, int *itlength);
-undef_int i_writejpeg_wiol(i_img *im, io_glue *ig, int qfactor);
-#endif /* HAVE_LIBJPEG */
-
-#ifdef HAVE_LIBTIFF
-i_img * i_readtiff_wiol(io_glue *ig, int length, int page);
-i_img ** i_readtiff_multi_wiol(io_glue *ig, int length, int *count);
-undef_int i_writetiff_wiol(i_img *im, io_glue *ig);
-undef_int i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count);
-undef_int i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine);
-undef_int i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine);
-
-#endif /* HAVE_LIBTIFF */
-
-#ifdef HAVE_LIBPNG
-i_img *i_readpng_wiol(io_glue *ig, int length);
-undef_int i_writepng_wiol(i_img *im, io_glue *ig);
-#endif /* HAVE_LIBPNG */
-
-#ifdef HAVE_LIBGIF
-i_img *i_readgif(int fd, int **colour_table, int *colours);
-i_img *i_readgif_wiol(io_glue *ig, int **colour_table, int *colours);
-i_img *i_readgif_scalar(char *data, int length, int **colour_table, int *colours);
-i_img *i_readgif_callback(i_read_callback_t callback, char *userdata, int **colour_table, int *colours);
-i_img *i_readgif_single_wiol(io_glue *ig, int page);
-extern i_img **i_readgif_multi(int fd, int *count);
-extern i_img **i_readgif_multi_scalar(char *data, int length, int *count);
-extern i_img **i_readgif_multi_callback(i_read_callback_t callback, char *userdata, int *count);
-extern i_img **i_readgif_multi_wiol(io_glue *ig, int *count);
-undef_int i_writegif(i_img *im,int fd,int colors,int pixdev,int fixedlen,i_color fixed[]);
-undef_int i_writegifmc(i_img *im,int fd,int colors);
-undef_int i_writegifex(i_img *im,int fd);
-undef_int i_writegif_gen(i_quantize *quant, int fd, i_img **imgs, int count);
-undef_int i_writegif_callback(i_quantize *quant, i_write_callback_t cb, char *userdata, int maxbuffer, i_img **imgs, int count);
-undef_int i_writegif_wiol(io_glue *ig, i_quantize *quant,
- i_img **imgs, int count);
-void i_qdist(i_img *im);
-
-#endif /* HAVE_LIBGIF */
-
-i_img * i_readraw_wiol(io_glue *ig, int x, int y, int datachannels, int storechannels, int intrl);
-undef_int i_writeraw_wiol(i_img* im, io_glue *ig);
-
-i_img * i_readpnm_wiol(io_glue *ig, int length);
-undef_int i_writeppm_wiol(i_img *im, io_glue *ig);
-
-extern int i_writebmp_wiol(i_img *im, io_glue *ig);
-extern i_img *i_readbmp_wiol(io_glue *ig);
-
-int tga_header_verify(unsigned char headbuf[18]);
-
-i_img * i_readtga_wiol(io_glue *ig, int length);
-undef_int i_writetga_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idstring, size_t idlen);
-
-i_img * i_readrgb_wiol(io_glue *ig, int length);
-undef_int i_writergb_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idstring, size_t idlen);
-
-i_img * i_scaleaxis(i_img *im, float Value, int Axis);
-i_img * i_scale_nn(i_img *im, float scx, float scy);
-i_img * i_haar(i_img *im);
-int i_count_colors(i_img *im,int maxc);
-
-i_img * i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen);
-
-struct rm_op;
-i_img * i_transform2(int width, int height, int channels,
- struct rm_op *ops, int ops_count,
- double *n_regs, int n_regs_count,
- i_color *c_regs, int c_regs_count,
- i_img **in_imgs, int in_imgs_count);
-
-/* filters */
-
-void i_contrast(i_img *im, float intensity);
-void i_hardinvert(i_img *im);
-void i_noise(i_img *im, float amount, unsigned char type);
-void i_bumpmap(i_img *im,i_img *bump,int channel,int light_x,int light_y,int strength);
-void i_bumpmap_complex(i_img *im, i_img *bump, int channel, int tx, int ty, float Lx, float Ly,
- float Lz, float cd, float cs, float n, i_color *Ia, i_color *Il, i_color *Is);
-void i_postlevels(i_img *im,int levels);
-void i_mosaic(i_img *im,int size);
-void i_watermark(i_img *im,i_img *wmark,int tx,int ty,int pixdiff);
-void i_autolevels(i_img *im,float lsat,float usat,float skew);
-void i_radnoise(i_img *im,int xo,int yo,float rscale,float ascale);
-void i_turbnoise(i_img *im,float xo,float yo,float scale);
-void i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
-void i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
-i_img *i_diff_image(i_img *im, i_img *im2, int mindist);
-typedef enum {
- i_fst_linear,
- i_fst_curved,
- i_fst_sine,
- i_fst_sphere_up,
- i_fst_sphere_down,
- i_fst_end
-} i_fountain_seg_type;
-typedef enum {
- i_fc_direct,
- i_fc_hue_up,
- i_fc_hue_down,
- i_fc_end
-} i_fountain_color;
-typedef struct {
- double start, middle, end;
- i_fcolor c[2];
- i_fountain_seg_type type;
- i_fountain_color color;
-} i_fountain_seg;
-typedef enum {
- i_fr_none,
- i_fr_sawtooth,
- i_fr_triangle,
- i_fr_saw_both,
- i_fr_tri_both
-} i_fountain_repeat;
-typedef enum {
- i_ft_linear,
- i_ft_bilinear,
- i_ft_radial,
- i_ft_radial_square,
- i_ft_revolution,
- i_ft_conical,
- i_ft_end
-} i_fountain_type;
-typedef enum {
- i_fts_none,
- i_fts_grid,
- i_fts_random,
- i_fts_circle
-} i_ft_supersample;
-void i_fountain(i_img *im, double xa, double ya, double xb, double yb,
- i_fountain_type type, i_fountain_repeat repeat,
- int combine, int super_sample, double ssample_param,
- int count, i_fountain_seg *segs);
-extern i_fill_t *
-i_new_fill_fount(double xa, double ya, double xb, double yb,
- i_fountain_type type, i_fountain_repeat repeat,
- int combine, int super_sample, double ssample_param,
- int count, i_fountain_seg *segs);
-
-/* Debug only functions */
-
-void malloc_state( void );
-
-/* this is sort of obsolete now */
-
-typedef struct {
- undef_int (*i_has_format)(char *frmt);
- i_color*(*ICL_set)(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a);
- void (*ICL_info)(i_color *cl);
-
- i_img*(*i_img_new)( void );
- i_img*(*i_img_empty)(i_img *im,int x,int y);
- i_img*(*i_img_empty_ch)(i_img *im,int x,int y,int ch);
- void(*i_img_exorcise)(i_img *im);
-
- void(*i_img_info)(i_img *im,int *info);
-
- void(*i_img_setmask)(i_img *im,int ch_mask);
- int (*i_img_getmask)(i_img *im);
-
- /*
- int (*i_ppix)(i_img *im,int x,int y,i_color *val);
- int (*i_gpix)(i_img *im,int x,int y,i_color *val);
- */
- void(*i_box)(i_img *im,int x1,int y1,int x2,int y2,i_color *val);
- void(*i_line)(i_img *im,int x1,int y1,int x2,int y2,i_color *val,int endp);
- void(*i_arc)(i_img *im,int x,int y,float rad,float d1,float d2,i_color *val);
- void(*i_copyto)(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty);
- void(*i_copyto_trans)(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,i_color *trans);
- int(*i_rubthru)(i_img *im,i_img *src,int tx,int ty);
-
-} symbol_table_t;
-
-/* error handling
- see error.c for documentation
- the error information is currently global
-*/
-typedef struct {
- char *msg;
- int code;
-} i_errmsg;
-
-typedef void (*i_error_cb)(int code, char const *msg);
-typedef void (*i_failed_cb)(i_errmsg *msgs);
-extern i_error_cb i_set_error_cb(i_error_cb);
-extern i_failed_cb i_set_failed_cb(i_failed_cb);
-extern void i_set_argv0(char const *);
-extern int i_set_errors_fatal(int new_fatal);
-extern i_errmsg *i_errors(void);
-
-extern void i_push_error(int code, char const *msg);
-extern void i_push_errorf(int code, char const *fmt, ...);
-extern void i_push_errorvf(int code, char const *fmt, va_list);
-extern void i_clear_error(void);
-extern int i_failed(int code, char const *msg);
-
-/* image tag processing */
-extern void i_tags_new(i_img_tags *tags);
-extern int i_tags_addn(i_img_tags *tags, char const *name, int code,
- int idata);
-extern int i_tags_add(i_img_tags *tags, char const *name, int code,
- char const *data, int size, int idata);
-extern void i_tags_destroy(i_img_tags *tags);
-extern int i_tags_find(i_img_tags *tags, char const *name, int start,
- int *entry);
-extern int i_tags_findn(i_img_tags *tags, int code, int start, int *entry);
-extern int i_tags_delete(i_img_tags *tags, int entry);
-extern int i_tags_delbyname(i_img_tags *tags, char const *name);
-extern int i_tags_delbycode(i_img_tags *tags, int code);
-extern int i_tags_get_float(i_img_tags *tags, char const *name, int code,
- double *value);
-extern int i_tags_set_float(i_img_tags *tags, char const *name, int code,
- double value);
-extern int i_tags_set_float2(i_img_tags *tags, char const *name, int code,
- double value, int places);
-extern int i_tags_get_int(i_img_tags *tags, char const *name, int code,
- int *value);
-extern int i_tags_get_string(i_img_tags *tags, char const *name, int code,
- char *value, size_t value_size);
-extern int i_tags_get_color(i_img_tags *tags, char const *name, int code,
- i_color *value);
-extern int i_tags_set_color(i_img_tags *tags, char const *name, int code,
- i_color const *value);
-extern void i_tags_print(i_img_tags *tags);
-
-/* image file limits */
-extern int
-i_set_image_file_limits(int width, int height, int bytes);
-extern int
-i_get_image_file_limits(int *width, int *height, int *bytes);
-
-#endif
+++ /dev/null
-/* Declares utility functions useful across various files which
- aren't meant to be available externally
-*/
-
-#ifndef IMAGEI_H_
-#define IMAGEI_H_
-
-#include "image.h"
-
-/* wrapper functions that implement the floating point sample version of a
- function in terms of the 8-bit sample version
-*/
-extern int i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix);
-extern int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix);
-extern int i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix);
-extern int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix);
-extern int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
- int const *chans, int chan_count);
-
-/* wrapper functions that forward palette calls to the underlying image,
- assuming the underlying image is the first pointer in whatever
- ext_data points at
-*/
-extern int i_addcolors_forward(i_img *im, i_color *, int count);
-extern int i_getcolors_forward(i_img *im, int i, i_color *, int count);
-extern int i_colorcount_forward(i_img *im);
-extern int i_maxcolors_forward(i_img *im);
-extern int i_findcolor_forward(i_img *im, i_color *color, i_palidx *entry);
-extern int i_setcolors_forward(i_img *im, int index, i_color *colors,
- int count);
-
-#define SampleFTo16(num) ((int)((num) * 65535.0 + 0.01))
-/* we add that little bit to avoid rounding issues */
-#define Sample16ToF(num) ((num) / 65535.0)
-
-#define SampleFTo8(num) ((int)((num) * 255.0 + 0.01))
-#define Sample8ToF(num) ((num) / 255.0)
-
-#define Sample16To8(num) ((num) / 257)
-#define Sample8To16(num) ((num) * 257)
-
-extern void i_get_combine(int combine, i_fill_combine_f *, i_fill_combinef_f *);
-
-extern int
-i_int_check_image_file_limits(int width, int height, int channels, int sample_size);
-
-#define im_min(a, b) ((a) < (b) ? (a) : (b))
-#define im_max(a, b) ((a) > (b) ? (a) : (b))
-
-#include "ext.h"
-
-extern UTIL_table_t i_UTIL_table;
-
-/* Ideally this will move into imconfig.h if we ever probe */
-#if defined(_GNU_SOURCE) || __STDC_VERSION__ >= 199901L
-/* snprintf() is part of C99 and provided by Glibc */
-#define HAVE_SNPRINTF
-#endif
-
-/* test if all channels are writable */
-#define I_ALL_CHANNELS_WRITABLE(im) (((im)->ch_mask & 0xF) == 0xf)
-
-typedef struct i_int_hline_seg_tag {
- int minx, x_limit;
-} i_int_hline_seg;
-
-typedef struct i_int_hline_entry_tag {
- int count;
- int alloc;
- i_int_hline_seg segs[1];
-} i_int_hline_entry;
-
-/* represents a set of horizontal line segments to be filled in later */
-typedef struct i_int_hlines_tag {
- int start_y, limit_y;
- int start_x, limit_x;
- i_int_hline_entry **entries;
-} i_int_hlines;
-
-extern void
-i_int_init_hlines(
- i_int_hlines *hlines,
- int start_y,
- int count_y,
- int start_x,
- int width_x
- );
-extern void i_int_init_hlines_img(i_int_hlines *hlines, i_img *img);
-extern void i_int_hlines_add(i_int_hlines *hlines, int y, int minx, int width);
-extern void i_int_hlines_destroy(i_int_hlines *hlines);
-
-extern void i_int_hlines_fill_color(i_img *im, i_int_hlines *hlines, i_color *val);
-extern void i_int_hlines_fill_fill(i_img *im, i_int_hlines *hlines, i_fill_t *fill);
-
-#endif
--- /dev/null
+#ifndef _IMAGE_H_
+#define _IMAGE_H_
+
+#include "imconfig.h"
+#include "imio.h"
+#include "iolayer.h"
+#include "log.h"
+#include "stackmach.h"
+
+
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+#ifdef SUNOS
+#include <strings.h>
+#endif
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+#ifndef MAXINT
+#define MAXINT 2147483647
+#endif
+
+#include "imdatatypes.h"
+
+undef_int i_has_format(char *frmt);
+
+/* constructors and destructors */
+
+i_color *ICL_new_internal( unsigned char r,unsigned char g,unsigned char b,unsigned char a);
+i_color *ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a);
+void ICL_info (i_color *cl);
+void ICL_DESTROY (i_color *cl);
+void ICL_add (i_color *dst, i_color *src, int ch);
+
+extern i_fcolor *i_fcolor_new(double r, double g, double b, double a);
+extern void i_fcolor_destroy(i_fcolor *cl);
+
+extern void i_rgb_to_hsvf(i_fcolor *color);
+extern void i_hsv_to_rgbf(i_fcolor *color);
+extern void i_rgb_to_hsv(i_color *color);
+extern void i_hsv_to_rgb(i_color *color);
+
+i_img *IIM_new(int x,int y,int ch);
+#define i_img_8_new IIM_new
+void IIM_DESTROY(i_img *im);
+i_img *i_img_new( void );
+i_img *i_img_empty(i_img *im,int x,int y);
+i_img *i_img_empty_ch(i_img *im,int x,int y,int ch);
+void i_img_exorcise(i_img *im);
+void i_img_destroy(i_img *im);
+
+void i_img_info(i_img *im,int *info);
+
+extern i_img *i_sametype(i_img *im, int xsize, int ysize);
+extern i_img *i_sametype_chans(i_img *im, int xsize, int ysize, int channels);
+
+i_img *i_img_pal_new(int x, int y, int ch, int maxpal);
+
+/* Image feature settings */
+
+void i_img_setmask (i_img *im,int ch_mask);
+int i_img_getmask (i_img *im);
+int i_img_getchannels(i_img *im);
+
+/* Base functions */
+
+extern int i_ppix(i_img *im,int x,int y,i_color *val);
+extern int i_gpix(i_img *im,int x,int y,i_color *val);
+extern int i_ppixf(i_img *im,int x,int y,i_fcolor *val);
+extern int i_gpixf(i_img *im,int x,int y,i_fcolor *val);
+
+#define i_ppix(im, x, y, val) (((im)->i_f_ppix)((im), (x), (y), (val)))
+#define i_gpix(im, x, y, val) (((im)->i_f_gpix)((im), (x), (y), (val)))
+#define i_ppixf(im, x, y, val) (((im)->i_f_ppixf)((im), (x), (y), (val)))
+#define i_gpixf(im, x, y, val) (((im)->i_f_gpixf)((im), (x), (y), (val)))
+
+extern int i_plin(i_img *im, int l, int r, int y, i_color *vals);
+extern int i_glin(i_img *im, int l, int r, int y, i_color *vals);
+extern int i_plinf(i_img *im, int l, int r, int y, i_fcolor *vals);
+extern int i_glinf(i_img *im, int l, int r, int y, i_fcolor *vals);
+extern int i_gsamp(i_img *im, int l, int r, int y, i_sample_t *samp,
+ const int *chans, int chan_count);
+extern int i_gsampf(i_img *im, int l, int r, int y, i_fsample_t *samp,
+ const int *chans, int chan_count);
+extern int i_gpal(i_img *im, int x, int r, int y, i_palidx *vals);
+extern int i_ppal(i_img *im, int x, int r, int y, i_palidx *vals);
+extern int i_addcolors(i_img *im, i_color *colors, int count);
+extern int i_getcolors(i_img *im, int i, i_color *, int count);
+extern int i_colorcount(i_img *im);
+extern int i_maxcolors(i_img *im);
+extern int i_findcolor(i_img *im, i_color *color, i_palidx *entry);
+extern int i_setcolors(i_img *im, int index, i_color *colors,
+ int count);
+
+#define i_plin(im, l, r, y, val) (((im)->i_f_plin)(im, l, r, y, val))
+#define i_glin(im, l, r, y, val) (((im)->i_f_glin)(im, l, r, y, val))
+#define i_plinf(im, l, r, y, val) (((im)->i_f_plinf)(im, l, r, y, val))
+#define i_glinf(im, l, r, y, val) (((im)->i_f_glinf)(im, l, r, y, val))
+
+#define i_gsamp(im, l, r, y, samps, chans, count) \
+ (((im)->i_f_gsamp)((im), (l), (r), (y), (samps), (chans), (count)))
+#define i_gsampf(im, l, r, y, samps, chans, count) \
+ (((im)->i_f_gsampf)((im), (l), (r), (y), (samps), (chans), (count)))
+
+#define i_findcolor(im, color, entry) \
+ (((im)->i_f_findcolor) ? ((im)->i_f_findcolor)((im), (color), (entry)) : 0)
+
+#define i_gpal(im, l, r, y, vals) \
+ (((im)->i_f_gpal) ? ((im)->i_f_gpal)((im), (l), (r), (y), (vals)) : 0)
+#define i_ppal(im, l, r, y, vals) \
+ (((im)->i_f_ppal) ? ((im)->i_f_ppal)((im), (l), (r), (y), (vals)) : 0)
+#define i_addcolors(im, colors, count) \
+ (((im)->i_f_addcolors) ? ((im)->i_f_addcolors)((im), (colors), (count)) : -1)
+#define i_getcolors(im, index, color, count) \
+ (((im)->i_f_getcolors) ? \
+ ((im)->i_f_getcolors)((im), (index), (color), (count)) : 0)
+#define i_setcolors(im, index, color, count) \
+ (((im)->i_f_setcolors) ? \
+ ((im)->i_f_setcolors)((im), (index), (color), (count)) : 0)
+#define i_colorcount(im) \
+ (((im)->i_f_colorcount) ? ((im)->i_f_colorcount)(im) : -1)
+#define i_maxcolors(im) \
+ (((im)->i_f_maxcolors) ? ((im)->i_f_maxcolors)(im) : -1)
+#define i_findcolor(im, color, entry) \
+ (((im)->i_f_findcolor) ? ((im)->i_f_findcolor)((im), (color), (entry)) : 0)
+
+#define i_img_virtual(im) ((im)->virtual)
+#define i_img_type(im) ((im)->type)
+#define i_img_bits(im) ((im)->bits)
+
+extern i_fill_t *i_new_fill_solidf(i_fcolor *c, int combine);
+extern i_fill_t *i_new_fill_solid(i_color *c, int combine);
+extern i_fill_t *
+i_new_fill_hatch(i_color *fg, i_color *bg, int combine, int hatch,
+ unsigned char *cust_hatch, int dx, int dy);
+extern i_fill_t *
+i_new_fill_hatchf(i_fcolor *fg, i_fcolor *bg, int combine, int hatch,
+ unsigned char *cust_hatch, int dx, int dy);
+extern i_fill_t *
+i_new_fill_image(i_img *im, double *matrix, int xoff, int yoff, int combine);
+extern void i_fill_destroy(i_fill_t *fill);
+
+float i_gpix_pch(i_img *im,int x,int y,int ch);
+
+/* functions for drawing primitives */
+
+void i_box (i_img *im,int x1,int y1,int x2,int y2,i_color *val);
+void i_box_filled (i_img *im,int x1,int y1,int x2,int y2,i_color *val);
+void i_box_cfill(i_img *im, int x1, int y1, int x2, int y2, i_fill_t *fill);
+void i_line (i_img *im,int x1,int y1,int x2,int y2,i_color *val, int endp);
+void i_line_aa (i_img *im,int x1,int y1,int x2,int y2,i_color *val, int endp);
+void i_arc (i_img *im,int x,int y,float rad,float d1,float d2,i_color *val);
+void i_arc_aa (i_img *im, double x, double y, double rad, double d1, double d2,i_color *val);
+void i_arc_cfill(i_img *im,int x,int y,float rad,float d1,float d2,i_fill_t *fill);
+void i_arc_aa_cfill(i_img *im,double x,double y,double rad,double d1,double d2,i_fill_t *fill);
+void i_circle_aa (i_img *im,float x, float y,float rad,i_color *val);
+void i_copyto (i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty);
+void i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,i_color *trans);
+i_img* i_copy (i_img *src);
+int i_rubthru (i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny, int src_maxx, int src_maxy);
+
+
+undef_int i_flipxy (i_img *im, int direction);
+extern i_img *i_rotate90(i_img *im, int degrees);
+extern i_img *i_rotate_exact(i_img *im, double amount);
+extern i_img *i_rotate_exact_bg(i_img *im, double amount, i_color *backp, i_fcolor *fbackp);
+extern i_img *i_matrix_transform(i_img *im, int xsize, int ysize, double *matrix);
+extern i_img *i_matrix_transform_bg(i_img *im, int xsize, int ysize, double *matrix, i_color *backp, i_fcolor *fbackp);
+
+void i_bezier_multi(i_img *im,int l,double *x,double *y,i_color *val);
+void i_poly_aa (i_img *im,int l,double *x,double *y,i_color *val);
+void i_poly_aa_cfill(i_img *im,int l,double *x,double *y,i_fill_t *fill);
+
+undef_int i_flood_fill (i_img *im,int seedx,int seedy,i_color *dcol);
+undef_int i_flood_cfill(i_img *im, int seedx, int seedy, i_fill_t *fill);
+
+
+/* image processing functions */
+
+void i_gaussian (i_img *im,float stdev);
+void i_conv (i_img *im,float *coeff,int len);
+void i_unsharp_mask(i_img *im, double stddev, double scale);
+
+/* colour manipulation */
+extern int i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan);
+extern void i_map(i_img *im, unsigned char (*maps)[256], unsigned int mask);
+
+float i_img_diff (i_img *im1,i_img *im2);
+
+/* font routines */
+
+undef_int i_init_fonts( int t1log );
+
+#ifdef HAVE_LIBT1
+
+undef_int i_init_t1( int t1log );
+int i_t1_new( char *pfb, char *afm );
+int i_t1_destroy( int font_id );
+undef_int i_t1_cp( i_img *im, int xb, int yb, int channel, int fontnum, float points, char* str, int len, int align, int utf8, char const *flags );
+undef_int i_t1_text( i_img *im, int xb, int yb, i_color *cl, int fontnum, float points, char* str, int len, int align, int utf8, char const *flags );
+int i_t1_bbox( int fontnum, float point, char *str, int len, int cords[6], int utf8, char const *flags );
+void i_t1_set_aa( int st );
+void close_t1( void );
+int i_t1_has_chars(int font_num, char const *text, int len, int utf8, char *out);
+extern int i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size);
+extern int i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf,
+ size_t name_buf_size);
+#endif
+
+#ifdef HAVE_LIBTT
+
+undef_int i_init_tt( void );
+TT_Fonthandle* i_tt_new(char *fontname);
+void i_tt_destroy( TT_Fonthandle *handle );
+undef_int i_tt_cp( TT_Fonthandle *handle,i_img *im,int xb,int yb,int channel,float points,char const* txt,int len,int smooth, int utf8, int align);
+undef_int i_tt_text( TT_Fonthandle *handle, i_img *im, int xb, int yb, i_color *cl, float points, char const* txt, int len, int smooth, int utf8, int align);
+undef_int i_tt_bbox( TT_Fonthandle *handle, float points,char *txt,int len,int cords[6], int utf8);
+int i_tt_has_chars(TT_Fonthandle *handle, char const *text, int len, int utf8, char *out);
+void i_tt_dump_names(TT_Fonthandle *handle);
+int i_tt_face_name(TT_Fonthandle *handle, char *name_buf,
+ size_t name_buf_size);
+int i_tt_glyph_name(TT_Fonthandle *handle, unsigned long ch, char *name_buf,
+ size_t name_buf_size);
+
+#endif /* End of freetype headers */
+
+#ifdef HAVE_FT2
+
+extern int i_ft2_init(void);
+extern FT2_Fonthandle * i_ft2_new(char *name, int index);
+extern void i_ft2_destroy(FT2_Fonthandle *handle);
+extern int i_ft2_setdpi(FT2_Fonthandle *handle, int xdpi, int ydpi);
+extern int i_ft2_getdpi(FT2_Fonthandle *handle, int *xdpi, int *ydpi);
+extern int i_ft2_settransform(FT2_Fonthandle *handle, double *matrix);
+extern int i_ft2_sethinting(FT2_Fonthandle *handle, int hinting);
+extern int i_ft2_bbox(FT2_Fonthandle *handle, double cheight, double cwidth,
+ char const *text, int len, int *bbox, int utf8);
+extern int i_ft2_bbox_r(FT2_Fonthandle *handle, double cheight, double cwidth,
+ char const *text, int len, int vlayout, int utf8, int *bbox);
+extern int i_ft2_text(FT2_Fonthandle *handle, i_img *im, int tx, int ty,
+ i_color *cl, double cheight, double cwidth,
+ char const *text, int len, int align, int aa,
+ int vlayout, int utf8);
+extern int i_ft2_cp(FT2_Fonthandle *handle, i_img *im, int tx, int ty,
+ int channel, double cheight, double cwidth,
+ char const *text, int len, int align, int aa, int vlayout,
+ int utf8);
+extern int i_ft2_has_chars(FT2_Fonthandle *handle, char const *text, int len,
+ int utf8, char *work);
+extern int i_ft2_face_name(FT2_Fonthandle *handle, char *name_buf,
+ size_t name_buf_size);
+extern int i_ft2_can_face_name(void);
+extern int i_ft2_glyph_name(FT2_Fonthandle *handle, unsigned long ch,
+ char *name_buf, size_t name_buf_size,
+ int reliable_only);
+extern int i_ft2_can_do_glyph_names(void);
+extern int i_ft2_face_has_glyph_names(FT2_Fonthandle *handle);
+
+extern int i_ft2_get_multiple_masters(FT2_Fonthandle *handle,
+ i_font_mm *mm);
+extern int
+i_ft2_is_multiple_master(FT2_Fonthandle *handle);
+extern int
+i_ft2_set_mm_coords(FT2_Fonthandle *handle, int coord_count, long *coords);
+#endif
+
+#ifdef WIN32
+
+extern int i_wf_bbox(char *face, int size, char *text, int length, int *bbox);
+extern int i_wf_text(char *face, i_img *im, int tx, int ty, i_color *cl,
+ int size, char *text, int len, int align, int aa);
+extern int i_wf_cp(char *face, i_img *im, int tx, int ty, int channel,
+ int size, char *text, int len, int align, int aa);
+extern int i_wf_addfont(char const *file);
+
+#endif
+
+/* functions for reading and writing formats */
+
+/* general reader callback
+ userdata - data the user passed into the reader
+ buffer - the buffer to fill with data
+ need - the amount of data needed
+ want - the amount of space we have to store data
+ fill buffer and return the number of bytes read, 0 for eof, -1 for error
+*/
+
+typedef int (*i_read_callback_t)(char *userdata, char *buffer, int need,
+ int want);
+
+/* i_gen_reader() translates the low-level requests from whatever library
+ into buffered requests.
+ but the called function can always bypass buffering by only ever
+ reading I<need> bytes.
+*/
+#define CBBUFSIZ 4096
+
+typedef struct {
+ i_read_callback_t cb;
+ char *userdata;
+ char buffer[CBBUFSIZ];
+ int length;
+ int cpos;
+} i_gen_read_data;
+
+extern int i_gen_reader(i_gen_read_data *info, char *buffer, int need);
+extern i_gen_read_data *i_gen_read_data_new(i_read_callback_t cb, char *userdata);
+extern void i_free_gen_read_data(i_gen_read_data *);
+
+/* general writer callback
+ userdata - the data the user passed into the writer
+ data - the data to write
+ data_size - the number of bytes to write
+ write the data, return non-zero on success, zero on failure.
+*/
+typedef int (*i_write_callback_t)(char *userdata, char const *data, int size);
+
+typedef struct {
+ i_write_callback_t cb;
+ char *userdata;
+ char buffer[CBBUFSIZ];
+ int maxlength;
+ int filledto;
+} i_gen_write_data;
+
+extern int i_gen_writer(i_gen_write_data *info, char const *data, int size);
+extern i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb, char *userdata, int maxlength);
+extern int i_free_gen_write_data(i_gen_write_data *, int flush);
+
+extern void i_quant_makemap(i_quantize *quant, i_img **imgs, int count);
+extern i_palidx *i_quant_translate(i_quantize *quant, i_img *img);
+extern void i_quant_transparent(i_quantize *quant, i_palidx *indices, i_img *img, i_palidx trans_index);
+
+extern i_img *i_img_pal_new(int x, int y, int channels, int maxpal);
+extern i_img *i_img_pal_new_low(i_img *im, int x, int y, int channels, int maxpal);
+extern i_img *i_img_to_pal(i_img *src, i_quantize *quant);
+extern i_img *i_img_to_rgb(i_img *src);
+extern i_img *i_img_masked_new(i_img *targ, i_img *mask, int x, int y,
+ int w, int h);
+extern i_img *i_img_16_new(int x, int y, int ch);
+extern i_img *i_img_16_new_low(i_img *im, int x, int y, int ch);
+extern i_img *i_img_double_new(int x, int y, int ch);
+extern i_img *i_img_double_new_low(i_img *im, int x, int y, int ch);
+
+
+char * i_test_format_probe(io_glue *data, int length);
+
+
+#ifdef HAVE_LIBJPEG
+i_img *
+i_readjpeg_wiol(io_glue *ig, int length, char** iptc_itext, int *itlength);
+undef_int i_writejpeg_wiol(i_img *im, io_glue *ig, int qfactor);
+#endif /* HAVE_LIBJPEG */
+
+#ifdef HAVE_LIBTIFF
+i_img * i_readtiff_wiol(io_glue *ig, int length, int page);
+i_img ** i_readtiff_multi_wiol(io_glue *ig, int length, int *count);
+undef_int i_writetiff_wiol(i_img *im, io_glue *ig);
+undef_int i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count);
+undef_int i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine);
+undef_int i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine);
+
+#endif /* HAVE_LIBTIFF */
+
+#ifdef HAVE_LIBPNG
+i_img *i_readpng_wiol(io_glue *ig, int length);
+undef_int i_writepng_wiol(i_img *im, io_glue *ig);
+#endif /* HAVE_LIBPNG */
+
+#ifdef HAVE_LIBGIF
+i_img *i_readgif(int fd, int **colour_table, int *colours);
+i_img *i_readgif_wiol(io_glue *ig, int **colour_table, int *colours);
+i_img *i_readgif_scalar(char *data, int length, int **colour_table, int *colours);
+i_img *i_readgif_callback(i_read_callback_t callback, char *userdata, int **colour_table, int *colours);
+i_img *i_readgif_single_wiol(io_glue *ig, int page);
+extern i_img **i_readgif_multi(int fd, int *count);
+extern i_img **i_readgif_multi_scalar(char *data, int length, int *count);
+extern i_img **i_readgif_multi_callback(i_read_callback_t callback, char *userdata, int *count);
+extern i_img **i_readgif_multi_wiol(io_glue *ig, int *count);
+undef_int i_writegif(i_img *im,int fd,int colors,int pixdev,int fixedlen,i_color fixed[]);
+undef_int i_writegifmc(i_img *im,int fd,int colors);
+undef_int i_writegifex(i_img *im,int fd);
+undef_int i_writegif_gen(i_quantize *quant, int fd, i_img **imgs, int count);
+undef_int i_writegif_callback(i_quantize *quant, i_write_callback_t cb, char *userdata, int maxbuffer, i_img **imgs, int count);
+undef_int i_writegif_wiol(io_glue *ig, i_quantize *quant,
+ i_img **imgs, int count);
+void i_qdist(i_img *im);
+
+#endif /* HAVE_LIBGIF */
+
+i_img * i_readraw_wiol(io_glue *ig, int x, int y, int datachannels, int storechannels, int intrl);
+undef_int i_writeraw_wiol(i_img* im, io_glue *ig);
+
+i_img * i_readpnm_wiol(io_glue *ig, int length);
+undef_int i_writeppm_wiol(i_img *im, io_glue *ig);
+
+extern int i_writebmp_wiol(i_img *im, io_glue *ig);
+extern i_img *i_readbmp_wiol(io_glue *ig);
+
+int tga_header_verify(unsigned char headbuf[18]);
+
+i_img * i_readtga_wiol(io_glue *ig, int length);
+undef_int i_writetga_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idstring, size_t idlen);
+
+i_img * i_readrgb_wiol(io_glue *ig, int length);
+undef_int i_writergb_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idstring, size_t idlen);
+
+i_img * i_scaleaxis(i_img *im, float Value, int Axis);
+i_img * i_scale_nn(i_img *im, float scx, float scy);
+i_img * i_haar(i_img *im);
+int i_count_colors(i_img *im,int maxc);
+
+i_img * i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen);
+
+struct rm_op;
+i_img * i_transform2(int width, int height, int channels,
+ struct rm_op *ops, int ops_count,
+ double *n_regs, int n_regs_count,
+ i_color *c_regs, int c_regs_count,
+ i_img **in_imgs, int in_imgs_count);
+
+/* filters */
+
+void i_contrast(i_img *im, float intensity);
+void i_hardinvert(i_img *im);
+void i_noise(i_img *im, float amount, unsigned char type);
+void i_bumpmap(i_img *im,i_img *bump,int channel,int light_x,int light_y,int strength);
+void i_bumpmap_complex(i_img *im, i_img *bump, int channel, int tx, int ty, float Lx, float Ly,
+ float Lz, float cd, float cs, float n, i_color *Ia, i_color *Il, i_color *Is);
+void i_postlevels(i_img *im,int levels);
+void i_mosaic(i_img *im,int size);
+void i_watermark(i_img *im,i_img *wmark,int tx,int ty,int pixdiff);
+void i_autolevels(i_img *im,float lsat,float usat,float skew);
+void i_radnoise(i_img *im,int xo,int yo,float rscale,float ascale);
+void i_turbnoise(i_img *im,float xo,float yo,float scale);
+void i_gradgen(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
+void i_nearest_color(i_img *im, int num, int *xo, int *yo, i_color *ival, int dmeasure);
+i_img *i_diff_image(i_img *im, i_img *im2, int mindist);
+void i_fountain(i_img *im, double xa, double ya, double xb, double yb,
+ i_fountain_type type, i_fountain_repeat repeat,
+ int combine, int super_sample, double ssample_param,
+ int count, i_fountain_seg *segs);
+extern i_fill_t *
+i_new_fill_fount(double xa, double ya, double xb, double yb,
+ i_fountain_type type, i_fountain_repeat repeat,
+ int combine, int super_sample, double ssample_param,
+ int count, i_fountain_seg *segs);
+
+/* Debug only functions */
+
+void malloc_state( void );
+
+/* this is sort of obsolete now */
+
+typedef struct {
+ undef_int (*i_has_format)(char *frmt);
+ i_color*(*ICL_set)(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a);
+ void (*ICL_info)(i_color *cl);
+
+ i_img*(*i_img_new)( void );
+ i_img*(*i_img_empty)(i_img *im,int x,int y);
+ i_img*(*i_img_empty_ch)(i_img *im,int x,int y,int ch);
+ void(*i_img_exorcise)(i_img *im);
+
+ void(*i_img_info)(i_img *im,int *info);
+
+ void(*i_img_setmask)(i_img *im,int ch_mask);
+ int (*i_img_getmask)(i_img *im);
+
+ /*
+ int (*i_ppix)(i_img *im,int x,int y,i_color *val);
+ int (*i_gpix)(i_img *im,int x,int y,i_color *val);
+ */
+ void(*i_box)(i_img *im,int x1,int y1,int x2,int y2,i_color *val);
+ void(*i_line)(i_img *im,int x1,int y1,int x2,int y2,i_color *val,int endp);
+ void(*i_arc)(i_img *im,int x,int y,float rad,float d1,float d2,i_color *val);
+ void(*i_copyto)(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty);
+ void(*i_copyto_trans)(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,i_color *trans);
+ int(*i_rubthru)(i_img *im,i_img *src,int tx,int ty);
+
+} symbol_table_t;
+
+/* error handling
+ see error.c for documentation
+ the error information is currently global
+*/
+typedef struct {
+ char *msg;
+ int code;
+} i_errmsg;
+
+typedef void (*i_error_cb)(int code, char const *msg);
+typedef void (*i_failed_cb)(i_errmsg *msgs);
+extern i_error_cb i_set_error_cb(i_error_cb);
+extern i_failed_cb i_set_failed_cb(i_failed_cb);
+extern void i_set_argv0(char const *);
+extern int i_set_errors_fatal(int new_fatal);
+extern i_errmsg *i_errors(void);
+
+extern void i_push_error(int code, char const *msg);
+extern void i_push_errorf(int code, char const *fmt, ...);
+extern void i_push_errorvf(int code, char const *fmt, va_list);
+extern void i_clear_error(void);
+extern int i_failed(int code, char const *msg);
+
+/* image tag processing */
+extern void i_tags_new(i_img_tags *tags);
+extern int i_tags_addn(i_img_tags *tags, char const *name, int code,
+ int idata);
+extern int i_tags_add(i_img_tags *tags, char const *name, int code,
+ char const *data, int size, int idata);
+extern int i_tags_set(i_img_tags *tags, char const *name,
+ char const *data, int size);
+extern int i_tags_setn(i_img_tags *tags, char const *name, int idata);
+
+extern void i_tags_destroy(i_img_tags *tags);
+extern int i_tags_find(i_img_tags *tags, char const *name, int start,
+ int *entry);
+extern int i_tags_findn(i_img_tags *tags, int code, int start, int *entry);
+extern int i_tags_delete(i_img_tags *tags, int entry);
+extern int i_tags_delbyname(i_img_tags *tags, char const *name);
+extern int i_tags_delbycode(i_img_tags *tags, int code);
+extern int i_tags_get_float(i_img_tags *tags, char const *name, int code,
+ double *value);
+extern int i_tags_set_float(i_img_tags *tags, char const *name, int code,
+ double value);
+extern int i_tags_set_float2(i_img_tags *tags, char const *name, int code,
+ double value, int places);
+extern int i_tags_get_int(i_img_tags *tags, char const *name, int code,
+ int *value);
+extern int i_tags_get_string(i_img_tags *tags, char const *name, int code,
+ char *value, size_t value_size);
+extern int i_tags_get_color(i_img_tags *tags, char const *name, int code,
+ i_color *value);
+extern int i_tags_set_color(i_img_tags *tags, char const *name, int code,
+ i_color const *value);
+extern void i_tags_print(i_img_tags *tags);
+
+/* image file limits */
+extern int
+i_set_image_file_limits(int width, int height, int bytes);
+extern int
+i_get_image_file_limits(int *width, int *height, int *bytes);
+
+#endif
--- /dev/null
+/* Declares utility functions useful across various files which
+ aren't meant to be available externally
+*/
+
+#ifndef IMAGEI_H_
+#define IMAGEI_H_
+
+#include "imager.h"
+
+/* wrapper functions that implement the floating point sample version of a
+ function in terms of the 8-bit sample version
+*/
+extern int i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix);
+extern int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix);
+extern int i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix);
+extern int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix);
+extern int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
+ int const *chans, int chan_count);
+
+/* wrapper functions that forward palette calls to the underlying image,
+ assuming the underlying image is the first pointer in whatever
+ ext_data points at
+*/
+extern int i_addcolors_forward(i_img *im, i_color *, int count);
+extern int i_getcolors_forward(i_img *im, int i, i_color *, int count);
+extern int i_colorcount_forward(i_img *im);
+extern int i_maxcolors_forward(i_img *im);
+extern int i_findcolor_forward(i_img *im, i_color *color, i_palidx *entry);
+extern int i_setcolors_forward(i_img *im, int index, i_color *colors,
+ int count);
+
+#define SampleFTo16(num) ((int)((num) * 65535.0 + 0.01))
+/* we add that little bit to avoid rounding issues */
+#define Sample16ToF(num) ((num) / 65535.0)
+
+#define SampleFTo8(num) ((int)((num) * 255.0 + 0.01))
+#define Sample8ToF(num) ((num) / 255.0)
+
+#define Sample16To8(num) ((num) / 257)
+#define Sample8To16(num) ((num) * 257)
+
+extern void i_get_combine(int combine, i_fill_combine_f *, i_fill_combinef_f *);
+
+extern int
+i_int_check_image_file_limits(int width, int height, int channels, int sample_size);
+
+#define im_min(a, b) ((a) < (b) ? (a) : (b))
+#define im_max(a, b) ((a) > (b) ? (a) : (b))
+
+#include "ext.h"
+
+extern UTIL_table_t i_UTIL_table;
+
+/* Ideally this will move into imconfig.h if we ever probe */
+#if defined(_GNU_SOURCE) || __STDC_VERSION__ >= 199901L
+/* snprintf() is part of C99 and provided by Glibc */
+#define HAVE_SNPRINTF
+#endif
+
+/* test if all channels are writable */
+#define I_ALL_CHANNELS_WRITABLE(im) (((im)->ch_mask & 0xF) == 0xf)
+
+typedef struct i_int_hline_seg_tag {
+ int minx, x_limit;
+} i_int_hline_seg;
+
+typedef struct i_int_hline_entry_tag {
+ int count;
+ int alloc;
+ i_int_hline_seg segs[1];
+} i_int_hline_entry;
+
+/* represents a set of horizontal line segments to be filled in later */
+typedef struct i_int_hlines_tag {
+ int start_y, limit_y;
+ int start_x, limit_x;
+ i_int_hline_entry **entries;
+} i_int_hlines;
+
+extern void
+i_int_init_hlines(
+ i_int_hlines *hlines,
+ int start_y,
+ int count_y,
+ int start_x,
+ int width_x
+ );
+extern void i_int_init_hlines_img(i_int_hlines *hlines, i_img *img);
+extern void i_int_hlines_add(i_int_hlines *hlines, int y, int minx, int width);
+extern void i_int_hlines_destroy(i_int_hlines *hlines);
+
+extern void i_int_hlines_fill_color(i_img *im, i_int_hlines *hlines, i_color *val);
+extern void i_int_hlines_fill_fill(i_img *im, i_int_hlines *hlines, i_fill_t *fill);
+
+#endif
--- /dev/null
+#ifndef _DATATYPES_H_
+#define _DATATYPES_H_
+
+#include "imio.h"
+#include "imconfig.h"
+
+#define MAXCHANNELS 4
+
+/* used for palette indices in some internal code (which might be
+ exposed at some point
+*/
+typedef unsigned char i_palidx;
+
+/* We handle 2 types of sample, this is hopefully the most common, and the
+ smaller of the ones we support */
+typedef unsigned char i_sample_t;
+
+typedef struct { i_sample_t gray_color; } gray_color;
+typedef struct { i_sample_t r,g,b; } rgb_color;
+typedef struct { i_sample_t r,g,b,a; } rgba_color;
+typedef struct { i_sample_t c,m,y,k; } cmyk_color;
+
+typedef int undef_int; /* special value to put in typemaps to retun undef on 0 and 1 on 1 */
+
+typedef union {
+ gray_color gray;
+ rgb_color rgb;
+ rgba_color rgba;
+ cmyk_color cmyk;
+ i_sample_t channel[MAXCHANNELS];
+ unsigned int ui;
+} i_color;
+
+/* this is the larger sample type, it should be able to accurately represent
+ any sample size we use */
+typedef double i_fsample_t;
+
+typedef struct { i_fsample_t gray_color; } i_fgray_color_t;
+typedef struct { i_fsample_t r, g, b; } i_frgb_color_t;
+typedef struct { i_fsample_t r, g, b, a; } i_frgba_color_t;
+typedef struct { i_fsample_t c, m, y, k; } i_fcmyk_color_t;
+
+typedef union {
+ i_fgray_color_t gray;
+ i_frgb_color_t rgb;
+ i_frgba_color_t rgba;
+ i_fcmyk_color_t cmyk;
+ i_fsample_t channel[MAXCHANNELS];
+} i_fcolor;
+
+typedef enum {
+ i_direct_type, /* direct colour, keeps RGB values per pixel */
+ i_palette_type /* keeps a palette index per pixel */
+} i_img_type_t;
+
+typedef enum {
+ /* bits per sample, not per pixel */
+ /* a paletted image might have one bit per sample */
+ i_8_bits = 8,
+ i_16_bits = 16,
+ i_double_bits = sizeof(double) * 8
+} i_img_bits_t;
+
+typedef struct {
+ char *name; /* name of a given tag, might be NULL */
+ int code; /* number of a given tag, -1 if it has no meaning */
+ char *data; /* value of a given tag if it's not an int, may be NULL */
+ int size; /* size of the data */
+ int idata; /* value of a given tag if data is NULL */
+} i_img_tag;
+
+typedef struct {
+ int count; /* how many tags have been set */
+ int alloc; /* how many tags have been allocated for */
+ i_img_tag *tags;
+} i_img_tags;
+
+typedef struct i_img_ i_img;
+typedef int (*i_f_ppix_t)(i_img *im, int x, int y, i_color *pix);
+typedef int (*i_f_ppixf_t)(i_img *im, int x, int y, i_fcolor *pix);
+typedef int (*i_f_plin_t)(i_img *im, int x, int r, int y, i_color *vals);
+typedef int (*i_f_plinf_t)(i_img *im, int x, int r, int y, i_fcolor *vals);
+typedef int (*i_f_gpix_t)(i_img *im, int x, int y, i_color *pix);
+typedef int (*i_f_gpixf_t)(i_img *im, int x, int y, i_fcolor *pix);
+typedef int (*i_f_glin_t)(i_img *im, int x, int r, int y, i_color *vals);
+typedef int (*i_f_glinf_t)(i_img *im, int x, int r, int y, i_fcolor *vals);
+
+typedef int (*i_f_gsamp_t)(i_img *im, int x, int r, int y, i_sample_t *samp,
+ const int *chans, int chan_count);
+typedef int (*i_f_gsampf_t)(i_img *im, int x, int r, int y, i_fsample_t *samp,
+ const int *chan, int chan_count);
+
+typedef int (*i_f_gpal_t)(i_img *im, int x, int r, int y, i_palidx *vals);
+typedef int (*i_f_ppal_t)(i_img *im, int x, int r, int y, i_palidx *vals);
+typedef int (*i_f_addcolors_t)(i_img *im, i_color *colors, int count);
+typedef int (*i_f_getcolors_t)(i_img *im, int i, i_color *, int count);
+typedef int (*i_f_colorcount_t)(i_img *im);
+typedef int (*i_f_maxcolors_t)(i_img *im);
+typedef int (*i_f_findcolor_t)(i_img *im, i_color *color, i_palidx *entry);
+typedef int (*i_f_setcolors_t)(i_img *im, int index, i_color *colors,
+ int count);
+
+typedef void (*i_f_destroy_t)(i_img *im);
+
+struct i_img_ {
+ int channels;
+ int xsize,ysize,bytes;
+ unsigned int ch_mask;
+ i_img_bits_t bits;
+ i_img_type_t type;
+ int virtual; /* image might not keep any data, must use functions */
+ unsigned char *idata; /* renamed to force inspection of existing code */
+ /* can be NULL if virtual is non-zero */
+ i_img_tags tags;
+
+ void *ext_data;
+
+ /* interface functions */
+ i_f_ppix_t i_f_ppix;
+ i_f_ppixf_t i_f_ppixf;
+ i_f_plin_t i_f_plin;
+ i_f_plinf_t i_f_plinf;
+ i_f_gpix_t i_f_gpix;
+ i_f_gpixf_t i_f_gpixf;
+ i_f_glin_t i_f_glin;
+ i_f_glinf_t i_f_glinf;
+ i_f_gsamp_t i_f_gsamp;
+ i_f_gsampf_t i_f_gsampf;
+
+ /* only valid for type == i_palette_type */
+ i_f_gpal_t i_f_gpal;
+ i_f_ppal_t i_f_ppal;
+ i_f_addcolors_t i_f_addcolors;
+ i_f_getcolors_t i_f_getcolors;
+ i_f_colorcount_t i_f_colorcount;
+ i_f_maxcolors_t i_f_maxcolors;
+ i_f_findcolor_t i_f_findcolor;
+ i_f_setcolors_t i_f_setcolors;
+
+ i_f_destroy_t i_f_destroy;
+};
+
+/* ext_data for paletted images
+ */
+typedef struct {
+ int count; /* amount of space used in palette (in entries) */
+ int alloc; /* amount of space allocated for palette (in entries) */
+ i_color *pal;
+ int last_found;
+} i_img_pal_ext;
+
+/* Helper datatypes
+ The types in here so far are:
+
+ doubly linked bucket list - pretty efficient
+ octtree - no idea about goodness
+
+ needed: hashes.
+
+*/
+
+
+
+
+
+/* bitmap mask */
+
+struct i_bitmap {
+ int xsize,ysize;
+ char *data;
+};
+
+struct i_bitmap* btm_new(int xsize,int ysize);
+void btm_destroy(struct i_bitmap *btm);
+int btm_test(struct i_bitmap *btm,int x,int y);
+void btm_set(struct i_bitmap *btm,int x,int y);
+
+
+
+
+
+
+
+
+/* Stack/Linked list */
+
+struct llink {
+ struct llink *p,*n;
+ void *data;
+ int fill; /* Number used in this link */
+};
+
+struct llist {
+ struct llink *h,*t;
+ int multip; /* # of copies in a single chain */
+ int ssize; /* size of each small element */
+ int count; /* number of elements on the list */
+};
+
+
+/* Links */
+
+struct llink *llink_new( struct llink* p,int size );
+int llist_llink_push( struct llist *lst, struct llink *lnk, void *data );
+
+/* Lists */
+
+struct llist *llist_new( int multip, int ssize );
+void llist_destroy( struct llist *l );
+void llist_push( struct llist *l, void *data );
+void llist_dump( struct llist *l );
+int llist_pop( struct llist *l,void *data );
+
+
+
+
+/* Octtree */
+
+struct octt {
+ struct octt *t[8];
+ int cnt;
+};
+
+struct octt *octt_new(void);
+int octt_add(struct octt *ct,unsigned char r,unsigned char g,unsigned char b);
+void octt_dump(struct octt *ct);
+void octt_count(struct octt *ct,int *tot,int max,int *overflow);
+void octt_delete(struct octt *ct);
+
+/* font bounding box results */
+enum bounding_box_index_t {
+ BBOX_NEG_WIDTH,
+ BBOX_GLOBAL_DESCENT,
+ BBOX_POS_WIDTH,
+ BBOX_GLOBAL_ASCENT,
+ BBOX_DESCENT,
+ BBOX_ASCENT,
+ BBOX_ADVANCE_WIDTH,
+ BBOX_RIGHT_BEARING,
+ BOUNDING_BOX_COUNT
+};
+
+/* Generic fills */
+struct i_fill_tag;
+
+typedef void (*i_fill_with_color_f)
+ (struct i_fill_tag *fill, int x, int y, int width, int channels,
+ i_color *data);
+typedef void (*i_fill_with_fcolor_f)
+ (struct i_fill_tag *fill, int x, int y, int width, int channels,
+ i_fcolor *data);
+typedef void (*i_fill_destroy_f)(struct i_fill_tag *fill);
+typedef void (*i_fill_combine_f)(i_color *out, i_color *in, int channels,
+ int count);
+typedef void (*i_fill_combinef_f)(i_fcolor *out, i_fcolor *in, int channels,
+ int count);
+
+/* fountain fill types */
+typedef enum {
+ i_fst_linear,
+ i_fst_curved,
+ i_fst_sine,
+ i_fst_sphere_up,
+ i_fst_sphere_down,
+ i_fst_end
+} i_fountain_seg_type;
+typedef enum {
+ i_fc_direct,
+ i_fc_hue_up,
+ i_fc_hue_down,
+ i_fc_end
+} i_fountain_color;
+typedef struct {
+ double start, middle, end;
+ i_fcolor c[2];
+ i_fountain_seg_type type;
+ i_fountain_color color;
+} i_fountain_seg;
+typedef enum {
+ i_fr_none,
+ i_fr_sawtooth,
+ i_fr_triangle,
+ i_fr_saw_both,
+ i_fr_tri_both
+} i_fountain_repeat;
+typedef enum {
+ i_ft_linear,
+ i_ft_bilinear,
+ i_ft_radial,
+ i_ft_radial_square,
+ i_ft_revolution,
+ i_ft_conical,
+ i_ft_end
+} i_fountain_type;
+typedef enum {
+ i_fts_none,
+ i_fts_grid,
+ i_fts_random,
+ i_fts_circle
+} i_ft_supersample;
+
+
+typedef struct i_fill_tag
+{
+ /* called for 8-bit/sample image (and maybe lower) */
+ /* this may be NULL, if so call fill_with_fcolor */
+ i_fill_with_color_f fill_with_color;
+
+ /* called for other sample sizes */
+ /* this must be non-NULL */
+ i_fill_with_fcolor_f fill_with_fcolor;
+
+ /* called if non-NULL to release any extra resources */
+ i_fill_destroy_f destroy;
+
+ /* if non-zero the caller will fill data with the original data
+ from the image */
+ i_fill_combine_f combine;
+ i_fill_combinef_f combinef;
+} i_fill_t;
+
+typedef enum {
+ ic_none,
+ ic_normal,
+ ic_multiply,
+ ic_dissolve,
+ ic_add,
+ ic_subtract,
+ ic_diff,
+ ic_lighten,
+ ic_darken,
+ ic_hue,
+ ic_sat,
+ ic_value,
+ ic_color
+} i_combine_t;
+
+/*
+ describes an axis of a MM font.
+ Modelled on FT2's FT_MM_Axis.
+ It would be nice to have a default entry too, but FT2
+ doesn't support it.
+*/
+typedef struct i_font_mm_axis_tag {
+ char const *name;
+ int minimum;
+ int maximum;
+} i_font_mm_axis;
+
+#define IM_FONT_MM_MAX_AXES 4
+
+/*
+ multiple master information for a font, if any
+ modelled on FT2's FT_Multi_Master.
+*/
+typedef struct i_font_mm_tag {
+ int num_axis;
+ int num_designs; /* provided but not necessarily useful */
+ i_font_mm_axis axis[IM_FONT_MM_MAX_AXES];
+} i_font_mm;
+
+#ifdef HAVE_LIBTT
+
+struct TT_Fonthandle_;
+
+typedef struct TT_Fonthandle_ TT_Fonthandle;
+
+#endif
+
+#ifdef HAVE_FT2
+
+typedef struct FT2_Fonthandle FT2_Fonthandle;
+
+#endif
+
+/* transparency handling for quantized output */
+typedef enum i_transp_tag {
+ tr_none, /* ignore any alpha channel */
+ tr_threshold, /* threshold the transparency - uses tr_threshold */
+ tr_errdiff, /* error diffusion */
+ tr_ordered /* an ordered dither */
+} i_transp;
+
+/* controls how we build the colour map */
+typedef enum i_make_colors_tag {
+ mc_none, /* user supplied colour map only */
+ mc_web_map, /* Use the 216 colour web colour map */
+ mc_addi, /* Addi's algorithm */
+ mc_median_cut, /* median cut - similar to giflib, hopefully */
+ mc_mask = 0xFF /* (mask for generator) */
+} i_make_colors;
+
+/* controls how we translate the colours */
+typedef enum i_translate_tag {
+ pt_giflib, /* get gif lib to do it (ignores make_colours) */
+ pt_closest, /* just use the closest match within the hashbox */
+ pt_perturb, /* randomly perturb the data - uses perturb_size*/
+ pt_errdiff /* error diffusion dither - uses errdiff */
+} i_translate;
+
+/* Which error diffusion map to use */
+typedef enum i_errdiff_tag {
+ ed_floyd, /* floyd-steinberg */
+ ed_jarvis, /* Jarvis, Judice and Ninke */
+ ed_stucki, /* Stucki */
+ ed_custom, /* the map found in ed_map|width|height|orig */
+ ed_mask = 0xFF, /* mask to get the map */
+ ed_bidir = 0x100 /* change direction for each row */
+} i_errdiff;
+
+/* which ordered dither map to use
+ currently only available for transparency
+ I don't know of a way to do ordered dither of an image against some
+ general palette
+ */
+typedef enum i_ord_dith_tag
+{
+ od_random, /* sort of random */
+ od_dot8, /* large dot */
+ od_dot4,
+ od_hline,
+ od_vline,
+ od_slashline, /* / line dither */
+ od_backline, /* \ line dither */
+ od_tiny, /* small checkerbox */
+ od_custom /* custom 8x8 map */
+} i_ord_dith;
+
+typedef struct i_gif_pos_tag {
+ int x, y;
+} i_gif_pos;
+
+/* passed into i_writegif_gen() to control quantization */
+typedef struct i_quantize_tag {
+ /* how to handle transparency */
+ i_transp transp;
+ /* the threshold at which to make pixels opaque */
+ int tr_threshold;
+ i_errdiff tr_errdiff;
+ i_ord_dith tr_orddith;
+ unsigned char tr_custom[64];
+
+ /* how to make the colour map */
+ i_make_colors make_colors;
+
+ /* any existing colours
+ mc_existing is an existing colour table
+ mc_count is the number of existing colours
+ mc_size is the total size of the array that mc_existing points
+ at - this must be at least 256
+ */
+ i_color *mc_colors;
+ int mc_size;
+ int mc_count;
+
+ /* how we translate the colours */
+ i_translate translate;
+
+ /* the error diffusion map to use if translate is mc_errdiff */
+ i_errdiff errdiff;
+ /* the following define the error diffusion values to use if
+ errdiff is ed_custom. ed_orig is the column on the top row that
+ represents the current
+ */
+ int *ed_map;
+ int ed_width, ed_height, ed_orig;
+
+ /* the amount of perturbation to use for translate is mc_perturb */
+ int perturb;
+} i_quantize;
+
+typedef struct i_gif_opts {
+ /* each image has a local color map */
+ int each_palette;
+
+ /* images are interlaced */
+ int interlace;
+
+ /* time for which image is displayed
+ (in 1/100 seconds)
+ default: 0
+ */
+ int delay_count;
+ int *delays;
+
+ /* user input flags
+ default: 0
+ */
+ int user_input_count;
+ char *user_input_flags;
+
+ /* disposal
+ default: 0 */
+ int disposal_count;
+ char *disposal;
+
+ /* this is added to the color table when we make an image transparent */
+ i_color tran_color;
+
+ /* image positions */
+ int position_count;
+ i_gif_pos *positions;
+
+ /* Netscape loop extension - number of loops */
+ int loop_count;
+
+ /* should be eliminate unused colors? */
+ int eliminate_unused;
+} i_gif_opts;
+
+
+
+#endif
+
/* imexif.h - interface to Exif handling */
#ifndef IMAGER_IMEXIF_H
-#define IMAGER_IMEXIT_H
+#define IMAGER_IMEXIF_H
#include <stddef.h>
-#include "imagei.h"
+#include "imageri.h"
extern int i_int_decode_exif(i_img *im, unsigned char *data, size_t length);
--- /dev/null
+#include "imexttypes.h"
+#include "imager.h"
+
+/*
+ DON'T ADD CASTS TO THESE
+*/
+im_ext_funcs imager_function_table =
+ {
+ mymalloc,
+ myfree,
+ myrealloc,
+
+ i_img_8_new,
+ i_img_16_new,
+ i_img_double_new,
+ i_img_pal_new,
+ i_img_destroy,
+ i_sametype,
+ i_sametype_chans,
+ i_img_info,
+
+ i_ppix,
+ i_gpix,
+ i_ppixf,
+ i_gpixf,
+ i_plin,
+ i_glin,
+ i_plinf,
+ i_glinf,
+ i_gsamp,
+ i_gsampf,
+ i_gpal,
+ i_ppal,
+ i_addcolors,
+ i_getcolors,
+ i_colorcount,
+ i_maxcolors,
+ i_findcolor,
+ i_setcolors,
+
+ i_new_fill_solid,
+ i_new_fill_solidf,
+ i_new_fill_hatch,
+ i_new_fill_hatchf,
+ i_new_fill_image,
+ i_new_fill_fount,
+ i_fill_destroy,
+
+ i_quant_makemap,
+ i_quant_translate,
+ i_quant_transparent,
+
+ i_clear_error,
+ i_push_error,
+ i_push_errorf,
+ i_push_errorvf,
+
+ i_tags_new,
+ i_tags_set,
+ i_tags_setn,
+ i_tags_destroy,
+ i_tags_find,
+ i_tags_findn,
+ i_tags_delete,
+ i_tags_delbyname,
+ i_tags_delbycode,
+ i_tags_get_float,
+ i_tags_set_float,
+ i_tags_set_float2,
+ i_tags_get_int,
+ i_tags_get_string,
+ i_tags_get_color,
+ i_tags_set_color,
+
+ i_box,
+ i_box_filled,
+ i_box_cfill,
+ i_line,
+ i_line_aa,
+ i_arc,
+ i_arc_aa,
+ i_arc_cfill,
+ i_arc_aa_cfill,
+ i_circle_aa,
+ i_flood_fill,
+ i_flood_cfill,
+
+ i_copyto,
+ i_copyto_trans,
+ i_copy,
+ i_rubthru,
+ };
+
+/* in general these functions aren't called by Imager internally, but
+ only via the pointers above, since faster macros that call the
+ image vtable pointers are used.
+
+ () are used around the function names to prevent macro replacement
+ on the function names.
+*/
+
+/*
+=item i_ppix(im, x, y, color)
+
+=category Drawing
+
+Sets the pixel at (x,y) to I<color>.
+
+Returns 0 if the pixel was drawn, or -1 if not.
+
+Does no alpha blending, just copies the channels from the supplied
+color to the image.
+
+=cut
+*/
+
+int
+(i_ppix)(i_img *im,int x,int y,i_color *val) {
+ return i_ppix(im, x, y, val);
+}
+
+/*
+=item i_gpix(im, x, y, color)
+
+=category Drawing
+
+Retrieves the I<color> of the pixel (x,y).
+
+Returns 0 if the pixel was retrieved, or -1 if not.
+
+=cut
+*/
+
+int
+(i_gpix)(i_img *im,int x,int y,i_color *val) {
+ return i_gpix(im, x, y, val);
+}
+
+/*
+=item i_ppixf(im, x, y, fcolor)
+
+=category Drawing
+
+Sets the pixel at (x,y) to the floating point color I<fcolor>.
+
+Returns 0 if the pixel was drawn, or -1 if not.
+
+Does no alpha blending, just copies the channels from the supplied
+color to the image.
+
+=cut
+*/
+int
+(i_ppixf)(i_img *im,int x,int y,i_fcolor *val) {
+ return i_ppixf(im, x, y, val);
+}
+
+/*
+=item i_gpixf(im, x, y, fcolor)
+
+=category Drawing
+
+Retrieves the color of the pixel (x,y) as a floating point color into
+I<fcolor>.
+
+Returns 0 if the pixel was retrieved, or -1 if not.
+
+=cut
+*/
+
+int
+(i_gpixf)(i_img *im,int x,int y,i_fcolor *val) {
+ return i_gpixf(im, x, y, val);
+}
+
+/*
+=item i_plin(im, l, r, y, colors)
+
+=category Drawing
+
+Sets (r-l) pixels starting from (l,y) using (r-l) values from
+I<colors>.
+
+Returns the number of pixels set.
+
+=cut
+*/
+
+int
+(i_plin)(i_img *im, int l, int r, int y, i_color *vals) {
+ return i_plin(im, l, r, y, vals);
+}
+
+/*
+=item i_glin(im, l, r, y, colors)
+
+=category Drawing
+
+Retrieves (r-l) pixels starting from (l,y) into I<colors>.
+
+Returns the number of pixels retrieved.
+
+=cut
+*/
+
+int
+(i_glin)(i_img *im, int l, int r, int y, i_color *vals) {
+ return i_glin(im, l, r, y, vals);
+}
+
+/*
+=item i_plinf(im, l, r, fcolors)
+
+=category Drawing
+
+Sets (r-l) pixels starting from (l,y) using (r-l) floating point
+colors from I<colors>.
+
+Returns the number of pixels set.
+
+=cut
+*/
+
+int
+(i_plinf)(i_img *im, int l, int r, int y, i_fcolor *vals) {
+ return i_plinf(im, l, r, y, vals);
+}
+
+/*
+=item i_glinf(im, l, r, y, colors)
+
+=category Drawing
+
+Retrieves (r-l) pixels starting from (l,y) into I<colors> as floating
+point colors.
+
+Returns the number of pixels retrieved.
+
+=cut
+*/
+
+int
+(i_glinf)(i_img *im, int l, int r, int y, i_fcolor *vals) {
+ return i_glinf(im, l, r, y, vals);
+}
+
+/*
+=item i_gsamp(im, l, r, y, samp, chans, chan_count)
+
+=category Drawing
+
+Reads sample values from im for the horizontal line (l, y) to (r-1,y)
+for the channels specified by chans, an array of int with chan_count
+elements.
+
+If chans is NULL then the first chan_count channels are retrieved for
+each pixel.
+
+Returns the number of samples read (which should be (r-l) *
+chan_count)
+
+=cut
+*/
+int
+(i_gsamp)(i_img *im, int l, int r, int y, i_sample_t *samp,
+ const int *chans, int chan_count) {
+ return i_gsamp(im, l, r, y, samp, chans, chan_count);
+}
+
+/*
+=item i_gsampf(im, l, r, y, samp, chans, chan_count)
+
+=category Drawing
+
+Reads floating point sample values from im for the horizontal line (l,
+y) to (r-1,y) for the channels specified by chans, an array of int
+with chan_count elements.
+
+If chans is NULL then the first chan_count channels are retrieved for
+each pixel.
+
+Returns the number of samples read (which should be (r-l) *
+chan_count)
+
+=cut
+*/
+int
+(i_gsampf)(i_img *im, int l, int r, int y, i_fsample_t *samp,
+ const int *chans, int chan_count) {
+ return i_gsampf(im, l, r, y, samp, chans, chan_count);
+}
+
+/*
+=item i_gpal(im, x, r, y, indexes)
+
+=category Drawing
+
+Reads palette indexes for the horizontal line (x, y) to (r-1, y) into
+indexes.
+
+Returns the number of indexes read.
+
+Always returns 0 for direct color images.
+
+=cut
+*/
+int
+(i_gpal)(i_img *im, int x, int r, int y, i_palidx *vals) {
+ return i_gpal(im, x, r, y, vals);
+}
+
+/*
+=item i_ppal(im, x, r, y, indexes)
+
+=category Drawing
+
+Writes palette indexes for the horizontal line (x, y) to (r-1, y) from
+indexes.
+
+Returns the number of indexes written.
+
+Always returns 0 for direct color images.
+
+=cut
+*/
+int
+(i_ppal)(i_img *im, int x, int r, int y, i_palidx *vals) {
+ return i_ppal(im, x, r, y, vals);
+}
+
+/*
+=item i_addcolors(im, colors, count)
+
+=category Paletted images
+
+Adds colors to the image's palette.
+
+On success returns the index of the lowest color added.
+
+On failure returns -1.
+
+Always fails for direct color images.
+
+=cut
+*/
+
+int
+(i_addcolors)(i_img *im, i_color *colors, int count) {
+ return i_addcolors(im, colors, count);
+}
+
+/*
+=item i_getcolors(im, index, colors, count)
+
+=category Paletted images
+
+Retrieves I<count> colors starting from I<index> in the image's
+palette.
+
+On success stores the colors into I<colors> and returns true.
+
+On failure returns false.
+
+Always fails for direct color images.
+
+Fails if there are less than I<index>+I<count> colors in the image's
+palette.
+
+=cut
+*/
+
+int
+(i_getcolors)(i_img *im, int i, i_color *colors, int count) {
+ return i_getcolors(im, i, colors, count);
+}
+
+/*
+=item i_colorcount(im)
+
+=category Paletted images
+
+Returns the number of colors in the image's palette.
+
+Returns -1 for direct images.
+
+=cut
+*/
+
+int
+(i_colorcount)(i_img *im) {
+ return i_colorcount(im);
+}
+
+/*
+=item i_maxcolors(im)
+
+=category Paletted images
+
+Returns the maximum number of colors the palette can hold for the
+image.
+
+Returns -1 for direct color images.
+
+=cut
+*/
+
+int
+(i_maxcolors)(i_img *im) {
+ return i_maxcolors(im);
+}
+
+/*
+=item i_findcolor(im, color, &entry)
+
+=category Paletted images
+
+Searches the images palette for the given color.
+
+On success sets *I<entry> to the index of the color, and returns true.
+
+On failure returns false.
+
+Always fails on direct color images.
+
+=cut
+*/
+int
+(i_findcolor)(i_img *im, i_color *color, i_palidx *entry) {
+ return i_findcolor(im, color, entry);
+}
+
+/*
+=item i_setcolors(im, index, colors, count)
+
+=category Paletted images
+
+Sets I<count> colors starting from I<index> in the image's palette.
+
+On sucess returns true.
+
+On failure returns false.
+
+The image must have at least I<index>+I<count> colors in it's palette
+for this to succeed.
+
+Always fails on direct color images.
+
+=cut
+*/
+int
+(i_setcolors)(i_img *im, int index, i_color *colors, int count) {
+ return i_setcolors(im, index, colors, count);
+}
+
--- /dev/null
+#ifndef IMAGER_IMEXT_H_
+#define IMAGER_IMEXT_H_
+
+#include "imexttypes.h"
+
+extern im_ext_funcs *imager_function_ext_table;
+
+#define DEFINE_IMAGER_CALLBACKS im_ext_funcs *imager_function_ext_table
+
+#define PERL_INITIALIZE_IMAGER_CALLBACKS \
+ imager_function_ext_table = INT2PTR(im_ext_funcs *, SvIV(get_sv(PERL_FUNCTION_TABLE_NAME, 1)))
+
+/* just for use here */
+#define im_extt imager_function_ext_table
+
+#define mymalloc(size) ((im_extt->f_mymalloc)(size))
+#define myfree(size) ((im_extt->f_myfree)(size))
+#define myrealloc(block, newsize) ((im_extt->f_myrealloc)((block), (newsize)))
+
+#define i_img_8_new(xsize, ysize, channels) ((im_extt->f_i_img_8_new)((xsize), (ysize), (channels)))
+#define i_img_16_new(xsize, ysize, channels) ((im_extt->f_i_img_16_new)((xsize), (ysize), (channels)))
+#define i_img_double_new(xsize, ysize, channels) ((im_extt->f_i_img_double_new)((xsize), (ysize), (channels)))
+#define i_img_pal_new(xsize, ysize, channels, maxpal) ((im_extt->f_i_img_pal_new)((xsize), (ysize), (channels), (maxpal)))
+
+#define i_img_destroy(im) ((im_extt->f_i_img_destroy)(im))
+#define i_sametype(im, xsize, ysize) ((im_extt->f_i_sametype)((im), (xsize), (ysize)))
+#define i_sametype_chans(im, xsize, ysize, channels) ((im_extt->f_i_sametype_chans)((im), (xsize), (ysize), (channels)))
+#define i_img_info(im, info) ((im_extt->f_i_img_info)((im), (info)))
+
+#ifndef IMAGER_DIRECT_IMAGE_CALLS
+#define IMAGER_DIRECT_IMAGE_CALLS 1
+#endif
+
+#if IMAGER_DIRECT_IMAGE_CALLS
+#define i_ppix(im, x, y, val) (((im)->i_f_ppix)((im), (x), (y), (val)))
+#define i_gpix(im, x, y, val) (((im)->i_f_gpix)((im), (x), (y), (val)))
+#define i_ppixf(im, x, y, val) (((im)->i_f_ppixf)((im), (x), (y), (val)))
+#define i_gpixf(im, x, y, val) (((im)->i_f_gpixf)((im), (x), (y), (val)))
+#define i_plin(im, l, r, y, val) (((im)->i_f_plin)(im, l, r, y, val))
+#define i_glin(im, l, r, y, val) (((im)->i_f_glin)(im, l, r, y, val))
+#define i_plinf(im, l, r, y, val) (((im)->i_f_plinf)(im, l, r, y, val))
+#define i_glinf(im, l, r, y, val) (((im)->i_f_glinf)(im, l, r, y, val))
+
+#define i_gsamp(im, l, r, y, samps, chans, count) \
+ (((im)->i_f_gsamp)((im), (l), (r), (y), (samps), (chans), (count)))
+#define i_gsampf(im, l, r, y, samps, chans, count) \
+ (((im)->i_f_gsampf)((im), (l), (r), (y), (samps), (chans), (count)))
+
+#define i_findcolor(im, color, entry) \
+ (((im)->i_f_findcolor) ? ((im)->i_f_findcolor)((im), (color), (entry)) : 0)
+
+#define i_gpal(im, l, r, y, vals) \
+ (((im)->i_f_gpal) ? ((im)->i_f_gpal)((im), (l), (r), (y), (vals)) : 0)
+#define i_ppal(im, l, r, y, vals) \
+ (((im)->i_f_ppal) ? ((im)->i_f_ppal)((im), (l), (r), (y), (vals)) : 0)
+#define i_addcolors(im, colors, count) \
+ (((im)->i_f_addcolors) ? ((im)->i_f_addcolors)((im), (colors), (count)) : -1)
+#define i_getcolors(im, index, color, count) \
+ (((im)->i_f_getcolors) ? \
+ ((im)->i_f_getcolors)((im), (index), (color), (count)) : 0)
+#define i_setcolors(im, index, color, count) \
+ (((im)->i_f_setcolors) ? \
+ ((im)->i_f_setcolors)((im), (index), (color), (count)) : 0)
+#define i_colorcount(im) \
+ (((im)->i_f_colorcount) ? ((im)->i_f_colorcount)(im) : -1)
+#define i_maxcolors(im) \
+ (((im)->i_f_maxcolors) ? ((im)->i_f_maxcolors)(im) : -1)
+#define i_findcolor(im, color, entry) \
+ (((im)->i_f_findcolor) ? ((im)->i_f_findcolor)((im), (color), (entry)) : 0)
+#else
+#define i_ppix(im, x, y, val) ((im_extt->f_i_ppix)((im), (x), (y), (val)))
+#define i_gpix(im, x, y, val) ((im_extt->f_i_gpix)((im), (x), (y), (val)))
+#define i_ppixf(im, x, y, val) ((im_extt->f_i_ppixf)((im), (x), (y), (val)))
+#define i_gpixf(im, x, y, val) ((im_extt->f_i_gpixf)((im), (x), (y), (val)))
+#define i_plin(im, l, r, y, val) ((im_extt->f_i_plin)((im), (l), (r), (y), (val)))
+#define i_glin(im, l, r, y, val) ((im_extt->f_i_glin)((im), (l), (r), (y), (val)))
+#define i_plinf(im, l, r, y, val) ((im_extt->f_i_plinf)((im), (l), (r), (y), (val)))
+#define i_glinf(im, l, r, y, val) ((im_extt->f_i_glinf)((im), (l), (r), (y), (val)))
+#define i_gsamp(im, l, r, y, samps, chans, count) \
+ ((im_extt->f_i_gsamp)((im), (l), (r), (y), (samps), (chans), (count)))
+#define i_gsampf(im, l, r, y, samps, chans, count) \
+ ((im_extt->f_i_gsampf)((im), (l), (r), (y), (samps), (chans), (count)))
+
+#endif
+
+#define i_new_fill_solid(c, combine) ((im_extt->f_i_new_fill_solid)((c), (combine)))
+#define i_new_fill_solidf(c, combine) ((im_extt->f_i_new_fill_solidf)((c), (combine)))
+#define i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy) \
+ ((im_extt->f_i_new_fill_hatch)((fg), (bg), (combine), (hatch), (cust_hatch), (dx), (dy)))
+#define i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy) \
+ ((im_extt->f_i_new_fill_hatchf)((fg), (bg), (combine), (hatch), (cust_hatch), (dx), (dy)))
+#define i_new_fill_image(im, matrix, xoff, yoff, combine) \
+ ((im_extt->f_i_new_fill_image)((im), (matrix), (xoff), (yoff), (combine)))
+#define i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, count, segs) \
+ ((im_extt->f_i_new_fill_fount)((xa), (ya), (xb), (yb), (type), (repeat), (combine), (super_sample), (ssample_param), (count), (segs)))
+#define i_fill_destroy(fill) ((im_extt->f_i_fill_destroy)(fill))
+
+#define i_quant_makemap(quant, imgs, count) \
+ ((im_extt->f_i_quant_makemap)((quant), (imgs), (count)))
+#define i_quant_translate(quant, img) \
+ ((im_extt->f_i_quant_translate)((quant), (img)))
+#define i_quant_transparent(quant, indices, img, trans_index) \
+ ((im_extt->f_i_quant_transparent)((quant), (indices), (img), (trans_index)))
+
+#define i_clear_error() ((im_extt->f_i_clear_error)())
+#define i_push_error(code, msg) ((im_extt->f_i_push_error)((code), (msg)))
+#define i_push_errorf (im_extt->f_i_push_errorf)
+#define i_push_errorvf(code, fmt, list) \
+ ((im_extt->f_i_push_errorvf)((code), (fmt), (list)))
+
+#define i_tags_new(tags) ((im_extt->f_i_tags_new)(tags))
+#define i_tags_set(tags, name, data, size) \
+ ((im_extt->f_i_tags_set)((tags), (name), (data), (size)))
+#define i_tags_setn(tags, name, idata) \
+ ((im_extt->f_i_tags_setn)((tags), (name), (idata)))
+#define i_tags_destroy(tags) ((im_extt->f_i_tags_destroy)(tags))
+#define i_tags_find(tags, name, start, entry) \
+ ((im_extt->f_i_tags_find)((tags), (name), (start), (entry)))
+#define i_tags_findn(tags, code, start, entry) \
+ ((im_extt->f_i_tags_findn)((tags), (code), (start), (entry)))
+#define i_tags_delete(tags, entry) \
+ ((im_extt->f_i_tags_delete)((tags), (entry)))
+#define i_tags_delbyname(tags, name) \
+ ((im_extt->f_i_tags_delbyname)((tags), (name)))
+#define i_tags_delbycode(tags, code) \
+ ((im_extt->f_i_tags_delbycode)((tags), (code)))
+#define i_tags_get_float(tags, name, code, value) \
+ ((im_extt->f_i_tags_get_float)((tags), (name), (code), (value)))
+#define i_tags_set_float(tags, name, code, value) \
+ ((im_extt->f_i_tags_set_float)((tags), (name), (code), (value)))
+#define i_tags_set_float2(tags, name, code, value, places) \
+ ((im_extt->f_i_tags_set_float2)((tags), (name), (code), (value), (places)))
+#define i_tags_get_int(tags, name, code, value) \
+ ((im_extt->f_i_tags_get_int)((tags), (name), (code), (value)))
+#define i_tags_get_string(tags, name, code, value, value_size) \
+ ((im_extt->f_i_tags_get_string)((tags), (name), (code), (value), (value_size)))
+#define i_tags_get_color(tags, name, code, value) \
+ ((im_extt->f_i_tags_get_color)((tags), (name), (code), (value)))
+#define i_tags_set_color(tags, name, code, value) \
+ ((im_extt->f_i_tags_set_color)((tags), (name), (code), (value)))
+
+#define i_box(im, x1, y1, x2, y2, val) ((im_extt->f_i_box)((im), (x1), (y1), (x2), (y2), (val)))
+#define i_box_filled(im, x1, y1, x2, y2, val) ((im_extt->f_i_box_filled)((im), (x1), (y1), (x2), (y2), (val)))
+#define i_box_cfill(im, x1, y1, x2, y2, fill) ((im_extt->f_i_box_cfill)((im), (x1), (y1), (x2), (y2), (fill)))
+#define i_line(im, x1, y1, x2, y2, val, endp) ((im_extt->f_i_line)((im), (x1), (y1), (x2), (y2), (val), (endp)))
+#define i_line_aa(im, x1, y1, x2, y2, val, endp) ((im_extt->f_i_line_aa)((im), (x1), (y1), (x2), (y2), (val), (endp)))
+#define i_arc(im, x, y, rad, d1, d2, val) ((im_extt->f_i_arc)((im), (x), (y), (rad), (d1), (d2), (val)))
+#define i_arc_aa(im, x, y, rad, d1, d2, val) ((im_extt->f_i_arc_aa)((im), (x), (y), (rad), (d1), (d2), (val)))
+#define i_arc_cfill(im, x, y, rad, d1, d2, fill) ((im_extt->f_i_arc_cfill)((im), (x), (y), (rad), (d1), (d2), (fill)))
+#define i_arc_aa_cfill(im, x, y, rad, d1, d2, fill) ((im_extt->f_i_arc_aa_cfill)((im), (x), (y), (rad), (d1), (d2), (fill)))
+#define i_circle_aa(im, x, y, rad, val) ((im_extt->f_i_circle_aa)((im), (x), (y), (rad), (val)))
+#define i_flood_fill(im, seedx, seedy, dcol) ((im_extt->f_i_flood_fill)((im), (seedx), (seedy), (dcol)))
+#define i_flood_cfill(im, seedx, seedy, fill) ((im_extt->f_i_flood_cfill)((im), (seedx), (seedy), (fill)))
+
+#define i_copyto(im, src, x1, y1, x2, y2, tx, ty) \
+ ((im_extt->f_i_copyto)((im), (src), (x1), (y1), (x2), (y2), (tx), (ty)))
+#define i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans) \
+ ((im_extt->f_i_copyto_trans)((im), (src), (x1), (y1), (x2), (y2), (tx), (ty), (trans)))
+#define i_copy(im) ((im_extt->f_i_copy)(im))
+#define i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy) \
+ ((im_extt->f_i_rubthru)((im), (src), (tx), (ty), (src_minx), (src_miny), (src_maxx), (src_maxy)))
+
+#endif
--- /dev/null
+#ifndef IMAGER_IMEXTDEF_H
+#define IMAGER_IMEXTDEF_H
+
+#include "imexttypes.h"
+
+extern im_ext_funcs imager_function_table;
+
+#define PERL_SET_GLOBAL_CALLBACKS \
+ sv_setiv(get_sv(PERL_FUNCTION_TABLE_NAME, 1), PTR2IV(&imager_function_table));
+
+#endif
--- /dev/null
+#ifndef IMAGER_IMEXTTYPES_H_
+#define IMAGER_IMEXTTYPES_H_
+
+/* keep this file simple - apidocs.perl parses it. */
+
+#include "imdatatypes.h"
+
+typedef struct {
+ void * (*f_mymalloc)(int size);
+ void (*f_myfree)(void *block);
+ void * (*f_myrealloc)(void *block, size_t newsize);
+
+ i_img *(*f_i_img_8_new)(int xsize, int ysize, int channels);
+ i_img *(*f_i_img_16_new)(int xsize, int ysize, int channels);
+ i_img *(*f_i_img_double_new)(int xsize, int ysize, int channels);
+ i_img *(*f_i_img_pal_new)(int xsize, int ysize, int channels, int maxpal);
+ void (*f_i_img_destroy)(i_img *im);
+ i_img *(*f_i_sametype)(i_img *im, int xsize, int ysize);
+ i_img *(*f_i_sametype_chans)(i_img *im, int xsize, int ysize, int channels);
+ void (*f_i_img_info)(i_img *im, int *info);
+
+ int (*f_i_ppix)(i_img *im, int x, int y, i_color *val);
+ int (*f_i_gpix)(i_img *im, int x, int y, i_color *val);
+ int (*f_i_ppixf)(i_img *im, int x, int y, i_fcolor *val);
+ int (*f_i_gpixf)(i_img *im, int x, int y, i_fcolor *val);
+ int (*f_i_plin)(i_img *im, int l, int r, int y, i_color *vals);
+ int (*f_i_glin)(i_img *im, int l, int r, int y, i_color *vals);
+ int (*f_i_plinf)(i_img *im, int l, int r, int y, i_fcolor *vals);
+ int (*f_i_glinf)(i_img *im, int l, int r, int y, i_fcolor *vals);
+ int (*f_i_gsamp)(i_img *im, int l, int r, int y, i_sample_t *samp,
+ const int *chans, int chan_count);
+ int (*f_i_gsampf)(i_img *im, int l, int r, int y, i_fsample_t *samp,
+ const int *chans, int chan_count);
+ int (*f_i_gpal)(i_img *im, int x, int r, int y, i_palidx *vals);
+ int (*f_i_ppal)(i_img *im, int x, int r, int y, i_palidx *vals);
+ int (*f_i_addcolors)(i_img *im, i_color *colors, int count);
+ int (*f_i_getcolors)(i_img *im, int i, i_color *, int count);
+ int (*f_i_colorcount)(i_img *im);
+ int (*f_i_maxcolors)(i_img *im);
+ int (*f_i_findcolor)(i_img *im, i_color *color, i_palidx *entry);
+ int (*f_i_setcolors)(i_img *im, int index, i_color *colors,
+ int count);
+
+ i_fill_t *(*f_i_new_fill_solid)(i_color *c, int combine);
+ i_fill_t *(*f_i_new_fill_solidf)(i_fcolor *c, int combine);
+
+ i_fill_t *(*f_i_new_fill_hatch)(i_color *fg, i_color *bg, int combine,
+ int hatch, unsigned char *cust_hatch,
+ int dx, int dy);
+ i_fill_t *(*f_i_new_fill_hatchf)(i_fcolor *fg, i_fcolor *bg, int combine,
+ int hatch, unsigned char *cust_hatch,
+ int dx, int dy);
+ i_fill_t *(*f_i_new_fill_image)(i_img *im, double *matrix, int xoff,
+ int yoff, int combine);
+ i_fill_t *(*f_i_new_fill_fount)(double xa, double ya, double xb, double yb,
+ i_fountain_type type, i_fountain_repeat repeat,
+ int combine, int super_sample, double ssample_param,
+ int count, i_fountain_seg *segs);
+
+ void (*f_i_fill_destroy)(i_fill_t *fill);
+
+ void (*f_i_quant_makemap)(i_quantize *quant, i_img **imgs, int count);
+ i_palidx * (*f_i_quant_translate)(i_quantize *quant, i_img *img);
+ void (*f_i_quant_transparent)(i_quantize *quant, i_palidx *indices,
+ i_img *img, i_palidx trans_index);
+
+ void (*f_i_clear_error)(void);
+ void (*f_i_push_error)(int code, char const *msg);
+ void (*f_i_push_errorf)(int code, char const *fmt, ...);
+ void (*f_i_push_errorvf)(int code, char const *fmt, va_list);
+
+ void (*f_i_tags_new)(i_img_tags *tags);
+ int (*f_i_tags_set)(i_img_tags *tags, char const *name, char const *data,
+ int size);
+ int (*f_i_tags_setn)(i_img_tags *tags, char const *name, int idata);
+ void (*f_i_tags_destroy)(i_img_tags *tags);
+ int (*f_i_tags_find)(i_img_tags *tags, char const *name, int start,
+ int *entry);
+ int (*f_i_tags_findn)(i_img_tags *tags, int code, int start, int *entry);
+ int (*f_i_tags_delete)(i_img_tags *tags, int entry);
+ int (*f_i_tags_delbyname)(i_img_tags *tags, char const *name);
+ int (*f_i_tags_delbycode)(i_img_tags *tags, int code);
+ int (*f_i_tags_get_float)(i_img_tags *tags, char const *name, int code,
+ double *value);
+ int (*f_i_tags_set_float)(i_img_tags *tags, char const *name, int code,
+ double value);
+ int (*f_i_tags_set_float2)(i_img_tags *tags, char const *name, int code,
+ double value, int places);
+ int (*f_i_tags_get_int)(i_img_tags *tags, char const *name, int code,
+ int *value);
+ int (*f_i_tags_get_string)(i_img_tags *tags, char const *name, int code,
+ char *value, size_t value_size);
+ int (*f_i_tags_get_color)(i_img_tags *tags, char const *name, int code,
+ i_color *value);
+ int (*f_i_tags_set_color)(i_img_tags *tags, char const *name, int code,
+ i_color const *value);
+
+ void (*f_i_box)(i_img *im, int x1, int y1, int x2, int y2, i_color *val);
+ void (*f_i_box_filled)(i_img *im, int x1, int y1, int x2, int y2, i_color *val);
+ void (*f_i_box_cfill)(i_img *im, int x1, int y1, int x2, int y2, i_fill_t *fill);
+ void (*f_i_line)(i_img *im, int x1, int y1, int x2, int y2, i_color *val, int endp);
+ void (*f_i_line_aa)(i_img *im, int x1, int y1, int x2, int y2, i_color *val, int endp);
+ void (*f_i_arc)(i_img *im, int x, int y, float rad, float d1, float d2, i_color *val);
+ void (*f_i_arc_aa)(i_img *im, double x, double y, double rad, double d1, double d2, i_color *val);
+ void (*f_i_arc_cfill)(i_img *im, int x, int y, float rad, float d1, float d2, i_fill_t *val);
+ void (*f_i_arc_aa_cfill)(i_img *im, double x, double y, double rad, double d1, double d2, i_fill_t *fill);
+ void (*f_i_circle_aa)(i_img *im, float x, float y, float rad, i_color *val);
+ int (*f_i_flood_fill)(i_img *im, int seedx, int seedy, i_color *dcol);
+ int (*f_i_flood_cfill)(i_img *im, int seedx, int seedy, i_fill_t *fill);
+
+ void (*f_i_copyto)(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty);
+ void (*f_i_copyto_trans)(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty, i_color *trans);
+ i_img *(*f_i_copy)(i_img *im);
+ int (*f_i_rubthru)(i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny, int src_maxx, int src_maxy);
+} im_ext_funcs;
+
+#define PERL_FUNCTION_TABLE_NAME "Imager::__ext_func_table"
+
+#endif
=cut
*/
-#include "image.h"
-#include "imagei.h"
+#include "imager.h"
+#include "imageri.h"
static int i_ppix_d16(i_img *im, int x, int y, i_color *val);
static int i_gpix_d16(i_img *im, int x, int y, i_color *val);
#endif
/*
-=item i_img_16_new(int x, int y, int ch)
+=item i_img_16_new_low(int x, int y, int ch)
Creates a new 16-bit per sample image.
return im;
}
+/*
+=item i_img_16_new(x, y, ch)
+
+=category Image creation
+
+Create a new 16-bit/sample image.
+
+Returns the image on success, or NULL on failure.
+
+=cut
+*/
+
i_img *i_img_16_new(int x, int y, int ch) {
i_img *im;
=cut
*/
-#include "image.h"
-#include "imagei.h"
+#include "imager.h"
+#include "imageri.h"
static int i_ppix_ddoub(i_img *im, int x, int y, i_color *val);
static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val);
/*
=item i_img_double_new(int x, int y, int ch)
+=category Image creation
+
Creates a new double per sample image.
=cut
--- /dev/null
+/*
+ This header file defines types that Imager's typemap uses to convert to
+ perl types.
+
+ This is meant for use in XS code, not in normal C source.
+ */
+#ifndef IMAGER_IMPERL_H
+#define IMAGER_IMPERL_H
+
+#include "imdatatypes.h"
+
+typedef i_color* Imager__Color;
+typedef i_fcolor* Imager__Color__Float;
+typedef i_img* Imager__ImgRaw;
+typedef int undef_neg_int;
+typedef i_img * Imager;
+
+#ifdef HAVE_LIBTT
+typedef TT_Fonthandle* Imager__Font__TT;
+#endif
+
+#ifdef HAVE_FT2
+typedef FT2_Fonthandle* Imager__Font__FT2;
+#endif
+
+/* for the fill objects
+ Since a fill object may later have dependent images, (or fills!)
+ we need perl wrappers - oh well
+*/
+#define IFILL_DESTROY(fill) i_fill_destroy(fill);
+typedef i_fill_t* Imager__FillHandle;
+
+#endif
#include <setjmp.h>
#include "iolayer.h"
-#include "imagei.h"
+#include "imageri.h"
#include "jpeglib.h"
#include "jerror.h"
#include <errno.h>
--- /dev/null
+=head1 NAME
+
+Imager::API - Imager's C API - introduction.
+
+=head1 SYNOPSIS
+
+ #include "imext.h"
+ #include "imperl.h"
+
+ DEFINE_IMAGER_CALLBACKS;
+
+ MODULE = Your::Module PACKAGE = Your::Module
+
+ ...
+
+ BOOT:
+ PERL_INITIALIZE_IMAGER_CALLBACKS;
+
+
+=head1 DESCRIPTION
+
+The API allows you to access Imager functions at the C level from XS
+and from Inline::C.
+
+The intent is to allow users to:
+
+=over
+
+=item *
+
+write C code that does Imager operations the user might do from Perl,
+but faster, for example, the Imager::CountColor example.
+
+=item *
+
+write C code that implements an application specific version of some
+core Imager object, for example, Imager::SDL.
+
+=item *
+
+write C code that hooks into Imagers existing methods, such as filter
+or file format handlers.
+
+=back
+
+See L<Imager::Inline> for information on using Imager's Inline::C
+support.
+
+=head1 Types
+
+The API makes the following types visible:
+
+=over
+
+=item *
+
+i_img - used to represent an image
+
+=item *
+
+i_color - used to represent a color with up to 8 bits per sample.
+
+=item *
+
+i_fcolor - used to represent a color with a double per sample.
+
+=item *
+
+i_fill_t - an abstract fill
+
+=back
+
+At this point there is no consolidated font object type, and hence the
+font functions are not visible through Imager's API.
+
+=head2 i_img - images
+
+This contains the dimensions of the image (xsize, ysize, channels),
+image metadata (ch_mask, bits, type, virtual), potentially image data
+(idata) and the a function table, with pointers to functions to
+perform various low level image operations.
+
+The only time you should directly write to any value in this type is
+if you're implementing your own image type.
+
+=head2 i_color - 8-bit color
+
+Represents an 8-bit per sample color. This is a union containing
+several different structs for access to components of a color:
+
+=over
+
+=item *
+
+gray - single member gray_color.
+
+=item *
+
+rgb - r, g, b members.
+
+=item *
+
+rgba - r, g, b, a members.
+
+=item *
+
+channels - array of channels.
+
+=back
+
+=head2 i_fcolor - floating point color
+
+Similar to i_fcolor except that each component is a double instead of
+an unsigned char.
+
+=head2 i_fill_t - fill objects
+
+Abstract type containing pointers called to perform low level fill
+operations.
+
+Unless you're defining your own fill objects you should treat this as
+an opaque type.
+
+=head1 Create an XS module using the Imager API
+
+=head2 Foo.xs
+
+You'll need the following in your XS source:
+
+=over
+
+=item *
+
+include the Imager external API header, and the perl interface header:
+
+ #include "imext.h"
+ #include "imperl.h"
+
+=item *
+
+create the variables used to hold the callback table:
+
+ DEFINE_IMAGER_CALLBACKS;
+
+=item *
+
+initialize the callback table in your BOOT code:
+
+ BOOT:
+ PERL_INITIALIZE_IMAGER_CALLBACKS;
+
+=back
+
+=head2 foo.c
+
+In any other source files where you want to access the Imager API,
+you'll need to:
+
+=over
+
+=item *
+
+include the Imager external API header:
+
+ #include "imext.h"
+
+=back
+
+=head2 Makefile.PL
+
+If you're creating an XS module that depends on Imager's API your
+Makefile.PL will need to do the following:
+
+=over
+
+=item *
+
+C<use Imager::ExtUtils;>
+
+=item *
+
+include Imager's include directory in INC:
+
+ INC => Imager::ExtUtils->includes
+
+=item *
+
+use Imager's typemap:
+
+ TYPEMAPS => [ Imager::ExtUtils->typemap ]
+
+=item *
+
+include Imager 0.48 as a PREREQ_PM:
+
+ PREREQ_PM =>
+ {
+ Imager => 0.48,
+ },
+
+=back
+
+=head1 AUTHOR
+
+Tony Cook <tony@imager.perl.org>
+
+=head1 SEE ALSO
+
+Imager, Imager::ExtUtils, Imager::APIRef, Imager::Inline
+
+=cut
--- /dev/null
+Do not edit this file, it is generated automatically by apidocs.perl
+from Imager's source files.
+
+Each function description has a comment listing the source file and
+line number where you can find the documentation.
+
+=head1 NAME
+
+Imager::APIRef - Imager's C API.
+
+=head1 SYNOPSIS
+
+ i_color color;
+ color.rgba.red = 255; color.rgba.green = 0; color.rgba.blue = 255;
+ i_fill_t *fill = i_new_fill_...(...);
+
+
+ # Drawing
+ i_arc(im, 50, 50, 20, 45, 135, &color);
+ i_arc_aa(im, 50, 50, 35, 90, 135, &color);
+ i_arc_aa_cfill(im, 50, 50, 35, 90, 135, fill);
+ i_arc_cfill(im, 50, 50, 35, 90, 135, fill);
+ i_box(im, 0, 0, im->xsize-1, im->ysize-1, &color).
+ i_box_cfill(im, 0, 0, im->xsize-1, im->ysize-1, fill);
+ i_box_filled(im, 0, 0, im->xsize-1, im->ysize-1, &color);
+ i_circle_aa(im, 50, 50, 45, &color);
+ i_flood_cfill(im, 50, 50, fill);
+ i_flood_fill(im, 50, 50, &color);
+
+ # Error handling
+
+ # Fills
+ fill = i_new_fill_fount(0, 0, 100, 100, i_ft_linear, i_ft_linear,
+ i_fr_triangle, 0, i_fts_grid, 9, 1, segs);
+
+ # Image
+
+ # Image creation
+
+ # Image quantization
+
+ # Paletted images
+
+ # Tags
+
+ i_fill_destroy(fill);
+
+=head1 DESCRIPTION
+
+=head2 Drawing
+
+=over
+
+=item i_arc(im, x, y, rad, d1, d2, color)
+
+
+Fills an arc centered at (x,y) with radius I<rad> covering the range
+of angles in degrees from d1 to d2, with the color.
+
+
+=for comment
+From: Line 205 in draw.c
+
+=item i_arc_aa(im, x, y, rad, d1, d2, color)
+
+
+Antialias fills an arc centered at (x,y) with radius I<rad> covering
+the range of angles in degrees from d1 to d2, with the color.
+
+
+=for comment
+From: Line 329 in draw.c
+
+=item i_arc_aa_cfill(im, x, y, rad, d1, d2, fill)
+
+
+Antialias fills an arc centered at (x,y) with radius I<rad> covering
+the range of angles in degrees from d1 to d2, with the fill object.
+
+
+=for comment
+From: Line 355 in draw.c
+
+=item i_arc_cfill(im, x, y, rad, d1, d2, fill)
+
+
+Fills an arc centered at (x,y) with radius I<rad> covering the range
+of angles in degrees from d1 to d2, with the fill object.
+
+
+=for comment
+From: Line 230 in draw.c
+
+=item i_box(im, x1, y1, x2, y2, color)
+
+
+Outlines the box from (x1,y1) to (x2,y2) inclusive with I<color>.
+
+
+=for comment
+From: Line 531 in draw.c
+
+=item i_box_cfill(im, x1, y1, x2, y2, fill)
+
+
+Fills the box from (x1,y1) to (x2,y2) inclusive with fill.
+
+
+=for comment
+From: Line 574 in draw.c
+
+=item i_box_filled(im, x1, y1, x2, y2, color)
+
+
+Fills the box from (x1,y1) to (x2,y2) inclusive with color.
+
+
+=for comment
+From: Line 556 in draw.c
+
+=item i_circle_aa(im, x, y, rad, color)
+
+
+Antialias fills a circle centered at (x,y) for radius I<rad> with
+color.
+
+
+=for comment
+From: Line 477 in draw.c
+
+=item i_flood_cfill(im, seedx, seedy, fill)
+
+
+Flood fills the 4-connected region starting from the point (seedx,
+seedy) with I<fill>.
+
+Returns false if (seedx, seedy) are outside the image.
+
+
+=for comment
+From: Line 1332 in draw.c
+
+=item i_flood_fill(im, seedx, seedy, color)
+
+
+Flood fills the 4-connected region starting from the point (seedx,
+seedy) with I<color>.
+
+Returns false if (seedx, seedy) are outside the image.
+
+
+=for comment
+From: Line 1295 in draw.c
+
+=item i_glin(im, l, r, y, colors)
+
+
+Retrieves (r-l) pixels starting from (l,y) into I<colors>.
+
+Returns the number of pixels retrieved.
+
+
+=for comment
+From: Line 195 in imext.c
+
+=item i_glinf(im, l, r, y, colors)
+
+
+Retrieves (r-l) pixels starting from (l,y) into I<colors> as floating
+point colors.
+
+Returns the number of pixels retrieved.
+
+
+=for comment
+From: Line 230 in imext.c
+
+=item i_gpal(im, x, r, y, indexes)
+
+
+Reads palette indexes for the horizontal line (x, y) to (r-1, y) into
+indexes.
+
+Returns the number of indexes read.
+
+Always returns 0 for direct color images.
+
+
+=for comment
+From: Line 294 in imext.c
+
+=item i_gpix(im, x, y, color)
+
+
+Retrieves the I<color> of the pixel (x,y).
+
+Returns 0 if the pixel was retrieved, or -1 if not.
+
+
+=for comment
+From: Line 123 in imext.c
+
+=item i_gpixf(im, x, y, fcolor)
+
+
+Retrieves the color of the pixel (x,y) as a floating point color into
+I<fcolor>.
+
+Returns 0 if the pixel was retrieved, or -1 if not.
+
+
+=for comment
+From: Line 159 in imext.c
+
+=item i_gsamp(im, l, r, y, samp, chans, chan_count)
+
+
+Reads sample values from im for the horizontal line (l, y) to (r-1,y)
+for the channels specified by chans, an array of int with chan_count
+elements.
+
+If chans is NULL then the first chan_count channels are retrieved for
+each pixel.
+
+Returns the number of samples read (which should be (r-l) *
+chan_count)
+
+
+=for comment
+From: Line 248 in imext.c
+
+=item i_gsampf(im, l, r, y, samp, chans, chan_count)
+
+
+Reads floating point sample values from im for the horizontal line (l,
+y) to (r-1,y) for the channels specified by chans, an array of int
+with chan_count elements.
+
+If chans is NULL then the first chan_count channels are retrieved for
+each pixel.
+
+Returns the number of samples read (which should be (r-l) *
+chan_count)
+
+
+=for comment
+From: Line 271 in imext.c
+
+=item i_line(im, x1, y1, x2, y2, val, endp)
+
+
+Draw a line to image using bresenhams linedrawing algorithm
+
+ im - image to draw to
+ x1 - starting x coordinate
+ y1 - starting x coordinate
+ x2 - starting x coordinate
+ y2 - starting x coordinate
+ val - color to write to image
+ endp - endpoint flag (boolean)
+
+
+=for comment
+From: Line 645 in draw.c
+
+=item i_line_aa(im, x1, x2, y1, y2, color, endp)
+
+
+Antialias draws a line from (x1,y1) to (x2, y2) in color.
+
+The point (x2, y2) is drawn only if endp is set.
+
+
+=for comment
+From: Line 849 in draw.c
+
+=item i_plin(im, l, r, y, colors)
+
+
+Sets (r-l) pixels starting from (l,y) using (r-l) values from
+I<colors>.
+
+Returns the number of pixels set.
+
+
+=for comment
+From: Line 177 in imext.c
+
+=item i_plinf(im, l, r, fcolors)
+
+
+Sets (r-l) pixels starting from (l,y) using (r-l) floating point
+colors from I<colors>.
+
+Returns the number of pixels set.
+
+
+=for comment
+From: Line 212 in imext.c
+
+=item i_ppal(im, x, r, y, indexes)
+
+
+Writes palette indexes for the horizontal line (x, y) to (r-1, y) from
+indexes.
+
+Returns the number of indexes written.
+
+Always returns 0 for direct color images.
+
+
+=for comment
+From: Line 313 in imext.c
+
+=item i_ppix(im, x, y, color)
+
+
+Sets the pixel at (x,y) to I<color>.
+
+Returns 0 if the pixel was drawn, or -1 if not.
+
+Does no alpha blending, just copies the channels from the supplied
+color to the image.
+
+
+=for comment
+From: Line 103 in imext.c
+
+=item i_ppixf(im, x, y, fcolor)
+
+
+Sets the pixel at (x,y) to the floating point color I<fcolor>.
+
+Returns 0 if the pixel was drawn, or -1 if not.
+
+Does no alpha blending, just copies the channels from the supplied
+color to the image.
+
+
+=for comment
+From: Line 140 in imext.c
+
+
+=back
+
+=head2 Error handling
+
+=over
+
+=item i_clear_error()
+
+
+Clears the error stack.
+
+Called by any imager function before doing any other processing.
+
+
+=for comment
+From: Line 185 in error.c
+
+=item i_push_error(int code, char const *msg)
+
+
+Called by an imager function to push an error message onto the stack.
+
+No message is pushed if the stack is full (since this means someone
+forgot to call i_clear_error(), or that a function that doesn't do
+error handling is calling function that does.).
+
+
+=for comment
+From: Line 211 in error.c
+
+=item i_push_errorf(int code, char const *fmt, ...)
+
+
+A version of i_push_error() that does printf() like formating.
+
+
+=for comment
+From: Line 273 in error.c
+
+=item i_push_errorvf(int code, char const *fmt, va_list ap)
+
+
+Intended for use by higher level functions, takes a varargs pointer
+and a format to produce the finally pushed error message.
+
+
+=for comment
+From: Line 249 in error.c
+
+
+=back
+
+=head2 Fills
+
+=over
+
+=item i_fill_destroy(fill)
+
+
+Call to destroy any fill object.
+
+
+=for comment
+From: Line 196 in fills.c
+
+=item i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, count, segs)
+
+
+
+Creates a new general fill which fills with a fountain fill.
+
+
+=for comment
+From: Line 1666 in filters.c
+
+=item i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
+
+
+Creates a new hatched fill with the fg color used for the 1 bits in
+the hatch and bg for the 0 bits. If combine is non-zero alpha values
+will be combined.
+
+If cust_hatch is non-NULL it should be a pointer to 8 bytes of the
+hash definition, with the high-bits to the left.
+
+If cust_hatch is NULL then one of the standard hatches is used.
+
+(dx, dy) are an offset into the hatch which can be used to unalign adjoining areas, or to align the origin of a hatch with the the side of a filled area.
+
+
+=for comment
+From: Line 427 in fills.c
+
+=item i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
+
+
+Creates a new hatched fill with the fg color used for the 1 bits in
+the hatch and bg for the 0 bits. If combine is non-zero alpha values
+will be combined.
+
+If cust_hatch is non-NULL it should be a pointer to 8 bytes of the
+hash definition, with the high-bits to the left.
+
+If cust_hatch is NULL then one of the standard hatches is used.
+
+(dx, dy) are an offset into the hatch which can be used to unalign adjoining areas, or to align the origin of a hatch with the the side of a filled area.
+
+
+=for comment
+From: Line 452 in fills.c
+
+=item i_new_fill_image(im, matrix, xoff, yoff, combine)
+
+
+Create an image based fill.
+
+matrix is an array of 9 doubles representing a transformation matrix.
+
+xoff and yoff are the offset into the image to start filling from.
+
+
+=for comment
+From: Line 489 in fills.c
+
+=item i_new_fill_solid(color, combine)
+
+
+Create a solid fill based on an 8-bit color.
+
+If combine is non-zero then alpha values will be combined.
+
+
+=for comment
+From: Line 244 in fills.c
+
+=item i_new_fill_solidf(color, combine)
+
+
+Create a solid fill based on a float color.
+
+If combine is non-zero then alpha values will be combined.
+
+
+=for comment
+From: Line 213 in fills.c
+
+
+=back
+
+=head2 Image
+
+=over
+
+=item i_copy(src)
+
+
+Creates a new image that is a copy of src.
+
+Tags are not copied, only the image data.
+
+Returns: i_img *
+
+
+=for comment
+From: Line 626 in image.c
+
+=item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
+
+
+Copies image data from the area (x1,y1)-[x2,y2] in the source image to
+a rectangle the same size with it's top-left corner at (tx,ty) in the
+destination image.
+
+If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
+
+
+=for comment
+From: Line 557 in image.c
+
+=item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
+
+
+(x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
+(tx,ty) specifies the upper left corner for the target image.
+pass NULL in trans for non transparent i_colors.
+
+
+=for comment
+From: Line 515 in image.c
+
+=item i_img_destroy(im)
+
+
+Destroy image and free data via exorcise.
+
+ im - Image pointer
+
+
+=for comment
+From: Line 424 in image.c
+
+=item i_img_info(im, info)
+
+
+Return image information
+
+ im - Image pointer
+ info - pointer to array to return data
+
+info is an array of 4 integers with the following values:
+
+ info[0] - width
+ info[1] - height
+ info[2] - channels
+ info[3] - channel mask
+
+
+=for comment
+From: Line 443 in image.c
+
+=item i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy )
+
+
+Takes the sub image I<src[src_minx, src_maxx)[src_miny, src_maxy)> and
+overlays it at (I<tx>,I<ty>) on the image object.
+
+The alpha channel of each pixel in I<src> is used to control how much
+the existing colour in I<im> is replaced, if it is 255 then the colour
+is completely replaced, if it is 0 then the original colour is left
+unmodified.
+
+
+=for comment
+From: Line 701 in image.c
+
+
+=back
+
+=head2 Image creation
+
+=over
+
+=item i_img_16_new(x, y, ch)
+
+
+Create a new 16-bit/sample image.
+
+Returns the image on success, or NULL on failure.
+
+
+=for comment
+From: Line 192 in img16.c
+
+=item i_img_8_new(x, y, ch)
+
+
+Creates a new image object I<x> pixels wide, and I<y> pixels high with
+I<ch> channels.
+
+
+=for comment
+From: Line 257 in image.c
+
+=item i_img_double_new(int x, int y, int ch)
+
+
+Creates a new double per sample image.
+
+
+=for comment
+From: Line 82 in imgdouble.c
+
+=item i_img_pal_new(x, y, channels, maxpal)
+
+
+Creates a new paletted image of the supplied dimensions.
+
+Returns a new image or NULL on failure.
+
+
+=for comment
+From: Line 136 in palimg.c
+
+=item i_sametype(i_img *im, int xsize, int ysize)
+
+
+Returns an image of the same type (sample size, channels, paletted/direct).
+
+For paletted images the palette is copied from the source.
+
+
+=for comment
+From: Line 1107 in image.c
+
+=item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
+
+
+Returns an image of the same type (sample size).
+
+For paletted images the equivalent direct type is returned.
+
+
+=for comment
+From: Line 1149 in image.c
+
+
+=back
+
+=head2 Image quantization
+
+=over
+
+=item i_quant_makemap(quant, imgs, count)
+
+
+Analyzes the I<count> images in I<imgs> according to the rules in
+I<quant> to build a color map (optimal or not depending on
+quant->make_colors).
+
+
+=for comment
+From: Line 30 in quant.c
+
+=item i_quant_translate(quant, img)
+
+
+Quantize the image given the palette in quant.
+
+On success returns a pointer to a memory block of img->xsize *
+img->ysize i_palidx entries.
+
+On failure returns NULL.
+
+You should call myfree() on the returned block when you're done with
+it.
+
+This function will fail if the supplied palette contains no colors.
+
+
+=for comment
+From: Line 86 in quant.c
+
+=item i_quant_transparent(quant, data, img, trans_index)
+
+
+Dither the alpha channel on I<img> into the palette indexes in
+I<data>. Pixels to be transparent are replaced with I<trans_pixel>.
+
+The method used depends on the tr_* members of quant.
+
+
+=for comment
+From: Line 1470 in quant.c
+
+
+=back
+
+=head2 Paletted images
+
+=over
+
+=item i_addcolors(im, colors, count)
+
+
+Adds colors to the image's palette.
+
+On success returns the index of the lowest color added.
+
+On failure returns -1.
+
+Always fails for direct color images.
+
+
+=for comment
+From: Line 332 in imext.c
+
+=item i_colorcount(im)
+
+
+Returns the number of colors in the image's palette.
+
+Returns -1 for direct images.
+
+
+=for comment
+From: Line 378 in imext.c
+
+=item i_findcolor(im, color, &entry)
+
+
+Searches the images palette for the given color.
+
+On success sets *I<entry> to the index of the color, and returns true.
+
+On failure returns false.
+
+Always fails on direct color images.
+
+
+=for comment
+From: Line 413 in imext.c
+
+=item i_getcolors(im, index, colors, count)
+
+
+Retrieves I<count> colors starting from I<index> in the image's
+palette.
+
+On success stores the colors into I<colors> and returns true.
+
+On failure returns false.
+
+Always fails for direct color images.
+
+Fails if there are less than I<index>+I<count> colors in the image's
+palette.
+
+
+=for comment
+From: Line 353 in imext.c
+
+=item i_maxcolors(im)
+
+
+Returns the maximum number of colors the palette can hold for the
+image.
+
+Returns -1 for direct color images.
+
+
+=for comment
+From: Line 395 in imext.c
+
+=item i_setcolors(im, index, colors, count)
+
+
+Sets I<count> colors starting from I<index> in the image's palette.
+
+On sucess returns true.
+
+On failure returns false.
+
+The image must have at least I<index>+I<count> colors in it's palette
+for this to succeed.
+
+Always fails on direct color images.
+
+
+=for comment
+From: Line 433 in imext.c
+
+
+=back
+
+=head2 Tags
+
+=over
+
+=item i_tags_delbycode(tags, code)
+
+
+Delete any tags with the given code.
+
+Returns the number of tags deleted.
+
+
+=for comment
+From: Line 294 in tags.c
+
+=item i_tags_delbyname(tags, name)
+
+
+Delete any tags with the given name.
+
+Returns the number of tags deleted.
+
+
+=for comment
+From: Line 264 in tags.c
+
+=item i_tags_delete(tags, index)
+
+
+Delete a tag by index.
+
+Returns true on success.
+
+
+=for comment
+From: Line 235 in tags.c
+
+=item i_tags_destroy(tags)
+
+
+Destroys the given tags structure. Called by i_img_destroy().
+
+
+=for comment
+From: Line 158 in tags.c
+
+=item i_tags_find(tags, name, start, &entry)
+
+
+Searchs for a tag of the given I<name> starting from index I<start>.
+
+On success returns true and sets *I<entry>.
+
+On failure returns false.
+
+
+=for comment
+From: Line 181 in tags.c
+
+=item i_tags_findn(tags, code, start, &entry)
+
+
+Searchs for a tag of the given I<code> starting from index I<start>.
+
+On success returns true and sets *I<entry>.
+
+On failure returns false.
+
+
+=for comment
+From: Line 208 in tags.c
+
+=item i_tags_get_color(tags, name, code, &value)
+
+
+Retrieve a tag specified by name or code as color.
+
+On success sets the i_color *I<value> to the color and returns true.
+
+On failure returns false.
+
+
+=for comment
+From: Line 505 in tags.c
+
+=item i_tags_get_float(tags, name, code, value)
+
+
+Retrieves a tag as a floating point value.
+
+If the tag has a string value then that is parsed as a floating point
+number, otherwise the integer value of the tag is used.
+
+On success sets *I<value> and returns true.
+
+On failure returns false.
+
+
+=for comment
+From: Line 320 in tags.c
+
+=item i_tags_get_int(tags, name, code, &value)
+
+
+Retrieve a tag specified by name or code as an integer.
+
+On success sets the i_color *I<value> to the color and returns true.
+
+On failure returns false.
+
+
+=for comment
+From: Line 406 in tags.c
+
+=item i_tags_get_string(tags, name, code, value, value_size)
+
+
+Retrieves a tag by name or code as a string.
+
+On success copies the string to value for a max of value_size and
+returns true.
+
+On failure returns false.
+
+value_size must be at least large enough for a string representation
+of an integer.
+
+The copied value is always NUL terminated.
+
+
+=for comment
+From: Line 569 in tags.c
+
+=item i_tags_new(i_img_tags *tags)
+
+
+Initialize a tags structure. Should not be used if the tags structure
+has been previously used.
+
+This should be called tags member of an i_img object on creation (in
+i_img_*_new() functions).
+
+To destroy the contents use i_tags_destroy()
+
+
+=for comment
+From: Line 61 in tags.c
+
+=item i_tags_set(tags, name, data, size)
+
+
+Sets the given tag to the string I<data>
+
+
+=for comment
+From: Line 617 in tags.c
+
+=item i_tags_set_color(tags, name, code, &value)
+
+
+Stores the given color as a tag with the given name and code.
+
+
+=for comment
+From: Line 545 in tags.c
+
+=item i_tags_set_float(tags, name, code, value)
+
+
+Equivalent to i_tags_set_float2(tags, name, code, value, 30).
+
+
+=for comment
+From: Line 359 in tags.c
+
+=item i_tags_set_float2(tags, name, code, value, places)
+
+
+Sets the tag with the given name and code to the given floating point
+value.
+
+Since tags are strings or ints, we convert the value to a string before
+storage at the precision specified by C<places>.
+
+
+=for comment
+From: Line 374 in tags.c
+
+=item i_tags_setn(tags, name, idata)
+
+
+Sets the given tag to the integer I<idata>
+
+
+=for comment
+From: Line 634 in tags.c
+
+
+=back
+
+
+=head1 AUTHOR
+
+Tony Cook <tony@imager.perl.org>
+
+=head1 SEE ALSO
+
+Imager, Imager::ExtUtils, Imager::Inline
+
+=cut
--- /dev/null
+package Imager::ExtUtils;
+use strict;
+
+=head1 NAME
+
+Imager::ExtUtils - functions handy in writing Imager extensions
+
+=head1 SYNOPSIS
+
+ # make Imager easier to use with Inline
+ # perldoc Imager::Inline
+ use Inline with => 'Imager';
+
+=head1 DESCRIPTION
+
+=over
+
+=item base_dir
+
+Returns the base directory where Imager is installed.
+
+=cut
+
+# figure out where Imager is installed
+sub base_dir {
+ for my $dir (@INC) {
+ if (-e "$dir/Imager.pm") {
+ return $dir;
+ }
+ }
+
+ die "Cannot locate an installed Imager!";
+}
+
+=item inline_config
+
+Implements Imager's Inline::C C<with> hook.
+
+=cut
+
+sub inline_config {
+ my ($class) = @_;
+ my $base = base_dir();
+
+ return
+ {
+ INC => $class->includes,
+ TYPEMAPS => $class->typemap,
+ AUTO_INCLUDE => <<'CODE',
+#include "imext.h"
+#include "imperl.h"
+DEFINE_IMAGER_CALLBACKS;
+CODE
+ BOOT => 'PERL_INITIALIZE_IMAGER_CALLBACKS;',
+ FILTERS => \&_inline_filter,
+ };
+}
+
+my @inline_replace =
+ qw(
+ Imager::ImgRaw
+ Imager::Color::Float
+ Imager::Color
+ Imager::IO
+ );
+
+my %inline_replace =
+ map { (my $tmp = $_) =~ s/::/__/g; $_ => $tmp } @inline_replace;
+
+my $inline_replace_re = "\\b(" . join('|', @inline_replace) . ")\\b";
+
+sub _inline_filter {
+ my $code = shift;
+
+ $code =~ s/$inline_replace_re/$inline_replace{$1}/g;
+
+ $code;
+}
+
+=item includes
+
+Returns -I options suitable for use with ExtUtils::MakeMaker's INC
+option.
+
+=cut
+
+sub includes {
+ my $class = shift;
+ my $base = $class->base_dir();
+
+ "-I" . $base . '/Imager/include',
+}
+
+=item typemap
+
+Returns the full path to Imager's installed typemap.
+
+=cut
+
+sub typemap {
+ my $class = shift;
+ my $base = $class->base_dir();
+
+ $base . '/Imager/typemap';
+}
+
+1;
+
+__END__
+
+=back
+
+=head1 AUTHOR
+
+Tony Cook <tony@imager.perl.org>
+
+=head1 REVISION
+
+$Revision$
+
+=head1 SEE ALSO
+
+Imager, Imager::API, Imager::Inline, Imager::APIRef.
+
+=cut
--- /dev/null
+=head1 NAME
+
+Imager::Inline - using Imager with Inline::C.
+
+=head1 SYNOPSIS
+
+ use Inline with => 'Imager';
+ use Inline C => <<'EOS';
+ Imager some_func(Imager::Color c, Imager::Fill f) {
+ Imager img = i_img_8_new(200, 200, 3);
+ /* fill with color */
+ i_box_filled(img, 0, 0, 199, 199, c);
+ /* inner area with fill */
+ i_box_cfill(img, 50, 50, 149, 149, f);
+
+ return img;
+ }
+ EOS
+
+=head1 DESCRIPTION
+
+Imager hooks into Inline's C<with> syntax to make it easier to write
+Inline::C code that works with Imager, you can call Imager functions
+without having to include headers or perform initialization.
+
+Imager's inline C<with> support does the following:
+
+=over
+
+=item *
+
+add the installed Imager include directory to INC
+
+=item *
+
+add the Imager typemap to TYPEMAPS
+
+=item *
+
+include the headers needed by Imager C extension modules.
+
+=item *
+
+declare and initialize the Imager API function table pointer
+
+=item *
+
+filter the supplied code to replace Imager's class names with those
+that Inline::C can handle.
+
+=back
+
+=head1 LIMITATIONS
+
+The filtering mechanism is global, it will replace the class names
+even inside string constants. If you need a string matching the name
+of one of Imager's classes, like C<"Imager::Color"> you will need to
+split it into 2 to use C's string pasting mechanism, for example:
+C<"Imager:" ":Color">.
+
+=head1 AUTHOR
+
+Tony Cook <tony@imager.perl.org>
+
+=head1 REVISION
+
+$Revision$
+
+=head1 SEE ALSO
+
+Imager, Imager::ExtUtils, Imager::API, Imager::APIRef
+
+=cut
=item paste
+X<paste>To copy an image to onto another image use the C<paste()>
+method.
-To copy an image to onto another image use the C<paste()> method.
-
- $dest->paste(left=>40,top=>20,img=>$logo);
+ $dest->paste(left=>40, top=>20, src=>$logo);
That copies the entire C<$logo> image onto the C<$dest> image so that the
upper left corner of the C<$logo> image is at (40,20).
+Parameters:
+
+=over
+
+=item *
+
+src, img - the source image. I<src> added for compatibility with
+rubthrough().
+
+=item *
+
+left, top - position in output of the top left of the pasted image.
+Default: (0,0)
+
+=item *
+
+src_minx, src_miny - the top left corner in the source image to start
+the paste from. Default: (0, 0)
+
+=item *
+
+src_maxx, src_maxy - the bottom right in the source image of the sub
+image to paste. This position is B<non> inclusive. Default: bottom
+right corner of the source image.
+
+=item *
+
+width, height - if the corresponding src_maxx or src_maxy is not
+defined then width or height is used for the width or height of the
+sub image to be pasted.
+
+=back
+ # copy the 20x20 pixel image from (20,20) in $src_image to (10,10) in $img
+ $img->paste(src=>$src_image,
+ left => 10, top => 10,
+ src_minx => 20, src_miny => 20,
+ src_maxx => 40, src_maxx => 40);
+
=item rubthrough
A more complicated way of blending images is where one image is
*/
-#include "imagei.h"
+#include "imageri.h"
static int max_width, max_height;
static int max_bytes;
=cut
*/
-#include "image.h"
+#include "imager.h"
/*
=cut
*/
-#include "image.h"
-#include "imagei.h"
+#include "imager.h"
+#include "imageri.h"
#include <stdio.h>
/*
--- /dev/null
+# some versions of EU::MM have problems with recursive Makefile.PLs with
+# this method defined.
+undef &MY::metafile;
+
+sub MY::metafile {
+ my ($self) = @_;
+
+ my $meta = <<YAML;
+--- #YAML:1.0
+name: $self->{NAME}
+version: $self->{VERSION}
+version_from: $self->{VERSION_FROM}
+author: $self->{AUTHOR}
+abstract: $self->{ABSTRACT}
+installdirs: $self->{INSTALLDIRS}
+YAML
+ if (keys %{$Recommends{$self->{NAME}}}) {
+ $meta .= "recommends:\n";
+ while (my ($module, $version) = each %{$Recommends{$self->{NAME}}}) {
+ $meta .= "$module: $version\n";
+ }
+ }
+ $meta .= <<YAML;
+license: perl
+dynamic_config: 1
+distribution_type: module
+generated_by: $self->{NAME} version $self->{VERSION}
+YAML
+ open META, "> meta.tmp" or die "Cannot create meta.tmp: $!";
+ print META $meta;
+ close META;
+
+ return sprintf "metafile :\n\t\$(CP) meta.tmp META.yml\n";
+}
+
+1;
=cut
*/
-#include "image.h"
-#include "imagei.h"
+#include "imager.h"
+#include "imageri.h"
#define PALEXT(im) ((i_img_pal_ext*)((im)->ext_data))
static int i_ppix_p(i_img *im, int x, int y, i_color *val);
};
/*
-=item i_img_pal_new_low(i_img *im, int x, int y, int channels, int maxpal)
+=item i_img_pal_new_low(im, x, y, channels, maxpal)
Creates a new paletted image.
return im;
}
+/*
+=item i_img_pal_new(x, y, channels, maxpal)
+
+=category Image creation
+
+Creates a new paletted image of the supplied dimensions.
+
+Returns a new image or NULL on failure.
+
+=cut
+*/
+
i_img *i_img_pal_new(int x, int y, int channels, int maxpal) {
i_img *im;
mm_log((1, "i_img_pal_new(x %d, y %d, channels %d, maxpal %d)\n", x, y, channels, maxpal));
i_clear_error();
- quant_makemap(quant, &src, 1);
- result = quant_translate(quant, src);
+ i_quant_makemap(quant, &src, 1);
+ result = i_quant_translate(quant, src);
if (result) {
}
/*
-=item i_gpix(i_img *im, int x, int y, i_color *val)
+=item i_gpix_p(i_img *im, int x, int y, i_color *val)
Retrieve a pixel, converting from a palette index to a color.
-#include "image.h"
+#include "imager.h"
/* structures for passing data between Imager-plugin and the Imager-module */
#include "iolayer.h"
-#include "imagei.h"
+#include "imageri.h"
#include "png.h"
/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp()
-#include "image.h"
+#include "imager.h"
#include "log.h"
#include "iolayer.h"
-#include "imagei.h"
+#include "imageri.h"
#include <stdlib.h>
#include <errno.h>
-#include "image.h"
+#include "imager.h"
#include "draw.h"
#include "log.h"
currently only used by gif.c, but maybe we'll support producing
8-bit (or bigger indexed) png files at some point
*/
-#include "image.h"
+#include "imager.h"
static void makemap_addi(i_quantize *, i_img **imgs, int count);
static void makemap_mediancut(i_quantize *, i_img **imgs, int count);
handle multiple colour maps.
*/
+/*
+=item i_quant_makemap(quant, imgs, count)
+
+=category Image quantization
+
+Analyzes the I<count> images in I<imgs> according to the rules in
+I<quant> to build a color map (optimal or not depending on
+quant->make_colors).
+
+=cut
+*/
+
void
-quant_makemap(i_quantize *quant, i_img **imgs, int count) {
+i_quant_makemap(i_quantize *quant, i_img **imgs, int count) {
if (quant->translate == pt_giflib) {
/* giflib does it's own color table generation */
static void translate_errdiff(i_quantize *, i_img *, i_palidx *);
static void translate_addi(i_quantize *, i_img *, i_palidx *);
-/* Quantize the image given the palette in quant.
+/*
+=item i_quant_translate(quant, img)
+
+=category Image quantization
+
+Quantize the image given the palette in quant.
+
+On success returns a pointer to a memory block of img->xsize *
+img->ysize i_palidx entries.
+
+On failure returns NULL.
- The giflib quantizer ignores the palette.
+You should call myfree() on the returned block when you're done with
+it.
+
+This function will fail if the supplied palette contains no colors.
+
+=cut
*/
-i_palidx *quant_translate(i_quantize *quant, i_img *img) {
+i_palidx *
+i_quant_translate(i_quantize *quant, i_img *img) {
i_palidx *result;
int bytes;
static void transparent_errdiff(i_quantize *, i_palidx *, i_img *, i_palidx);
static void transparent_ordered(i_quantize *, i_palidx *, i_img *, i_palidx);
-void quant_transparent(i_quantize *quant, i_palidx *data, i_img *img,
+/*
+=item i_quant_transparent(quant, data, img, trans_index)
+
+=category Image quantization
+
+Dither the alpha channel on I<img> into the palette indexes in
+I<data>. Pixels to be transparent are replaced with I<trans_pixel>.
+
+The method used depends on the tr_* members of quant.
+
+=cut
+*/
+
+void
+i_quant_transparent(i_quantize *quant, i_palidx *data, i_img *img,
i_palidx trans_index)
{
switch (quant->transp) {
-#include "image.h"
+#include "imager.h"
#include <stdio.h>
#include "iolayer.h"
#ifndef _MSC_VER
#include <stdio.h>
#include <math.h>
-#include "image.h"
+#include "imager.h"
enum rm_byte_codes {
rbc_add, /* ra + rb -> r*/
-#include "image.h"
+#include "imager.h"
#include "log.h"
#include "iolayer.h"
=cut
*/
-#include "image.h"
+#include "imager.h"
#include <math.h> /* for floor() */
i_img *i_rotate90(i_img *src, int degrees) {
# check that the image is copied correctly
my $oocopy = $ooimg->copy;
-ok($oocopy->bits eq 'double', "oo copy didn't give double image");
+is($oocopy->bits, 'double', "oo copy didn't give double image");
ok(!Imager->new(xsize=>0, ysize=>1, bits=>'double'),
"fail making 0 width image");
-BEGIN { $| = 1; print "1..4\n"; }
-END {print "not ok 1\n" unless $loaded;}
-use Imager;
+#!perl -w
+use strict;
+use Test::More tests => 15;
-$loaded = 1;
+BEGIN { use_ok("Imager") }
#$Imager::DEBUG=1;
Imager::init('log'=>'testout/t66paste.log');
-$img=Imager->new() || die "unable to create image object\n";
+# the original smoke tests
+my $img=Imager->new() || die "unable to create image object\n";
-print "ok 1\n";
+ok($img->open(file=>'testimg/scale.ppm',type=>'pnm'), "load test img");
-$img->open(file=>'testimg/scale.ppm',type=>'pnm');
+my $nimg=Imager->new() or die "Unable to create image object\n";
+ok($nimg->open(file=>'testimg/scale.ppm',type=>'pnm'), "load test img again");
-$nimg=Imager->new() or die "Unable to create image object\n";
-$nimg->open(file=>'testimg/scale.ppm',type=>'pnm');
-print "ok 2\n";
+ok($img->paste(img=>$nimg, top=>30, left=>30), "paste it")
+ or print "# ", $img->errstr, "\n";;
-$img->paste(img=>$nimg, top=>30, left=>30) or die $img->{ERRSTR};
-print "ok 3\n";
+ok($img->write(type=>'pnm',file=>'testout/t66.ppm'), "save it")
+ or print "# ", $img->errstr, "\n";
+# more stringent tests
+{
+ my $src = Imager->new(xsize => 100, ysize => 100);
+ $src->box(filled=>1, color=>'FF0000');
-$img->write(type=>'pnm',file=>'testout/t66.ppm') || die "error in write()\n";
-print "ok 4\n";
+ $src->box(filled=>1, color=>'0000FF', xmin => 20, ymin=>20,
+ xmax=>79, ymax=>79);
+ my $targ = Imager->new(xsize => 100, ysize => 100);
+ $targ->box(filled=>1, color=>'00FF00', xmin=>20, ymin=>20, xmax=>79,
+ ymax=>79);
+ my $work = $targ->copy;
+ ok($work->paste(src=>$src, left => 15, top => 10), "paste whole image");
+ # build comparison image
+ my $cmp = $targ->copy;
+ $cmp->box(filled=>1, xmin=>15, ymin => 10, color=>'FF0000');
+ $cmp->box(filled=>1, xmin=>35, ymin => 30, xmax=>94, ymax=>89,
+ color=>'0000FF');
+
+ is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
+ "compare pasted and expected");
+
+ $work = $targ->copy;
+ ok($work->paste(src=>$src, left=>2, top=>7, src_minx => 10, src_miny => 15),
+ "paste from inside src");
+ $cmp = $targ->copy;
+ $cmp->box(filled=>1, xmin=>2, ymin=>7, xmax=>91, ymax=>91, color=>'FF0000');
+ $cmp->box(filled=>1, xmin=>12, ymin=>12, xmax=>71, ymax=>71,
+ color=>'0000FF');
+ is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
+ "compare pasted and expected");
+
+ # paste part source
+ $work = $targ->copy;
+ ok($work->paste(src=>$src, left=>15, top=>20,
+ src_minx=>10, src_miny=>15, src_maxx=>80, src_maxy =>70),
+ "paste src cropped all sides");
+ $cmp = $targ->copy;
+ $cmp->box(filled=>1, xmin=>15, ymin=>20, xmax=>84, ymax=>74,
+ color=>'FF0000');
+ $cmp->box(filled=>1, xmin=>25, ymin=>25, xmax=>84, ymax=>74,
+ color=>'0000FF');
+ is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
+ "compare pasted and expected");
+
+ # go by width instead
+ $work = $targ->copy;
+ ok($work->paste(src=>$src, left=>15, top=>20,
+ src_minx=>10, src_miny => 15, width => 70, height => 55),
+ "same but specify width/height instead");
+ is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
+ "compare pasted and expected");
+
+ # use src_coords
+ $work = $targ->copy;
+ ok($work->paste(src=>$src, left => 15, top => 20,
+ src_coords => [ 10, 15, 80, 70 ]),
+ "using src_coords");
+ is(Imager::i_img_diff($work->{IMG}, $cmp->{IMG}), 0,
+ "compare pasted and expected");
+}
--- /dev/null
+#!perl -w
+#
+# this tests both the Inline interface and the API
+use strict;
+use lib 't';
+use Test::More;
+eval "require Inline::C;";
+plan skip_all => "Inline required for testing API - $@" if $@;
+
+plan tests => 8;
+require Inline;
+Inline->import(with => 'Imager');
+
+Inline->bind(C => <<'EOS');
+#include <math.h>
+
+int pixel_count(Imager::ImgRaw im) {
+ return im->xsize * im->ysize;
+}
+
+int count_color(Imager::ImgRaw im, Imager::Color c) {
+ int count = 0, x, y, chan;
+ i_color read_c;
+
+ for (x = 0; x < im->xsize; ++x) {
+ for (y = 0; y < im->ysize; ++y) {
+ int match = 1;
+ i_gpix(im, x, y, &read_c);
+ for (chan = 0; chan < im->channels; ++chan) {
+ if (read_c.channel[chan] != c->channel[chan]) {
+ match = 0;
+ break;
+ }
+ }
+ if (match)
+ ++count;
+ }
+ }
+
+ return count;
+}
+
+Imager make_10x10() {
+ i_img *im = i_img_8_new(10, 10, 3);
+ i_color c;
+ c.channel[0] = c.channel[1] = c.channel[2] = 255;
+ i_box_filled(im, 0, 0, im->xsize-1, im->ysize-1, &c);
+
+ return im;
+}
+
+/* tests that all of the APIs are visible - most of them anyway */
+Imager do_lots(Imager src) {
+ i_img *im = i_img_8_new(100, 100, 3);
+ i_img *fill_im = i_img_8_new(5, 5, 3);
+ i_img *testim;
+ i_color red, blue, temp_color;
+ i_fcolor redf, bluef;
+ i_fill_t *hatch, *fhatch_fill;
+ i_fill_t *im_fill;
+ i_fill_t *solid_fill, *fsolid_fill;
+ i_fill_t *fount_fill;
+ void *block;
+ double matrix[9] = /* 30 degree rotation */
+ {
+ 0.866025, -0.5, 0,
+ 0.5, 0.866025, 0,
+ 0, 0, 1,
+ };
+ i_fountain_seg fseg;
+ i_img_tags tags;
+ int entry;
+ double temp_double;
+
+ red.channel[0] = 255; red.channel[1] = 0; red.channel[2] = 0;
+ red.channel[3] = 255;
+ blue.channel[0] = 0; blue.channel[1] = 0; blue.channel[2] = 255;
+ blue.channel[3] = 255;
+ hatch = i_new_fill_hatch(&red, &blue, 0, 1, NULL, 0, 0);
+
+ i_box(im, 0, 0, 9, 9, &red);
+ i_box_filled(im, 10, 0, 19, 9, &blue);
+ i_box_cfill(im, 20, 0, 29, 9, hatch);
+
+ /* make an image fill, and try it */
+ i_box_cfill(fill_im, 0, 0, 4, 4, hatch);
+ im_fill = i_new_fill_image(fill_im, matrix, 2, 2, 0);
+
+ i_box_cfill(im, 30, 0, 39, 9, im_fill);
+
+ /* make a solid fill and try it */
+ solid_fill = i_new_fill_solid(&red, 0);
+ i_box_cfill(im, 40, 0, 49, 9, solid_fill);
+
+ /* floating fills */
+ redf.channel[0] = 1.0; redf.channel[1] = 0; redf.channel[2] = 0;
+ redf.channel[3] = 1.0;
+ bluef.channel[0] = 0; bluef.channel[1] = 0; bluef.channel[2] = 1.0;
+ bluef.channel[3] = 1.0;
+
+ fsolid_fill = i_new_fill_solidf(&redf, 0);
+ i_box_cfill(im, 50, 0, 59, 9, fsolid_fill);
+
+ fhatch_fill = i_new_fill_hatchf(&redf, &bluef, 0, 2, NULL, 0, 0);
+ i_box_cfill(im, 60, 0, 69, 9, fhatch_fill);
+
+ /* fountain fill */
+ fseg.start = 0;
+ fseg.middle = 0.5;
+ fseg.end = 1.0;
+ fseg.c[0] = redf;
+ fseg.c[1] = bluef;
+ fseg.type = i_fst_linear;
+ fseg.color = i_fc_hue_down;
+ fount_fill = i_new_fill_fount(70, 0, 80, 0, i_ft_linear, i_fr_triangle, 0, i_fts_none, 1, 1, &fseg);
+
+ i_box_cfill(im, 70, 0, 79, 9, fount_fill);
+
+ i_line(im, 0, 10, 10, 15, &blue, 1);
+ i_line_aa(im, 0, 19, 10, 15, &red, 1);
+
+ i_arc(im, 15, 15, 4, 45, 160, &blue);
+ i_arc_aa(im, 25, 15, 4, 75, 280, &red);
+ i_arc_cfill(im, 35, 15, 4, 0, 215, hatch);
+ i_arc_aa_cfill(im, 45, 15, 4, 30, 210, hatch);
+ i_circle_aa(im, 55, 15, 4, &red);
+
+ i_box(im, 61, 11, 68, 18, &red);
+ i_flood_fill(im, 65, 15, &blue);
+ i_box(im, 71, 11, 78, 18, &red);
+ i_flood_cfill(im, 75, 15, hatch);
+
+ i_fill_destroy(fount_fill);
+ i_fill_destroy(fhatch_fill);
+ i_fill_destroy(solid_fill);
+ i_fill_destroy(fsolid_fill);
+ i_fill_destroy(hatch);
+ i_fill_destroy(im_fill);
+ i_img_destroy(fill_im);
+
+ /* make sure we can make each image type */
+ testim = i_img_16_new(100, 100, 3);
+ i_img_destroy(testim);
+ testim = i_img_double_new(100, 100, 3);
+ i_img_destroy(testim);
+ testim = i_img_pal_new(100, 100, 3, 256);
+ i_img_destroy(testim);
+ testim = i_sametype(im, 50, 50);
+ i_img_destroy(testim);
+ testim = i_sametype_chans(im, 50, 50, 4);
+ i_img_destroy(testim);
+
+ i_clear_error();
+ i_push_error(0, "Hello");
+ i_push_errorf(0, "%s", "World");
+
+ /* make sure tags create/destroy work */
+ i_tags_new(&tags);
+ i_tags_destroy(&tags);
+
+ block = mymalloc(20);
+ block = myrealloc(block, 50);
+ myfree(block);
+
+ i_tags_set(&im->tags, "lots_string", "foo", -1);
+ i_tags_setn(&im->tags, "lots_number", 101);
+
+ if (!i_tags_find(&im->tags, "lots_number", 0, &entry)) {
+ i_push_error(0, "lots_number tag not found");
+ i_img_destroy(im);
+ return NULL;
+ }
+ i_tags_delete(&im->tags, entry);
+
+ /* these won't delete anything, but it makes sure the macros and function
+ pointers are correct */
+ i_tags_delbyname(&im->tags, "unknown");
+ i_tags_delbycode(&im->tags, 501);
+ i_tags_set_float(&im->tags, "lots_float", 0, 3.14);
+ if (!i_tags_get_float(&im->tags, "lots_float", 0, &temp_double)) {
+ i_push_error(0, "lots_float not found");
+ i_img_destroy(im);
+ return NULL;
+ }
+ if (fabs(temp_double - 3.14) > 0.001) {
+ i_push_errorf(0, "lots_float incorrect %g", temp_double);
+ i_img_destroy(im);
+ return NULL;
+ }
+ i_tags_set_float2(&im->tags, "lots_float2", 0, 100 * sqrt(2.0), 5);
+ if (!i_tags_get_int(&im->tags, "lots_float2", 0, &entry)) {
+ i_push_error(0, "lots_float2 not found as int");
+ i_img_destroy(im);
+ return NULL;
+ }
+ if (entry != 141) {
+ i_push_errorf(0, "lots_float2 unexpected value %d", entry);
+ i_img_destroy(im);
+ return NULL;
+ }
+
+ i_tags_set_color(&im->tags, "lots_color", 0, &red);
+ if (!i_tags_get_color(&im->tags, "lots_color", 0, &temp_color)) {
+ i_push_error(0, "lots_color not found as color");
+ i_img_destroy(im);
+ return NULL;
+ }
+
+ return im;
+}
+
+EOS
+
+my $im = Imager->new(xsize=>50, ysize=>50);
+is(pixel_count($im), 2500, "pixel_count");
+
+my $black = Imager::Color->new(0,0,0);
+is(count_color($im, $black), 2500, "count_color black on black image");
+
+my $im2 = make_10x10();
+my $white = Imager::Color->new(255, 255, 255);
+is(count_color($im2, $white), 100, "check new image white count");
+ok($im2->box(filled=>1, xmin=>1, ymin=>1, xmax => 8, ymax=>8, color=>$black),
+ "try new image");
+is(count_color($im2, $black), 64, "check modified black count");
+is(count_color($im2, $white), 36, "check modified white count");
+
+my $im3 = do_lots($im2);
+ok($im3, "do_lots()")
+ or print "# ", Imager->_error_as_msg, "\n";
+ok($im3->write(file=>'testout/t82lots.ppm'), "write t82lots.ppm");
=cut
*/
-#include "image.h"
+#include "imager.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
/*
=item i_tags_new(i_img_tags *tags)
+=category Tags
+
Initialize a tags structure. Should not be used if the tags structure
has been previously used.
+This should be called tags member of an i_img object on creation (in
+i_img_*_new() functions).
+
To destroy the contents use i_tags_destroy()
=cut
return 1;
}
+/*
+=item i_tags_destroy(tags)
+
+=category Tags
+
+Destroys the given tags structure. Called by i_img_destroy().
+
+=cut
+*/
+
void i_tags_destroy(i_img_tags *tags) {
if (tags->tags) {
int i;
}
}
+/*
+=item i_tags_find(tags, name, start, &entry)
+
+=category Tags
+
+Searchs for a tag of the given I<name> starting from index I<start>.
+
+On success returns true and sets *I<entry>.
+
+On failure returns false.
+
+=cut
+*/
+
int i_tags_find(i_img_tags *tags, char const *name, int start, int *entry) {
if (tags->tags) {
while (start < tags->count) {
return 0;
}
+/*
+=item i_tags_findn(tags, code, start, &entry)
+
+=category Tags
+
+Searchs for a tag of the given I<code> starting from index I<start>.
+
+On success returns true and sets *I<entry>.
+
+On failure returns false.
+
+=cut
+*/
+
int i_tags_findn(i_img_tags *tags, int code, int start, int *entry) {
if (tags->tags) {
while (start < tags->count) {
return 0;
}
+/*
+=item i_tags_delete(tags, index)
+
+=category Tags
+
+Delete a tag by index.
+
+Returns true on success.
+
+=cut
+*/
int i_tags_delete(i_img_tags *tags, int entry) {
/*printf("i_tags_delete(tags %p [count %d], entry %d)\n",
tags, tags->count, entry);*/
return 0;
}
+/*
+=item i_tags_delbyname(tags, name)
+
+=category Tags
+
+Delete any tags with the given name.
+
+Returns the number of tags deleted.
+
+=cut
+*/
+
int i_tags_delbyname(i_img_tags *tags, char const *name) {
int count = 0;
int i;
return count;
}
+/*
+=item i_tags_delbycode(tags, code)
+
+=category Tags
+
+Delete any tags with the given code.
+
+Returns the number of tags deleted.
+
+=cut
+*/
+
int i_tags_delbycode(i_img_tags *tags, int code) {
int count = 0;
int i;
return count;
}
+/*
+=item i_tags_get_float(tags, name, code, value)
+
+=category Tags
+
+Retrieves a tag as a floating point value.
+
+If the tag has a string value then that is parsed as a floating point
+number, otherwise the integer value of the tag is used.
+
+On success sets *I<value> and returns true.
+
+On failure returns false.
+
+=cut
+*/
+
int i_tags_get_float(i_img_tags *tags, char const *name, int code,
double *value) {
int index;
return 1;
}
+/*
+=item i_tags_set_float(tags, name, code, value)
+
+=category Tags
+
+Equivalent to i_tags_set_float2(tags, name, code, value, 30).
+
+=cut
+*/
+
int i_tags_set_float(i_img_tags *tags, char const *name, int code,
double value) {
return i_tags_set_float2(tags, name, code, value, 30);
/*
=item i_tags_set_float2(tags, name, code, value, places)
+=category Tags
+
Sets the tag with the given name and code to the given floating point
value.
return i_tags_add(tags, name, code, temp, strlen(temp), 0);
}
+/*
+=item i_tags_get_int(tags, name, code, &value)
+
+=category Tags
+
+Retrieve a tag specified by name or code as an integer.
+
+On success sets the i_color *I<value> to the color and returns true.
+
+On failure returns false.
+
+=cut
+*/
+
int i_tags_get_int(i_img_tags *tags, char const *name, int code, int *value) {
int index;
i_img_tag *entry;
return 1;
}
+/*
+=item i_tags_get_color(tags, name, code, &value)
+
+=category Tags
+
+Retrieve a tag specified by name or code as color.
+
+On success sets the i_color *I<value> to the color and returns true.
+
+On failure returns false.
+
+=cut
+*/
+
int i_tags_get_color(i_img_tags *tags, char const *name, int code,
i_color *value) {
int index;
return 1;
}
+/*
+=item i_tags_set_color(tags, name, code, &value)
+
+=category Tags
+
+Stores the given color as a tag with the given name and code.
+
+=cut
+*/
+
int i_tags_set_color(i_img_tags *tags, char const *name, int code,
i_color const *value) {
char temp[80];
return i_tags_add(tags, name, code, temp, strlen(temp), 0);
}
+/*
+=item i_tags_get_string(tags, name, code, value, value_size)
+
+=category Tags
+
+Retrieves a tag by name or code as a string.
+
+On success copies the string to value for a max of value_size and
+returns true.
+
+On failure returns false.
+
+value_size must be at least large enough for a string representation
+of an integer.
+
+The copied value is always NUL terminated.
+
+=cut
+*/
+
int i_tags_get_string(i_img_tags *tags, char const *name, int code,
char *value, size_t value_size) {
int index;
return 1;
}
+/*
+=item i_tags_set(tags, name, data, size)
+
+=category Tags
+
+Sets the given tag to the string I<data>
+
+=cut
+*/
+
+int
+i_tags_set(i_img_tags *tags, char const *name, char const *data, int size) {
+ i_tags_delbyname(tags, name);
+
+ return i_tags_add(tags, name, 0, data, size, 0);
+}
+
+/*
+=item i_tags_setn(tags, name, idata)
+
+=category Tags
+
+Sets the given tag to the integer I<idata>
+
+=cut
+*/
+
+int
+i_tags_setn(i_img_tags *tags, char const *name, int idata) {
+ i_tags_delbyname(tags, name);
+
+ return i_tags_addn(tags, name, 0, idata);
+}
+
void i_tags_print(i_img_tags *tags) {
int i;
printf("Alloc %d\n", tags->alloc);
-#include "imagei.h"
+#include "imageri.h"
#include "log.h"
#include "iolayer.h"
-#include "image.h"
+#include "imager.h"
#include "tiffio.h"
#include "iolayer.h"
-#include "imagei.h"
+#include "imageri.h"
/*
=head1 NAME
-#include "image.h"
+#include "imager.h"
#include "regmach.h"
/*
#i_img * T_PTR_NULL
Imager::Color T_PTROBJ
Imager::Color::Float T_PTROBJ
-Imager::ImgRaw T_PTROBJ
+Imager::ImgRaw T_IMAGER_IMAGE
Imager::Font::TT T_PTROBJ
Imager::IO T_PTROBJ
Imager::Font::FT2 T_PTROBJ
undef_neg_int T_IV_NEGU
HASH T_HVREF
utf8_str T_UTF8_STR
+
+# these types are for use by Inline, which can't handle types containing ::
+Imager__Color T_PTROBJ_INV
+Imager__Color__Float T_PTROBJ_INV
+Imager__ImgRaw T_IMAGER_IMAGE
+Imager__FillHandle T_PTROBJ_INV
+Imager__IO T_PTROBJ_INV
+
+# mostly intended for non-Imager-core use
+Imager T_IMAGER_FULL_IMAGE
+
#############################################################################
INPUT
T_PTR_NULL
else
Perl_croak(aTHX_ \"$var is not an array reference\")
+# handles Imager objects rather than just raw objects
+T_IMAGER_IMAGE
+ if (sv_derived_from($arg, \"Imager::ImgRaw\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = INT2PTR($type,tmp);
+ }
+ else if (sv_derived_from($arg, \"Imager\") &&
+ SvTYPE(SvRV($arg)) == SVt_PVHV) {
+ HV *hv = (HV *)SvRV($arg);
+ SV **sv = hv_fetch(hv, \"IMG\", 3, 0);
+ if (sv && *sv && sv_derived_from(*sv, \"Imager::ImgRaw\")) {
+ IV tmp = SvIV((SV*)SvRV(*sv));
+ $var = INT2PTR($type,tmp);
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type Imager::ImgRaw\");
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type Imager::ImgRaw\");
+
+T_IMAGER_FULL_IMAGE
+ if (sv_derived_from($arg, \"Imager\") &&
+ SvTYPE(SvRV($arg)) == SVt_PVHV) {
+ HV *hv = (HV *)SvRV($arg);
+ SV **sv = hv_fetch(hv, \"IMG\", 3, 0);
+ if (sv && *sv && sv_derived_from(*sv, \"Imager::ImgRaw\")) {
+ IV tmp = SvIV((SV*)SvRV(*sv));
+ $var = INT2PTR($type,tmp);
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type Imager::ImgRaw\");
+ }
+ else
+ Perl_croak(aTHX_ \"$var is not of type Imager\");
+
+# same as T_PTROBJ, but replace __ with ::, the opposite of the way
+# xsubpp's processing works
+# this is to compensate for Inline's problem with type names containing ::
+T_PTROBJ_INV
+ if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/__/::/g;\$ntt}\")) {
+ IV tmp = SvIV((SV*)SvRV($arg));
+ $var = INT2PTR($type,tmp);
+ }
+ else
+ croak(\"$var is not of type ${(my $ntt=$ntype)=~s/__/::/g;\$ntt}\");
+
+
#############################################################################
OUTPUT
T_IV_U
else sv_setiv($arg, (IV)$var);
T_PTR_NULL
sv_setiv($arg, (IV)$var);
+
+# same as T_PTROBJ
+T_IMAGER_IMAGE
+ sv_setref_pv($arg, \"Imager::ImgRaw\", (void*)$var);
+
+T_PTROBJ_INV
+ sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/__/::/g;\$ntt}\", (void*)$var);
+
+# ugh, the things we do for ease of use
+# this isn't suitable in some cases
+T_IMAGER_FULL_IMAGE
+ if ($var) {
+ SV *imobj = NEWSV(0, 0);
+ HV *hv = newHV();
+ SV *hvref;
+ SV *imgref;
+ sv_setref_pv(imobj, \"Imager::ImgRaw\", $var);
+ hv_store(hv, "IMG", 3, imobj, 0);
+ $arg = sv_2mortal(sv_bless(newRV((SV*)hv), gv_stashpv("Imager", 1)));
+ }
+ else {
+ $arg = &PL_sv_undef;
+ }
#define _WIN32_WINNT 0x500
-#include "image.h"
+#include "imager.h"
#define STRICT
#include <windows.h>