]> git.imager.perl.org - imager.git/blobdiff - Imager.pm
changed Imager::read() to always return an arrayref of Imager::Color
[imager.git] / Imager.pm
index 8e81935f783410deca30b482ecc545afea7d7806..38f7d152645b9c86c731afaa9ae02adc5c420f96 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -493,9 +493,35 @@ sub read {
   if ($input{fd}) { $fd=$input{fd} };
 
   if ( $input{type} eq 'gif' ) {
-    if (exists $input{data}) { $self->{IMG}=i_readgif_scalar($input{data}); }
-    else { $self->{IMG}=i_readgif( $fd ) }
-    if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read gif image'; return undef; }
+    my $colors;
+    if ($input{colors} && !ref($input{colors})) {
+      # must be a reference to a scalar that accepts the colour map
+      $self->{ERRSTR} = "option 'colors' must be a scalar reference";
+      return undef;
+    }
+    if (exists $input{data}) {
+      if ($input{colors}) {
+       ($self->{IMG}, $colors) = i_readgif_scalar($input{data});
+      }
+      else {
+       $self->{IMG}=i_readgif_scalar($input{data});
+      }
+    }
+    else { 
+      if ($input{colors}) {
+       ($self->{IMG}, $colors) = i_readgif( $fd );
+      }
+      else {
+       $self->{IMG} = i_readgif( $fd )
+      }
+    }
+    if ($colors) {
+      # we may or may not change i_readgif to return blessed objects...
+      ${$input{colors}} = [ map { NC(@$_) } @$colors ];
+    }
+    if ( !defined($self->{IMG}) ) {
+      $self->{ERRSTR}= 'reading GIF:'._error_as_msg(); return undef;
+    }
     $self->{DEBUG} && print "loading a gif file\n";
   } elsif ( $input{type} eq 'jpeg' ) {
     if (exists $input{data}) { ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_scalar($input{data}); }
@@ -617,7 +643,7 @@ sub write {
        $rc=i_writegifmc($self->{IMG},$fd,$input{gifplanes});
       }
       if ( !defined($rc) ) {
-       $self->{ERRSTR}='unable to write gif image'; return undef;
+       $self->{ERRSTR} = "Writing GIF file: "._error_as_msg(); return undef;
       }
       $self->{DEBUG} && print "writing a gif file\n";
 
@@ -993,6 +1019,18 @@ sub rubthrough {
 }
 
 
+sub flip {
+  my $self  = shift;
+  my %opts  = @_;
+  my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
+  my $dir;
+  return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
+  $dir = $xlate{$opts{'dir'}};
+  return $self if i_flipxy($self->{IMG}, $dir);
+  return ();
+}
+
+
 
 # These two are supported for legacy code only
 
@@ -1465,6 +1503,23 @@ The second example shows how to read an image from a scalar, this is
 usefull if your data originates from somewhere else than a filesystem
 such as a database over a DBI connection.
 
+If you are reading from a gif image file, you can supply a 'colors'
+parameter which must be a reference to a scalar.  The referenced
+scalar will receive an array reference which contains the colors, each
+represented as an Imager::Color object.
+
+If you already have an open file handle, for example a socket or a
+pipe, you can specify the 'fd' parameter instead of supplying a
+filename.  Please be aware that you need to use fileno() to retrieve
+the file descriptor for the file:
+
+  $img->read(fd=>fileno(FILE), type=>'gif') or die $img->errstr;
+
+For writing using the 'fd' option you will probably want to set $| for
+that descriptor, since the writes to the file descriptor bypass Perl's
+(or the C libraries) buffering.  Setting $| should avoid out of order
+output.
+
 *Note that load() is now an alias for read but will be removed later*
 
 C<$img-E<gt>write> has the same interface as C<read()>.  The earlier
@@ -1492,6 +1547,32 @@ is sufficient:
   use Imager;
   print "@{[keys %Imager::formats]}";
 
+When reading raw images you need to supply the width and height of the
+image in the xsize and ysize options:
+
+  $img->read(file=>'foo.raw', xsize=>100, ysize=>100)
+    or die "Cannot read raw image\n";
+
+If your input file has more channels than you want, or (as is common),
+junk in the fourth channel, you can use the datachannels and
+storechannels options to control the number of channels in your input
+file and the resulting channels in your image.  For example, if your
+input image uses 32-bits per pixel with red, green, blue and junk
+values for each pixel you could do:
+
+  $img->read(file=>'foo.raw', xsize=>100, ysize=>100, datachannels=>4,
+            storechannels=>3)
+    or die "Cannot read raw image\n";
+
+Normally the raw image is expected to have the value for channel 1
+immediately following channel 0 and channel 2 immediately following
+channel 1 for each pixel.  If your input image has all the channel 0
+values for the first line of the image, followed by all the channel 1
+values for the first line and so on, you can use the interleave option:
+
+  $img->read(file=>'foo.raw', xsize=100, ysize=>100, interleave=>1)
+    or die "Cannot read raw image\n";
+
 =head2 Multi-image files
 
 Currently just for gif files, you can create files that contain more
@@ -1583,7 +1664,9 @@ the previous value.
 =item gif_tran_color
 
 A reference to an Imager::Color object, which is the colour to use for
-the palette entry used to represent transparency in the palette.
+the palette entry used to represent transparency in the palette.  You
+need to set the transp option (see L<Quantization options>) for this
+value to be used.
 
 =item gif_positions
 
@@ -1641,6 +1724,9 @@ channel.
 
 =back
 
+This will only be used if the image has an alpha channel, and if there
+is space in the palette for a transparency colour.
+
 =item tr_threshold
 
 The highest alpha value at which a pixel will be made transparent when
@@ -1652,17 +1738,16 @@ The type of error diffusion to perform on the alpha channel when
 transp is 'errdiff'.  This can be any defined error diffusion type
 except for custom (see errdiff below).
 
-=item tr_ordered
+=item tr_orddith
 
 The type of ordered dither to perform on the alpha channel when transp
-is 'orddith'.  Possible values are:
+is 'ordered'.  Possible values are:
 
 =over 4
 
 =item random
 
-A semi-random map is used.  The map is the same each time.  Currently
-the default (which may change.)
+A semi-random map is used.  The map is the same each time.
 
 =item dot8
 
@@ -1692,6 +1777,11 @@ diagonal line dither
 
 diagonal line dither
 
+=item tiny
+
+dot matrix dither (currently the default).  This is probably the best
+for displays (like web pages).
+
 =item custom
 
 A custom dither matrix is used - see tr_map
@@ -1852,7 +1942,6 @@ the function return undef.  Examples:
 =head2 Drawing Methods
 
 IMPLEMENTATION MORE OR LESS DONE CHECK THE TESTS
-
 DOCUMENTATION OF THIS SECTION OUT OF SYNC
 
 It is possible to draw with graphics primitives onto images.  Such
@@ -1959,10 +2048,23 @@ To copy an image to onto another image use the C<paste()> method.
 That copies the entire C<$logo> image onto the C<$dest> image so that the
 upper left corner of the C<$logo> image is at (40,20).
 
+
+=head2 Flipping images
+
+An inplace horizontal or vertical flip is possible by calling the
+C<flip()> method.  If the original is to be preserved it's possible to
+make a copy first.  The only parameter it takes is the C<dir>
+parameter which can take the values C<h>, C<v>, C<vh> and C<hv>.
+
+  $img->flip(dir=>"h");       # horizontal flip
+  $img->flip(dir=>"vh");      # vertical and horizontal flip
+  $nimg = $img->copy->flip(dir=>"v"); # make a copy and flip it vertically
+
 =head2 Blending Images
-To put an image or a part of an image directly into another it is
-best to call the C<paste()> method on the image you want to add to.
+
+To put an image or a part of an image directly
+into another it is best to call the C<paste()> method on the image you
+want to add to.
 
   $img->paste(img=>$srcimage,left=>30,top=>50);