added POD to trans2.c
authorTony Cook <tony@develop=help.com>
Sun, 21 Oct 2001 12:20:25 +0000 (12:20 +0000)
committerTony Cook <tony@develop=help.com>
Sun, 21 Oct 2001 12:20:25 +0000 (12:20 +0000)
added i_error handling to transform2
clean up the perl side of transform2
tests for same

Changes
Imager.pm
t/t58trans2.t
trans2.c

diff --git a/Changes b/Changes
index 69abf5bf39dc7417509aa8cebf9996444406ef07..c5af246ad9099ba23fec3c26f2bb1a3558c06505 100644 (file)
--- a/Changes
+++ b/Changes
@@ -524,6 +524,8 @@ Revision history for Perl extension Imager.
         - Added i_bumpmap_complex to do more accurate bumpmapping
         - added an image type with doubles as samples
         - change i_copy() and i_sametype() to handle double/sample images
+        - added basic POD to trans2.c
+        - transform2 now uses the error interface
 
 =================================================================
 
index 8f7a12f4563a7e48939f9427001b7baec45d3100..abcc89d9953ede803b380705797dd9e7a6b1ad85 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -1496,65 +1496,57 @@ sub transform {
 }
 
 
-{
-  my $got_expr;
-  sub transform2 {
-    my ($opts, @imgs) = @_;
-
-    if (!$got_expr) {
-      # this is fairly big, delay loading it
-      eval "use Imager::Expr";
-      die $@ if $@;
-      ++$got_expr;
-    }
-
-    $opts->{variables} = [ qw(x y) ];
-    my ($width, $height) = @{$opts}{qw(width height)};
-    if (@imgs) {
-       $width ||= $imgs[0]->getwidth();
-       $height ||= $imgs[0]->getheight();
-       my $img_num = 1;
-       for my $img (@imgs) {
-           $opts->{constants}{"w$img_num"} = $img->getwidth();
-           $opts->{constants}{"h$img_num"} = $img->getheight();
-           $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
-           $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
-           ++$img_num;
-       }
-    }
-    if ($width) {
-      $opts->{constants}{w} = $width;
-      $opts->{constants}{cx} = $width/2;
-    }
-    else {
-      $Imager::ERRSTR = "No width supplied";
-      return;
-    }
-    if ($height) {
-      $opts->{constants}{h} = $height;
-      $opts->{constants}{cy} = $height/2;
-    }
-    else {
-      $Imager::ERRSTR = "No height supplied";
-      return;
-    }
-    my $code = Imager::Expr->new($opts);
-    if (!$code) {
-      $Imager::ERRSTR = Imager::Expr::error();
-      return;
-    }
-
-    my $img = Imager->new();
-    $img->{IMG} = i_transform2($opts->{width}, $opts->{height}, $code->code(),
-                              $code->nregs(), $code->cregs(),
-                              [ map { $_->{IMG} } @imgs ]);
-    if (!defined $img->{IMG}) {
-      $Imager::ERRSTR = "transform2 failed";
-      return;
-    }
-
-    return $img;
+sub transform2 {
+  my ($opts, @imgs) = @_;
+  
+  require "Imager/Expr.pm";
+
+  $opts->{variables} = [ qw(x y) ];
+  my ($width, $height) = @{$opts}{qw(width height)};
+  if (@imgs) {
+    $width ||= $imgs[0]->getwidth();
+    $height ||= $imgs[0]->getheight();
+    my $img_num = 1;
+    for my $img (@imgs) {
+      $opts->{constants}{"w$img_num"} = $img->getwidth();
+      $opts->{constants}{"h$img_num"} = $img->getheight();
+      $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
+      $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
+      ++$img_num;
+    }
+  }
+  if ($width) {
+    $opts->{constants}{w} = $width;
+    $opts->{constants}{cx} = $width/2;
+  }
+  else {
+    $Imager::ERRSTR = "No width supplied";
+    return;
+  }
+  if ($height) {
+    $opts->{constants}{h} = $height;
+    $opts->{constants}{cy} = $height/2;
+  }
+  else {
+    $Imager::ERRSTR = "No height supplied";
+    return;
+  }
+  my $code = Imager::Expr->new($opts);
+  if (!$code) {
+    $Imager::ERRSTR = Imager::Expr::error();
+    return;
   }
+  
+  my $img = Imager->new();
+  $img->{IMG} = i_transform2($opts->{width}, $opts->{height}, $code->code(),
+                             $code->nregs(), $code->cregs(),
+                             [ map { $_->{IMG} } @imgs ]);
+  if (!defined $img->{IMG}) {
+    $Imager::ERRSTR = Imager->_error_as_msg();
+    return;
+  }
+  
+  return $img;
 }
 
 sub rubthrough {
index 2f027af660fc5dd14aee72e1c18a615c71f3a79d..70309281b608bc7db806a24cf37b27a135d19018 100644 (file)
@@ -1,7 +1,9 @@
-BEGIN { $| = 1; print "1..10\n"; }
+BEGIN { $| = 1; print "1..12\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Imager;
 
+sub ok($$$);
+
 $loaded = 1;
 print "ok 1\n";
 
@@ -19,14 +21,14 @@ $im2->open(file=>'testimg/scale.ppm',type=>'pnm')
 # error handling
 my $opts = { rpnexpr=>'x x 10 / sin 10 * y + get1' };
 my $im3 = Imager::transform2($opts);
-print $im3 ? "not ok 2\n" : "ok 2\n";
-print defined($Imager::ERRSTR) ? "ok 3\n" : "not ok 3\n";
+ok(2, !$im3, "returned an image on error");
+ok(3, defined($Imager::ERRSTR), "No error message on failure");
 
 # image synthesis
 my $im4 = Imager::transform2({
        width=>300, height=>300,
        rpnexpr=>'x y cx cy distance !d y cy - x cx - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a2 cy * 3.1416 / 1 @a2 sin 1 + 2 / hsv'});
-print $im4 ? "ok 4\n" : "not ok 4\n";
+ok(4, $im4, "synthesis failed");
 
 if ($im4) {
   $im4->write(type=>'pnm', file=>'testout/t56a.ppm')
@@ -37,7 +39,7 @@ if ($im4) {
 my $im5 = Imager::transform2({
        rpnexpr=>'x x 10 / sin 10 * y + getp1'
 }, $im1);
-print $im5 ? "ok 5\n" : "not ok 5\n";
+ok(5, $im5, "image distortion");
 if ($im5) {
   $im5->write(type=>'pnm', file=>'testout/t56b.ppm')
     || die "Cannot write testout/t56b.ppm";
@@ -48,7 +50,7 @@ $opts = {
 rpnexpr=>'x h / !rat x w2 % y h2 % getp2 !pat x y getp1 @rat * @pat 1 @rat - * +'
 };
 my $im6 = Imager::transform2($opts,$im1,$im2);
-print $im6 ? "ok 6\n" : "not ok 6 # $opts->{error}\n";
+ok(6, $im6, "image combination");
 if ($im6) {
   $im6->write(type=>'pnm', file=>'testout/t56c.ppm')
     || die "Cannot write testout/t56c.ppm";
@@ -70,3 +72,22 @@ my @inputs = Imager::Transform->new($needsinputs[0])->inputs;
 $inputs[0]{desc} or print "not ";
 print "ok 10\n";
 # at some point I might want to test the actual transformations
+
+# check lower level error handling
+my $im7 = Imager::transform2({rpnexpr=>'x y getp2', width=>100, height=>100});
+ok(11, !$im7, "expected failure on accessing invalid image");
+print "# ", Imager->errstr, "\n";
+ok(12, Imager->errstr =~ /not enough images/, "didn't get expected error");
+
+sub ok ($$$) {
+  my ($num, $test, $desc) = @_;
+
+  if ($test) {
+    print "ok $num\n";
+  }
+  else {
+    print "not ok $num # $desc\n";
+  }
+  $test;
+}
+
index ad0b9ea79a5a31c5c130935866b64bb96f693554..810c436b0476927ad13aa8a5caaf36094d982e14 100644 (file)
--- a/trans2.c
+++ b/trans2.c
@@ -1,7 +1,33 @@
 #include "image.h"
 #include "regmach.h"
 
-/* foo test */
+/*
+=head1 NAME
+
+trans2.c - entry point for the general transformation engine
+
+=head1 SYNOPSIS
+
+  int width, height, channels;
+  struct rm_ops *ops;
+  int op_count;
+  double *n_regs;
+  int n_regs_count;
+  i_color *c_regs;
+  int c_regs_count;
+  i_img **in_imgs;
+  int in_imgs_count;
+  i_img *result = transform2(width, height, channels, ops, ops_count,
+                             n_regs, n_regs_count, c_regs, c_regs_count,
+                             in_imgs, in_imgs_count);
+
+=head1 DESCRIPTION
+
+This (short) file implements the transform2() function, just iterating 
+over the image - most of the work is done in L<regmach.c>
+
+=cut
+*/
 
 i_img* i_transform2(int width, int height, int channels,
                    struct rm_op *ops, int ops_count, 
@@ -13,21 +39,30 @@ i_img* i_transform2(int width, int height, int channels,
   int x, y;
   i_color val;
   int i;
+  int need_images;
+
+  i_clear_error();
   
   /* since the number of images is variable and the image numbers
      for getp? are fixed, we can check them here instead of in the 
      register machine - this will help performance */
+  need_images = 0;
   for (i = 0; i < ops_count; ++i) {
     switch (ops[i].code) {
     case rbc_getp1:
     case rbc_getp2:
     case rbc_getp3:
-      if (ops[i].code - rbc_getp1 + 1 > in_imgs_count) {
-       /* Foo */
-       return NULL;
+      if (ops[i].code - rbc_getp1 + 1 > need_images) {
+        need_images = ops[i].code - rbc_getp1 + 1;
       }
     }
   }
+  
+  if (need_images > in_imgs_count) {
+    i_push_errorf(0, "not enough images, code requires %d, %d supplied", 
+                  need_images, in_imgs_count);
+    return NULL;
+  }
 
   new_img = i_img_empty_ch(NULL, width, height, channels);
   for (x = 0; x < width; ++x) {
@@ -42,3 +77,15 @@ i_img* i_transform2(int width, int height, int channels,
   
   return new_img;
 }
+
+/*
+=head1 AUTHOR
+
+Tony Cook <tony@develop-help.com>
+
+=head1 SEE ALSO
+
+Imager(3), regmach.c
+
+=cut
+*/