Index: /trunk/pswarp/src/pswarp.c
===================================================================
--- /trunk/pswarp/src/pswarp.c	(revision 10951)
+++ /trunk/pswarp/src/pswarp.c	(revision 10952)
@@ -7,5 +7,5 @@
     fprintf (stderr, "    [-mask mask.fits] : provide a corresponding mask image\n");
     fprintf (stderr, "    [-weight weight.fits] : provide a corresponding weight image (pixel varience)\n");
-    psErrorStackPrint(stderr, "");
+    psErrorStackPrint(stderr, "\n");
     exit (2);
 }
Index: /trunk/pswarp/src/pswarp.h
===================================================================
--- /trunk/pswarp/src/pswarp.h	(revision 10951)
+++ /trunk/pswarp/src/pswarp.h	(revision 10952)
@@ -13,2 +13,8 @@
 # define PSWARP_RECIPE "PSWARP" // Name of the recipe to use
 
+pmConfig *pswarpArguments (int argc, char **argv);
+bool pswarpParseCamera (pmConfig *config);
+bool pswarpDefine (pmConfig *config);
+bool pswarpDataLoad (pmConfig *config);
+bool pswarpDataSave (pmConfig *config);
+void pswarpCleanup (pmConfig *config);
Index: /trunk/pswarp/src/pswarpCleanup.c
===================================================================
--- /trunk/pswarp/src/pswarpCleanup.c	(revision 10951)
+++ /trunk/pswarp/src/pswarpCleanup.c	(revision 10952)
@@ -3,5 +3,4 @@
 void pswarpCleanup (pmConfig *config) {
 
-    psFree (refs);
     psFree (config);
 
Index: /trunk/pswarp/src/pswarpDataLoad.c
===================================================================
--- /trunk/pswarp/src/pswarpDataLoad.c	(revision 10951)
+++ /trunk/pswarp/src/pswarpDataLoad.c	(revision 10952)
@@ -17,4 +17,15 @@
     if (!input) {
 	psError(PSWARP_ERR_CONFIG, true, "Can't find input data!\n");
+	return false;
+    }
+
+    // select the output readout
+    pmFPAview *outView = pmFPAviewAlloc (0);
+    outView->chip = 0;
+    outView->cell = 0;
+    outView->readout = 0;
+    pmReadout  *output = pmFPAfileThisReadout (config->files, outView, "PSWARP.OUTPUT");
+    if (!output) {
+	psError(PSWARP_ERR_CONFIG, true, "Can't find output data!\n");
 	return false;
     }
@@ -45,5 +56,5 @@
 		if (! readout->data_exists) { continue; }
 
-		pswarpConvertReadout (readout, config);
+		pswarpConvertReadout (output, readout, config);
 
 		pmFPAfileIOChecks (config, view, PM_FPA_AFTER);
Index: /trunk/pswarp/src/pswarpDefine.c
===================================================================
--- /trunk/pswarp/src/pswarpDefine.c	(revision 10951)
+++ /trunk/pswarp/src/pswarpDefine.c	(revision 10952)
@@ -30,5 +30,5 @@
     }
 
-    pmFPAfileCreate (output, view, config);
+    pmFPAfileCreate (output, view);
 
     psFree (view);
Index: /trunk/pswarp/src/pswarpParseCamera.c
===================================================================
--- /trunk/pswarp/src/pswarpParseCamera.c	(revision 10951)
+++ /trunk/pswarp/src/pswarpParseCamera.c	(revision 10952)
@@ -11,7 +11,4 @@
 	return false;
     }
-
-    // select recipe options supplied on command line
-    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSWARP_RECIPE);
 
     // the input skycell is a required argument: it defines the output image
Index: /trunk/pswarp/src/pswarpTransformReadout.c
===================================================================
--- /trunk/pswarp/src/pswarpTransformReadout.c	(revision 10952)
+++ /trunk/pswarp/src/pswarpTransformReadout.c	(revision 10952)
@@ -0,0 +1,77 @@
+# include "pswarp.h"
+
+bool pswarpTransformReadout (pmReadout *output, pmReadout *input, pmConfig *config) {
+
+    // XXX this implementation currently ignores the use of the region 
+    psImage *region = NULL;
+    pmCell *cell = NULL;
+
+    // select the current recipe
+    psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);
+
+    int outNx = output->image->numCols;
+    int outNy = output->image->numRows;
+
+    psPlane *inPix = psPlaneAlloc();	// Coordinates on the input detector
+    psPlane *outPix = psPlaneAlloc();	// Coordinates on the output detector
+
+    psPlane *FP = psPlaneAlloc();	// Coordinates on the focal plane
+    psPlane *TP = psPlaneAlloc();	// Coordinates on the tangent plane
+    psSphere *sky = psSphereAlloc();	// Coordinates on the sky
+
+    cell = input->parent;
+    pmChip *chipInput = cell->parent;
+    pmFPA *fpaInput = chipInput->parent;
+
+    cell = output->parent;
+    pmChip *chipOutput = cell->parent;
+    pmFPA *fpaOutput = chipOutput->parent;
+
+    // Iterate over the output image pixels
+    for (int y = 0; y < outNy; y++) {
+	for (int x = 0; x < outNx; x++) {
+	    // Only transform those pixels requested
+	    if (!region || (region && region->data.U8[y][x])) {
+		// Transform!
+
+		// XXX double check this 1/2 pixel offset
+		outPix->x = (double)x + 0.5;
+		outPix->y = (double)y + 0.5;
+
+		psPlaneTransformApply(FP, chipOutput->toFPA, outPix);
+		psPlaneTransformApply (TP, fpaOutput->toTPA, FP);
+		psDeproject (sky, TP, fpaOutput->toSky);
+		
+		psProject (TP, sky, fpaInput->toSky);
+		psPlaneTransformApply (FP, fpaInput->fromTPA, TP);
+		psPlaneTransformApply (inPix, chipInput->fromFPA, FP);
+
+		// XXX get interpolation method from the recipe
+		outImage->data.F32[y][x] = (psF32)psImagePixelInterpolate(image, inPix->x, inPix->y, mask, 1, NAN, PS_INTERPOLATE_BILINEAR);
+
+# if (0)
+		if (error) {
+		    // Error is actually the variance
+		    outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error,
+											    detector->x,
+											    detector->y,
+											    mask, 1, NAN);
+		}
+# endif
+
+		outImage->data.F32[y][x] = (outImage->data.F32[y][x] - offset) / scale;
+# if (0)
+		if (error) {
+		    outError->data.F32[y][x] = outError->data.F32[y][x] / SQUARE(scale);
+		}
+# endif
+
+	    } // Pixels of interest
+
+	}
+    } // Iterating over output pixels
+
+    return true;
+}
+
+    
