fix polygon() call sequence
[imager.git] / Imager.pm
CommitLineData
02d1d628
AMH
1package Imager;
2
02d1d628
AMH
3use strict;
4use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS %formats $DEBUG %filters %DSOs $ERRSTR $fontstate %OPCODES $I2P $FORMATGUESS);
5use IO::File;
6
7use Imager::Color;
8use Imager::Font;
9
10@EXPORT_OK = qw(
11 init
12 init_log
13 DSO_open
14 DSO_close
15 DSO_funclist
16 DSO_call
dd55acc8 17
02d1d628
AMH
18 load_plugin
19 unload_plugin
dd55acc8 20
02d1d628
AMH
21 i_list_formats
22 i_has_format
dd55acc8 23
02d1d628
AMH
24 i_color_new
25 i_color_set
26 i_color_info
dd55acc8 27
02d1d628
AMH
28 i_img_empty
29 i_img_empty_ch
30 i_img_exorcise
31 i_img_destroy
32
33 i_img_info
34
35 i_img_setmask
36 i_img_getmask
37
38 i_draw
39 i_line_aa
40 i_box
41 i_box_filled
42 i_arc
18063344 43 i_circle_aa
dd55acc8 44
02d1d628
AMH
45 i_bezier_multi
46 i_poly_aa
43c5dacb 47 i_poly_aa_cfill
02d1d628
AMH
48
49 i_copyto
50 i_rubthru
51 i_scaleaxis
52 i_scale_nn
53 i_haar
54 i_count_colors
dd55acc8 55
02d1d628
AMH
56 i_gaussian
57 i_conv
dd55acc8 58
f5991c03 59 i_convert
40eba1ea 60 i_map
dd55acc8 61
02d1d628
AMH
62 i_img_diff
63
64 i_init_fonts
65 i_t1_new
66 i_t1_destroy
67 i_t1_set_aa
68 i_t1_cp
69 i_t1_text
70 i_t1_bbox
71
02d1d628
AMH
72 i_tt_set_aa
73 i_tt_cp
74 i_tt_text
75 i_tt_bbox
76
02d1d628
AMH
77 i_readjpeg_wiol
78 i_writejpeg_wiol
79
80 i_readtiff_wiol
81 i_writetiff_wiol
d2dfdcc9 82 i_writetiff_wiol_faxable
02d1d628 83
790923a4
AMH
84 i_readpng_wiol
85 i_writepng_wiol
02d1d628
AMH
86
87 i_readgif
88 i_readgif_callback
89 i_writegif
90 i_writegifmc
91 i_writegif_gen
92 i_writegif_callback
93
94 i_readpnm_wiol
067d6bdc 95 i_writeppm_wiol
02d1d628 96
895dbd34
AMH
97 i_readraw_wiol
98 i_writeraw_wiol
02d1d628
AMH
99
100 i_contrast
101 i_hardinvert
102 i_noise
103 i_bumpmap
104 i_postlevels
105 i_mosaic
106 i_watermark
dd55acc8 107
02d1d628
AMH
108 malloc_state
109
110 list_formats
dd55acc8 111
02d1d628
AMH
112 i_gifquant
113
114 newfont
115 newcolor
116 newcolour
117 NC
118 NF
02d1d628
AMH
119);
120
9982a307 121@EXPORT=qw(
02d1d628
AMH
122 init_log
123 i_list_formats
124 i_has_format
125 malloc_state
126 i_color_new
127
128 i_img_empty
129 i_img_empty_ch
130 );
131
132%EXPORT_TAGS=
133 (handy => [qw(
134 newfont
135 newcolor
136 NF
137 NC
138 )],
139 all => [@EXPORT_OK],
140 default => [qw(
141 load_plugin
142 unload_plugin
143 )]);
144
02d1d628
AMH
145BEGIN {
146 require Exporter;
147 require DynaLoader;
148
412e7a35 149 $VERSION = '0.39';
02d1d628
AMH
150 @ISA = qw(Exporter DynaLoader);
151 bootstrap Imager $VERSION;
152}
153
154BEGIN {
155 i_init_fonts(); # Initialize font engines
faa9b3e7 156 Imager::Font::__init();
02d1d628
AMH
157 for(i_list_formats()) { $formats{$_}++; }
158
159 if ($formats{'t1'}) {
160 i_t1_set_aa(1);
161 }
162
faa9b3e7
TC
163 if (!$formats{'t1'} and !$formats{'tt'}
164 && !$formats{'ft2'} && !$formats{'w32'}) {
02d1d628
AMH
165 $fontstate='no font support';
166 }
167
168 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
169
170 $DEBUG=0;
171
6607600c
TC
172 # the members of the subhashes under %filters are:
173 # callseq - a list of the parameters to the underlying filter in the
174 # order they are passed
175 # callsub - a code ref that takes a named parameter list and calls the
176 # underlying filter
177 # defaults - a hash of default values
178 # names - defines names for value of given parameters so if the names
179 # field is foo=> { bar=>1 }, and the user supplies "bar" as the
180 # foo parameter, the filter will receive 1 for the foo
181 # parameter
02d1d628
AMH
182 $filters{contrast}={
183 callseq => ['image','intensity'],
184 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
185 };
186
187 $filters{noise} ={
188 callseq => ['image', 'amount', 'subtype'],
189 defaults => { amount=>3,subtype=>0 },
190 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
191 };
192
193 $filters{hardinvert} ={
194 callseq => ['image'],
195 defaults => { },
196 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
197 };
198
199 $filters{autolevels} ={
200 callseq => ['image','lsat','usat','skew'],
201 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
202 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
203 };
204
205 $filters{turbnoise} ={
206 callseq => ['image'],
207 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
208 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
209 };
210
211 $filters{radnoise} ={
212 callseq => ['image'],
213 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
214 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
215 };
216
217 $filters{conv} ={
218 callseq => ['image', 'coef'],
219 defaults => { },
220 callsub => sub { my %hsh=@_; i_conv($hsh{image},$hsh{coef}); }
221 };
222
223 $filters{gradgen} ={
224 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
225 defaults => { },
226 callsub => sub { my %hsh=@_; i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
227 };
228
229 $filters{nearest_color} ={
230 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
231 defaults => { },
232 callsub => sub { my %hsh=@_; i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
233 };
faa9b3e7
TC
234 $filters{gaussian} = {
235 callseq => [ 'image', 'stddev' ],
236 defaults => { },
237 callsub => sub { my %hsh = @_; i_gaussian($hsh{image}, $hsh{stddev}); },
238 };
d08b8f85
TC
239 $filters{mosaic} =
240 {
241 callseq => [ qw(image size) ],
242 defaults => { size => 20 },
243 callsub => sub { my %hsh = @_; i_mosaic($hsh{image}, $hsh{size}) },
244 };
245 $filters{bumpmap} =
246 {
247 callseq => [ qw(image bump elevation lightx lighty st) ],
248 defaults => { elevation=>0, st=> 2 },
b2778574 249 callsub => sub {
d08b8f85
TC
250 my %hsh = @_;
251 i_bumpmap($hsh{image}, $hsh{bump}{IMG}, $hsh{elevation},
252 $hsh{lightx}, $hsh{lighty}, $hsh{st});
253 },
254 };
b2778574
AMH
255 $filters{bumpmap_complex} =
256 {
257 callseq => [ qw(image bump channel tx ty Lx Ly Lz cd cs n Ia Il Is) ],
258 defaults => {
259 channel => 0,
260 tx => 0,
261 ty => 0,
262 Lx => 0.2,
263 Ly => 0.4,
264 Lz => -1.0,
265 cd => 1.0,
266 cs => 40,
267 n => 1.3,
268 Ia => Imager::Color->new(rgb=>[0,0,0]),
269 Il => Imager::Color->new(rgb=>[255,255,255]),
270 Is => Imager::Color->new(rgb=>[255,255,255]),
271 },
272 callsub => sub {
273 my %hsh = @_;
274 i_bumpmap_complex($hsh{image}, $hsh{bump}{IMG}, $hsh{channel},
275 $hsh{tx}, $hsh{ty}, $hsh{Lx}, $hsh{Ly}, $hsh{Lz},
276 $hsh{cd}, $hsh{cs}, $hsh{n}, $hsh{Ia}, $hsh{Il},
277 $hsh{Is});
278 },
279 };
d08b8f85
TC
280 $filters{postlevels} =
281 {
282 callseq => [ qw(image levels) ],
283 defaults => { levels => 10 },
284 callsub => sub { my %hsh = @_; i_postlevels($hsh{image}, $hsh{levels}); },
285 };
286 $filters{watermark} =
287 {
288 callseq => [ qw(image wmark tx ty pixdiff) ],
289 defaults => { pixdiff=>10, tx=>0, ty=>0 },
290 callsub =>
291 sub {
292 my %hsh = @_;
293 i_watermark($hsh{image}, $hsh{wmark}{IMG}, $hsh{tx}, $hsh{ty},
294 $hsh{pixdiff});
295 },
296 };
6607600c
TC
297 $filters{fountain} =
298 {
299 callseq => [ qw(image xa ya xb yb ftype repeat combine super_sample ssample_param segments) ],
300 names => {
301 ftype => { linear => 0,
302 bilinear => 1,
303 radial => 2,
304 radial_square => 3,
305 revolution => 4,
306 conical => 5 },
307 repeat => { none => 0,
308 sawtooth => 1,
309 triangle => 2,
310 saw_both => 3,
311 tri_both => 4,
312 },
313 super_sample => {
314 none => 0,
315 grid => 1,
316 random => 2,
317 circle => 3,
318 },
efdc2568
TC
319 combine => {
320 none => 0,
321 normal => 1,
322 multiply => 2, mult => 2,
323 dissolve => 3,
324 add => 4,
9d540150 325 subtract => 5, 'sub' => 5,
efdc2568
TC
326 diff => 6,
327 lighten => 7,
328 darken => 8,
329 hue => 9,
330 sat => 10,
331 value => 11,
332 color => 12,
333 },
6607600c
TC
334 },
335 defaults => { ftype => 0, repeat => 0, combine => 0,
336 super_sample => 0, ssample_param => 4,
337 segments=>[
338 [ 0, 0.5, 1,
339 Imager::Color->new(0,0,0),
340 Imager::Color->new(255, 255, 255),
341 0, 0,
342 ],
343 ],
344 },
345 callsub =>
346 sub {
347 my %hsh = @_;
348 i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
349 $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
350 $hsh{ssample_param}, $hsh{segments});
351 },
352 };
b6381851
TC
353 $filters{unsharpmask} =
354 {
355 callseq => [ qw(image stddev scale) ],
356 defaults => { stddev=>2.0, scale=>1.0 },
357 callsub =>
358 sub {
359 my %hsh = @_;
360 i_unsharp_mask($hsh{image}, $hsh{stddev}, $hsh{scale});
361 },
362 };
02d1d628
AMH
363
364 $FORMATGUESS=\&def_guess_type;
365}
366
367#
368# Non methods
369#
370
371# initlize Imager
372# NOTE: this might be moved to an import override later on
373
374#sub import {
375# my $pack = shift;
376# (look through @_ for special tags, process, and remove them);
377# use Data::Dumper;
378# print Dumper($pack);
379# print Dumper(@_);
380#}
381
382sub init {
383 my %parms=(loglevel=>1,@_);
384 if ($parms{'log'}) {
385 init_log($parms{'log'},$parms{'loglevel'});
386 }
387
388# if ($parms{T1LIB_CONFIG}) { $ENV{T1LIB_CONFIG}=$parms{T1LIB_CONFIG}; }
389# if ( $ENV{T1LIB_CONFIG} and ( $fontstate eq 'missing conf' )) {
390# i_init_fonts();
391# $fontstate='ok';
392# }
393}
394
395END {
396 if ($DEBUG) {
397 print "shutdown code\n";
398 # for(keys %instances) { $instances{$_}->DESTROY(); }
399 malloc_state(); # how do decide if this should be used? -- store something from the import
400 print "Imager exiting\n";
401 }
402}
403
404# Load a filter plugin
405
406sub load_plugin {
407 my ($filename)=@_;
408 my $i;
409 my ($DSO_handle,$str)=DSO_open($filename);
410 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
411 my %funcs=DSO_funclist($DSO_handle);
412 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
413 $i=0;
414 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
415
416 $DSOs{$filename}=[$DSO_handle,\%funcs];
417
418 for(keys %funcs) {
419 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
420 $DEBUG && print "eval string:\n",$evstr,"\n";
421 eval $evstr;
422 print $@ if $@;
423 }
424 return 1;
425}
426
427# Unload a plugin
428
429sub unload_plugin {
430 my ($filename)=@_;
431
432 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
433 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
434 for(keys %{$funcref}) {
435 delete $filters{$_};
436 $DEBUG && print "unloading: $_\n";
437 }
438 my $rc=DSO_close($DSO_handle);
439 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
440 return 1;
441}
442
64606cc7
TC
443# take the results of i_error() and make a message out of it
444sub _error_as_msg {
445 return join(": ", map $_->[0], i_errors());
446}
447
02d1d628
AMH
448#
449# Methods to be called on objects.
450#
451
452# Create a new Imager object takes very few parameters.
453# usually you call this method and then call open from
454# the resulting object
455
456sub new {
457 my $class = shift;
458 my $self ={};
459 my %hsh=@_;
460 bless $self,$class;
461 $self->{IMG}=undef; # Just to indicate what exists
462 $self->{ERRSTR}=undef; #
463 $self->{DEBUG}=$DEBUG;
464 $self->{DEBUG} && print "Initialized Imager\n";
465 if ($hsh{xsize} && $hsh{ysize}) { $self->img_set(%hsh); }
466 return $self;
467}
468
02d1d628
AMH
469# Copy an entire image with no changes
470# - if an image has magic the copy of it will not be magical
471
472sub copy {
473 my $self = shift;
474 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
475
476 my $newcopy=Imager->new();
477 $newcopy->{IMG}=i_img_new();
478 i_copy($newcopy->{IMG},$self->{IMG});
479 return $newcopy;
480}
481
482# Paste a region
483
484sub paste {
485 my $self = shift;
486 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
487 my %input=(left=>0, top=>0, @_);
488 unless($input{img}) {
489 $self->{ERRSTR}="no source image";
490 return;
491 }
492 $input{left}=0 if $input{left} <= 0;
493 $input{top}=0 if $input{top} <= 0;
494 my $src=$input{img};
495 my($r,$b)=i_img_info($src->{IMG});
496
497 i_copyto($self->{IMG}, $src->{IMG},
498 0,0, $r, $b, $input{left}, $input{top});
499 return $self; # What should go here??
500}
501
502# Crop an image - i.e. return a new image that is smaller
503
504sub crop {
505 my $self=shift;
506 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
507 my %hsh=(left=>0,right=>0,top=>0,bottom=>0,@_);
508
509 my ($w,$h,$l,$r,$b,$t)=($self->getwidth(),$self->getheight(),
510 @hsh{qw(left right bottom top)});
511 $l=0 if not defined $l;
512 $t=0 if not defined $t;
299a3866
AMH
513
514 $r||=$l+delete $hsh{'width'} if defined $l and exists $hsh{'width'};
515 $b||=$t+delete $hsh{'height'} if defined $t and exists $hsh{'height'};
516 $l||=$r-delete $hsh{'width'} if defined $r and exists $hsh{'width'};
517 $t||=$b-delete $hsh{'height'} if defined $b and exists $hsh{'height'};
518
02d1d628
AMH
519 $r=$self->getwidth if not defined $r;
520 $b=$self->getheight if not defined $b;
521
522 ($l,$r)=($r,$l) if $l>$r;
523 ($t,$b)=($b,$t) if $t>$b;
524
299a3866
AMH
525 if ($hsh{'width'}) {
526 $l=int(0.5+($w-$hsh{'width'})/2);
527 $r=$l+$hsh{'width'};
02d1d628
AMH
528 } else {
529 $hsh{'width'}=$r-$l;
530 }
299a3866
AMH
531 if ($hsh{'height'}) {
532 $b=int(0.5+($h-$hsh{'height'})/2);
533 $t=$h+$hsh{'height'};
02d1d628
AMH
534 } else {
535 $hsh{'height'}=$b-$t;
536 }
537
538# print "l=$l, r=$r, h=$hsh{'width'}\n";
539# print "t=$t, b=$b, w=$hsh{'height'}\n";
540
299a3866 541 my $dst=Imager->new(xsize=>$hsh{'width'}, ysize=>$hsh{'height'}, channels=>$self->getchannels());
02d1d628
AMH
542
543 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
544 return $dst;
545}
546
547# Sets an image to a certain size and channel number
548# if there was previously data in the image it is discarded
549
550sub img_set {
551 my $self=shift;
552
faa9b3e7 553 my %hsh=(xsize=>100, ysize=>100, channels=>3, bits=>8, type=>'direct', @_);
02d1d628
AMH
554
555 if (defined($self->{IMG})) {
faa9b3e7
TC
556 # let IIM_DESTROY destroy it, it's possible this image is
557 # referenced from a virtual image (like masked)
558 #i_img_destroy($self->{IMG});
02d1d628
AMH
559 undef($self->{IMG});
560 }
561
faa9b3e7
TC
562 if ($hsh{type} eq 'paletted' || $hsh{type} eq 'pseudo') {
563 $self->{IMG} = i_img_pal_new($hsh{xsize}, $hsh{ysize}, $hsh{channels},
564 $hsh{maxcolors} || 256);
565 }
365ea842
TC
566 elsif ($hsh{bits} eq 'double') {
567 $self->{IMG} = i_img_double_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
568 }
faa9b3e7
TC
569 elsif ($hsh{bits} == 16) {
570 $self->{IMG} = i_img_16_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
571 }
572 else {
573 $self->{IMG}=Imager::ImgRaw::new($hsh{'xsize'}, $hsh{'ysize'},
574 $hsh{'channels'});
575 }
576}
577
578# created a masked version of the current image
579sub masked {
580 my $self = shift;
581
582 $self or return undef;
583 my %opts = (left => 0,
584 top => 0,
585 right => $self->getwidth,
586 bottom => $self->getheight,
587 @_);
588 my $mask = $opts{mask} ? $opts{mask}{IMG} : undef;
589
590 my $result = Imager->new;
591 $result->{IMG} = i_img_masked_new($self->{IMG}, $mask, $opts{left},
592 $opts{top}, $opts{right} - $opts{left},
593 $opts{bottom} - $opts{top});
594 # keep references to the mask and base images so they don't
595 # disappear on us
596 $result->{DEPENDS} = [ $self->{IMG}, $mask ];
597
598 $result;
599}
600
601# convert an RGB image into a paletted image
602sub to_paletted {
603 my $self = shift;
604 my $opts;
605 if (@_ != 1 && !ref $_[0]) {
606 $opts = { @_ };
607 }
608 else {
609 $opts = shift;
610 }
611
612 my $result = Imager->new;
613 $result->{IMG} = i_img_to_pal($self->{IMG}, $opts);
614
615 #print "Type ", i_img_type($result->{IMG}), "\n";
616
617 $result->{IMG} or undef $result;
618
619 return $result;
620}
621
622# convert a paletted (or any image) to an 8-bit/channel RGB images
623sub to_rgb8 {
624 my $self = shift;
625 my $result;
626
627 if ($self->{IMG}) {
628 $result = Imager->new;
629 $result->{IMG} = i_img_to_rgb($self->{IMG})
630 or undef $result;
631 }
632
633 return $result;
634}
635
636sub addcolors {
637 my $self = shift;
638 my %opts = (colors=>[], @_);
639
640 @{$opts{colors}} or return undef;
641
642 $self->{IMG} and i_addcolors($self->{IMG}, @{$opts{colors}});
643}
644
645sub setcolors {
646 my $self = shift;
647 my %opts = (start=>0, colors=>[], @_);
648 @{$opts{colors}} or return undef;
649
650 $self->{IMG} and i_setcolors($self->{IMG}, $opts{start}, @{$opts{colors}});
651}
652
653sub getcolors {
654 my $self = shift;
655 my %opts = @_;
656 if (!exists $opts{start} && !exists $opts{count}) {
657 # get them all
658 $opts{start} = 0;
659 $opts{count} = $self->colorcount;
660 }
661 elsif (!exists $opts{count}) {
662 $opts{count} = 1;
663 }
664 elsif (!exists $opts{start}) {
665 $opts{start} = 0;
666 }
667
668 $self->{IMG} and
669 return i_getcolors($self->{IMG}, $opts{start}, $opts{count});
670}
671
672sub colorcount {
673 i_colorcount($_[0]{IMG});
674}
675
676sub maxcolors {
677 i_maxcolors($_[0]{IMG});
678}
679
680sub findcolor {
681 my $self = shift;
682 my %opts = @_;
683 $opts{color} or return undef;
684
685 $self->{IMG} and i_findcolor($self->{IMG}, $opts{color});
686}
687
688sub bits {
689 my $self = shift;
af3c2450
TC
690 my $bits = $self->{IMG} && i_img_bits($self->{IMG});
691 if ($bits && $bits == length(pack("d", 1)) * 8) {
692 $bits = 'double';
693 }
694 $bits;
faa9b3e7
TC
695}
696
697sub type {
698 my $self = shift;
699 if ($self->{IMG}) {
700 return i_img_type($self->{IMG}) ? "paletted" : "direct";
701 }
702}
703
704sub virtual {
705 my $self = shift;
706 $self->{IMG} and i_img_virtual($self->{IMG});
707}
708
709sub tags {
710 my ($self, %opts) = @_;
711
712 $self->{IMG} or return;
713
714 if (defined $opts{name}) {
715 my @result;
716 my $start = 0;
717 my $found;
718 while (defined($found = i_tags_find($self->{IMG}, $opts{name}, $start))) {
719 push @result, (i_tags_get($self->{IMG}, $found))[1];
720 $start = $found+1;
721 }
722 return wantarray ? @result : $result[0];
723 }
724 elsif (defined $opts{code}) {
725 my @result;
726 my $start = 0;
727 my $found;
728 while (defined($found = i_tags_findn($self->{IMG}, $opts{code}, $start))) {
729 push @result, (i_tags_get($self->{IMG}, $found))[1];
730 $start = $found+1;
731 }
732 return @result;
733 }
734 else {
735 if (wantarray) {
736 return map { [ i_tags_get($self->{IMG}, $_) ] } 0.. i_tags_count($self->{IMG})-1;
737 }
738 else {
739 return i_tags_count($self->{IMG});
740 }
741 }
742}
743
744sub addtag {
745 my $self = shift;
746 my %opts = @_;
747
748 return -1 unless $self->{IMG};
749 if ($opts{name}) {
750 if (defined $opts{value}) {
751 if ($opts{value} =~ /^\d+$/) {
752 # add as a number
753 return i_tags_addn($self->{IMG}, $opts{name}, 0, $opts{value});
754 }
755 else {
756 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{value}, 0);
757 }
758 }
759 elsif (defined $opts{data}) {
760 # force addition as a string
761 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{data}, 0);
762 }
763 else {
764 $self->{ERRSTR} = "No value supplied";
765 return undef;
766 }
767 }
768 elsif ($opts{code}) {
769 if (defined $opts{value}) {
770 if ($opts{value} =~ /^\d+$/) {
771 # add as a number
772 return i_tags_addn($self->{IMG}, $opts{code}, 0, $opts{value});
773 }
774 else {
775 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{value}, 0);
776 }
777 }
778 elsif (defined $opts{data}) {
779 # force addition as a string
780 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{data}, 0);
781 }
782 else {
783 $self->{ERRSTR} = "No value supplied";
784 return undef;
785 }
786 }
787 else {
788 return undef;
789 }
790}
791
792sub deltag {
793 my $self = shift;
794 my %opts = @_;
795
796 return 0 unless $self->{IMG};
797
9d540150
TC
798 if (defined $opts{'index'}) {
799 return i_tags_delete($self->{IMG}, $opts{'index'});
faa9b3e7
TC
800 }
801 elsif (defined $opts{name}) {
802 return i_tags_delbyname($self->{IMG}, $opts{name});
803 }
804 elsif (defined $opts{code}) {
805 return i_tags_delbycode($self->{IMG}, $opts{code});
806 }
807 else {
808 $self->{ERRSTR} = "Need to supply index, name, or code parameter";
809 return 0;
810 }
02d1d628
AMH
811}
812
813# Read an image from file
814
815sub read {
816 my $self = shift;
817 my %input=@_;
818 my ($fh, $fd, $IO);
819
820 if (defined($self->{IMG})) {
faa9b3e7
TC
821 # let IIM_DESTROY do the destruction, since the image may be
822 # referenced from elsewhere
823 #i_img_destroy($self->{IMG});
02d1d628
AMH
824 undef($self->{IMG});
825 }
826
895dbd34
AMH
827 if (!$input{fd} and !$input{file} and !$input{data}) {
828 $self->{ERRSTR}='no file, fd or data parameter'; return undef;
829 }
02d1d628
AMH
830 if ($input{file}) {
831 $fh = new IO::File($input{file},"r");
895dbd34
AMH
832 if (!defined $fh) {
833 $self->{ERRSTR}='Could not open file'; return undef;
834 }
02d1d628
AMH
835 binmode($fh);
836 $fd = $fh->fileno();
837 }
895dbd34
AMH
838 if ($input{fd}) {
839 $fd=$input{fd};
840 }
02d1d628
AMH
841
842 # FIXME: Find the format here if not specified
843 # yes the code isn't here yet - next week maybe?
dd55acc8
AMH
844 # Next week? Are you high or something? That comment
845 # has been there for half a year dude.
cf692b64 846 # Look, i just work here, ok?
02d1d628 847
9d540150
TC
848 if (!$input{'type'} and $input{file}) {
849 $input{'type'}=$FORMATGUESS->($input{file});
895dbd34 850 }
9d540150 851 if (!$formats{$input{'type'}}) {
895dbd34
AMH
852 $self->{ERRSTR}='format not supported'; return undef;
853 }
02d1d628 854
1ec86afa 855 my %iolready=(jpeg=>1, png=>1, tiff=>1, pnm=>1, raw=>1, bmp=>1, tga=>1);
02d1d628 856
9d540150 857 if ($iolready{$input{'type'}}) {
02d1d628 858 # Setup data source
a6c47345 859 $IO = defined $fd ? io_new_fd($fd) : io_new_buffer($input{data});
02d1d628 860
9d540150 861 if ( $input{'type'} eq 'jpeg' ) {
02d1d628 862 ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_wiol( $IO );
895dbd34
AMH
863 if ( !defined($self->{IMG}) ) {
864 $self->{ERRSTR}='unable to read jpeg image'; return undef;
865 }
02d1d628
AMH
866 $self->{DEBUG} && print "loading a jpeg file\n";
867 return $self;
868 }
869
9d540150 870 if ( $input{'type'} eq 'tiff' ) {
02d1d628 871 $self->{IMG}=i_readtiff_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
895dbd34
AMH
872 if ( !defined($self->{IMG}) ) {
873 $self->{ERRSTR}='unable to read tiff image'; return undef;
874 }
02d1d628
AMH
875 $self->{DEBUG} && print "loading a tiff file\n";
876 return $self;
877 }
878
9d540150 879 if ( $input{'type'} eq 'pnm' ) {
02d1d628 880 $self->{IMG}=i_readpnm_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
895dbd34
AMH
881 if ( !defined($self->{IMG}) ) {
882 $self->{ERRSTR}='unable to read pnm image: '._error_as_msg(); return undef;
883 }
02d1d628
AMH
884 $self->{DEBUG} && print "loading a pnm file\n";
885 return $self;
886 }
887
9d540150 888 if ( $input{'type'} eq 'png' ) {
790923a4
AMH
889 $self->{IMG}=i_readpng_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
890 if ( !defined($self->{IMG}) ) {
891 $self->{ERRSTR}='unable to read png image';
892 return undef;
893 }
894 $self->{DEBUG} && print "loading a png file\n";
895 }
896
9d540150 897 if ( $input{'type'} eq 'bmp' ) {
705fd961
TC
898 $self->{IMG}=i_readbmp_wiol( $IO );
899 if ( !defined($self->{IMG}) ) {
900 $self->{ERRSTR}='unable to read bmp image';
901 return undef;
902 }
903 $self->{DEBUG} && print "loading a bmp file\n";
904 }
905
9d540150 906 if ( $input{'type'} eq 'tga' ) {
1ec86afa
AMH
907 $self->{IMG}=i_readtga_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
908 if ( !defined($self->{IMG}) ) {
909 $self->{ERRSTR}=$self->_error_as_msg();
910# $self->{ERRSTR}='unable to read tga image';
911 return undef;
912 }
913 $self->{DEBUG} && print "loading a tga file\n";
914 }
915
9d540150 916 if ( $input{'type'} eq 'raw' ) {
895dbd34 917 my %params=(datachannels=>3,storechannels=>3,interleave=>1,%input);
02d1d628 918
895dbd34
AMH
919 if ( !($params{xsize} && $params{ysize}) ) {
920 $self->{ERRSTR}='missing xsize or ysize parameter for raw';
921 return undef;
922 }
02d1d628 923
895dbd34
AMH
924 $self->{IMG} = i_readraw_wiol( $IO,
925 $params{xsize},
926 $params{ysize},
927 $params{datachannels},
928 $params{storechannels},
929 $params{interleave});
930 if ( !defined($self->{IMG}) ) {
931 $self->{ERRSTR}='unable to read raw image';
932 return undef;
933 }
934 $self->{DEBUG} && print "loading a raw file\n";
935 }
790923a4 936
895dbd34 937 } else {
02d1d628 938
895dbd34 939 # Old code for reference while changing the new stuff
02d1d628 940
9d540150
TC
941 if (!$input{'type'} and $input{file}) {
942 $input{'type'}=$FORMATGUESS->($input{file});
895dbd34
AMH
943 }
944
9d540150 945 if (!$input{'type'}) {
895dbd34
AMH
946 $self->{ERRSTR}='type parameter missing and not possible to guess from extension'; return undef;
947 }
02d1d628 948
9d540150 949 if (!$formats{$input{'type'}}) {
895dbd34 950 $self->{ERRSTR}='format not supported';
a59ffd27
TC
951 return undef;
952 }
895dbd34
AMH
953
954 if ($input{file}) {
955 $fh = new IO::File($input{file},"r");
956 if (!defined $fh) {
957 $self->{ERRSTR}='Could not open file';
958 return undef;
a59ffd27 959 }
895dbd34
AMH
960 binmode($fh);
961 $fd = $fh->fileno();
a59ffd27 962 }
895dbd34
AMH
963
964 if ($input{fd}) {
965 $fd=$input{fd};
966 }
967
9d540150 968 if ( $input{'type'} eq 'gif' ) {
895dbd34
AMH
969 my $colors;
970 if ($input{colors} && !ref($input{colors})) {
971 # must be a reference to a scalar that accepts the colour map
972 $self->{ERRSTR} = "option 'colors' must be a scalar reference";
973 return undef;
a59ffd27 974 }
895dbd34
AMH
975 if (exists $input{data}) {
976 if ($input{colors}) {
977 ($self->{IMG}, $colors) = i_readgif_scalar($input{data});
978 } else {
979 $self->{IMG}=i_readgif_scalar($input{data});
980 }
981 } else {
982 if ($input{colors}) {
983 ($self->{IMG}, $colors) = i_readgif( $fd );
984 } else {
985 $self->{IMG} = i_readgif( $fd )
986 }
a59ffd27 987 }
895dbd34
AMH
988 if ($colors) {
989 # we may or may not change i_readgif to return blessed objects...
990 ${ $input{colors} } = [ map { NC(@$_) } @$colors ];
991 }
992 if ( !defined($self->{IMG}) ) {
993 $self->{ERRSTR}= 'reading GIF:'._error_as_msg();
994 return undef;
995 }
996 $self->{DEBUG} && print "loading a gif file\n";
dd55acc8 997 }
02d1d628
AMH
998 }
999 return $self;
02d1d628
AMH
1000}
1001
02d1d628 1002# Write an image to file
02d1d628
AMH
1003sub write {
1004 my $self = shift;
febba01f
AMH
1005 my %input=(jpegquality=>75,
1006 gifquant=>'mc',
1007 lmdither=>6.0,
1008 lmfixed=>[],
1009 idstring=>"",
1010 compress=>1,
1011 wierdpack=>0,
4c2d6970 1012 fax_fine=>1, @_);
02d1d628
AMH
1013 my ($fh, $rc, $fd, $IO);
1014
1ec86afa 1015 my %iolready=( tiff=>1, raw=>1, png=>1, pnm=>1, bmp=>1, jpeg=>1, tga=>1 ); # this will be SO MUCH BETTER once they are all in there
02d1d628
AMH
1016
1017 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1018
1019 if (!$input{file} and !$input{'fd'} and !$input{'data'}) { $self->{ERRSTR}='file/fd/data parameter missing'; return undef; }
9d540150
TC
1020 if (!$input{'type'} and $input{file}) {
1021 $input{'type'}=$FORMATGUESS->($input{file});
1022 }
1023 if (!$input{'type'}) {
1024 $self->{ERRSTR}='type parameter missing and not possible to guess from extension';
1025 return undef;
1026 }
02d1d628 1027
9d540150 1028 if (!$formats{$input{'type'}}) { $self->{ERRSTR}='format not supported'; return undef; }
02d1d628
AMH
1029
1030 if (exists $input{'fd'}) {
1031 $fd=$input{'fd'};
1032 } elsif (exists $input{'data'}) {
1033 $IO = Imager::io_new_bufchain();
1034 } else {
1035 $fh = new IO::File($input{file},"w+");
1036 if (!defined $fh) { $self->{ERRSTR}='Could not open file'; return undef; }
faa9b3e7 1037 binmode($fh) or die;
02d1d628
AMH
1038 $fd = $fh->fileno();
1039 }
1040
9d540150 1041 if ($iolready{$input{'type'}}) {
4c2d6970 1042 if (defined $fd) {
02d1d628
AMH
1043 $IO = io_new_fd($fd);
1044 }
1045
9d540150 1046 if ($input{'type'} eq 'tiff') {
4c2d6970
TC
1047 if (defined $input{class} && $input{class} eq 'fax') {
1048 if (!i_writetiff_wiol_faxable($self->{IMG}, $IO, $input{fax_fine})) {
d2dfdcc9
TC
1049 $self->{ERRSTR}='Could not write to buffer';
1050 return undef;
1051 }
04418ecc 1052 } else {
930c67c8
AMH
1053 if (!i_writetiff_wiol($self->{IMG}, $IO)) {
1054 $self->{ERRSTR}='Could not write to buffer';
1055 return undef;
d2dfdcc9
TC
1056 }
1057 }
9d540150 1058 } elsif ( $input{'type'} eq 'pnm' ) {
04418ecc
AMH
1059 if ( ! i_writeppm_wiol($self->{IMG},$IO) ) {
1060 $self->{ERRSTR}='unable to write pnm image';
1061 return undef;
1062 }
1063 $self->{DEBUG} && print "writing a pnm file\n";
9d540150 1064 } elsif ( $input{'type'} eq 'raw' ) {
ec9b9c3e 1065 if ( !i_writeraw_wiol($self->{IMG},$IO) ) {
04418ecc
AMH
1066 $self->{ERRSTR}='unable to write raw image';
1067 return undef;
1068 }
1069 $self->{DEBUG} && print "writing a raw file\n";
9d540150 1070 } elsif ( $input{'type'} eq 'png' ) {
ec9b9c3e
AMH
1071 if ( !i_writepng_wiol($self->{IMG}, $IO) ) {
1072 $self->{ERRSTR}='unable to write png image';
1073 return undef;
1074 }
1075 $self->{DEBUG} && print "writing a png file\n";
9d540150 1076 } elsif ( $input{'type'} eq 'jpeg' ) {
cf692b64 1077 if ( !i_writejpeg_wiol($self->{IMG}, $IO, $input{jpegquality})) {
f873cb01 1078 $self->{ERRSTR} = $self->_error_as_msg();
cf692b64
TC
1079 return undef;
1080 }
1081 $self->{DEBUG} && print "writing a jpeg file\n";
9d540150 1082 } elsif ( $input{'type'} eq 'bmp' ) {
705fd961
TC
1083 if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
1084 $self->{ERRSTR}='unable to write bmp image';
1085 return undef;
1086 }
1087 $self->{DEBUG} && print "writing a bmp file\n";
9d540150 1088 } elsif ( $input{'type'} eq 'tga' ) {
febba01f
AMH
1089
1090 if ( !i_writetga_wiol($self->{IMG}, $IO, $input{wierdpack}, $input{compress}, $input{idstring}) ) {
1ec86afa 1091 $self->{ERRSTR}=$self->_error_as_msg();
1ec86afa
AMH
1092 return undef;
1093 }
1094 $self->{DEBUG} && print "writing a tga file\n";
02d1d628
AMH
1095 }
1096
930c67c8
AMH
1097 if (exists $input{'data'}) {
1098 my $data = io_slurp($IO);
1099 if (!$data) {
1100 $self->{ERRSTR}='Could not slurp from buffer';
1101 return undef;
1102 }
1103 ${$input{data}} = $data;
1104 }
02d1d628
AMH
1105 return $self;
1106 } else {
9d540150 1107 if ( $input{'type'} eq 'gif' ) {
02d1d628
AMH
1108 if (not $input{gifplanes}) {
1109 my $gp;
1110 my $count=i_count_colors($self->{IMG}, 256);
1111 $gp=8 if $count == -1;
1112 $gp=1 if not $gp and $count <= 2;
1113 $gp=2 if not $gp and $count <= 4;
1114 $gp=3 if not $gp and $count <= 8;
1115 $gp=4 if not $gp and $count <= 16;
1116 $gp=5 if not $gp and $count <= 32;
1117 $gp=6 if not $gp and $count <= 64;
1118 $gp=7 if not $gp and $count <= 128;
1119 $input{gifplanes} = $gp || 8;
1120 }
1121
1122 if ($input{gifplanes}>8) {
1123 $input{gifplanes}=8;
1124 }
1125 if ($input{gifquant} eq 'gen' || $input{callback}) {
1126
1127
1128 if ($input{gifquant} eq 'lm') {
1129
1130 $input{make_colors} = 'addi';
1131 $input{translate} = 'perturb';
1132 $input{perturb} = $input{lmdither};
1133 } elsif ($input{gifquant} eq 'gen') {
1134 # just pass options through
1135 } else {
1136 $input{make_colors} = 'webmap'; # ignored
1137 $input{translate} = 'giflib';
1138 }
1139
1140 if ($input{callback}) {
1141 defined $input{maxbuffer} or $input{maxbuffer} = -1;
1142 $rc = i_writegif_callback($input{callback}, $input{maxbuffer},
1143 \%input, $self->{IMG});
1144 } else {
1145 $rc = i_writegif_gen($fd, \%input, $self->{IMG});
1146 }
1147
02d1d628
AMH
1148 } elsif ($input{gifquant} eq 'lm') {
1149 $rc=i_writegif($self->{IMG},$fd,$input{gifplanes},$input{lmdither},$input{lmfixed});
1150 } else {
1151 $rc=i_writegifmc($self->{IMG},$fd,$input{gifplanes});
1152 }
1153 if ( !defined($rc) ) {
3827fae0 1154 $self->{ERRSTR} = "Writing GIF file: "._error_as_msg(); return undef;
02d1d628
AMH
1155 }
1156 $self->{DEBUG} && print "writing a gif file\n";
1157
02d1d628 1158 }
02d1d628
AMH
1159 }
1160 return $self;
1161}
1162
1163sub write_multi {
1164 my ($class, $opts, @images) = @_;
1165
9d540150 1166 if ($opts->{'type'} eq 'gif') {
ed88b092
TC
1167 my $gif_delays = $opts->{gif_delays};
1168 local $opts->{gif_delays} = $gif_delays;
1169 unless (ref $opts->{gif_delays}) {
1170 # assume the caller wants the same delay for each frame
1171 $opts->{gif_delays} = [ ($gif_delays) x @images ];
1172 }
02d1d628
AMH
1173 # translate to ImgRaw
1174 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
1175 $ERRSTR = "Usage: Imager->write_multi({ options }, @images)";
1176 return 0;
1177 }
1178 my @work = map $_->{IMG}, @images;
1179 if ($opts->{callback}) {
1180 # Note: you may need to fix giflib for this one to work
1181 my $maxbuffer = $opts->{maxbuffer};
1182 defined $maxbuffer or $maxbuffer = -1; # max by default
1183 return i_writegif_callback($opts->{callback}, $maxbuffer,
1184 $opts, @work);
1185 }
1186 if ($opts->{fd}) {
1187 return i_writegif_gen($opts->{fd}, $opts, @work);
1188 }
1189 else {
1190 my $fh = IO::File->new($opts->{file}, "w+");
1191 unless ($fh) {
1192 $ERRSTR = "Error creating $opts->{file}: $!";
1193 return 0;
1194 }
1195 binmode($fh);
1196 return i_writegif_gen(fileno($fh), $opts, @work);
1197 }
1198 }
1199 else {
9d540150 1200 $ERRSTR = "Sorry, write_multi doesn't support $opts->{'type'} yet";
02d1d628
AMH
1201 return 0;
1202 }
1203}
1204
faa9b3e7
TC
1205# read multiple images from a file
1206sub read_multi {
1207 my ($class, %opts) = @_;
1208
9d540150 1209 if ($opts{file} && !exists $opts{'type'}) {
faa9b3e7
TC
1210 # guess the type
1211 my $type = $FORMATGUESS->($opts{file});
9d540150 1212 $opts{'type'} = $type;
faa9b3e7 1213 }
9d540150 1214 unless ($opts{'type'}) {
faa9b3e7
TC
1215 $ERRSTR = "No type parameter supplied and it couldn't be guessed";
1216 return;
1217 }
1218 my $fd;
1219 my $file;
1220 if ($opts{file}) {
1221 $file = IO::File->new($opts{file}, "r");
1222 unless ($file) {
1223 $ERRSTR = "Could not open file $opts{file}: $!";
1224 return;
1225 }
1226 binmode $file;
1227 $fd = fileno($file);
1228 }
1229 elsif ($opts{fh}) {
1230 $fd = fileno($opts{fh});
1231 unless ($fd) {
1232 $ERRSTR = "File handle specified with fh option not open";
1233 return;
1234 }
1235 }
1236 elsif ($opts{fd}) {
1237 $fd = $opts{fd};
1238 }
1239 elsif ($opts{callback} || $opts{data}) {
1240 # don't fail here
1241 }
1242 else {
1243 $ERRSTR = "You need to specify one of file, fd, fh, callback or data";
1244 return;
1245 }
1246
9d540150 1247 if ($opts{'type'} eq 'gif') {
faa9b3e7
TC
1248 my @imgs;
1249 if ($fd) {
1250 @imgs = i_readgif_multi($fd);
1251 }
1252 else {
1253 if (Imager::i_giflib_version() < 4.0) {
1254 $ERRSTR = "giflib3.x does not support callbacks";
1255 return;
1256 }
1257 if ($opts{callback}) {
1258 @imgs = i_readgif_multi_callback($opts{callback})
1259 }
1260 else {
1261 @imgs = i_readgif_multi_scalar($opts{data});
1262 }
1263 }
1264 if (@imgs) {
1265 return map {
1266 bless { IMG=>$_, DEBUG=>$DEBUG, ERRSTR=>undef }, 'Imager'
1267 } @imgs;
1268 }
1269 else {
1270 $ERRSTR = _error_as_msg();
1271 return;
1272 }
1273 }
1274
9d540150 1275 $ERRSTR = "Cannot read multiple images from $opts{'type'} files";
faa9b3e7
TC
1276 return;
1277}
1278
02d1d628
AMH
1279# Destroy an Imager object
1280
1281sub DESTROY {
1282 my $self=shift;
1283 # delete $instances{$self};
1284 if (defined($self->{IMG})) {
faa9b3e7
TC
1285 # the following is now handled by the XS DESTROY method for
1286 # Imager::ImgRaw object
1287 # Re-enabling this will break virtual images
1288 # tested for in t/t020masked.t
1289 # i_img_destroy($self->{IMG});
02d1d628
AMH
1290 undef($self->{IMG});
1291 } else {
1292# print "Destroy Called on an empty image!\n"; # why did I put this here??
1293 }
1294}
1295
1296# Perform an inplace filter of an image
1297# that is the image will be overwritten with the data
1298
1299sub filter {
1300 my $self=shift;
1301 my %input=@_;
1302 my %hsh;
1303 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1304
9d540150 1305 if (!$input{'type'}) { $self->{ERRSTR}='type parameter missing'; return undef; }
02d1d628 1306
9d540150 1307 if ( (grep { $_ eq $input{'type'} } keys %filters) != 1) {
02d1d628
AMH
1308 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
1309 }
1310
9d540150
TC
1311 if ($filters{$input{'type'}}{names}) {
1312 my $names = $filters{$input{'type'}}{names};
6607600c
TC
1313 for my $name (keys %$names) {
1314 if (defined $input{$name} && exists $names->{$name}{$input{$name}}) {
1315 $input{$name} = $names->{$name}{$input{$name}};
1316 }
1317 }
1318 }
9d540150
TC
1319 if (defined($filters{$input{'type'}}{defaults})) {
1320 %hsh=('image',$self->{IMG},%{$filters{$input{'type'}}{defaults}},%input);
02d1d628
AMH
1321 } else {
1322 %hsh=('image',$self->{IMG},%input);
1323 }
1324
9d540150 1325 my @cs=@{$filters{$input{'type'}}{callseq}};
02d1d628
AMH
1326
1327 for(@cs) {
1328 if (!defined($hsh{$_})) {
9d540150 1329 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{'type'}; return undef;
02d1d628
AMH
1330 }
1331 }
1332
9d540150 1333 &{$filters{$input{'type'}}{callsub}}(%hsh);
02d1d628
AMH
1334
1335 my @b=keys %hsh;
1336
1337 $self->{DEBUG} && print "callseq is: @cs\n";
1338 $self->{DEBUG} && print "matching callseq is: @b\n";
1339
1340 return $self;
1341}
1342
1343# Scale an image to requested size and return the scaled version
1344
1345sub scale {
1346 my $self=shift;
9d540150 1347 my %opts=(scalefactor=>0.5,'type'=>'max',qtype=>'normal',@_);
02d1d628
AMH
1348 my $img = Imager->new();
1349 my $tmp = Imager->new();
1350
1351 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1352
9d540150 1353 if ($opts{xpixels} and $opts{ypixels} and $opts{'type'}) {
02d1d628 1354 my ($xpix,$ypix)=( $opts{xpixels}/$self->getwidth() , $opts{ypixels}/$self->getheight() );
9d540150
TC
1355 if ($opts{'type'} eq 'min') { $opts{scalefactor}=min($xpix,$ypix); }
1356 if ($opts{'type'} eq 'max') { $opts{scalefactor}=max($xpix,$ypix); }
02d1d628
AMH
1357 } elsif ($opts{xpixels}) { $opts{scalefactor}=$opts{xpixels}/$self->getwidth(); }
1358 elsif ($opts{ypixels}) { $opts{scalefactor}=$opts{ypixels}/$self->getheight(); }
1359
1360 if ($opts{qtype} eq 'normal') {
1361 $tmp->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},0);
1362 if ( !defined($tmp->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1363 $img->{IMG}=i_scaleaxis($tmp->{IMG},$opts{scalefactor},1);
1364 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1365 return $img;
1366 }
1367 if ($opts{'qtype'} eq 'preview') {
1368 $img->{IMG}=i_scale_nn($self->{IMG},$opts{'scalefactor'},$opts{'scalefactor'});
1369 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1370 return $img;
1371 }
1372 $self->{ERRSTR}='scale: invalid value for qtype'; return undef;
1373}
1374
1375# Scales only along the X axis
1376
1377sub scaleX {
1378 my $self=shift;
1379 my %opts=(scalefactor=>0.5,@_);
1380
1381 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1382
1383 my $img = Imager->new();
1384
1385 if ($opts{pixels}) { $opts{scalefactor}=$opts{pixels}/$self->getwidth(); }
1386
1387 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1388 $img->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},0);
1389
1390 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1391 return $img;
1392}
1393
1394# Scales only along the Y axis
1395
1396sub scaleY {
1397 my $self=shift;
1398 my %opts=(scalefactor=>0.5,@_);
1399
1400 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1401
1402 my $img = Imager->new();
1403
1404 if ($opts{pixels}) { $opts{scalefactor}=$opts{pixels}/$self->getheight(); }
1405
1406 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1407 $img->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},1);
1408
1409 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1410 return $img;
1411}
1412
1413
1414# Transform returns a spatial transformation of the input image
1415# this moves pixels to a new location in the returned image.
1416# NOTE - should make a utility function to check transforms for
1417# stack overruns
1418
1419sub transform {
1420 my $self=shift;
1421 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1422 my %opts=@_;
1423 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
1424
1425# print Dumper(\%opts);
1426# xopcopdes
1427
1428 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
1429 if (!$I2P) {
1430 eval ("use Affix::Infix2Postfix;");
1431 print $@;
1432 if ( $@ ) {
1433 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
1434 return undef;
1435 }
1436 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
1437 {op=>'-',trans=>'Sub'},
1438 {op=>'*',trans=>'Mult'},
1439 {op=>'/',trans=>'Div'},
9d540150 1440 {op=>'-','type'=>'unary',trans=>'u-'},
02d1d628 1441 {op=>'**'},
9d540150 1442 {op=>'func','type'=>'unary'}],
02d1d628
AMH
1443 'grouping'=>[qw( \( \) )],
1444 'func'=>[qw( sin cos )],
1445 'vars'=>[qw( x y )]
1446 );
1447 }
1448
1449 @xt=$I2P->translate($opts{'xexpr'});
1450 @yt=$I2P->translate($opts{'yexpr'});
1451
1452 $numre=$I2P->{'numre'};
1453 @pt=(0,0);
1454
1455 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
1456 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
1457 @{$opts{'parm'}}=@pt;
1458 }
1459
1460# print Dumper(\%opts);
1461
1462 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
1463 $self->{ERRSTR}='transform: no xopcodes given.';
1464 return undef;
1465 }
1466
1467 @op=@{$opts{'xopcodes'}};
1468 for $iop (@op) {
1469 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
1470 $self->{ERRSTR}="transform: illegal opcode '$_'.";
1471 return undef;
1472 }
1473 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
1474 }
1475
1476
1477# yopcopdes
1478
1479 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
1480 $self->{ERRSTR}='transform: no yopcodes given.';
1481 return undef;
1482 }
1483
1484 @op=@{$opts{'yopcodes'}};
1485 for $iop (@op) {
1486 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
1487 $self->{ERRSTR}="transform: illegal opcode '$_'.";
1488 return undef;
1489 }
1490 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
1491 }
1492
1493#parameters
1494
1495 if ( !exists $opts{'parm'}) {
1496 $self->{ERRSTR}='transform: no parameter arg given.';
1497 return undef;
1498 }
1499
1500# print Dumper(\@ropx);
1501# print Dumper(\@ropy);
1502# print Dumper(\@ropy);
1503
1504 my $img = Imager->new();
1505 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
1506 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
1507 return $img;
1508}
1509
1510
bf94b653
TC
1511sub transform2 {
1512 my ($opts, @imgs) = @_;
1513
1514 require "Imager/Expr.pm";
1515
1516 $opts->{variables} = [ qw(x y) ];
1517 my ($width, $height) = @{$opts}{qw(width height)};
1518 if (@imgs) {
1519 $width ||= $imgs[0]->getwidth();
1520 $height ||= $imgs[0]->getheight();
1521 my $img_num = 1;
1522 for my $img (@imgs) {
1523 $opts->{constants}{"w$img_num"} = $img->getwidth();
1524 $opts->{constants}{"h$img_num"} = $img->getheight();
1525 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
1526 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
1527 ++$img_num;
02d1d628 1528 }
02d1d628 1529 }
bf94b653
TC
1530 if ($width) {
1531 $opts->{constants}{w} = $width;
1532 $opts->{constants}{cx} = $width/2;
1533 }
1534 else {
1535 $Imager::ERRSTR = "No width supplied";
1536 return;
1537 }
1538 if ($height) {
1539 $opts->{constants}{h} = $height;
1540 $opts->{constants}{cy} = $height/2;
1541 }
1542 else {
1543 $Imager::ERRSTR = "No height supplied";
1544 return;
1545 }
1546 my $code = Imager::Expr->new($opts);
1547 if (!$code) {
1548 $Imager::ERRSTR = Imager::Expr::error();
1549 return;
1550 }
9982a307 1551
bf94b653
TC
1552 my $img = Imager->new();
1553 $img->{IMG} = i_transform2($opts->{width}, $opts->{height}, $code->code(),
1554 $code->nregs(), $code->cregs(),
1555 [ map { $_->{IMG} } @imgs ]);
1556 if (!defined $img->{IMG}) {
1557 $Imager::ERRSTR = Imager->_error_as_msg();
1558 return;
1559 }
9982a307 1560
bf94b653 1561 return $img;
02d1d628
AMH
1562}
1563
02d1d628
AMH
1564sub rubthrough {
1565 my $self=shift;
1566 my %opts=(tx=>0,ty=>0,@_);
1567
1568 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1569 unless ($opts{src} && $opts{src}->{IMG}) { $self->{ERRSTR}='empty input image for source'; return undef; }
1570
faa9b3e7
TC
1571 unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $opts{tx},$opts{ty})) {
1572 $self->{ERRSTR} = $self->_error_as_msg();
1573 return undef;
1574 }
02d1d628
AMH
1575 return $self;
1576}
1577
1578
142c26ff
AMH
1579sub flip {
1580 my $self = shift;
1581 my %opts = @_;
9191e525 1582 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
142c26ff
AMH
1583 my $dir;
1584 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
1585 $dir = $xlate{$opts{'dir'}};
1586 return $self if i_flipxy($self->{IMG}, $dir);
1587 return ();
1588}
1589
faa9b3e7
TC
1590sub rotate {
1591 my $self = shift;
1592 my %opts = @_;
1593 if (defined $opts{right}) {
1594 my $degrees = $opts{right};
1595 if ($degrees < 0) {
1596 $degrees += 360 * int(((-$degrees)+360)/360);
1597 }
1598 $degrees = $degrees % 360;
1599 if ($degrees == 0) {
1600 return $self->copy();
1601 }
1602 elsif ($degrees == 90 || $degrees == 180 || $degrees == 270) {
1603 my $result = Imager->new();
1604 if ($result->{IMG} = i_rotate90($self->{IMG}, $degrees)) {
1605 return $result;
1606 }
1607 else {
1608 $self->{ERRSTR} = $self->_error_as_msg();
1609 return undef;
1610 }
1611 }
1612 else {
1613 $self->{ERRSTR} = "Parameter 'right' must be a multiple of 90 degrees";
1614 return undef;
1615 }
1616 }
1617 elsif (defined $opts{radians} || defined $opts{degrees}) {
1618 my $amount = $opts{radians} || $opts{degrees} * 3.1415926535 / 180;
1619
1620 my $result = Imager->new;
1621 if ($result->{IMG} = i_rotate_exact($self->{IMG}, $amount)) {
1622 return $result;
1623 }
1624 else {
1625 $self->{ERRSTR} = $self->_error_as_msg();
1626 return undef;
1627 }
1628 }
1629 else {
1630 $self->{ERRSTR} = "Only the 'right' parameter is available";
1631 return undef;
1632 }
1633}
1634
1635sub matrix_transform {
1636 my $self = shift;
1637 my %opts = @_;
1638
1639 if ($opts{matrix}) {
1640 my $xsize = $opts{xsize} || $self->getwidth;
1641 my $ysize = $opts{ysize} || $self->getheight;
142c26ff 1642
faa9b3e7
TC
1643 my $result = Imager->new;
1644 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
1645 $opts{matrix})
1646 or return undef;
1647
1648 return $result;
1649 }
1650 else {
1651 $self->{ERRSTR} = "matrix parameter required";
1652 return undef;
1653 }
1654}
1655
1656# blame Leolo :)
1657*yatf = \&matrix_transform;
02d1d628
AMH
1658
1659# These two are supported for legacy code only
1660
1661sub i_color_new {
faa9b3e7 1662 return Imager::Color->new(@_);
02d1d628
AMH
1663}
1664
1665sub i_color_set {
faa9b3e7 1666 return Imager::Color::set(@_);
02d1d628
AMH
1667}
1668
02d1d628 1669# Draws a box between the specified corner points.
02d1d628
AMH
1670sub box {
1671 my $self=shift;
1672 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1673 my $dflcl=i_color_new(255,255,255,255);
1674 my %opts=(color=>$dflcl,xmin=>0,ymin=>0,xmax=>$self->getwidth()-1,ymax=>$self->getheight()-1,@_);
1675
1676 if (exists $opts{'box'}) {
1677 $opts{'xmin'} = min($opts{'box'}->[0],$opts{'box'}->[2]);
1678 $opts{'xmax'} = max($opts{'box'}->[0],$opts{'box'}->[2]);
1679 $opts{'ymin'} = min($opts{'box'}->[1],$opts{'box'}->[3]);
1680 $opts{'ymax'} = max($opts{'box'}->[1],$opts{'box'}->[3]);
1681 }
1682
f1ac5027
TC
1683 if ($opts{filled}) {
1684 i_box_filled($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},
1685 $opts{ymax},$opts{color});
1686 }
1687 elsif ($opts{fill}) {
1688 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
1689 # assume it's a hash ref
1690 require 'Imager/Fill.pm';
141a6114
TC
1691 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
1692 $self->{ERRSTR} = $Imager::ERRSTR;
1693 return undef;
1694 }
f1ac5027
TC
1695 }
1696 i_box_cfill($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},
1697 $opts{ymax},$opts{fill}{fill});
1698 }
1699 else {
1700 i_box($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},$opts{ymax},$opts{color});
1701 }
02d1d628
AMH
1702 return $self;
1703}
1704
1705# Draws an arc - this routine SUCKS and is buggy - it sometimes doesn't work when the arc is a convex polygon
1706
1707sub arc {
1708 my $self=shift;
1709 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1710 my $dflcl=i_color_new(255,255,255,255);
1711 my %opts=(color=>$dflcl,
1712 'r'=>min($self->getwidth(),$self->getheight())/3,
1713 'x'=>$self->getwidth()/2,
1714 'y'=>$self->getheight()/2,
1715 'd1'=>0, 'd2'=>361, @_);
f1ac5027
TC
1716 if ($opts{fill}) {
1717 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
1718 # assume it's a hash ref
1719 require 'Imager/Fill.pm';
569795e8
TC
1720 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
1721 $self->{ERRSTR} = $Imager::ERRSTR;
1722 return;
1723 }
f1ac5027
TC
1724 }
1725 i_arc_cfill($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},
1726 $opts{'d2'}, $opts{fill}{fill});
1727 }
1728 else {
0d321238
TC
1729 if ($opts{d1} == 0 && $opts{d2} == 361 && $opts{aa}) {
1730 i_circle_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'r'},
1731 $opts{'color'});
1732 }
1733 else {
7456c26c
AMH
1734 # i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'}, $opts{'d2'},$opts{'color'});
1735 if ($opts{'d1'} <= $opts{'d2'}) { i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},$opts{'d2'},$opts{'color'}); }
1736 else { i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'}, 361,$opts{'color'});
1737 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'}, 0,$opts{'d2'},$opts{'color'}); }
0d321238 1738 }
f1ac5027
TC
1739 }
1740
02d1d628
AMH
1741 return $self;
1742}
1743
1744# Draws a line from one point to (but not including) the destination point
1745
1746sub line {
1747 my $self=shift;
1748 my $dflcl=i_color_new(0,0,0,0);
1749 my %opts=(color=>$dflcl,@_);
1750 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1751
1752 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
1753 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
1754
1755 if ($opts{antialias}) {
1756 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2}, $opts{color});
1757 } else {
1758 i_draw($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2}, $opts{color});
1759 }
1760 return $self;
1761}
1762
1763# Draws a line between an ordered set of points - It more or less just transforms this
1764# into a list of lines.
1765
1766sub polyline {
1767 my $self=shift;
1768 my ($pt,$ls,@points);
1769 my $dflcl=i_color_new(0,0,0,0);
1770 my %opts=(color=>$dflcl,@_);
1771
1772 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1773
1774 if (exists($opts{points})) { @points=@{$opts{points}}; }
1775 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
1776 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
1777 }
1778
1779# print Dumper(\@points);
1780
1781 if ($opts{antialias}) {
1782 for $pt(@points) {
1783 if (defined($ls)) { i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$opts{color}); }
1784 $ls=$pt;
1785 }
1786 } else {
1787 for $pt(@points) {
1788 if (defined($ls)) { i_draw($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$opts{color}); }
1789 $ls=$pt;
1790 }
1791 }
1792 return $self;
1793}
1794
d0e7bfee
AMH
1795sub polygon {
1796 my $self = shift;
1797 my ($pt,$ls,@points);
1798 my $dflcl = i_color_new(0,0,0,0);
1799 my %opts = (color=>$dflcl, @_);
1800
1801 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1802
1803 if (exists($opts{points})) {
1804 $opts{'x'} = [ map { $_->[0] } @{$opts{points}} ];
1805 $opts{'y'} = [ map { $_->[1] } @{$opts{points}} ];
1806 }
1807
1808 if (!exists $opts{'x'} or !exists $opts{'y'}) {
1809 $self->{ERRSTR} = 'no points array, or x and y arrays.'; return undef;
1810 }
1811
43c5dacb
TC
1812 if ($opts{'fill'}) {
1813 unless (UNIVERSAL::isa($opts{'fill'}, 'Imager::Fill')) {
1814 # assume it's a hash ref
1815 require 'Imager/Fill.pm';
1816 unless ($opts{'fill'} = Imager::Fill->new(%{$opts{'fill'}})) {
1817 $self->{ERRSTR} = $Imager::ERRSTR;
1818 return undef;
1819 }
1820 }
1821 i_poly_aa_cfill($self->{IMG}, $opts{'x'}, $opts{'y'},
1822 $opts{'fill'}{'fill'});
1823 }
1824 else {
1825 i_poly_aa($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{'color'});
1826 }
1827
d0e7bfee
AMH
1828 return $self;
1829}
1830
1831
1832# this the multipoint bezier curve
02d1d628
AMH
1833# this is here more for testing that actual usage since
1834# this is not a good algorithm. Usually the curve would be
1835# broken into smaller segments and each done individually.
1836
1837sub polybezier {
1838 my $self=shift;
1839 my ($pt,$ls,@points);
1840 my $dflcl=i_color_new(0,0,0,0);
1841 my %opts=(color=>$dflcl,@_);
1842
1843 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1844
1845 if (exists $opts{points}) {
1846 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
1847 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
1848 }
1849
1850 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
1851 $self->{ERRSTR}='Missing or invalid points.';
1852 return;
1853 }
1854
1855 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$opts{'color'});
1856 return $self;
1857}
1858
cc6483e0
TC
1859sub flood_fill {
1860 my $self = shift;
1861 my %opts = ( color=>Imager::Color->new(255, 255, 255), @_ );
1862
9d540150 1863 unless (exists $opts{'x'} && exists $opts{'y'}) {
cc6483e0
TC
1864 $self->{ERRSTR} = "missing seed x and y parameters";
1865 return undef;
1866 }
07d70837 1867
cc6483e0
TC
1868 if ($opts{fill}) {
1869 unless (UNIVERSAL::isa($opts{fill}, 'Imager::Fill')) {
1870 # assume it's a hash ref
1871 require 'Imager/Fill.pm';
569795e8
TC
1872 unless ($opts{fill} = Imager::Fill->new(%{$opts{fill}})) {
1873 $self->{ERRSTR} = $Imager::ERRSTR;
1874 return;
1875 }
cc6483e0 1876 }
9d540150 1877 i_flood_cfill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{fill}{fill});
cc6483e0
TC
1878 }
1879 else {
9d540150 1880 i_flood_fill($self->{IMG}, $opts{'x'}, $opts{'y'}, $opts{color});
cc6483e0
TC
1881 }
1882
1883 $self;
1884}
1885
f5991c03
TC
1886# make an identity matrix of the given size
1887sub _identity {
1888 my ($size) = @_;
1889
1890 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
1891 for my $c (0 .. ($size-1)) {
1892 $matrix->[$c][$c] = 1;
1893 }
1894 return $matrix;
1895}
1896
1897# general function to convert an image
1898sub convert {
1899 my ($self, %opts) = @_;
1900 my $matrix;
1901
1902 # the user can either specify a matrix or preset
1903 # the matrix overrides the preset
1904 if (!exists($opts{matrix})) {
1905 unless (exists($opts{preset})) {
1906 $self->{ERRSTR} = "convert() needs a matrix or preset";
1907 return;
1908 }
1909 else {
1910 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
1911 # convert to greyscale, keeping the alpha channel if any
1912 if ($self->getchannels == 3) {
1913 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
1914 }
1915 elsif ($self->getchannels == 4) {
1916 # preserve the alpha channel
1917 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
1918 [ 0, 0, 0, 1 ] ];
1919 }
1920 else {
1921 # an identity
1922 $matrix = _identity($self->getchannels);
1923 }
1924 }
1925 elsif ($opts{preset} eq 'noalpha') {
1926 # strip the alpha channel
1927 if ($self->getchannels == 2 or $self->getchannels == 4) {
1928 $matrix = _identity($self->getchannels);
1929 pop(@$matrix); # lose the alpha entry
1930 }
1931 else {
1932 $matrix = _identity($self->getchannels);
1933 }
1934 }
1935 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
1936 # extract channel 0
1937 $matrix = [ [ 1 ] ];
1938 }
1939 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
1940 $matrix = [ [ 0, 1 ] ];
1941 }
1942 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
1943 $matrix = [ [ 0, 0, 1 ] ];
1944 }
1945 elsif ($opts{preset} eq 'alpha') {
1946 if ($self->getchannels == 2 or $self->getchannels == 4) {
1947 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
1948 }
1949 else {
1950 # the alpha is just 1 <shrug>
1951 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
1952 }
1953 }
1954 elsif ($opts{preset} eq 'rgb') {
1955 if ($self->getchannels == 1) {
1956 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
1957 }
1958 elsif ($self->getchannels == 2) {
1959 # preserve the alpha channel
1960 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
1961 }
1962 else {
1963 $matrix = _identity($self->getchannels);
1964 }
1965 }
1966 elsif ($opts{preset} eq 'addalpha') {
1967 if ($self->getchannels == 1) {
1968 $matrix = _identity(2);
1969 }
1970 elsif ($self->getchannels == 3) {
1971 $matrix = _identity(4);
1972 }
1973 else {
1974 $matrix = _identity($self->getchannels);
1975 }
1976 }
1977 else {
1978 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
1979 return undef;
1980 }
1981 }
1982 }
1983 else {
1984 $matrix = $opts{matrix};
1985 }
1986
1987 my $new = Imager->new();
1988 $new->{IMG} = i_img_new();
1989 unless (i_convert($new->{IMG}, $self->{IMG}, $matrix)) {
1990 # most likely a bad matrix
1991 $self->{ERRSTR} = _error_as_msg();
1992 return undef;
1993 }
1994 return $new;
1995}
40eba1ea
AMH
1996
1997
40eba1ea 1998# general function to map an image through lookup tables
9495ee93 1999
40eba1ea
AMH
2000sub map {
2001 my ($self, %opts) = @_;
9495ee93 2002 my @chlist = qw( red green blue alpha );
40eba1ea
AMH
2003
2004 if (!exists($opts{'maps'})) {
2005 # make maps from channel maps
2006 my $chnum;
2007 for $chnum (0..$#chlist) {
9495ee93
AMH
2008 if (exists $opts{$chlist[$chnum]}) {
2009 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
2010 } elsif (exists $opts{'all'}) {
2011 $opts{'maps'}[$chnum] = $opts{'all'};
2012 }
40eba1ea
AMH
2013 }
2014 }
2015 if ($opts{'maps'} and $self->{IMG}) {
2016 i_map($self->{IMG}, $opts{'maps'} );
2017 }
2018 return $self;
2019}
2020
02d1d628
AMH
2021# destructive border - image is shrunk by one pixel all around
2022
2023sub border {
2024 my ($self,%opts)=@_;
2025 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
2026 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
2027}
2028
2029
2030# Get the width of an image
2031
2032sub getwidth {
2033 my $self = shift;
2034 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
2035 return (i_img_info($self->{IMG}))[0];
2036}
2037
2038# Get the height of an image
2039
2040sub getheight {
2041 my $self = shift;
2042 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
2043 return (i_img_info($self->{IMG}))[1];
2044}
2045
2046# Get number of channels in an image
2047
2048sub getchannels {
2049 my $self = shift;
2050 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
2051 return i_img_getchannels($self->{IMG});
2052}
2053
2054# Get channel mask
2055
2056sub getmask {
2057 my $self = shift;
2058 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
2059 return i_img_getmask($self->{IMG});
2060}
2061
2062# Set channel mask
2063
2064sub setmask {
2065 my $self = shift;
2066 my %opts = @_;
2067 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
2068 i_img_setmask( $self->{IMG} , $opts{mask} );
2069}
2070
2071# Get number of colors in an image
2072
2073sub getcolorcount {
2074 my $self=shift;
9d540150 2075 my %opts=('maxcolors'=>2**30,@_);
02d1d628
AMH
2076 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
2077 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
2078 return ($rc==-1? undef : $rc);
2079}
2080
2081# draw string to an image
2082
2083sub string {
2084 my $self = shift;
2085 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
2086
2087 my %input=('x'=>0, 'y'=>0, @_);
2088 $input{string}||=$input{text};
2089
2090 unless(exists $input{string}) {
2091 $self->{ERRSTR}="missing required parameter 'string'";
2092 return;
2093 }
2094
2095 unless($input{font}) {
2096 $self->{ERRSTR}="missing required parameter 'font'";
2097 return;
2098 }
2099
faa9b3e7
TC
2100 unless ($input{font}->draw(image=>$self, %input)) {
2101 $self->{ERRSTR} = $self->_error_as_msg();
2102 return;
2103 }
02d1d628
AMH
2104
2105 return $self;
2106}
2107
02d1d628
AMH
2108# Shortcuts that can be exported
2109
2110sub newcolor { Imager::Color->new(@_); }
2111sub newfont { Imager::Font->new(@_); }
2112
2113*NC=*newcolour=*newcolor;
2114*NF=*newfont;
2115
2116*open=\&read;
2117*circle=\&arc;
2118
2119
2120#### Utility routines
2121
faa9b3e7
TC
2122sub errstr {
2123 ref $_[0] ? $_[0]->{ERRSTR} : $ERRSTR
2124}
02d1d628
AMH
2125
2126# Default guess for the type of an image from extension
2127
2128sub def_guess_type {
2129 my $name=lc(shift);
2130 my $ext;
2131 $ext=($name =~ m/\.([^\.]+)$/)[0];
2132 return 'tiff' if ($ext =~ m/^tiff?$/);
2133 return 'jpeg' if ($ext =~ m/^jpe?g$/);
2134 return 'pnm' if ($ext =~ m/^p[pgb]m$/);
2135 return 'png' if ($ext eq "png");
705fd961 2136 return 'bmp' if ($ext eq "bmp" || $ext eq "dib");
1ec86afa 2137 return 'tga' if ($ext eq "tga");
02d1d628
AMH
2138 return 'gif' if ($ext eq "gif");
2139 return ();
2140}
2141
2142# get the minimum of a list
2143
2144sub min {
2145 my $mx=shift;
2146 for(@_) { if ($_<$mx) { $mx=$_; }}
2147 return $mx;
2148}
2149
2150# get the maximum of a list
2151
2152sub max {
2153 my $mx=shift;
2154 for(@_) { if ($_>$mx) { $mx=$_; }}
2155 return $mx;
2156}
2157
2158# string stuff for iptc headers
2159
2160sub clean {
2161 my($str)=$_[0];
2162 $str = substr($str,3);
2163 $str =~ s/[\n\r]//g;
2164 $str =~ s/\s+/ /g;
2165 $str =~ s/^\s//;
2166 $str =~ s/\s$//;
2167 return $str;
2168}
2169
2170# A little hack to parse iptc headers.
2171
2172sub parseiptc {
2173 my $self=shift;
2174 my(@sar,$item,@ar);
2175 my($caption,$photogr,$headln,$credit);
2176
2177 my $str=$self->{IPTCRAW};
2178
2179 #print $str;
2180
2181 @ar=split(/8BIM/,$str);
2182
2183 my $i=0;
2184 foreach (@ar) {
2185 if (/^\004\004/) {
2186 @sar=split(/\034\002/);
2187 foreach $item (@sar) {
2188 if ($item =~ m/^x/) {
2189 $caption=&clean($item);
2190 $i++;
2191 }
2192 if ($item =~ m/^P/) {
2193 $photogr=&clean($item);
2194 $i++;
2195 }
2196 if ($item =~ m/^i/) {
2197 $headln=&clean($item);
2198 $i++;
2199 }
2200 if ($item =~ m/^n/) {
2201 $credit=&clean($item);
2202 $i++;
2203 }
2204 }
2205 }
2206 }
2207 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
2208}
2209
02d1d628
AMH
2210# Autoload methods go after =cut, and are processed by the autosplit program.
2211
22121;
2213__END__
2214# Below is the stub of documentation for your module. You better edit it!
2215
2216=head1 NAME
2217
2218Imager - Perl extension for Generating 24 bit Images
2219
2220=head1 SYNOPSIS
2221
2222 use Imager qw(init);
2223
2224 init();
2225 $img = Imager->new();
2226 $img->open(file=>'image.ppm',type=>'pnm')
2227 || print "failed: ",$img->{ERRSTR},"\n";
2228 $scaled=$img->scale(xpixels=>400,ypixels=>400);
2229 $scaled->write(file=>'sc_image.ppm',type=>'pnm')
2230 || print "failed: ",$scaled->{ERRSTR},"\n";
2231
2232=head1 DESCRIPTION
2233
2234Imager is a module for creating and altering images - It is not meant
2235as a replacement or a competitor to ImageMagick or GD. Both are
2236excellent packages and well supported.
2237
2238=head2 API
2239
2240Almost all functions take the parameters in the hash fashion.
2241Example:
2242
2243 $img->open(file=>'lena.png',type=>'png');
2244
2245or just:
2246
2247 $img->open(file=>'lena.png');
2248
2249=head2 Basic concept
2250
2251An Image object is created with C<$img = Imager-E<gt>new()> Should
2252this fail for some reason an explanation can be found in
2253C<$Imager::ERRSTR> usually error messages are stored in
2254C<$img-E<gt>{ERRSTR}>, but since no object is created this is the only
2255way to give back errors. C<$Imager::ERRSTR> is also used to report
2256all errors not directly associated with an image object. Examples:
2257
2258 $img=Imager->new(); # This is an empty image (size is 0 by 0)
2259 $img->open(file=>'lena.png',type=>'png'); # initializes from file
2260
2261or if you want to create an empty image:
2262
2263 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
2264
2265This example creates a completely black image of width 400 and
2266height 300 and 4 channels.
2267
2268If you have an existing image, use img_set() to change it's dimensions
2269- this will destroy any existing image data:
2270
2271 $img->img_set(xsize=>500, ysize=>500, channels=>4);
2272
faa9b3e7
TC
2273To create paletted images, set the 'type' parameter to 'paletted':
2274
2275 $img = Imager->new(xsize=>200, ysize=>200, channels=>3, type=>'paletted');
2276
2277which creates an image with a maxiumum of 256 colors, which you can
2278change by supplying the C<maxcolors> parameter.
2279
2280You can create a new paletted image from an existing image using the
2281to_paletted() method:
2282
2283 $palimg = $img->to_paletted(\%opts)
2284
2285where %opts contains the options specified under L<Quantization options>.
2286
2287You can convert a paletted image (or any image) to an 8-bit/channel
2288RGB image with:
2289
2290 $rgbimg = $img->to_rgb8;
2291
2292Warning: if you draw on a paletted image with colors that aren't in
2293the palette, the image will be internally converted to a normal image.
2294
2295For improved color precision you can use the bits parameter to specify
365ea842 229616 bit per channel:
faa9b3e7
TC
2297
2298 $img = Imager->new(xsize=>200, ysize=>200, channels=>3, bits=>16);
2299
365ea842
TC
2300or for even more precision:
2301
2302 $img = Imager->new(xsize=>200, ysize=>200, channels=>3, bits=>'double');
2303
2304to get an image that uses a double for each channel.
2305
2306Note that as of this writing all functions should work on images with
2307more than 8-bits/channel, but many will only work at only
23088-bit/channel precision.
faa9b3e7 2309
365ea842
TC
2310Currently only 8-bit, 16-bit, and double per channel image types are
2311available, this may change later.
faa9b3e7 2312
02d1d628
AMH
2313Color objects are created by calling the Imager::Color->new()
2314method:
2315
2316 $color = Imager::Color->new($red, $green, $blue);
2317 $color = Imager::Color->new($red, $green, $blue, $alpha);
2318 $color = Imager::Color->new("#C0C0FF"); # html color specification
2319
2320This object can then be passed to functions that require a color parameter.
2321
2322Coordinates in Imager have the origin in the upper left corner. The
2323horizontal coordinate increases to the right and the vertical
2324downwards.
2325
2326=head2 Reading and writing images
2327
2328C<$img-E<gt>read()> generally takes two parameters, 'file' and 'type'.
2329If the type of the file can be determined from the suffix of the file
2330it can be omitted. Format dependant parameters are: For images of
2331type 'raw' two extra parameters are needed 'xsize' and 'ysize', if the
2332'channel' parameter is omitted for type 'raw' it is assumed to be 3.
2333gif and png images might have a palette are converted to truecolor bit
2334when read. Alpha channel is preserved for png images irregardless of
2335them being in RGB or gray colorspace. Similarly grayscale jpegs are
2336one channel images after reading them. For jpeg images the iptc
2337header information (stored in the APP13 header) is avaliable to some
2338degree. You can get the raw header with C<$img-E<gt>{IPTCRAW}>, but
2339you can also retrieve the most basic information with
d2dfdcc9
TC
2340C<%hsh=$img-E<gt>parseiptc()> as always patches are welcome. pnm has no
2341extra options. Examples:
02d1d628
AMH
2342
2343 $img = Imager->new();
2344 $img->read(file=>"cover.jpg") or die $img->errstr; # gets type from name
2345
2346 $img = Imager->new();
2347 { local(*FH,$/); open(FH,"file.gif") or die $!; $a=<FH>; }
2348 $img->read(data=>$a,type=>'gif') or die $img->errstr;
2349
2350The second example shows how to read an image from a scalar, this is
2351usefull if your data originates from somewhere else than a filesystem
2352such as a database over a DBI connection.
2353
d2dfdcc9
TC
2354When writing to a tiff image file you can also specify the 'class'
2355parameter, which can currently take a single value, "fax". If class
2356is set to fax then a tiff image which should be suitable for faxing
2357will be written. For the best results start with a grayscale image.
4c2d6970
TC
2358By default the image is written at fine resolution you can override
2359this by setting the "fax_fine" parameter to 0.
d2dfdcc9 2360
a59ffd27
TC
2361If you are reading from a gif image file, you can supply a 'colors'
2362parameter which must be a reference to a scalar. The referenced
2363scalar will receive an array reference which contains the colors, each
e72d3bb1 2364represented as an Imager::Color object.
a59ffd27 2365
04516c2b
TC
2366If you already have an open file handle, for example a socket or a
2367pipe, you can specify the 'fd' parameter instead of supplying a
2368filename. Please be aware that you need to use fileno() to retrieve
2369the file descriptor for the file:
2370
2371 $img->read(fd=>fileno(FILE), type=>'gif') or die $img->errstr;
2372
2373For writing using the 'fd' option you will probably want to set $| for
2374that descriptor, since the writes to the file descriptor bypass Perl's
2375(or the C libraries) buffering. Setting $| should avoid out of order
70f6c2cf
TC
2376output. For example a common idiom when writing a CGI script is:
2377
2378 # the $| _must_ come before you send the content-type
2379 $| = 1;
2380 print "Content-Type: image/jpeg\n\n";
2381 $img->write(fd=>fileno(STDOUT), type=>'jpeg') or die $img->errstr;
04516c2b 2382
02d1d628
AMH
2383*Note that load() is now an alias for read but will be removed later*
2384
2385C<$img-E<gt>write> has the same interface as C<read()>. The earlier
2386comments on C<read()> for autodetecting filetypes apply. For jpegs
2387quality can be adjusted via the 'jpegquality' parameter (0-100). The
2388number of colorplanes in gifs are set with 'gifplanes' and should be
2389between 1 (2 color) and 8 (256 colors). It is also possible to choose
2390between two quantizing methods with the parameter 'gifquant'. If set
2391to mc it uses the mediancut algorithm from either giflibrary. If set
2392to lm it uses a local means algorithm. It is then possible to give
2393some extra settings. lmdither is the dither deviation amount in pixels
2394(manhattan distance). lmfixed can be an array ref who holds an array
2395of Imager::Color objects. Note that the local means algorithm needs
2396much more cpu time but also gives considerable better results than the
2397median cut algorithm.
2398
07d70837
AMH
2399When storing targa images rle compression can be activated with the
2400'compress' parameter, the 'idstring' parameter can be used to set the
2401targa comment field and the 'wierdpack' option can be used to use the
240215 and 16 bit targa formats for rgb and rgba data. The 15 bit format
2403has 5 of each red, green and blue. The 16 bit format in addition
2404allows 1 bit of alpha. The most significant bits are used for each
2405channel.
2406
02d1d628
AMH
2407Currently just for gif files, you can specify various options for the
2408conversion from Imager's internal RGB format to the target's indexed
2409file format. If you set the gifquant option to 'gen', you can use the
2410options specified under L<Quantization options>.
2411
2412To see what Imager is compiled to support the following code snippet
2413is sufficient:
2414
2415 use Imager;
2416 print "@{[keys %Imager::formats]}";
2417
7febf116
TC
2418When reading raw images you need to supply the width and height of the
2419image in the xsize and ysize options:
2420
2421 $img->read(file=>'foo.raw', xsize=>100, ysize=>100)
2422 or die "Cannot read raw image\n";
2423
2424If your input file has more channels than you want, or (as is common),
2425junk in the fourth channel, you can use the datachannels and
2426storechannels options to control the number of channels in your input
2427file and the resulting channels in your image. For example, if your
2428input image uses 32-bits per pixel with red, green, blue and junk
2429values for each pixel you could do:
2430
2431 $img->read(file=>'foo.raw', xsize=>100, ysize=>100, datachannels=>4,
2432 storechannels=>3)
2433 or die "Cannot read raw image\n";
2434
d04ee244
TC
2435Normally the raw image is expected to have the value for channel 1
2436immediately following channel 0 and channel 2 immediately following
2437channel 1 for each pixel. If your input image has all the channel 0
2438values for the first line of the image, followed by all the channel 1
2439values for the first line and so on, you can use the interleave option:
2440
2441 $img->read(file=>'foo.raw', xsize=100, ysize=>100, interleave=>1)
2442 or die "Cannot read raw image\n";
2443
02d1d628
AMH
2444=head2 Multi-image files
2445
2446Currently just for gif files, you can create files that contain more
2447than one image.
2448
2449To do this:
2450
2451 Imager->write_multi(\%opts, @images)
2452
b9029e27 2453Where %opts describes 4 possible types of outputs:
02d1d628 2454
b9029e27
AMH
2455=over 5
2456
2457=item type
2458
2459This is C<gif> for gif animations.
02d1d628
AMH
2460
2461=item callback
2462
2463A code reference which is called with a single parameter, the data to
2464be written. You can also specify $opts{maxbuffer} which is the
2465maximum amount of data buffered. Note that there can be larger writes
2466than this if the file library writes larger blocks. A smaller value
2467maybe useful for writing to a socket for incremental display.
2468
2469=item fd
2470
2471The file descriptor to save the images to.
2472
2473=item file
2474
2475The name of the file to write to.
2476
2477%opts may also include the keys from L<Gif options> and L<Quantization
2478options>.
2479
2480=back
2481
f5991c03
TC
2482You must also specify the file format using the 'type' option.
2483
02d1d628
AMH
2484The current aim is to support other multiple image formats in the
2485future, such as TIFF, and to support reading multiple images from a
2486single file.
2487
2488A simple example:
2489
2490 my @images;
2491 # ... code to put images in @images
2492 Imager->write_multi({type=>'gif',
2493 file=>'anim.gif',
f5991c03 2494 gif_delays=>[ (10) x @images ] },
02d1d628
AMH
2495 @images)
2496 or die "Oh dear!";
2497
faa9b3e7
TC
2498You can read multi-image files (currently only GIF files) using the
2499read_multi() method:
2500
2501 my @imgs = Imager->read_multi(file=>'foo.gif')
2502 or die "Cannot read images: ",Imager->errstr;
2503
2504The possible parameters for read_multi() are:
2505
2506=over
2507
2508=item file
2509
2510The name of the file to read in.
2511
2512=item fh
2513
2514A filehandle to read in. This can be the name of a filehandle, but it
2515will need the package name, no attempt is currently made to adjust
2516this to the caller's package.
2517
2518=item fd
2519
2520The numeric file descriptor of an open file (or socket).
2521
2522=item callback
2523
2524A function to be called to read in data, eg. reading a blob from a
2525database incrementally.
2526
2527=item data
2528
2529The data of the input file in memory.
2530
2531=item type
2532
2533The type of file. If the file is parameter is given and provides
2534enough information to guess the type, then this parameter is optional.
2535
2536=back
2537
2538Note: you cannot use the callback or data parameter with giflib
2539versions before 4.0.
2540
2541When reading from a GIF file with read_multi() the images are returned
2542as paletted images.
2543
02d1d628
AMH
2544=head2 Gif options
2545
2546These options can be specified when calling write_multi() for gif
2547files, when writing a single image with the gifquant option set to
2548'gen', or for direct calls to i_writegif_gen and i_writegif_callback.
2549
2550Note that some viewers will ignore some of these options
2551(gif_user_input in particular).
2552
2553=over 4
2554
2555=item gif_each_palette
2556
2557Each image in the gif file has it's own palette if this is non-zero.
2558All but the first image has a local colour table (the first uses the
2559global colour table.
2560
2561=item interlace
2562
2563The images are written interlaced if this is non-zero.
2564
2565=item gif_delays
2566
2567A reference to an array containing the delays between images, in 1/100
2568seconds.
2569
ed88b092
TC
2570If you want the same delay for every frame you can simply set this to
2571the delay in 1/100 seconds.
2572
02d1d628
AMH
2573=item gif_user_input
2574
2575A reference to an array contains user input flags. If the given flag
2576is non-zero the image viewer should wait for input before displaying
2577the next image.
2578
2579=item gif_disposal
2580
2581A reference to an array of image disposal methods. These define what
2582should be done to the image before displaying the next one. These are
2583integers, where 0 means unspecified, 1 means the image should be left
2584in place, 2 means restore to background colour and 3 means restore to
2585the previous value.
2586
2587=item gif_tran_color
2588
2589A reference to an Imager::Color object, which is the colour to use for
ae235ea6
TC
2590the palette entry used to represent transparency in the palette. You
2591need to set the transp option (see L<Quantization options>) for this
2592value to be used.
02d1d628
AMH
2593
2594=item gif_positions
2595
2596A reference to an array of references to arrays which represent screen
2597positions for each image.
2598
2599=item gif_loop_count
2600
2601If this is non-zero the Netscape loop extension block is generated,
2602which makes the animation of the images repeat.
2603
2604This is currently unimplemented due to some limitations in giflib.
2605
bf9dd17c
TC
2606=item gif_eliminate_unused
2607
2608If this is true, when you write a paletted image any unused colors
2609will be eliminated from its palette. This is set by default.
2610
02d1d628
AMH
2611=back
2612
2613=head2 Quantization options
2614
2615These options can be specified when calling write_multi() for gif
2616files, when writing a single image with the gifquant option set to
2617'gen', or for direct calls to i_writegif_gen and i_writegif_callback.
2618
2619=over 4
2620
2621=item colors
2622
2623A arrayref of colors that are fixed. Note that some color generators
2624will ignore this.
2625
2626=item transp
2627
2628The type of transparency processing to perform for images with an
2629alpha channel where the output format does not have a proper alpha
2630channel (eg. gif). This can be any of:
2631
2632=over 4
2633
2634=item none
2635
2636No transparency processing is done. (default)
2637
2638=item threshold
2639
2640Pixels more transparent that tr_threshold are rendered as transparent.
2641
2642=item errdiff
2643
2644An error diffusion dither is done on the alpha channel. Note that
2645this is independent of the translation performed on the colour
2646channels, so some combinations may cause undesired artifacts.
2647
2648=item ordered
2649
2650The ordered dither specified by tr_orddith is performed on the alpha
2651channel.
2652
2653=back
2654
ae235ea6
TC
2655This will only be used if the image has an alpha channel, and if there
2656is space in the palette for a transparency colour.
2657
02d1d628
AMH
2658=item tr_threshold
2659
2660The highest alpha value at which a pixel will be made transparent when
2661transp is 'threshold'. (0-255, default 127)
2662
2663=item tr_errdiff
2664
2665The type of error diffusion to perform on the alpha channel when
2666transp is 'errdiff'. This can be any defined error diffusion type
2667except for custom (see errdiff below).
2668
626cabcc 2669=item tr_orddith
02d1d628
AMH
2670
2671The type of ordered dither to perform on the alpha channel when transp
626cabcc 2672is 'ordered'. Possible values are:
02d1d628
AMH
2673
2674=over 4
2675
2676=item random
2677
529ef1f3 2678A semi-random map is used. The map is the same each time.
02d1d628
AMH
2679
2680=item dot8
2681
26828x8 dot dither.
2683
2684=item dot4
2685
26864x4 dot dither
2687
2688=item hline
2689
2690horizontal line dither.
2691
2692=item vline
2693
2694vertical line dither.
2695
2696=item "/line"
2697
2698=item slashline
2699
2700diagonal line dither
2701
2702=item '\line'
2703
2704=item backline
2705
2706diagonal line dither
2707
529ef1f3
TC
2708=item tiny
2709
2710dot matrix dither (currently the default). This is probably the best
2711for displays (like web pages).
2712
02d1d628
AMH
2713=item custom
2714
2715A custom dither matrix is used - see tr_map
2716
2717=back
2718
2719=item tr_map
2720
2721When tr_orddith is custom this defines an 8 x 8 matrix of integers
2722representing the transparency threshold for pixels corresponding to
2723each position. This should be a 64 element array where the first 8
2724entries correspond to the first row of the matrix. Values should be
2725betweern 0 and 255.
2726
2727=item make_colors
2728
2729Defines how the quantization engine will build the palette(s).
2730Currently this is ignored if 'translate' is 'giflib', but that may
2731change. Possible values are:
2732
2733=over 4
2734
2735=item none
2736
2737Only colors supplied in 'colors' are used.
2738
2739=item webmap
2740
2741The web color map is used (need url here.)
2742
2743=item addi
2744
2745The original code for generating the color map (Addi's code) is used.
2746
2747=back
2748
2749Other methods may be added in the future.
2750
2751=item colors
2752
2753A arrayref containing Imager::Color objects, which represents the
2754starting set of colors to use in translating the images. webmap will
2755ignore this. The final colors used are copied back into this array
2756(which is expanded if necessary.)
2757
2758=item max_colors
2759
2760The maximum number of colors to use in the image.
2761
2762=item translate
2763
2764The method used to translate the RGB values in the source image into
2765the colors selected by make_colors. Note that make_colors is ignored
2766whene translate is 'giflib'.
2767
2768Possible values are:
2769
2770=over 4
2771
2772=item giflib
2773
2774The giflib native quantization function is used.
2775
2776=item closest
2777
2778The closest color available is used.
2779
2780=item perturb
2781
2782The pixel color is modified by perturb, and the closest color is chosen.
2783
2784=item errdiff
2785
2786An error diffusion dither is performed.
2787
2788=back
2789
2790It's possible other transate values will be added.
2791
2792=item errdiff
2793
2794The type of error diffusion dither to perform. These values (except
2795for custom) can also be used in tr_errdif.
2796
2797=over 4
2798
2799=item floyd
2800
2801Floyd-Steinberg dither
2802
2803=item jarvis
2804
2805Jarvis, Judice and Ninke dither
2806
2807=item stucki
2808
2809Stucki dither
2810
2811=item custom
2812
2813Custom. If you use this you must also set errdiff_width,
2814errdiff_height and errdiff_map.
2815
2816=back
2817
2818=item errdiff_width
2819
2820=item errdiff_height
2821
2822=item errdiff_orig
2823
2824=item errdiff_map
2825
2826When translate is 'errdiff' and errdiff is 'custom' these define a
2827custom error diffusion map. errdiff_width and errdiff_height define
2828the size of the map in the arrayref in errdiff_map. errdiff_orig is
2829an integer which indicates the current pixel position in the top row
2830of the map.
2831
2832=item perturb
2833
2834When translate is 'perturb' this is the magnitude of the random bias
2835applied to each channel of the pixel before it is looked up in the
2836color table.
2837
2838=back
2839
2840=head2 Obtaining/setting attributes of images
2841
2842To get the size of an image in pixels the C<$img-E<gt>getwidth()> and
2843C<$img-E<gt>getheight()> are used.
2844
2845To get the number of channels in
2846an image C<$img-E<gt>getchannels()> is used. $img-E<gt>getmask() and
2847$img-E<gt>setmask() are used to get/set the channel mask of the image.
2848
2849 $mask=$img->getmask();
2850 $img->setmask(mask=>1+2); # modify red and green only
2851 $img->setmask(mask=>8); # modify alpha only
2852 $img->setmask(mask=>$mask); # restore previous mask
2853
2854The mask of an image describes which channels are updated when some
2855operation is performed on an image. Naturally it is not possible to
2856apply masks to operations like scaling that alter the dimensions of
2857images.
2858
2859It is possible to have Imager find the number of colors in an image
2860by using C<$img-E<gt>getcolorcount()>. It requires memory proportionally
2861to the number of colors in the image so it is possible to have it
2862stop sooner if you only need to know if there are more than a certain number
2863of colors in the image. If there are more colors than asked for
2864the function return undef. Examples:
2865
2866 if (!defined($img->getcolorcount(maxcolors=>512)) {
2867 print "Less than 512 colors in image\n";
2868 }
2869
faa9b3e7 2870The bits() method retrieves the number of bits used to represent each
af3c2450
TC
2871channel in a pixel, 8 for a normal image, 16 for 16-bit image and
2872'double' for a double/channel image. The type() method returns either
faa9b3e7
TC
2873'direct' for truecolor images or 'paletted' for paletted images. The
2874virtual() method returns non-zero if the image contains no actual
2875pixels, for example masked images.
2876
2877=head2 Paletted Images
2878
2879In general you can work with paletted images in the same way as RGB
2880images, except that if you attempt to draw to a paletted image with a
2881color that is not in the image's palette, the image will be converted
2882to an RGB image. This means that drawing on a paletted image with
2883anti-aliasing enabled will almost certainly convert the image to RGB.
2884
2885You can add colors to a paletted image with the addcolors() method:
2886
2887 my @colors = ( Imager::Color->new(255, 0, 0),
2888 Imager::Color->new(0, 255, 0) );
2889 my $index = $img->addcolors(colors=>\@colors);
2890
2891The return value is the index of the first color added, or undef if
2892adding the colors would overflow the palette.
2893
2894Once you have colors in the palette you can overwrite them with the
2895setcolors() method:
2896
2897 $img->setcolors(start=>$start, colors=>\@colors);
2898
2899Returns true on success.
2900
2901To retrieve existing colors from the palette use the getcolors() method:
2902
2903 # get the whole palette
2904 my @colors = $img->getcolors();
2905 # get a single color
2906 my $color = $img->getcolors(start=>$index);
2907 # get a range of colors
2908 my @colors = $img->getcolors(start=>$index, count=>$count);
2909
2910To quickly find a color in the palette use findcolor():
2911
2912 my $index = $img->findcolor(color=>$color);
2913
2914which returns undef on failure, or the index of the color.
2915
2916You can get the current palette size with $img->colorcount, and the
2917maximum size of the palette with $img->maxcolors.
2918
02d1d628
AMH
2919=head2 Drawing Methods
2920
2921IMPLEMENTATION MORE OR LESS DONE CHECK THE TESTS
02d1d628
AMH
2922DOCUMENTATION OF THIS SECTION OUT OF SYNC
2923
2924It is possible to draw with graphics primitives onto images. Such
ec88fc0a
TC
2925primitives include boxes, arcs, circles, polygons and lines. A
2926reference oriented list follows.
02d1d628
AMH
2927
2928Box:
2929 $img->box(color=>$blue,xmin=>10,ymin=>30,xmax=>200,ymax=>300,filled=>1);
2930
2931The above example calls the C<box> method for the image and the box
2932covers the pixels with in the rectangle specified. If C<filled> is
2933ommited it is drawn as an outline. If any of the edges of the box are
2934ommited it will snap to the outer edge of the image in that direction.
2935Also if a color is omitted a color with (255,255,255,255) is used
2936instead.
2937
2938Arc:
2939 $img->arc(color=>$red, r=20, x=>200, y=>100, d1=>10, d2=>20 );
2940
2941This creates a filled red arc with a 'center' at (200, 100) and spans
294210 degrees and the slice has a radius of 20. SEE section on BUGS.
2943
2944Circle:
2945 $img->circle(color=>$green, r=50, x=>200, y=>100);
2946
2947This creates a green circle with its center at (200, 100) and has a
2948radius of 20.
2949
2950Line:
9982a307 2951 $img->line(color=>$green, x1=>10, x2=>100,
02d1d628
AMH
2952 y1=>20, y2=>50, antialias=>1 );
2953
2954That draws an antialiased line from (10,100) to (20,50).
2955
2956Polyline:
2957 $img->polyline(points=>[[$x0,$y0],[$x1,$y1],[$x2,$y2]],color=>$red);
2958 $img->polyline(x=>[$x0,$x1,$x2], y=>[$y0,$y1,$y2], antialias=>1);
2959
2960Polyline is used to draw multilple lines between a series of points.
2961The point set can either be specified as an arrayref to an array of
2962array references (where each such array represents a point). The
2963other way is to specify two array references.
2964
d0e7bfee
AMH
2965Polygon:
2966 $img->polygon(points=>[[$x0,$y0],[$x1,$y1],[$x2,$y2]],color=>$red);
ec88fc0a 2967 $img->polygon(x=>[$x0,$x1,$x2], y=>[$y0,$y1,$y2]);
d0e7bfee
AMH
2968
2969Polygon is used to draw a filled polygon. Currently the polygon is
2970always drawn antialiased, although that will change in the future.
2971Like other antialiased drawing functions its coordinates can be
2972specified with floating point values.
2973
ec88fc0a 2974Flood Fill:
d0e7bfee 2975
cc6483e0
TC
2976You can fill a region that all has the same color using the
2977flood_fill() method, for example:
2978
2979 $img->flood_fill(x=>50, y=>50, color=>$color);
2980
2981will fill all regions the same color connected to the point (50, 50).
2982
ec88fc0a
TC
2983The arc(), box(), polygon() and flood_fill() methods can take a
2984C<fill> parameter which can either be an Imager::Fill object, or a
2985reference to a hash containing the parameters used to create the fill:
cc6483e0 2986
ec88fc0a
TC
2987 $img->box(xmin=>10, ymin=>30, xmax=>150, ymax=>60,
2988 fill => { hatch=>'cross2' });
2989 use Imager::Fill;
2990 my $fill = Imager::Fill->new(hatch=>'stipple');
2991 $img->box(fill=>$fill);
cc6483e0 2992
ec88fc0a
TC
2993Currently you can create opaque or transparent plain color fills,
2994hatched fills, image based fills and fountain fills. See
2995L<Imager::Fill> for more information.
cc6483e0 2996
02d1d628
AMH
2997=head2 Text rendering
2998
2999Text rendering is described in the Imager::Font manpage.
3000
3001=head2 Image resizing
3002
3003To scale an image so porportions are maintained use the
3004C<$img-E<gt>scale()> method. if you give either a xpixels or ypixels
3005parameter they will determine the width or height respectively. If
3006both are given the one resulting in a larger image is used. example:
3007C<$img> is 700 pixels wide and 500 pixels tall.
3008
afe5a082
TC
3009 $newimg = $img->scale(xpixels=>400); # 400x285
3010 $newimg = $img->scale(ypixels=>400); # 560x400
02d1d628 3011
afe5a082
TC
3012 $newimg = $img->scale(xpixels=>400,ypixels=>400); # 560x400
3013 $newimg = $img->scale(xpixels=>400,ypixels=>400,type=>min); # 400x285
02d1d628 3014
afe5a082
TC
3015 $newimg = $img->scale(scalefactor=>0.25); 175x125
3016 $newimg = $img->scale(); # 350x250
02d1d628
AMH
3017
3018if you want to create low quality previews of images you can pass
3019C<qtype=E<gt>'preview'> to scale and it will use nearest neighbor
3020sampling instead of filtering. It is much faster but also generates
3021worse looking images - especially if the original has a lot of sharp
3022variations and the scaled image is by more than 3-5 times smaller than
3023the original.
3024
3025If you need to scale images per axis it is best to do it simply by
3026calling scaleX and scaleY. You can pass either 'scalefactor' or
3027'pixels' to both functions.
3028
3029Another way to resize an image size is to crop it. The parameters
3030to crop are the edges of the area that you want in the returned image.
3031If a parameter is omited a default is used instead.
3032
3033 $newimg = $img->crop(left=>50, right=>100, top=>10, bottom=>100);
3034 $newimg = $img->crop(left=>50, top=>10, width=>50, height=>90);
3035 $newimg = $img->crop(left=>50, right=>100); # top
3036
3037You can also specify width and height parameters which will produce a
3038new image cropped from the center of the input image, with the given
3039width and height.
3040
3041 $newimg = $img->crop(width=>50, height=>50);
3042
3043The width and height parameters take precedence over the left/right
3044and top/bottom parameters respectively.
3045
3046=head2 Copying images
3047
3048To create a copy of an image use the C<copy()> method. This is usefull
3049if you want to keep an original after doing something that changes the image
3050inplace like writing text.
3051
3052 $img=$orig->copy();
3053
3054To copy an image to onto another image use the C<paste()> method.
3055
3056 $dest->paste(left=>40,top=>20,img=>$logo);
3057
3058That copies the entire C<$logo> image onto the C<$dest> image so that the
3059upper left corner of the C<$logo> image is at (40,20).
3060
142c26ff
AMH
3061
3062=head2 Flipping images
3063
3064An inplace horizontal or vertical flip is possible by calling the
9191e525
AMH
3065C<flip()> method. If the original is to be preserved it's possible to
3066make a copy first. The only parameter it takes is the C<dir>
3067parameter which can take the values C<h>, C<v>, C<vh> and C<hv>.
142c26ff 3068
9191e525
AMH
3069 $img->flip(dir=>"h"); # horizontal flip
3070 $img->flip(dir=>"vh"); # vertical and horizontal flip
3071 $nimg = $img->copy->flip(dir=>"v"); # make a copy and flip it vertically
142c26ff 3072
faa9b3e7
TC
3073=head2 Rotating images
3074
80684605
TC
3075Use the rotate() method to rotate an image. This method will return a
3076new, rotated image.
faa9b3e7
TC
3077
3078To rotate by an exact amount in degrees or radians, use the 'degrees'
3079or 'radians' parameter:
3080
3081 my $rot20 = $img->rotate(degrees=>20);
3082 my $rotpi4 = $img->rotate(radians=>3.14159265/4);
3083
80684605
TC
3084Exact image rotation uses the same underlying transformation engine as
3085the matrix_transform() method.
3086
faa9b3e7
TC
3087To rotate in steps of 90 degrees, use the 'right' parameter:
3088
3089 my $rotated = $img->rotate(right=>270);
3090
3091Rotations are clockwise for positive values.
3092
9191e525 3093=head2 Blending Images
142c26ff 3094
9191e525 3095To put an image or a part of an image directly
142c26ff
AMH
3096into another it is best to call the C<paste()> method on the image you
3097want to add to.
02d1d628
AMH
3098
3099 $img->paste(img=>$srcimage,left=>30,top=>50);
3100
3101That will take paste C<$srcimage> into C<$img> with the upper
3102left corner at (30,50). If no values are given for C<left>
3103or C<top> they will default to 0.
3104
b2778574 3105A more complicated way of blending images is where one image is
02d1d628
AMH
3106put 'over' the other with a certain amount of opaqueness. The
3107method that does this is rubthrough.
3108
b2778574 3109 $img->rubthrough(src=>$srcimage,tx=>30,ty=>50);
02d1d628 3110
faa9b3e7
TC
3111That will take the image C<$srcimage> and overlay it with the upper
3112left corner at (30,50). You can rub 2 or 4 channel images onto a 3
3113channel image, or a 2 channel image onto a 1 channel image. The last
3114channel is used as an alpha channel.
02d1d628
AMH
3115
3116
3117=head2 Filters
3118
3119A special image method is the filter method. An example is:
3120
3121 $img->filter(type=>'autolevels');
3122
3123This will call the autolevels filter. Here is a list of the filters
3124that are always avaliable in Imager. This list can be obtained by
3125running the C<filterlist.perl> script that comes with the module
3126source.
3127
3128 Filter Arguments
02d1d628 3129 autolevels lsat(0.1) usat(0.1) skew(0)
d08b8f85 3130 bumpmap bump elevation(0) lightx lighty st(2)
b2778574
AMH
3131 bumpmap_complex bump channel(0) tx(0) ty(0) Lx(0.2) Ly(0.4)
3132 Lz(-1) cd(1.0) cs(40.0) n(1.3) Ia(0 0 0) Il(255 255 255)
3133 Is(255 255 255)
02d1d628 3134 contrast intensity
faa9b3e7 3135 conv coef
efdc2568 3136 fountain xa ya xb yb ftype(linear) repeat(none) combine(none)
6607600c 3137 super_sample(none) ssample_param(4) segments(see below)
faa9b3e7 3138 gaussian stddev
02d1d628 3139 gradgen xo yo colors dist
faa9b3e7 3140 hardinvert
6607600c 3141 mosaic size(20)
faa9b3e7 3142 noise amount(3) subtype(0)
d08b8f85 3143 postlevels levels(10)
faa9b3e7
TC
3144 radnoise xo(100) yo(100) ascale(17.0) rscale(0.02)
3145 turbnoise xo(0.0) yo(0.0) scale(10.0)
b6381851 3146 unsharpmask stddev(2.0) scale(1.0)
d08b8f85 3147 watermark wmark pixdiff(10) tx(0) ty(0)
02d1d628
AMH
3148
3149The default values are in parenthesis. All parameters must have some
3150value but if a parameter has a default value it may be omitted when
3151calling the filter function.
3152
faa9b3e7
TC
3153The filters are:
3154
3155=over
3156
3157=item autolevels
3158
3159scales the value of each channel so that the values in the image will
3160cover the whole possible range for the channel. I<lsat> and I<usat>
3161truncate the range by the specified fraction at the top and bottom of
3162the range respectivly..
3163
d08b8f85
TC
3164=item bumpmap
3165
3166uses the channel I<elevation> image I<bump> as a bumpmap on your
3167image, with the light at (I<lightx>, I<lightty>), with a shadow length
3168of I<st>.
3169
b2778574
AMH
3170=item bumpmap_complex
3171
3172uses the channel I<channel> image I<bump> as a bumpmap on your image.
3173If Lz<0 the three L parameters are considered to be the direction of
3174the light. If Lz>0 the L parameters are considered to be the light
3175position. I<Ia> is the ambient colour, I<Il> is the light colour,
3176I<Is> is the color of specular highlights. I<cd> is the diffuse
3177coefficient and I<cs> is the specular coefficient. I<n> is the
3178shininess of the surface.
3179
faa9b3e7
TC
3180=item contrast
3181
3182scales each channel by I<intensity>. Values of I<intensity> < 1.0
3183will reduce the contrast.
3184
3185=item conv
3186
3187performs 2 1-dimensional convolutions on the image using the values
3188from I<coef>. I<coef> should be have an odd length.
3189
6607600c
TC
3190=item fountain
3191
3192renders a fountain fill, similar to the gradient tool in most paint
3193software. The default fill is a linear fill from opaque black to
3194opaque white. The points A(xa, ya) and B(xb, yb) control the way the
3195fill is performed, depending on the ftype parameter:
3196
3197=over
3198
3199=item linear
3200
3201the fill ramps from A through to B.
3202
3203=item bilinear
3204
3205the fill ramps in both directions from A, where AB defines the length
3206of the gradient.
3207
3208=item radial
3209
3210A is the center of a circle, and B is a point on it's circumference.
3211The fill ramps from the center out to the circumference.
3212
3213=item radial_square
3214
3215A is the center of a square and B is the center of one of it's sides.
3216This can be used to rotate the square. The fill ramps out to the
3217edges of the square.
3218
3219=item revolution
3220
3221A is the centre of a circle and B is a point on it's circumference. B
3222marks the 0 and 360 point on the circle, with the fill ramping
3223clockwise.
3224
3225=item conical
3226
3227A is the center of a circle and B is a point on it's circumference. B
3228marks the 0 and point on the circle, with the fill ramping in both
3229directions to meet opposite.
3230
3231=back
3232
3233The I<repeat> option controls how the fill is repeated for some
3234I<ftype>s after it leaves the AB range:
3235
3236=over
3237
3238=item none
3239
3240no repeats, points outside of each range are treated as if they were
3241on the extreme end of that range.
3242
3243=item sawtooth
3244
3245the fill simply repeats in the positive direction
3246
3247=item triangle
3248
3249the fill repeats in reverse and then forward and so on, in the
3250positive direction
3251
3252=item saw_both
3253
3254the fill repeats in both the positive and negative directions (only
3255meaningful for a linear fill).
3256
3257=item tri_both
3258
3259as for triangle, but in the negative direction too (only meaningful
3260for a linear fill).
3261
3262=back
3263
3264By default the fill simply overwrites the whole image (unless you have
3265parts of the range 0 through 1 that aren't covered by a segment), if
3266any segments of your fill have any transparency, you can set the
efdc2568
TC
3267I<combine> option to 'normal' to have the fill combined with the
3268existing pixels. See the description of I<combine> in L<Imager/Fill>.
6607600c
TC
3269
3270If your fill has sharp edges, for example between steps if you use
3271repeat set to 'triangle', you may see some aliased or ragged edges.
3272You can enable super-sampling which will take extra samples within the
3273pixel in an attempt anti-alias the fill.
3274
3275The possible values for the super_sample option are:
3276
3277=over
3278
3279=item none
3280
3281no super-sampling is done
3282
3283=item grid
3284
3285a square grid of points are sampled. The number of points sampled is
3286the square of ceil(0.5 + sqrt(ssample_param)).
3287
3288=item random
3289
3290a random set of points within the pixel are sampled. This looks
3291pretty bad for low ssample_param values.
3292
3293=item circle
3294
3295the points on the radius of a circle within the pixel are sampled.
3296This seems to produce the best results, but is fairly slow (for now).
3297
3298=back
3299
3300You can control the level of sampling by setting the ssample_param
3301option. This is roughly the number of points sampled, but depends on
3302the type of sampling.
3303
3304The segments option is an arrayref of segments. You really should use
3305the Imager::Fountain class to build your fountain fill. Each segment
3306is an array ref containing:
3307
3308=over
3309
3310=item start
3311
3312a floating point number between 0 and 1, the start of the range of fill parameters covered by this segment.
3313
3314=item middle
3315
3316a floating point number between start and end which can be used to
3317push the color range towards one end of the segment.
3318
3319=item end
3320
3321a floating point number between 0 and 1, the end of the range of fill
3322parameters covered by this segment. This should be greater than
3323start.
3324
3325=item c0
3326
3327=item c1
3328
3329The colors at each end of the segment. These can be either
3330Imager::Color or Imager::Color::Float objects.
3331
3332=item segment type
3333
3334The type of segment, this controls the way the fill parameter varies
3335over the segment. 0 for linear, 1 for curved (unimplemented), 2 for
3336sine, 3 for sphere increasing, 4 for sphere decreasing.
3337
3338=item color type
3339
3340The way the color varies within the segment, 0 for simple RGB, 1 for
3341hue increasing and 2 for hue decreasing.
3342
3343=back
3344
3345Don't forgot to use Imager::Fountain instead of building your own.
3346Really. It even loads GIMP gradient files.
3347
faa9b3e7
TC
3348=item gaussian
3349
3350performs a gaussian blur of the image, using I<stddev> as the standard
3351deviation of the curve used to combine pixels, larger values give
3352bigger blurs. For a definition of Gaussian Blur, see:
3353
3354 http://www.maths.abdn.ac.uk/~igc/tch/mx4002/notes/node99.html
3355
3356=item gradgen
3357
3358renders a gradient, with the given I<colors> at the corresponding
3359points (x,y) in I<xo> and I<yo>. You can specify the way distance is
3360measured for color blendeing by setting I<dist> to 0 for Euclidean, 1
3361for Euclidean squared, and 2 for Manhattan distance.
3362
3363=item hardinvert
3364
3365inverts the image, black to white, white to black. All channels are
3366inverted, including the alpha channel if any.
3367
6607600c
TC
3368=item mosaic
3369
3370produces averaged tiles of the given I<size>.
3371
faa9b3e7
TC
3372=item noise
3373
3374adds noise of the given I<amount> to the image. If I<subtype> is
3375zero, the noise is even to each channel, otherwise noise is added to
3376each channel independently.
3377
3378=item radnoise
3379
3380renders radiant Perlin turbulent noise. The centre of the noise is at
3381(I<xo>, I<yo>), I<ascale> controls the angular scale of the noise ,
3382and I<rscale> the radial scale, higher numbers give more detail.
3383
d08b8f85
TC
3384=item postlevels
3385
3386alters the image to have only I<levels> distinct level in each
3387channel.
3388
faa9b3e7
TC
3389=item turbnoise
3390
3391renders Perlin turbulent noise. (I<xo>, I<yo>) controls the origin of
3392the noise, and I<scale> the scale of the noise, with lower numbers
3393giving more detail.
3394
b6381851
TC
3395=item unsharpmask
3396
3397performs an unsharp mask on the image. This is the result of
3398subtracting a gaussian blurred version of the image from the original.
3399I<stddev> controls the stddev parameter of the gaussian blur. Each
3400output pixel is: in + I<scale> * (in - blurred).
3401
d08b8f85
TC
3402=item watermark
3403
3404applies I<wmark> as a watermark on the image with strength I<pixdiff>,
3405with an origin at (I<tx>, I<ty>)
3406
faa9b3e7
TC
3407=back
3408
d08b8f85 3409A demonstration of most of the filters can be found at:
faa9b3e7
TC
3410
3411 http://www.develop-help.com/imager/filters.html
3412
3413(This is a slow link.)
02d1d628 3414
f5991c03
TC
3415=head2 Color transformations
3416
3417You can use the convert method to transform the color space of an
3418image using a matrix. For ease of use some presets are provided.
3419
3420The convert method can be used to:
3421
3422=over 4
3423
3424=item *
3425
3426convert an RGB or RGBA image to grayscale.
3427
3428=item *
3429
3430convert a grayscale image to RGB.
3431
3432=item *
3433
3434extract a single channel from an image.
3435
3436=item *
3437
3438set a given channel to a particular value (or from another channel)
3439
3440=back
3441
3442The currently defined presets are:
3443
3444=over
3445
3446=item gray
3447
3448=item grey
3449
3450converts an RGBA image into a grayscale image with alpha channel, or
3451an RGB image into a grayscale image without an alpha channel.
3452
3453This weights the RGB channels at 22.2%, 70.7% and 7.1% respectively.
3454
3455=item noalpha
3456
3457removes the alpha channel from a 2 or 4 channel image. An identity
3458for other images.
3459
3460=item red
3461
3462=item channel0
3463
3464extracts the first channel of the image into a single channel image
3465
3466=item green
3467
3468=item channel1
3469
3470extracts the second channel of the image into a single channel image
3471
3472=item blue
3473
3474=item channel2
3475
3476extracts the third channel of the image into a single channel image
3477
3478=item alpha
3479
3480extracts the alpha channel of the image into a single channel image.
3481
3482If the image has 1 or 3 channels (assumed to be grayscale of RGB) then
3483the resulting image will be all white.
3484
3485=item rgb
3486
3487converts a grayscale image to RGB, preserving the alpha channel if any
3488
3489=item addalpha
3490
3491adds an alpha channel to a grayscale or RGB image. Preserves an
3492existing alpha channel for a 2 or 4 channel image.
3493
3494=back
3495
3496For example, to convert an RGB image into a greyscale image:
3497
3498 $new = $img->convert(preset=>'grey'); # or gray
3499
3500or to convert a grayscale image to an RGB image:
3501
3502 $new = $img->convert(preset=>'rgb');
3503
3504The presets aren't necessary simple constants in the code, some are
3505generated based on the number of channels in the input image.
3506
3507If you want to perform some other colour transformation, you can use
3508the 'matrix' parameter.
3509
3510For each output pixel the following matrix multiplication is done:
3511
3512 channel[0] [ [ $c00, $c01, ... ] inchannel[0]
3513 [ ... ] = ... x [ ... ]
3514 channel[n-1] [ $cn0, ..., $cnn ] ] inchannel[max]
3515 1
3516
3517So if you want to swap the red and green channels on a 3 channel image:
3518
3519 $new = $img->convert(matrix=>[ [ 0, 1, 0 ],
3520 [ 1, 0, 0 ],
3521 [ 0, 0, 1 ] ]);
3522
3523or to convert a 3 channel image to greyscale using equal weightings:
3524
3525 $new = $img->convert(matrix=>[ [ 0.333, 0.333, 0.334 ] ])
3526
9495ee93
AMH
3527=head2 Color Mappings
3528
3529You can use the map method to map the values of each channel of an
3530image independently using a list of lookup tables. It's important to
3531realize that the modification is made inplace. The function simply
3532returns the input image again or undef on failure.
3533
3534Each channel is mapped independently through a lookup table with 256
3535entries. The elements in the table should not be less than 0 and not
3536greater than 255. If they are out of the 0..255 range they are
3537clamped to the range. If a table does not contain 256 entries it is
3538silently ignored.
3539
3540Single channels can mapped by specifying their name and the mapping
3541table. The channel names are C<red>, C<green>, C<blue>, C<alpha>.
3542
3543 @map = map { int( $_/2 } 0..255;
3544 $img->map( red=>\@map );
3545
3546It is also possible to specify a single map that is applied to all
3547channels, alpha channel included. For example this applies a gamma
3548correction with a gamma of 1.4 to the input image.
3549
3550 $gamma = 1.4;
3551 @map = map { int( 0.5 + 255*($_/255)**$gamma ) } 0..255;
3552 $img->map(all=> \@map);
3553
3554The C<all> map is used as a default channel, if no other map is
3555specified for a channel then the C<all> map is used instead. If we
3556had not wanted to apply gamma to the alpha channel we would have used:
3557
3558 $img->map(all=> \@map, alpha=>[]);
3559
3560Since C<[]> contains fewer than 256 element the gamma channel is
3561unaffected.
3562
3563It is also possible to simply specify an array of maps that are
3564applied to the images in the rgba order. For example to apply
3565maps to the C<red> and C<blue> channels one would use:
3566
3567 $img->map(maps=>[\@redmap, [], \@bluemap]);
3568
3569
3570
02d1d628
AMH
3571=head2 Transformations
3572
3573Another special image method is transform. It can be used to generate
3574warps and rotations and such features. It can be given the operations
3575in postfix notation or the module Affix::Infix2Postfix can be used.
3576Look in the test case t/t55trans.t for an example.
3577
3578transform() needs expressions (or opcodes) that determine the source
3579pixel for each target pixel. Source expressions are infix expressions
3580using any of the +, -, *, / or ** binary operators, the - unary
3581operator, ( and ) for grouping and the sin() and cos() functions. The
3582target pixel is input as the variables x and y.
3583
3584You specify the x and y expressions as xexpr and yexpr respectively.
3585You can also specify opcodes directly, but that's magic deep enough
3586that you can look at the source code.
3587
3588You can still use the transform() function, but the transform2()
3589function is just as fast and is more likely to be enhanced and
3590maintained.
3591
3592Later versions of Imager also support a transform2() class method
3593which allows you perform a more general set of operations, rather than
3594just specifying a spatial transformation as with the transform()
3595method, you can also perform colour transformations, image synthesis
3596and image combinations.
3597
3598transform2() takes an reference to an options hash, and a list of
3599images to operate one (this list may be empty):
3600
3601 my %opts;
3602 my @imgs;
3603 ...
3604 my $img = Imager::transform2(\%opts, @imgs)
3605 or die "transform2 failed: $Imager::ERRSTR";
3606
3607The options hash may define a transformation function, and optionally:
3608
3609=over 4
3610
3611=item *
3612
3613width - the width of the image in pixels. If this isn't supplied the
3614width of the first input image is used. If there are no input images
3615an error occurs.
3616
3617=item *
3618
3619height - the height of the image in pixels. If this isn't supplied
3620the height of the first input image is used. If there are no input
3621images an error occurs.
3622
3623=item *
3624
3625constants - a reference to hash of constants to define for the
3626expression engine. Some extra constants are defined by Imager
3627
3628=back
3629
3630The tranformation function is specified using either the expr or
3631rpnexpr member of the options.
3632
3633=over 4
3634
3635=item Infix expressions
3636
3637You can supply infix expressions to transform 2 with the expr keyword.
3638
3639$opts{expr} = 'return getp1(w-x, h-y)'
3640
3641The 'expression' supplied follows this general grammar:
3642
3643 ( identifier '=' expr ';' )* 'return' expr
3644
3645This allows you to simplify your expressions using variables.
3646
3647A more complex example might be:
3648
3649$opts{expr} = 'pix = getp1(x,y); return if(value(pix)>0.8,pix*0.8,pix)'
3650
3651Currently to use infix expressions you must have the Parse::RecDescent
3652module installed (available from CPAN). There is also what might be a
3653significant delay the first time you run the infix expression parser
3654due to the compilation of the expression grammar.
3655
3656=item Postfix expressions
3657
3658You can supply postfix or reverse-polish notation expressions to
3659transform2() through the rpnexpr keyword.
3660
3661The parser for rpnexpr emulates a stack machine, so operators will
3662expect to see their parameters on top of the stack. A stack machine
3663isn't actually used during the image transformation itself.
3664
3665You can store the value at the top of the stack in a variable called
3666foo using !foo and retrieve that value again using @foo. The !foo
3667notation will pop the value from the stack.
3668
3669An example equivalent to the infix expression above:
3670
3671 $opts{rpnexpr} = 'x y getp1 !pix @pix value 0.8 gt @pix 0.8 * @pix ifp'
3672
3673=back
3674
3675transform2() has a fairly rich range of operators.
3676
3677=over 4
3678
3679=item +, *, -, /, %, **
3680
3681multiplication, addition, subtraction, division, remainder and
3682exponentiation. Multiplication, addition and subtraction can be used
3683on colour values too - though you need to be careful - adding 2 white
3684values together and multiplying by 0.5 will give you grey, not white.
3685
3686Division by zero (or a small number) just results in a large number.
3687Modulo zero (or a small number) results in zero.
3688
3689=item sin(N), cos(N), atan2(y,x)
3690
3691Some basic trig functions. They work in radians, so you can't just
3692use the hue values.
3693
3694=item distance(x1, y1, x2, y2)
3695
3696Find the distance between two points. This is handy (along with
3697atan2()) for producing circular effects.
3698
3699=item sqrt(n)
3700
3701Find the square root. I haven't had much use for this since adding
3702the distance() function.
3703
3704=item abs(n)
3705
3706Find the absolute value.
3707
3708=item getp1(x,y), getp2(x,y), getp3(x, y)
3709
3710Get the pixel at position (x,y) from the first, second or third image
3711respectively. I may add a getpn() function at some point, but this
3712prevents static checking of the instructions against the number of
3713images actually passed in.
3714
3715=item value(c), hue(c), sat(c), hsv(h,s,v)
3716
3717Separates a colour value into it's value (brightness), hue (colour)
3718and saturation elements. Use hsv() to put them back together (after
3719suitable manipulation).
3720
3721=item red(c), green(c), blue(c), rgb(r,g,b)
3722
3723Separates a colour value into it's red, green and blue colours. Use
3724rgb(r,g,b) to put it back together.
3725
3726=item int(n)
3727
3728Convert a value to an integer. Uses a C int cast, so it may break on
3729large values.
3730
3731=item if(cond,ntrue,nfalse), if(cond,ctrue,cfalse)
3732
3733A simple (and inefficient) if function.
3734
3735=item <=,<,==,>=,>,!=
3736
3737Relational operators (typically used with if()). Since we're working
3738with floating point values the equalities are 'near equalities' - an
3739epsilon value is used.
3740
3741=item &&, ||, not(n)
3742
3743Basic logical operators.
3744
3745=back
3746
3747A few examples:
3748
3749=over 4
3750
3751=item rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat x y getp1 !pix @pix sat 0.7 gt @pat @pix ifp'
3752
9495ee93
AMH
3753tiles a smaller version of the input image over itself where the
3754colour has a saturation over 0.7.
02d1d628
AMH
3755
3756=item rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat y 360 / !rat x y getp1 1 @rat - pmult @pat @rat pmult padd'
3757
3758tiles the input image over itself so that at the top of the image the
3759full-size image is at full strength and at the bottom the tiling is
3760most visible.
3761
3762=item rpnexpr=>'x y getp1 !pix @pix value 0.96 gt @pix sat 0.1 lt and 128 128 255 rgb @pix ifp'
3763
3764replace pixels that are white or almost white with a palish blue
3765
3766=item rpnexpr=>'x 35 % 10 * y 45 % 8 * getp1 !pat x y getp1 !pix @pix sat 0.2 lt @pix value 0.9 gt and @pix @pat @pix value 2 / 0.5 + pmult ifp'
3767
3768Tiles the input image overitself where the image isn't white or almost
3769white.
3770
3771=item rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a2 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv'
3772
3773Produces a spiral.
3774
3775=item rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv'
3776
3777A spiral built on top of a colour wheel.
3778
3779=back
3780
3781For details on expression parsing see L<Imager::Expr>. For details on
3782the virtual machine used to transform the images, see
3783L<Imager::regmach.pod>.
3784
faa9b3e7
TC
3785=head2 Matrix Transformations
3786
3787Rather than having to write code in a little language, you can use a
3788matrix to perform transformations, using the matrix_transform()
3789method:
3790
3791 my $im2 = $im->matrix_transform(matrix=>[ -1, 0, $im->getwidth-1,
3792 0, 1, 0,
3793 0, 0, 1 ]);
3794
3795By default the output image will be the same size as the input image,
3796but you can supply the xsize and ysize parameters to change the size.
3797
3798Rather than building matrices by hand you can use the Imager::Matrix2d
3799module to build the matrices. This class has methods to allow you to
3800scale, shear, rotate, translate and reflect, and you can combine these
3801with an overloaded multiplication operator.
3802
3803WARNING: the matrix you provide in the matrix operator transforms the
3804co-ordinates within the B<destination> image to the co-ordinates
3805within the I<source> image. This can be confusing.
3806
3807Since Imager has 3 different fairly general ways of transforming an
3808image spatially, this method also has a yatf() alias. Yet Another
3809Transformation Function.
3810
3811=head2 Masked Images
3812
3813Masked images let you control which pixels are modified in an
3814underlying image. Where the first channel is completely black in the
3815mask image, writes to the underlying image are ignored.
3816
3817For example, given a base image called $img:
3818
3819 my $mask = Imager->new(xsize=>$img->getwidth, ysize=>getheight,
3820 channels=>1);
3821 # ... draw something on the mask
3822 my $maskedimg = $img->masked(mask=>$mask);
3823
3824You can specifiy the region of the underlying image that is masked
3825using the left, top, right and bottom options.
3826
3827If you just want a subset of the image, without masking, just specify
3828the region without specifying a mask.
3829
02d1d628
AMH
3830=head2 Plugins
3831
3832It is possible to add filters to the module without recompiling the
3833module itself. This is done by using DSOs (Dynamic shared object)
3834avaliable on most systems. This way you can maintain our own filters
3835and not have to get me to add it, or worse patch every new version of
3836the Module. Modules can be loaded AND UNLOADED at runtime. This
3837means that you can have a server/daemon thingy that can do something
3838like:
3839
3840 load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
3841 %hsh=(a=>35,b=>200,type=>lin_stretch);
3842 $img->filter(%hsh);
3843 unload_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
3844 $img->write(type=>'pnm',file=>'testout/t60.jpg')
3845 || die "error in write()\n";
3846
3847Someone decides that the filter is not working as it should -
3848dyntest.c modified and recompiled.
3849
3850 load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
07d70837 3851 $img->filter(%hsh);
02d1d628 3852
07d70837 3853An example plugin comes with the module - Please send feedback to
02d1d628
AMH
3854addi@umich.edu if you test this.
3855
3856Note: This seems to test ok on the following systems:
3857Linux, Solaris, HPUX, OpenBSD, FreeBSD, TRU64/OSF1, AIX.
3858If you test this on other systems please let me know.
3859
faa9b3e7
TC
3860=head2 Tags
3861
3862Image tags contain meta-data about the image, ie. information not
3863stored as pixels of the image.
3864
3865At the perl level each tag has a name or code and a value, which is an
3866integer or an arbitrary string. An image can contain more than one
3867tag with the same name or code.
3868
3869You can retrieve tags from an image using the tags() method, you can
3870get all of the tags in an image, as a list of array references, with
3871the code or name of the tag followed by the value of the tag:
3872
3873 my @alltags = $img->tags;
3874
3875or you can get all tags that have a given name:
3876
3877 my @namedtags = $img->tags(name=>$name);
3878
3879or a given code:
3880
3881 my @tags = $img->tags(code=>$code);
3882
3883You can add tags using the addtag() method, either by name:
3884
3885 my $index = $img->addtag(name=>$name, value=>$value);
3886
3887or by code:
3888
3889 my $index = $img->addtag(code=>$code, value=>$value);
3890
3891You can remove tags with the deltag() method, either by index:
3892
3893 $img->deltag(index=>$index);
3894
3895or by name:
3896
3897 $img->deltag(name=>$name);
3898
3899or by code:
3900
3901 $img->deltag(code=>$code);
3902
3903In each case deltag() returns the number of tags deleted.
3904
3905When you read a GIF image using read_multi(), each image can include
3906the following tags:
3907
3908=over
3909
3910=item gif_left
3911
3912the offset of the image from the left of the "screen" ("Image Left
3913Position")
3914
3915=item gif_top
3916
3917the offset of the image from the top of the "screen" ("Image Top Position")
3918
3919=item gif_interlace
3920
3921non-zero if the image was interlaced ("Interlace Flag")
3922
3923=item gif_screen_width
3924
3925=item gif_screen_height
3926
3927the size of the logical screen ("Logical Screen Width",
3928"Logical Screen Height")
3929
3930=item gif_local_map
3931
3932Non-zero if this image had a local color map.
3933
3934=item gif_background
3935
3936The index in the global colormap of the logical screen's background
3937color. This is only set if the current image uses the global
3938colormap.
3939
3940=item gif_trans_index
3941
3942The index of the color in the colormap used for transparency. If the
3943image has a transparency then it is returned as a 4 channel image with
3944the alpha set to zero in this palette entry. ("Transparent Color Index")
3945
3946=item gif_delay
3947
3948The delay until the next frame is displayed, in 1/100 of a second.
3949("Delay Time").
3950
3951=item gif_user_input
3952
3953whether or not a user input is expected before continuing (view dependent)
3954("User Input Flag").
3955
3956=item gif_disposal
3957
3958how the next frame is displayed ("Disposal Method")
3959
3960=item gif_loop
3961
3962the number of loops from the Netscape Loop extension. This may be zero.
3963
3964=item gif_comment
3965
3966the first block of the first gif comment before each image.
3967
3968=back
3969
3970Where applicable, the ("name") is the name of that field from the GIF89
3971standard.
3972
705fd961 3973The following tags are set in a TIFF image when read, and can be set
faa9b3e7
TC
3974to control output:
3975
3976=over
3977
3978=item tiff_resolutionunit
3979
3980The value of the ResolutionUnit tag. This is ignored on writing if
3981the i_aspect_only tag is non-zero.
3982
3983=back
3984
1ec86afa 3985The following tags are set when a Windows BMP file is read:
705fd961
TC
3986
3987=over
3988
3989=item bmp_compression
3990
3991The type of compression, if any.
3992
3993=item bmp_important_colors
3994
3995The number of important colors as defined by the writer of the image.
3996
3997=back
3998
faa9b3e7
TC
3999Some standard tags will be implemented as time goes by:
4000
4001=over
4002
4003=item i_xres
4004
4005=item i_yres
4006
4007The spatial resolution of the image in pixels per inch. If the image
4008format uses a different scale, eg. pixels per meter, then this value
4009is converted. A floating point number stored as a string.
4010
4011=item i_aspect_only
4012
4013If this is non-zero then the values in i_xres and i_yres are treated
4014as a ratio only. If the image format does not support aspect ratios
4015then this is scaled so the smaller value is 72dpi.
4016
4017=back
4018
02d1d628
AMH
4019=head1 BUGS
4020
4021box, arc, circle do not support antialiasing yet. arc, is only filled
4022as of yet. Some routines do not return $self where they should. This
4023affects code like this, C<$img-E<gt>box()-E<gt>arc()> where an object
4024is expected.
4025
4026When saving Gif images the program does NOT try to shave of extra
4027colors if it is possible. If you specify 128 colors and there are
4028only 2 colors used - it will have a 128 colortable anyway.
4029
4030=head1 AUTHOR
4031
9495ee93
AMH
4032Arnar M. Hrafnkelsson, addi@umich.edu, and recently lots of assistance
4033from Tony Cook. See the README for a complete list.
02d1d628 4034
9495ee93 4035=head1 SEE ALSO
02d1d628 4036
07d70837 4037perl(1), Imager::Color(3), Imager::Font(3), Imager::Matrix2d(3),
faa9b3e7
TC
4038Affix::Infix2Postfix(3), Parse::RecDescent(3)
4039http://www.eecs.umich.edu/~addi/perl/Imager/
02d1d628
AMH
4040
4041=cut