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