]> git.imager.perl.org - imager.git/blobdiff - Imager.pm
- t1 library re-initialization modified to support T1Lib 5.1.0
[imager.git] / Imager.pm
index 5c70b49aa4dbee7692ad82cd6d08910f4c62ac41..a2a6af857644f57e9c07ea844714ed1bb46fa825 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -147,7 +147,7 @@ BEGIN {
   require Exporter;
   require DynaLoader;
 
-  $VERSION = '0.44';
+  $VERSION = '0.45';
   @ISA = qw(Exporter DynaLoader);
   bootstrap Imager $VERSION;
 }
@@ -354,9 +354,19 @@ BEGIN {
      callsub  => 
      sub {
        my %hsh = @_;
+
+       # make sure the segments are specified with colors
+       my @segments;
+       for my $segment (@{$hsh{segments}}) {
+         my @new_segment = @$segment;
+         
+         $_ = _color($_) or die $Imager::ERRSTR."\n" for @new_segment[3,4];
+         push @segments, \@new_segment;
+       }
+
        i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
                   $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
-                  $hsh{ssample_param}, $hsh{segments});
+                  $hsh{ssample_param}, \@segments);
      },
     };
   $filters{unsharpmask} =
@@ -550,6 +560,12 @@ sub copy {
   my $self = shift;
   unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
 
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   my $newcopy=Imager->new();
   $newcopy->{IMG}=i_img_new();
   i_copy($newcopy->{IMG},$self->{IMG});
@@ -581,8 +597,13 @@ sub paste {
 sub crop {
   my $self=shift;
   unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
-
   
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "crop() called in void context - crop() returns the cropped image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   my %hsh=@_;
 
   my ($w, $h, $l, $r, $b, $t) =
@@ -753,6 +774,12 @@ sub to_paletted {
     $opts = shift;
   }
 
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "to_paletted() called in void context - to_paletted() returns the converted image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   my $result = Imager->new;
   $result->{IMG} = i_img_to_pal($self->{IMG}, $opts);
 
@@ -772,6 +799,12 @@ sub to_rgb8 {
   my $self = shift;
   my $result;
 
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "to_rgb8() called in void context - to_rgb8() returns the cropped image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   if ($self->{IMG}) {
     $result = Imager->new;
     $result->{IMG} = i_img_to_rgb($self->{IMG})
@@ -1089,35 +1122,37 @@ sub read {
     undef($self->{IMG});
   }
 
-  # FIXME: Find the format here if not specified
-  # yes the code isn't here yet - next week maybe?
-  # Next week?  Are you high or something?  That comment
-  # has been there for half a year dude.
-  # Look, i just work here, ok?
-
   my ($IO, $fh) = $self->_get_reader_io(\%input) or return;
 
   unless ($input{'type'}) {
-               $input{'type'} = i_test_format_probe($IO, -1);
-       }
+    $input{'type'} = i_test_format_probe($IO, -1);
+  }
 
   unless ($input{'type'}) {
          $self->_set_error('type parameter missing and not possible to guess from extension'); 
     return undef;
   }
 
+  unless ($formats{$input{'type'}}) {
+    $self->_set_error("format '$input{'type'}' not supported");
+    return;
+  }
+
   # Setup data source
   if ( $input{'type'} eq 'jpeg' ) {
     ($self->{IMG},$self->{IPTCRAW}) = i_readjpeg_wiol( $IO );
     if ( !defined($self->{IMG}) ) {
-      $self->{ERRSTR}='unable to read jpeg image'; return undef;
+      $self->{ERRSTR}=$self->_error_as_msg(); return undef;
     }
     $self->{DEBUG} && print "loading a jpeg file\n";
     return $self;
   }
 
   if ( $input{'type'} eq 'tiff' ) {
-    $self->{IMG}=i_readtiff_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
+    my $page = $input{'page'};
+    defined $page or $page = 0;
+    # Fixme, check if that length parameter is ever needed
+    $self->{IMG}=i_readtiff_wiol( $IO, -1, $page ); 
     if ( !defined($self->{IMG}) ) {
       $self->{ERRSTR}=$self->_error_as_msg(); return undef;
     }
@@ -1137,7 +1172,7 @@ sub read {
   if ( $input{'type'} eq 'png' ) {
     $self->{IMG}=i_readpng_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
     if ( !defined($self->{IMG}) ) {
-      $self->{ERRSTR}='unable to read png image';
+      $self->{ERRSTR} = $self->_error_as_msg();
       return undef;
     }
     $self->{DEBUG} && print "loading a png file\n";
@@ -1158,16 +1193,28 @@ sub read {
       $self->{ERRSTR} = "option 'colors' must be a scalar reference";
       return undef;
     }
-    if ($input{colors}) {
-      my $colors;
-      ($self->{IMG}, $colors) =i_readgif_wiol( $IO );
-      if ($colors) {
-       ${ $input{colors} } = [ map { NC(@$_) } @$colors ];
+    if ($input{'gif_consolidate'}) {
+      if ($input{colors}) {
+       my $colors;
+       ($self->{IMG}, $colors) =i_readgif_wiol( $IO );
+       if ($colors) {
+         ${ $input{colors} } = [ map { NC(@$_) } @$colors ];
+       }
+      }
+      else {
+       $self->{IMG} =i_readgif_wiol( $IO );
       }
     }
     else {
-      $self->{IMG} =i_readgif_wiol( $IO );
+      my $page = $input{'page'};
+      defined $page or $page = 0;
+      $self->{IMG} = i_readgif_single_wiol( $IO, $page );
+      if ($input{colors}) {
+       ${ $input{colors} } =
+         [ i_getcolors($self->{IMG}, 0, i_colorcount($self->{IMG})) ];
+      }
     }
+
     if ( !defined($self->{IMG}) ) {
       $self->{ERRSTR}=$self->_error_as_msg();
       return undef;
@@ -1591,7 +1638,14 @@ sub filter {
     }
   }
 
-  &{$filters{$input{'type'}}{callsub}}(%hsh);
+  eval {
+    local $SIG{__DIE__}; # we don't want this processed by confess, etc
+    &{$filters{$input{'type'}}{callsub}}(%hsh);
+  };
+  if ($@) {
+    chomp($self->{ERRSTR} = $@);
+    return;
+  }
 
   my @b=keys %hsh;
 
@@ -1645,6 +1699,12 @@ sub scaleX {
   my $self=shift;
   my %opts=(scalefactor=>0.5,@_);
 
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "scaleX() called in void context - scaleX() returns the scaled image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
 
   my $img = Imager->new();
@@ -1664,6 +1724,12 @@ sub scaleY {
   my $self=shift;
   my %opts=(scalefactor=>0.5,@_);
 
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "scaleY() called in void context - scaleY() returns the scaled image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
 
   my $img = Imager->new();
@@ -1869,6 +1935,13 @@ sub flip {
 sub rotate {
   my $self = shift;
   my %opts = @_;
+
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "rotate() called in void context - rotate() returns the rotated image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   if (defined $opts{right}) {
     my $degrees = $opts{right};
     if ($degrees < 0) {
@@ -1921,6 +1994,12 @@ sub matrix_transform {
   my $self = shift;
   my %opts = @_;
 
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "copy() called in void context - copy() returns the copied image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   if ($opts{matrix}) {
     my $xsize = $opts{xsize} || $self->getwidth;
     my $ysize = $opts{ysize} || $self->getheight;
@@ -2319,6 +2398,111 @@ sub getpixel {
   $self;
 }
 
+sub getscanline {
+  my $self = shift;
+  my %opts = ( type => '8bit', x=>0, @_);
+
+  defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
+
+  unless (defined $opts{'y'}) {
+    $self->_set_error("missing y parameter");
+    return;
+  }
+
+  if ($opts{type} eq '8bit') {
+    return i_glin($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+                 $opts{y});
+  }
+  elsif ($opts{type} eq 'float') {
+    return i_glinf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+                 $opts{y});
+  }
+  else {
+    $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+    return;
+  }
+}
+
+sub setscanline {
+  my $self = shift;
+  my %opts = ( x=>0, @_);
+
+  unless (defined $opts{'y'}) {
+    $self->_set_error("missing y parameter");
+    return;
+  }
+
+  if (!$opts{type}) {
+    if (ref $opts{pixels} && @{$opts{pixels}}) {
+      # try to guess the type
+      if ($opts{pixels}[0]->isa('Imager::Color')) {
+       $opts{type} = '8bit';
+      }
+      elsif ($opts{pixels}[0]->isa('Imager::Color::Float')) {
+       $opts{type} = 'float';
+      }
+      else {
+       $self->_set_error("missing type parameter and could not guess from pixels");
+       return;
+      }
+    }
+    else {
+      # default
+      $opts{type} = '8bit';
+    }
+  }
+
+  if ($opts{type} eq '8bit') {
+    if (ref $opts{pixels}) {
+      return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
+    }
+    else {
+      return i_plin($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
+    }
+  }
+  elsif ($opts{type} eq 'float') {
+    if (ref $opts{pixels}) {
+      return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, @{$opts{pixels}});
+    }
+    else {
+      return i_plinf($self->{IMG}, $opts{x}, $opts{'y'}, $opts{pixels});
+    }
+  }
+  else {
+    $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+    return;
+  }
+}
+
+sub getsamples {
+  my $self = shift;
+  my %opts = ( type => '8bit', x=>0, @_);
+
+  defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
+
+  unless (defined $opts{'y'}) {
+    $self->_set_error("missing y parameter");
+    return;
+  }
+  
+  unless ($opts{channels}) {
+    $opts{channels} = [ 0 .. $self->getchannels()-1 ];
+  }
+
+  if ($opts{type} eq '8bit') {
+    return i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+                  $opts{y}, @{$opts{channels}});
+  }
+  elsif ($opts{type} eq 'float') {
+    return i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+                   $opts{y}, @{$opts{channels}});
+  }
+  else {
+    $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+    return;
+  }
+}
+
 # make an identity matrix of the given size
 sub _identity {
   my ($size) = @_;
@@ -2335,6 +2519,12 @@ sub convert {
   my ($self, %opts) = @_;
   my $matrix;
 
+  unless (defined wantarray) {
+    my @caller = caller;
+    warn "convert() called in void context - convert() returns the converted image at $caller[1] line $caller[2]\n";
+    return;
+  }
+
   # the user can either specify a matrix or preset
   # the matrix overrides the preset
   if (!exists($opts{matrix})) {
@@ -2562,6 +2752,32 @@ sub string {
   return $self;
 }
 
+my @file_limit_names = qw/width height bytes/;
+
+sub set_file_limits {
+  shift;
+
+  my %opts = @_;
+  my %values;
+  
+  if ($opts{reset}) {
+    @values{@file_limit_names} = (0) x @file_limit_names;
+  }
+  else {
+    @values{@file_limit_names} = i_get_image_file_limits();
+  }
+
+  for my $key (keys %values) {
+    defined $opts{$key} and $values{$key} = $opts{$key};
+  }
+
+  i_set_image_file_limits($values{width}, $values{height}, $values{bytes});
+}
+
+sub get_file_limits {
+  i_get_image_file_limits();
+}
+
 # Shortcuts that can be exported
 
 sub newcolor { Imager::Color->new(@_); }
@@ -2747,6 +2963,10 @@ Overview.
 
 =item *
 
+L<Imager::Tutorial> - a brief introduction to Imager.
+
+=item *
+
 L<Imager::Cookbook> - how to do various things with Imager.
 
 =item *
@@ -2855,6 +3075,8 @@ box() - L<Imager::Draw/box>
 
 circle() - L<Imager::Draw/circle>
 
+colorcount() - L<Imager::Draw/colorcount>
+
 convert() - L<Imager::Transformations/"Color transformations"> -
 transform the color space
 
@@ -2884,10 +3106,16 @@ getcolorcount() -  L<Imager::ImageTypes>
 getcolors() - L<Imager::ImageTypes> - get colors from the image
 palette, if it has one
 
+get_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
+
 getheight() - L<Imager::ImageTypes>
 
 getpixel() - L<Imager::Draw/setpixel and getpixel>
 
+getsamples() - L<Imager::Draw/getsamples>
+
+getscanline() - L<Imager::Draw/getscanline>
+
 getwidth() - L<Imager::ImageTypes>
 
 img_set() - L<Imager::ImageTypes>
@@ -2901,6 +3129,8 @@ masked() -  L<Imager::ImageTypes> - make a masked image
 
 matrix_transform() - L<Imager::Engines/"Matrix Transformations">
 
+maxcolors() - L<Imager::ImageTypes/maxcolor>
+
 new() - L<Imager::ImageTypes>
 
 open() - L<Imager::Files> - an alias for read()
@@ -2923,6 +3153,8 @@ image and use the alpha channel
 
 scale() - L<Imager::Transformations/scale>
 
+setscanline() - L<Imager::Draw/setscanline>
+
 scaleX() - L<Imager::Transformations/scaleX>
 
 scaleY() - L<Imager::Transformations/scaleY>
@@ -2931,6 +3163,8 @@ setcolors() - L<Imager::ImageTypes> - set palette colors in a paletted image
 
 setpixel() - L<Imager::Draw/setpixel and getpixel>
 
+set_file_limits() - L<Imager::Files/"Limiting the sizes of images you read">
+
 string() - L<Imager::Font/string> - draw text on an image
 
 tags() -  L<Imager::ImageTypes> - fetch image tags
@@ -2982,7 +3216,7 @@ drawing boxes - L<Imager::Draw/box>
 
 drawing lines - L<Imager::Draw/line>
 
-drawing text - L<Imager::Font/string>
+drawing text - L<Imager::Font/string>, L<Imager::Font/align>
 
 error message - L<Imager/"Basic Overview">
 
@@ -3027,6 +3261,8 @@ invert image - L<Imager::Filter/hardinvert>
 
 JPEG - L<Imager::Files/"JPEG">
 
+limiting image sizes - L<Imager::Files/"Limiting the sizes of images you read">
+
 lines, drawing - L<Imager::Draw/line>
 
 matrix - L<Imager::Matrix2d>, 
@@ -3046,7 +3282,7 @@ posterize - L<Imager::Filter/postlevels>
 
 png files - L<Imager::Files>, L<Imager::Files/"PNG">
 
-pnm - L<Imager::Files/"PNM (Portable aNy Map">
+pnm - L<Imager::Files/"PNM (Portable aNy Map)">
 
 rectangles, drawing - L<Imager::Draw/box>
 
@@ -3099,11 +3335,7 @@ If you're into IRC, you can typically find the developers in #Imager
 on irc.perl.org.  As with any IRC channel, the participants could be
 occupied or asleep, so please be patient.
 
-You can report bugs either by sending email to:
-
-  bug-Imager@rt.cpan.org
-
-or by pointing your browser at:
+You can report bugs by pointing your browser at:
 
   https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager