Index: trunk/PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm
===================================================================
--- trunk/PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm	(revision 25077)
+++ trunk/PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm	(revision 25107)
@@ -36,4 +36,5 @@
     my $id       = shift;   # required unless req_type eq bycoord
     my $component= shift;   # class_id or skycell_id
+    my $inverse  = shift;
     my $x        = shift;
     my $y        = shift;
@@ -43,7 +44,9 @@
     my $verbose  = shift;
 
+
     # we die in response to bad data in request files
     die "Unknown req_type: $req_type" if ($req_type ne "byid") and ($req_type ne "byexp")
                                         and ($req_type ne "bycoord") and ($req_type ne "bydiff");
+
     if (($req_type eq "byid") and ($img_type eq "diff")) {
         # lookups of all of the information for diff images requires a two level lookup to
@@ -51,27 +54,27 @@
         # in one place
         $req_type = "bydiff";
-    }
+        my $results = lookup_diff($ipprc, $image_db, $id, $component, 1, $inverse, $img_type, $verbose);
+        return $results;
+    }
+
     if ($req_type eq "bydiff") {
-        my $results = lookup_bydiff($ipprc, $image_db, $id, $img_type, $verbose);
+        my $results = lookup_diff($ipprc, $image_db, $id, $component, 0, $inverse, $img_type, $verbose);
         if (!$results) {
             return undef;
         }
         if (($img_type eq "warp") or ($img_type eq "diff")) {
-            # lookup_bydiff has done all of the work
-            return [$results];
-        } elsif (($img_type eq "raw") or ($img_type eq "chip")) {
+            # lookup_diff has done all of the work
+            return $results;
+        } 
+
+        my $image = $results->[0];
+        if (($img_type eq "raw") or ($img_type eq "chip")) {
             $req_type = "byexp";
-            $id = $results->{exp_name};
+            $id = $image->{exp_name};
             return undef if !$id;
             # fall through and lookup byexp
-#        } elsif ($img_type eq "warp") {
-#            $req_type = "byid";
-#            $id = $results->{warp_id};
-#            $component = $results->{skycell_id};
-#            return undef if !$id;
-#            # fall through and lookup by warp_id 
         } elsif ($img_type eq "stack") {
             $req_type = "byid";
-            $id = $results->{stack_id};
+            $id = $image->{stack_id};
             return undef if !$id;
             # fall though and lookup by stack id
@@ -254,8 +257,11 @@
     return $output;
 }
-sub lookup_bydiff {
+sub lookup_diff {
     my $ipprc    = shift;
     my $image_db = shift;
     my $id       = shift;
+    my $skycell_id = shift;
+    my $byid     = shift;
+    my $inverse  = shift;
     my $img_type = shift;
     my $verbose = shift;
@@ -268,5 +274,12 @@
     }
 
-    my $command = "$difftool -diffskyfile -diff_image_id $id -dbname $image_db";
+    my $command = "$difftool -diffskyfile -dbname $image_db";
+    
+    if ($byid) {
+        $command .= " -diff_id $id";
+    } else {
+        $command .= " -diff_skyfile_id $id";
+    }
+    $command .= " -skycell_id $skycell_id" if $skycell_id;
 
     # run the tool and parse the output
@@ -289,5 +302,5 @@
 
     my $n = @$images;
-    if ($n > 1) {
+    if (!$byid && ($n > 1)) {
         die ("difftool returned an unexpected number of diffskyfiles: $n");
     } elsif ($n == 0) {
@@ -295,78 +308,94 @@
     }
 
-    my $image = $images->[0];
-
-    my $skycell_id = $image->{skycell_id};
-
-    if ($image->{fault}) {
-        print STDERR "selected difference image $id $image->{diff_id} $skycell_id has fault: $image->{fault}\n";
-        return undef;
-    }
-
-    # The standard way to do a diff is warp - stack 
-    # so we interpret the requested image in that way
-
-    my $stack_id = $image->{stack2};
-    # XXX difftool currently returns max long long for null
-    # this line is ready if we switch the code to return zero for null
-    if ($stack_id and ($stack_id != 9223372036854775807)) {
-        $image->{stack_id} = $stack_id;
-    }
-
-    my $warp_id =  $image->{warp1};
-    # XXX difftool currently returns max long long for null
-    # this line is ready if we switch the code to return zero for null
-    if ($warp_id and ($warp_id != 9223372036854775807)) {
-        $image->{warp_id} = $warp_id;
-
-        ## now use the warp and go get the exposure information
-        $command = "warptool -warped -warp_id $warp_id -skycell_id $skycell_id -dbname $image_db -limit 1";
-        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                    run(command => $command, verbose => $verbose);
-        unless ($success) {
-            # not sure if we should die here
-            print STDERR @$stderr_buf;
-            return undef;
-        }
-
-        my $buf = join "", @$stdout_buf;
-        if (!$buf) {
-            return undef;
-        }
-
-        my $mdcParser = PS::IPP::Metadata::Config->new;
-        my $warps = parse_md_fast($mdcParser, $buf)
-            or die ("Unable to parse metadata config doc");
-        my $warp = $warps->[0];
-
-        if ($img_type eq "warp") {
-            $image = $warp;
+    my @results;
+    foreach my $image (@$images) {
+        my $skycell_id = $image->{skycell_id};
+
+        if ($image->{fault}) {
+            print STDERR "selected difference image $id $image->{diff_id} $skycell_id has fault: $image->{fault}\n";
+            next;
+        }
+
+        # The standard way to do a diff is warp - stack 
+        # so we interpret the requested image in that way
+
+        my $stack_id = $image->{stack2};
+        # XXX difftool currently returns max long long for null
+        # this line is ready if we switch the code to return zero for null
+        if ($stack_id and ($stack_id != 9223372036854775807)) {
+            $image->{stack_id} = $stack_id;
+        }
+
+        my $warp_id;
+        if ($inverse and !$image->{bothways}) {
+            print STDERR "inverse image requested for diffRun that is not bothways ignoring\n";
+            $inverse = 0;
+        }
+        if ($inverse) {
+            $warp_id =  $image->{warp2};
         } else {
-            $image->{exp_id} = $warp->{exp_id};
-            $image->{exp_name} = $warp->{exp_name};
-            $image->{camera} = $warp->{camera};
-        }
-    }
-
-    if (($img_type eq "diff") or ($img_type eq "warp")) {
-        # the $image is going to be returned directly in this case so we need to duplicate
-        # some of processing that lookup does for other img_types
-        $image->{image} = $image->{uri};
-        if ($image->{camera}) {
-            $ipprc->define_camera($image->{camera});
-            if ($img_type eq "diff") {
-                $image->{mask}   = $ipprc->filename("PPSUB.OUTPUT.MASK", $image->{path_base});
-                $image->{weight} = $ipprc->filename("PPSUB.OUTPUT.VARIANCE", $image->{path_base});
+            $warp_id =  $image->{warp1};
+        }
+        # XXX difftool currently returns max long long for null
+        # this line is ready if we switch the code to return zero for null
+        if ($warp_id and ($warp_id != 9223372036854775807)) {
+            $image->{warp_id} = $warp_id;
+
+            ## now use the warp and go get the exposure information
+            $command = "warptool -warped -warp_id $warp_id -skycell_id $skycell_id -dbname $image_db -limit 1";
+            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                        run(command => $command, verbose => $verbose);
+            unless ($success) {
+                # XXX: I'm not sure if we should die here
+                print STDERR @$stderr_buf;
+                return undef;
+            }
+
+            my $buf = join "", @$stdout_buf;
+            if (!$buf) {
+                next;
+            }
+
+            my $mdcParser = PS::IPP::Metadata::Config->new;
+            my $warps = parse_md_fast($mdcParser, $buf)
+                or die ("Unable to parse metadata config doc");
+            my $warp = $warps->[0];
+
+            if ($img_type eq "warp") {
+                $image = $warp;
             } else {
-                $image->{mask}   = $ipprc->filename("PSWARP.OUTPUT.MASK",   $image->{path_base});
-                $image->{weight} = $ipprc->filename("PSWARP.OUTPUT.VARIANCE", $image->{path_base});
+                $image->{exp_id} = $warp->{exp_id};
+                $image->{exp_name} = $warp->{exp_name};
+                $image->{camera} = $warp->{camera};
             }
         } else {
-            # XXX this will only happen if the minuend is not a warp
-            print STDERR "WARNING: cannot resolve camera so cannot get weight and mask images\n";
-        }
-    }
-
-    return $image;
+            print STDERR "unexpected result warp_id not defined\n";
+            next;
+        }
+
+        if (($img_type eq "diff") or ($img_type eq "warp")) {
+            # the $image is going to be returned directly in this case so we need to duplicate
+            # some of processing that lookup does for other img_types
+            if ($image->{camera}) {
+                $ipprc->define_camera($image->{camera});
+                if ($img_type eq "diff") {
+                    my $filerule_base = $inverse ? "PPSUB.INVERSE" : "PPSUB.OUTPUT";
+                    $image->{image}  = $ipprc->filename($filerule_base, $image->{path_base});
+                    $image->{mask}   = $ipprc->filename($filerule_base . ".MASK", $image->{path_base});
+                    $image->{weight} = $ipprc->filename($filerule_base . ".VARIANCE", $image->{path_base});
+                } else {
+                    $image->{image}  = $ipprc->filename("PSWARP.OUTPUT",   $image->{path_base});
+                    $image->{mask}   = $ipprc->filename("PSWARP.OUTPUT.MASK",   $image->{path_base});
+                    $image->{weight} = $ipprc->filename("PSWARP.OUTPUT.VARIANCE", $image->{path_base});
+                }
+            } else {
+                # XXX this will only happen if the minuend is not a warp
+                print STDERR "WARNING: cannot resolve camera so cannot get weight and mask images\n";
+                next;
+            }
+        }
+        push @results, $image;
+    }
+    return \@results;
 }
 
Index: trunk/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm
===================================================================
--- trunk/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm	(revision 25077)
+++ trunk/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm	(revision 25107)
@@ -22,4 +22,5 @@
                     $PSTAMP_SELECT_MASK
                     $PSTAMP_SELECT_WEIGHT
+                    $PSTAMP_SELECT_INVERSE
                     $PSTAMP_SUCCESS
                     $PSTAMP_SYSTEM_ERROR
@@ -46,4 +47,6 @@
 our $PSTAMP_SELECT_WEIGHT    = 4;
 
+our $PSTAMP_SELECT_INVERSE   = 1024;
+
 # job and result codes
 # NOTE: these must match the values in pstamp/src/pstamp.h
@@ -51,5 +54,5 @@
 our $PSTAMP_SYSTEM_ERROR     = 10;
 our $PSTAMP_NOT_IMPLEMENTED  = 11;
-our $PSTAMP_UNKNOWN_ERROR   = 12;
+our $PSTAMP_UNKNOWN_ERROR    = 12;
 
 our $PSTAMP_DUP_REQUEST      = 20;
