]> git.imager.perl.org - imager.git/blobdiff - Imager.pm
can't add to a void *
[imager.git] / Imager.pm
index a5c039cd3f7fc5180ff5cdb2e434c71158517f7d..5b3dccd14d03a1256cda60e8e19566bc5ccf8e6c 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -117,6 +117,7 @@ use Imager::Font;
                newcolour
                NC
                NF
+                NCF
 );
 
 @EXPORT=qw(
@@ -136,6 +137,7 @@ use Imager::Font;
                newcolor
                NF
                NC
+                NCF
               )],
    all => [@EXPORT_OK],
    default => [qw(
@@ -152,10 +154,13 @@ my %writers;
 # modules we attempted to autoload
 my %attempted_to_load;
 
+# library keys that are image file formats
+my %file_formats = map { $_ => 1 } qw/tiff pnm gif png jpeg raw bmp tga/;
+
 BEGIN {
   require Exporter;
   @ISA = qw(Exporter);
-  $VERSION = '0.59';
+  $VERSION = '0.61';
   eval {
     require XSLoader;
     XSLoader::load(Imager => $VERSION);
@@ -423,13 +428,19 @@ BEGIN {
 # initlize Imager
 # NOTE: this might be moved to an import override later on
 
-#sub import {
-#  my $pack = shift;
-#  (look through @_ for special tags, process, and remove them);   
-#  use Data::Dumper;
-#  print Dumper($pack);
-#  print Dumper(@_);
-#}
+sub import {
+  my $i = 1;
+  while ($i < @_) {
+    if ($_[$i] eq '-log-stderr') {
+      init_log(undef, 4);
+      splice(@_, $i, 1);
+    }
+    else {
+      ++$i;
+    }
+  }
+  goto &Exporter::import;
+}
 
 sub init_log {
   i_init_log($_[0],$_[1]);
@@ -1022,6 +1033,14 @@ sub virtual {
   $self->{IMG} and i_img_virtual($self->{IMG});
 }
 
+sub is_bilevel {
+  my ($self) = @_;
+
+  $self->{IMG} or return;
+
+  return i_img_is_monochrome($self->{IMG});
+}
+
 sub tags {
   my ($self, %opts) = @_;
 
@@ -1278,7 +1297,8 @@ sub read {
   }
 
   unless ($formats{$input{'type'}}) {
-    $self->_set_error("format '$input{'type'}' not supported");
+    my $read_types = join ', ', sort Imager->read_types();
+    $self->_set_error("format '$input{'type'}' not supported - formats $read_types available for reading");
     return;
   }
 
@@ -1446,6 +1466,30 @@ sub register_writer {
   return 1;
 }
 
+sub read_types {
+  my %types =
+    (
+     map { $_ => 1 }
+     keys %readers,
+     grep($file_formats{$_}, keys %formats),
+     qw(ico sgi), # formats not handled directly, but supplied with Imager
+    );
+
+  return keys %types;
+}
+
+sub write_types {
+  my %types =
+    (
+     map { $_ => 1 }
+     keys %writers,
+     grep($file_formats{$_}, keys %formats),
+     qw(ico sgi), # formats not handled directly, but supplied with Imager
+    );
+
+  return keys %types;
+}
+
 # probes for an Imager::File::whatever module
 sub _reader_autoload {
   my $type = shift;
@@ -1628,7 +1672,8 @@ sub write {
   }
   else {
     if (!$formats{$input{'type'}}) { 
-      $self->{ERRSTR}='format not supported'; 
+      my $write_types = join ', ', sort Imager->write_types();
+      $self->_set_error("format '$input{'type'}' not supported - formats $write_types available for writing");
       return undef;
     }
     
@@ -1768,7 +1813,8 @@ sub write_multi {
   }
   else {
     if (!$formats{$type}) { 
-      $class->_set_error("format $type not supported"); 
+      my $write_types = join ', ', sort Imager->write_types();
+      $class->_set_error("format '$type' not supported - formats $write_types available for writing");
       return undef;
     }
     
@@ -1889,9 +1935,9 @@ sub read_multi {
     if ($img->read(%opts, io => $IO, type => $type)) {
       return ( $img );
     }
+    Imager->_set_error($img->errstr);
   }
 
-  $ERRSTR = "Cannot read multiple images from $type files";
   return;
 }
 
@@ -3011,7 +3057,7 @@ sub setscanline {
 
 sub getsamples {
   my $self = shift;
-  my %opts = ( type => '8bit', x=>0, @_);
+  my %opts = ( type => '8bit', x=>0, offset => 0, @_);
 
   defined $opts{width} or $opts{width} = $self->getwidth - $opts{x};
 
@@ -3024,18 +3070,103 @@ sub getsamples {
     $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}});
+  if ($opts{target}) {
+    my $target = $opts{target};
+    my $offset = $opts{offset};
+    if ($opts{type} eq '8bit') {
+      my @samples = i_gsamp($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+                           $opts{y}, @{$opts{channels}})
+       or return;
+      @{$target}{$offset .. $offset + @samples - 1} = @samples;
+      return scalar(@samples);
+    }
+    elsif ($opts{type} eq 'float') {
+      my @samples = i_gsampf($self->{IMG}, $opts{x}, $opts{x}+$opts{width},
+                            $opts{y}, @{$opts{channels}});
+      @{$target}{$offset .. $offset + @samples - 1} = @samples;
+      return scalar(@samples);
+    }
+    elsif ($opts{type} =~ /^(\d+)bit$/) {
+      my $bits = $1;
+
+      my @data;
+      my $count = i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width}, 
+                              $opts{y}, $bits, $target, 
+                              $offset, @{$opts{channels}});
+      unless (defined $count) {
+       $self->_set_error(Imager->_error_as_msg);
+       return;
+      }
+
+      return $count;
+    }
+    else {
+      $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+      return;
+    }
   }
   else {
-    $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+    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}});
+    }
+    elsif ($opts{type} =~ /^(\d+)bit$/) {
+      my $bits = $1;
+
+      my @data;
+      i_gsamp_bits($self->{IMG}, $opts{x}, $opts{x}+$opts{width}, 
+                  $opts{y}, $bits, \@data, 0, @{$opts{channels}})
+       or return;
+      return @data;
+    }
+    else {
+      $self->_set_error("invalid type parameter - must be '8bit' or 'float'");
+      return;
+    }
+  }
+}
+
+sub setsamples {
+  my $self = shift;
+  my %opts = ( x => 0, offset => 0, @_ );
+
+  unless ($self->{IMG}) {
+    $self->_set_error('setsamples: empty input image');
+    return;
+  }
+
+  unless(defined $opts{data} && ref $opts{data}) {
+    $self->_set_error('setsamples: data parameter missing or invalid');
     return;
   }
+
+  unless ($opts{channels}) {
+    $opts{channels} = [ 0 .. $self->getchannels()-1 ];
+  }
+
+  unless ($opts{type} && $opts{type} =~ /^(\d+)bit$/) {
+    $self->_set_error('setsamples: type parameter missing or invalid');
+    return;
+  }
+  my $bits = $1;
+
+  unless (defined $opts{width}) {
+    $opts{width} = $self->getwidth() - $opts{x};
+  }
+
+  my $count = i_psamp_bits($self->{IMG}, $opts{x}, $opts{y}, $bits,
+                          $opts{channels}, $opts{data}, $opts{offset}, 
+                          $opts{width});
+  unless (defined $count) {
+    $self->_set_error(Imager->_error_as_msg);
+    return;
+  }
+
+  return $count;
 }
 
 # make an identity matrix of the given size
@@ -3416,6 +3547,7 @@ sub get_file_limits {
 
 sub newcolor { Imager::Color->new(@_); }
 sub newfont  { Imager::Font->new(@_); }
+sub NCF { Imager::Color::Float->new(@_) }
 
 *NC=*newcolour=*newcolor;
 *NF=*newfont;
@@ -3810,6 +3942,8 @@ img_set() - L<Imager::ImageTypes/img_set>
 
 init() - L<Imager::ImageTypes/init>
 
+is_bilevel() - L<Imager::ImageTypes/is_bilevel>
+
 line() - L<Imager::Draw/line>
 
 load_plugin() - L<Imager::Filters/load_plugin>
@@ -3825,6 +3959,8 @@ maxcolors() - L<Imager::ImageTypes/maxcolors>
 
 NC() - L<Imager::Handy/NC>
 
+NCF() - L<Imager::Handy/NCF>
+
 new() - L<Imager::ImageTypes/new>
 
 newcolor() - L<Imager::Handy/newcolor>
@@ -3851,6 +3987,9 @@ read() - L<Imager::Files> - read a single image from an image file
 read_multi() - L<Imager::Files> - read multiple images from an image
 file
 
+read_types() - L<Imager::Files/read_types> - list image types Imager
+can read.
+
 register_filter() - L<Imager::Filters/register_filter>
 
 register_reader() - L<Imager::Filters/register_reader>
@@ -3877,6 +4016,8 @@ setmask() - L<Imager::ImageTypes/setmask>
 
 setpixel() - L<Imager::Draw/setpixel>
 
+setsamples() - L<Imager::Draw/setsamples>
+
 setscanline() - L<Imager::Draw/setscanline>
 
 settag() - L<Imager::ImageTypes/settag>
@@ -3907,9 +4048,12 @@ write() - L<Imager::Files> - write an image to a file
 write_multi() - L<Imager::Files> - write multiple image to an image
 file.
 
+write_types() - L<Imager::Files/read_types> - list image types Imager
+can write.
+
 =head1 CONCEPT INDEX
 
-animated GIF - L<Imager::File/"Writing an animated GIF">
+animated GIF - L<Imager::Files/"Writing an animated GIF">
 
 aspect ratio - L<Imager::ImageTypes/i_xres>,
 L<Imager::ImageTypes/i_yres>, L<Imager::ImageTypes/i_aspect_only>
@@ -3985,6 +4129,8 @@ gradient fill - L<Imager::Fill/"Fountain fills">,
 L<Imager::Filters/fountain>, L<Imager::Fountain>,
 L<Imager::Filters/gradgen>
 
+grayscale, convert image to - L<Imager::Transformations/convert>
+
 guassian blur - L<Imager::Filter/guassian>
 
 hatch fills - L<Imager::Fill/"Hatched fills">
@@ -4087,6 +4233,14 @@ L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Imager>
 
 =back
 
+or by sending an email to:
+
+=over
+
+bug-Imager@rt.cpan.org
+
+=back
+
 Please remember to include the versions of Imager, perl, supporting
 libraries, and any relevant code.  If you have specific images that
 cause the problems, please include those too.