Index: trunk/pswarp/src/pswarpTransformReadout_Opt.c
===================================================================
--- trunk/pswarp/src/pswarpTransformReadout_Opt.c	(revision 12526)
+++ trunk/pswarp/src/pswarpTransformReadout_Opt.c	(revision 12528)
@@ -1,16 +1,42 @@
 # include "pswarp.h"
+psImageInterpolateMode psImageInterpolateModeFromString (char *name);
 
 // NOTE: in this function, the coordinates are transformed from the OUTPUT to the INPUT
 bool pswarpTransformReadout_Opt (pmReadout *output, pmReadout *input, pmConfig *config) {
 
+    bool status;
     int minX, minY, maxX, maxY;
     int gridXo, gridX, gridY, nextGridXo, nextGridX, nextGridY;
     pswarpMap *map = NULL;
+    psImageInterpolateMode interpolationMode = PS_INTERPOLATE_NONE;
 
     // XXX this implementation currently ignores the use of the region 
     psImage *region = NULL;
 
+    psTimerStart ("warp");
+
     // select the current recipe
-    // psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
+    psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
+    if (!recipe) {
+	psError(PSWARP_ERR_CONFIG, true, "Can't find PSWARP recipe!\n");
+	return false;
+    }
+    
+    int nGridX = psMetadataLookupS32 (&status, recipe, "GRID.NX");
+    if (!status) nGridX = 128;
+    int nGridY = psMetadataLookupS32 (&status, recipe, "GRID.NY");
+    if (!status) nGridY = 128;
+
+    char *name = psMetadataLookupStr (&status, recipe, "INTERPOLATION.MODE");
+    if (!name) {
+	interpolationMode = PS_INTERPOLATE_BILINEAR;
+	psLogMsg ("pswarp", 3, "defaulting to bilinear interpolation\n");
+    } else {
+	interpolationMode = psImageInterpolateModeFromString (name);
+	if (interpolationMode == PS_INTERPOLATE_NONE) {
+	    interpolationMode = PS_INTERPOLATE_BILINEAR;
+	    psLogMsg ("pswarp", 3, "unknown interpolation mode %s, defaulting to bilinear interpolation\n", name);
+	}
+    }
 
     psPlane *inPix = psPlaneAlloc();	// Coordinates on the input detector
@@ -33,5 +59,5 @@
     // pswarpMapGridFromImage builds a set of locally-linear maps which convert the
     // output coordinates to input coordinates
-    pswarpMapGrid *grid = pswarpMapGridFromImage (input, output, 128, 128);
+    pswarpMapGrid *grid = pswarpMapGridFromImage (input, output, nGridX, nGridY);
 
     // XXX need to modify the grid based on this result and force the maxError < XXX
@@ -81,9 +107,8 @@
 	    if (inPix->y - inRow0 >= inImage->numRows) continue;
 
-	    // XXX get interpolation method from the recipe
 	    // XXX include mask
 	    // XXX apply scale and offset?
 	    // psImagePixelInterpolate determines the value at pixel coordinate (x,y) in child coordinates 
-	    outData[y-outRow0][x-outCol0] = (psF32)psImagePixelInterpolate(inImage, inPix->x - inCol0, inPix->y - inRow0, NULL, 1, NAN, PS_INTERPOLATE_BILINEAR);
+	    outData[y-outRow0][x-outCol0] = (psF32)psImagePixelInterpolate(inImage, inPix->x - inCol0, inPix->y - inRow0, NULL, 1, NAN, interpolationMode);
 	}
     }
@@ -91,4 +116,6 @@
     psFree (inPix);
     psFree (grid);
+    psLogMsg ("pswarp", 3, "warping analysis: %f sec\n", psTimerMark ("warp"));
+
     return true;
 }
