+
+In list context this method will return a list of Imager::Color
+objects when I<type> is C<8bit>, or a list of Imager::Color::Float
+objects when I<type> if C<float>, or a list of integers when I<type>
+is C<index>.
+
+In scalar context this returns a packed 8-bit pixels when I<type> is
+C<8bit>, or a list of packed floating point pixels when I<type> is
+C<float>, or packed palette color indexes when I<type> is C<index>.
+
+The values of samples for which the image does not have channels is
+undefined. For example, for a single channel image the values of
+channels 1 through 3 are undefined.
+
+Check image for a given color:
+
+ my $found;
+ YLOOP: for my $y (0..$img->getheight-1) {
+ my @colors = $img->getscanline(y=>$y);
+ for my $color (@colors) {
+ my ($red, $green, $blue, $alpha) = $color->rgba;
+ if ($red == $test_red && $green == $test_green && $blue == $test_blue
+ && $alpha == $test_alpha) {
+ ++$found;
+ last YLOOP;
+ }
+ }
+ }
+
+Or do it using packed data:
+
+ my $found;
+ my $test_packed = pack("CCCC", $test_red, $test_green, $test_blue,
+ $test_alpha);
+ YLOOP: for my $y (0..$img->getheight-1) {
+ my $colors = $img->getscanline(y=>$y);
+ while (length $colors) {
+ if (substr($colors, 0, 4, '') eq $test_packed) {
+ ++$found;
+ last YLOOP;
+ }
+ }
+ }
+
+Some of the examples for L</setscanline()> for more examples.
+
+=item getsamples()
+
+Read specified channels from all or part of a horizontal line of
+pixels from an image.
+
+The parameters you can pass are:
+
+=over
+
+=item *
+
+C<y> - vertical position of the scan line. This parameter is required.
+
+=item *
+
+C<x> - position to start on the scan line. Default: 0
+
+=item *
+
+C<width> - number of pixels to read. Default: C<< $img->getwidth - x >>
+
+=item *
+
+C<type> - the type of sample data to return. Default: C<8bit>.
+
+Permitted values are C<8bit> and C<float>.
+
+As of Imager 0.61 this can be C<16bit> only for 16 bit images.
+
+=item *
+
+C<channels> - a reference to an array of channels to return, where 0
+is the first channel. Default: C<< [ 0 .. $self->getchannels()-1 ] >>
+
+=item *
+
+C<target> - if an array reference is supplied in target then the samples
+will be stored here instead of being returned.
+
+=item *
+
+C<offset> - the offset within the array referenced by I<target>
+
+=back
+
+In list context this will return a list of integers between 0 and 255
+inclusive when I<type> is C<8bit>, or a list of floating point numbers
+between 0.0 and 1.0 inclusive when I<type> is C<float>.
+
+In scalar context this will return a string of packed bytes, as with
+C< pack("C*", ...) > when I<type> is C<8bit> or a string of packed
+doubles as with C< pack("d*", ...) > when I<type> is C<float>.
+
+If the I<target> option is supplied then only a count of samples is
+returned.
+
+Example: Check if any pixels in an image have a non-zero alpha
+channel:
+
+ my $has_coverage;
+ for my $y (0 .. $img->getheight()-1) {
+ my $alpha = $img->getsamples(y=>$y, channels=>[0]);
+ if ($alpha =~ /[^\0]/) {
+ ++$has_coverage;
+ last;
+ }
+ }
+
+Example: Convert a 2 channel gray image into a 4 channel RGBA image:
+
+ # this could be done with convert() instead
+ my $out = Imager->new(xsize => $src->getwidth(),
+ ysize => $src->getheight(),
+ channels => 4);
+ for my $y ( 0 .. $src->getheight()-1 ) {
+ my $data = $src->getsamples(y=>$y, channels=>[ 0, 0, 0, 1 ]);
+ $out->setscanline(y=>$y, pixels=>$data);
+ }
+
+Retrieve 16-bit samples:
+
+ if ($img->bits == 16) {
+ my @samples;
+ $img->getsamples(x => 0, y => $y, target => \@samples, type => '16bit');
+ }
+
+=item setsamples()
+
+This allows writing of samples back to some images. Currently this is
+only supported for 16-bit/sample images.
+
+Parameters:
+
+=over
+
+=item *
+
+C<y> - vertical position of the scan line. This parameter is required.
+
+=item *
+
+C<x> - position to start on the scan line. Default: 0
+
+=item *
+
+C<width> - number of pixels to write. Default: C<< $img->getwidth - x >>.
+The minimum of this and the number of pixels represented by the
+samples provided will be written.
+
+=item *
+
+C<type> - the type of sample data to write. This parameter is required.
+
+This can be C<8bit>, C<float> or for 16-bit images only, C<16bit>.
+
+=item *
+
+C<channels> - a reference to an array of channels to return, where 0 is
+the first channel. Default: C<< [ 0 .. $self->getchannels()-1 ] >>
+
+=item *
+
+C<data> - for a type of C<8bit> or C<float> this can be a reference to
+an array of samples or a scalar containing packed samples. If C<data>
+is a scalar it may only contain characters from \x00 to \xFF.
+
+For a type of C<16bit> this can only be a reference to an array of
+samples to write.
+
+Required.
+
+=item *
+
+C<offset> - the starting offset within the array referenced by
+I<data>. If C<data> is a scalar containing packed samples this offset
+is in samples.
+
+=back
+
+Returns the number of samples written.
+
+ $targ->setsamples(y => $y, data => \@data);
+
+ $targ->setsamples(y => $y, data => \@data, offset => $src->getchannels);
+
+Copy from one image to another:
+
+ my $targ = Imager->new(xsize => $src->getwidth,
+ ysize => $src->getheight, channels => $src->getchannels);
+ for my $y (0 .. $targ->getheight()-1) {
+ my $row = $src->getsamples(y => $y)
+ or die $src->errstr;
+ $targ->setsamples(y => $y, data => $row)
+ or die $targ->errstr;;
+ }
+
+Compose an image from separate source channels:
+
+ my @src = ...; # images to work from, up to 4
+ my $targ = Imager->new(xsize => $src[0]->getwidth,
+ ysize => $src[0]->getheight, channels => scalar(@src));
+ for my $y (0 .. $targ->getheight()-1) {
+ for my $ch (0 .. $#src) {
+ my $row = $src[$ch]->getsamples(y => $y, channels => [ 0 ]);
+ $targ->setsamples(y => $y, data => $row, channels => [ $ch ] );
+ }
+ }
+
+=back
+
+=head1 Packed Color Data
+
+The getscanline() and setscanline() methods can work with pixels
+packed into scalars. This is useful to remove the cost of creating
+color objects, but should only be used when performance is an issue.
+
+The getsamples() and setsamples() methods can work with samples packed
+into scalars.
+
+Packed data can either be 1 byte per sample or 1 double per sample.
+
+Each pixel returned by getscanline() or supplied to setscanline()
+contains 4 samples, even if the image has fewer then 4 channels. The
+values of the extra samples as returned by getscanline() is not
+specified. The extra samples passed to setscanline() are ignored.
+
+To produce packed 1 byte/sample pixels, use the pack C<C> template:
+
+ my $packed_8bit_pixel = pack("CCCC", $red, $blue, $green, $alpha);
+
+To produce packed double/sample pixels, use the pack C<d> template:
+
+ my $packed_float_pixel = pack("dddd", $red, $blue, $green, $alpha);
+
+If you use a I<type> parameter of C<index> then the values are palette
+color indexes, not sample values:
+
+ my $im = Imager->new(xsize => 100, ysize => 100, type => 'paletted');
+ my $black_index = $im->addcolors(colors => [ 'black' ]);
+ my $red_index = $im->addcolors(colors => [ 'red' ]);
+ # 2 pixels
+ my $packed_index_data = pack("C*", $black_index, $red_index);
+ $im->setscanline(y => $y, pixels => $packed_index_data, type => 'index');
+
+=head1 Combine Types
+
+Some methods accept a C<combine> parameter, this can be any of the
+following:
+
+=over
+
+=item C<none>
+
+The fill pixel replaces the target pixel.
+
+=item C<normal>
+
+The fill pixels alpha value is used to combine it with the target pixel.
+
+=item C<multiply>
+
+=item C<mult>
+
+Each channel of fill and target is multiplied, and the result is
+combined using the alpha channel of the fill pixel.
+
+=item C<dissolve>
+
+If the alpha of the fill pixel is greater than a random number, the
+fill pixel is alpha combined with the target pixel.
+
+=item C<add>
+
+The channels of the fill and target are added together, clamped to the range of the samples and alpha combined with the target.
+
+=item C<subtract>
+
+The channels of the fill are subtracted from the target, clamped to be
+>= 0, and alpha combined with the target.
+
+=item C<diff>
+
+The channels of the fill are subtracted from the target and the
+absolute value taken this is alpha combined with the target.
+
+=item C<lighten>
+
+The higher value is taken from each channel of the fill and target
+pixels, which is then alpha combined with the target.
+
+=item C<darken>
+
+The higher value is taken from each channel of the fill and target
+pixels, which is then alpha combined with the target.
+
+=item C<hue>
+
+The combination of the saturation and value of the target is combined
+with the hue of the fill pixel, and is then alpha combined with the
+target.
+
+=item C<sat>
+
+The combination of the hue and value of the target is combined
+with the saturation of the fill pixel, and is then alpha combined with the
+target.
+
+=item C<value>
+
+The combination of the hue and value of the target is combined
+with the value of the fill pixel, and is then alpha combined with the
+target.
+
+=item C<color>
+
+The combination of the value of the target is combined with the hue
+and saturation of the fill pixel, and is then alpha combined with the
+target.
+
+=back
+
+=over
+
+=item combines()
+
+Returns a list of possible combine types.
+
+=back
+
+=head1 BUGS
+
+box() does not support anti-aliasing yet. Default color is not
+unified yet.
+
+=head1 AUTHOR
+
+Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson.
+
+=head1 SEE ALSO
+
+L<Imager>(3), L<Imager::Cookbook>(3)
+
+=head1 REVISION
+
+$Revision$
+
+=cut