[rt #79990] don't copy setsamples() data parameter
authorTony Cook <tony@develop-help.com>
Mon, 8 Oct 2012 10:08:06 +0000 (21:08 +1100)
committerTony Cook <tony@develop-help.com>
Mon, 8 Oct 2012 10:08:06 +0000 (21:08 +1100)
since it may be a large scalar.

Imager.pm
t/t01introvert.t

index 1d5a048..79a9e4b 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -3417,18 +3417,35 @@ sub getsamples {
 
 sub setsamples {
   my $self = shift;
-  my %opts = ( x => 0, offset => 0, @_ );
 
   unless ($self->{IMG}) {
     $self->_set_error('setsamples: empty input image');
     return;
   }
 
-  my $data = $opts{data};
-  unless(defined $data) {
+  my %opts = ( x => 0, offset => 0 );
+  my $data_index;
+  # avoid duplicating the data parameter, it may be a large scalar
+  my $i = 0;
+  while ($i < @_ -1) {
+    if ($_[$i] eq 'data') {
+      $data_index = $i+1;
+    }
+    else {
+      $opts{$_[$i]} = $_[$i+1];
+    }
+
+    $i += 2;
+  }
+
+  unless(defined $data_index) {
     $self->_set_error('setsamples: data parameter missing');
     return;
   }
+  unless (defined $_[$data_index]) {
+    $self->_set_error('setsamples: data parameter not defined');
+    return;
+  }
 
   my $type = $opts{type};
   defined $type or $type = '8bit';
@@ -3439,22 +3456,22 @@ sub setsamples {
   my $count;
   if ($type eq '8bit') {
     $count = i_psamp($self->{IMG}, $opts{x}, $opts{y}, $opts{channels},
-                    $data, $opts{offset}, $width);
+                    $_[$data_index], $opts{offset}, $width);
   }
   elsif ($type eq 'float') {
     $count = i_psampf($self->{IMG}, $opts{x}, $opts{y}, $opts{channels},
-                     $data, $opts{offset}, $width);
+                     $_[$data_index], $opts{offset}, $width);
   }
   elsif ($type =~ /^([0-9]+)bit$/) {
     my $bits = $1;
 
-    unless (ref $data) {
+    unless (ref $_[$data_index]) {
       $self->_set_error("setsamples: data must be an array ref for type not 8bit or float");
       return;
     }
 
     $count = i_psamp_bits($self->{IMG}, $opts{x}, $opts{y}, $bits,
-                         $opts{channels}, $data, $opts{offset}, 
+                         $opts{channels}, $_[$data_index], $opts{offset}, 
                          $width);
   }
   else {
index 542791c..9f682ce 100644 (file)
@@ -3,7 +3,7 @@
 # to make sure we get expected values
 
 use strict;
-use Test::More tests => 431;
+use Test::More tests => 433;
 
 BEGIN { use_ok(Imager => qw(:handy :all)) }
 
@@ -848,6 +848,11 @@ my $psamp_outside_error = "Image position outside of image";
   is($im->errstr, "setsamples: data parameter missing",
      "check error message");
 
+  is($im->setsamples(y => 5, data => undef),
+     undef, "setsamples with undef data");
+  is($im->errstr, "setsamples: data parameter not defined",
+     "check error message");
+
   my $imempty = Imager->new;
   is($imempty->setsamples(y => 0, data => [ (0) x 3 ]), undef,
      "setsamples to empty image");