Index: /trunk/ppImage/src/Makefile.am
===================================================================
--- /trunk/ppImage/src/Makefile.am	(revision 6259)
+++ /trunk/ppImage/src/Makefile.am	(revision 6260)
@@ -1,28 +1,44 @@
-bin_PROGRAMS = ppImage
+bin_PROGRAMS = ppImage ppTest
+
+ppTest_CPPFLAGS = $(PSLIB_CFLAGS) $(PSMODULE_CFLAGS) $(ppImage_CFLAGS)
+ppTest_LDADD = $(PSLIB_LIBS) $(PSMODULE_LIBS)
+ppTest_SOURCES = \
+	ppTest.c \
+	ppMem.c
 
 ppImage_CPPFLAGS = $(PSLIB_CFLAGS) $(PSMODULE_CFLAGS) $(ppImage_CFLAGS)
 ppImage_LDADD = $(PSLIB_LIBS) $(PSMODULE_LIBS)
 ppImage_SOURCES = \
-	ppDetrendBias.c \
-	ppDetrendCell.c \
-	ppDetrendMask.c \
-	ppDetrendNonLinear.c \
-	ppDetrendPedestal.c \
+	ppConfig.c \
 	ppFile.c \
+	ppMem.c \
 	ppImage.c \
 	ppImageConfig.c \
+	ppImageData.c \
+	ppImageDetrendBias.c \
+	ppImageDetrendCell.c \
+	ppImageDetrendMask.c \
+	ppImageDetrendNonLinear.c \
 	ppImageLoop.c \
 	ppImageOptions.c \
 	ppImageParseCamera.c \
 	ppImageParseDetrend.c \
-	ppImageWeights.c \
-	ppImageOutput.c \
-	ppImagePhot.c
+	ppImageWeights.c
 #	ppImageLoadPixels.c
 #	ppDetrendFlat.c
 #	ppImageOutput.c
+#	ppImageDetrendPedestal.c
+#	ppImageOutput.c
+#	ppImagePhot.c
+
 
 noinst_HEADERS = \
-	ppImage.h
+	ppConfig.h \
+	ppFile.h \
+	ppMem.h \
+	ppImage.h \
+	ppImageData.h \
+	ppImageDetrend.h \
+	ppImageOptions.h
 
 clean-local:
Index: /trunk/ppImage/src/ppConfig.c
===================================================================
--- /trunk/ppImage/src/ppConfig.c	(revision 6260)
+++ /trunk/ppImage/src/ppConfig.c	(revision 6260)
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include "pslib.h"
+#include "ppConfig.h"
+
+static void configFree(ppConfig *config)
+{
+    psFree(config->site);
+    psFree(config->camera);
+    psFree(config->recipe);
+    psFree(config->arguments);
+    psFree(config->database);
+}
+
+ppConfig *ppConfigAlloc(void)
+{
+    ppConfig *config = psAlloc(sizeof(ppConfig));
+    psMemSetDeallocator(config, (psFreeFunc)configFree);
+
+    config->site = NULL;
+    config->camera = NULL;
+    config->recipe = NULL;
+    config->arguments = NULL;
+    config->database = NULL;
+
+    return config;
+}
+
Index: /trunk/ppImage/src/ppConfig.h
===================================================================
--- /trunk/ppImage/src/ppConfig.h	(revision 6260)
+++ /trunk/ppImage/src/ppConfig.h	(revision 6260)
@@ -0,0 +1,16 @@
+#ifndef PP_CONFIG_H
+#define PP_CONFIG_H
+
+#include "pslib.h"
+
+typedef struct {
+    psMetadata *site;                   // Site configuration
+    psMetadata *camera;                 // Camera specification
+    psMetadata *recipe;                 // Recipe for processing
+    psMetadata *arguments;              // Command-line arguments
+    psDB *database;                     // Database handle
+} ppConfig;
+
+ppConfig *ppConfigAlloc(void);
+
+#endif
Index: /trunk/ppImage/src/ppFile.c
===================================================================
--- /trunk/ppImage/src/ppFile.c	(revision 6259)
+++ /trunk/ppImage/src/ppFile.c	(revision 6260)
@@ -1,6 +1,8 @@
-#include "ppImage.h"
+#include <stdio.h>
+#include "pslib.h"
+#include "ppFile.h"
 
 // Free a ppFile
-static void ppFileFree(ppFile *file)
+static void fileFree(ppFile *file)
 {
     psFree(file->filename);
@@ -17,5 +19,5 @@
 
     ppFile *file = psAlloc(sizeof(ppFile));
-    psMemSetDeallocator(file, (psFreeFunc)ppFileFree);
+    psMemSetDeallocator(file, (psFreeFunc)fileFree);
 
     file->filename = NULL;
Index: /trunk/ppImage/src/ppFile.h
===================================================================
--- /trunk/ppImage/src/ppFile.h	(revision 6260)
+++ /trunk/ppImage/src/ppFile.h	(revision 6260)
@@ -0,0 +1,20 @@
+#ifndef PP_FILE_H
+#define PP_FILE_H
+
+#include "pslib.h"
+#include "pmFPA.h"
+
+// A file to process
+typedef struct {
+    char *filename;                     // File name
+    psFits *fits;                       // The FITS file handle
+    psMetadata *phu;                    // The FITS header
+    pmFPA *fpa;                         // The FPA, with pixels and extensions
+} ppFile;
+
+
+// Allocators
+ppFile *ppFileAlloc(void);
+
+
+#endif
Index: /trunk/ppImage/src/ppImage.c
===================================================================
--- /trunk/ppImage/src/ppImage.c	(revision 6259)
+++ /trunk/ppImage/src/ppImage.c	(revision 6260)
@@ -1,71 +1,42 @@
+#include <stdio.h>
+#include "pslib.h"
 #include "ppImage.h"
-
-psMemId ppMemAlloc(const psMemBlock *ptr)
-{
-    psLogMsg(__func__, PS_LOG_INFO,
-             "Allocated memory block %d: %ld references\n"
-             "\tFile %s, line %d, size %d\n"
-             "\tPosts: %lx %lx %lx\n"
-             "\tLast operation: %s:%d\n",
-             ptr->id, ptr->refCounter, ptr->file, ptr->lineno, ptr->userMemorySize, ptr->startblock,
-             ptr->endblock, *(void**)((int8_t *)(ptr + 1) + ptr->userMemorySize),
-             ptr->lastopFile, ptr->lastopLine);
-    return 0;
-}
-
-psMemId ppMemFree(const psMemBlock *ptr)
-{
-    psLogMsg(__func__, PS_LOG_INFO,
-             "Freed memory block %d: %ld references\n"
-             "\tFile %s, line %d, size %d\n"
-             "\tPosts: %lx %lx %lx\n"
-             "\tLast operation: %s:%d\n",
-             ptr->id, ptr->refCounter-1, ptr->file, ptr->lineno, ptr->userMemorySize, ptr->startblock,
-             ptr->endblock, *(void**)((int8_t *)(ptr + 1) + ptr->userMemorySize),
-             ptr->lastopFile, ptr->lastopLine);
-    return 0;
-}
+#include "ppMem.h"
 
 
 int main(int argc, char **argv)
 {
-#if 0
-    psMemAllocCallbackSet(ppMemAlloc);
-    psMemFreeCallbackSet(ppMemFree);
-//    psMemAllocCallbackSetID(6967);
-//    psMemFreeCallbackSetID(6967);
-    psMemAllocCallbackSetID(51804);
-    psMemFreeCallbackSetID(51804);
-#endif
+//    psErrorRegister(NULL, -1);
 
-    ppData data;
-    ppConfig config;
-    ppOptions options;
+    ppImageData *data = ppImageDataAlloc();
+    ppImageOptions *options = ppImageOptionsAlloc();
+    ppConfig *config = ppConfigAlloc();
 
     psTimerStart(TIMERNAME);
 
     // Parse the configuration and arguments
-    ppImageConfig(&config, argc, argv);
+    ppImageConfig(config, argc, argv);
 
     // Open the input image, output image, output mask
     // Get camera configuration from header if not already defined
     // Construct camera in preparation for reading
-    ppImageParseCamera(&data, &config);
+    ppImageParseCamera(data, config);
+
+    // Cleaning up
+    psFree(data);
+    psFree(options);
+    psFree(config);
+    psTimerStop();
+    ppMemCheck();
+#if 0
 
     // Set various tasks (define optional operations)
-    ppImageOptions(&data, &options, &config);
+    ppImageOptionsParse(data, options, config);
 
     // open detrend images, load headers, optionally load pixels
-    ppImageParseDetrend(&data, &options, &config);
+    ppImageParseDetrend(data, options, config);
 
     // Image Arithmetic Loop
-    ppImageLoop(&data, &options, &config);
-
-#if 0
-    // Output image
-    ppImageOutput(&data, &config);
-
-    // Do photometry
-    ppImagePhot(&data, &options, &config);
+    ppImageLoop(data, options, config);
 #endif
 
Index: /trunk/ppImage/src/ppImage.h
===================================================================
--- /trunk/ppImage/src/ppImage.h	(revision 6259)
+++ /trunk/ppImage/src/ppImage.h	(revision 6260)
@@ -2,11 +2,15 @@
 #define PP_IMAGE_H
 
-#include <stdio.h>
+#include "pslib.h"
+#include "pmFPA.h"
+#include "ppConfig.h"
+#include "ppFile.h"
+#include "ppImageData.h"
+#include "ppImageOptions.h"
+
+
+#if 0
 #include <strings.h>
-
-#include "pslib.h"
-
 #include "psAdditionals.h"
-
 #include "pmFPA.h"
 #include "pmFPAConstruct.h"
@@ -15,107 +19,26 @@
 #include "pmReadout.h"
 #include "pmConfig.h"
-
 #include "pmFlatField.h"
 #include "pmMaskBadPixels.h"
 #include "pmNonLinear.h"
+#include "pmChipMosaic.h"
 #include "pmSubtractBias.h"
-#include "pmChipMosaic.h"
-//#include "pmFPAMorph.h"
-#include "pmSubtractBias.h"
+#endif
+
 
 #define RECIPE "PHASE2"                 // Name of the recipe to use
 #define TIMERNAME "ppImage"             // Name of timer
 
-// How much of the FPA to load at a time
-typedef enum {
-    PP_LOAD_NONE,                       // Don't load anything
-    PP_LOAD_FPA,                        // Load the entire FPA at once
-    PP_LOAD_CHIP,                       // Load by chip
-    PP_LOAD_CELL,                       // Load by cell
-} ppImageLoadDepth;
-
-// Configuration data
-typedef struct {
-    psMetadata *site;                   // The site configuration
-    psMetadata *camera;                 // The camera configuration
-    psMetadata *recipe;                 // The recipe (i.e., specific setups)
-    psMetadata *arguments;              // The command-line arguments
-    psDB       *database;               // Database handle
-} ppConfig;
-
-// Options
-typedef struct {
-    bool doMask;                        // Mask bad pixels
-    bool doBias;                        // Bias subtraction
-    bool doDark;                        // Dark subtraction
-    bool doFlat;                        // Flat-field normalisation
-    bool doFringe;                      // Fringe subtraction
-    bool doSource;                      // Source identification and photometry
-    bool doAstrom;                      // Astrometry
-    bool doOverscan;                    // Overscan subtraction
-    pmOverscanOptions *overscan;        // Overscan options
-    bool doNonLin;                      // Non-linearity correction
-    psDataType nonLinearType;
-    psMetadataItem *nonLinearData;
-    void *nonLinearSource;
-    ppImageLoadDepth imageLoadDepth;    // How much of the FPA to load at once
-} ppOptions;
-
-// A file to process
-typedef struct {
-    char *filename;                     // File name
-    psFits *fits;                       // The FITS file handle
-    psMetadata *phu;                    // The FITS header
-    pmFPA *fpa;                         // The FPA, with pixels and extensions
-} ppFile;
-
-// The data to be processed
-typedef struct {
-    ppFile *input;                      // The input, to be operated upon
-    ppFile *mask;                       // The bad pixel mask image
-    ppFile *bias;                       // The bias correction image
-    ppFile *dark;                       // The dark correction image
-    ppFile *flat;                       // The flat-field correction image
-    ppFile *fringe;                     // The fringe correction image
-    psFits *output;                     // The output file
-#if 0
-    ppFile *process;                    // A dummy file pointing out what needs to be processed
-#endif
-} ppData;
-
-// Cells to be used in the detrend
-typedef struct {
-    pmCell *input;                      // The input cell, to be operated upon
-    pmCell *mask;                       // The bad pixel mask
-    pmCell *bias;                       // The bias correction
-    pmCell *dark;                       // The dark correction
-    pmCell *flat;                       // The flat-field correction
-} ppDetrend;
-
-
-// Allocators
-ppFile *ppFileAlloc(void);
-
-
-
-// Parse the site configuration (and camera and recipe if specified); read the command-line arguments
-bool ppImageConfig(ppConfig *config,   // The configuration(output)
-                   int argc, char **argv // Command-line arguments
-                   );
+// Get the configuration
+bool ppImageConfig(ppConfig *config, int argc, char **argv);
 
 // Determine what type of camera, and initialise
-bool ppImageParseCamera(ppData *data,   // The data to be processed
+bool ppImageParseCamera(ppImageData *data,   // The data to be processed
                         ppConfig *config // Configuration
                         );
 
-// Determine the procession options
-bool ppImageOptions(ppData *data,       // The data to be processed
-                    ppOptions *options, // Processing options
-                    ppConfig *config    // Configuration
-                    );
 
-
-// Loop over the
-bool ppImageLoop(ppData *data, ppOptions *options, ppConfig *config);
+// Loop over the input
+bool ppImageLoop(ppImageData *data, ppImageOptions *options, ppConfig *config);
 
 // Load the pixels for the given file
@@ -126,26 +49,15 @@
                        );
 
-bool ppImageParseDetrend(ppData *data, ppOptions *options, ppConfig *config);
+bool ppImageParseDetrend(ppImageData *data, ppImageOptions *options, ppConfig *config);
 
 bool ppReadoutWeights(pmReadout *readout);
 
-bool ppDetrendCell(ppDetrend *detrend, ppOptions *options, ppConfig *config);
-
-bool ppDetrendMask(pmCell *cell, pmReadout *input, pmReadout *mask);
-bool ppDetrendNonLinear(pmCell *cell, pmReadout *input, ppOptions *options);
-bool ppDetrendNonLinearLookup(pmReadout *input, psMetadataItem *dataItem);
-bool ppDetrendNonLinearPolynomial(pmReadout *input, psMetadataItem *dataItem);
-bool ppDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppOptions *options);
 #if 0
-pmReadout* ppDetrendPedestal(pmReadout *pedestal, pmCell *input, pmReadout *bias, pmReadout *dark, float darkTime, ppOptions *options);
-#endif
-pmReadout* ppDetrendSelectFirst(pmCell *cell, char *name, bool doThis);
-
-#if 0
+// These functions are not implemented, or not needed
+pmReadout* ppDetrendPedestal(pmReadout *pedestal, pmCell *input, pmReadout *bias, pmReadout *dark, float darkTime, ppImageOptions *options);
+bool ppImageOutput(ppImageData *data, ppConfig *config);
+bool ppImagePhot(ppImageData *data, ppImageOptions *options, ppConfig *config);
 bool ppFileOpen(ppFile *fpa, psMetadata *camera, char *name, bool doThis);
 #endif
 
-bool ppImageOutput(ppData *data, ppConfig *config);
-bool ppImagePhot(ppData *data, ppOptions *options, ppConfig *config);
-
 #endif // Pau.
Index: /trunk/ppImage/src/ppImageConfig.c
===================================================================
--- /trunk/ppImage/src/ppImageConfig.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageConfig.c	(revision 6260)
@@ -1,13 +1,10 @@
+#include <stdio.h>
+#include "pslib.h"
+#include "pmConfig.h"
+#include "ppConfig.h"
 #include "ppImage.h"
 
 bool ppImageConfig(ppConfig *config, int argc, char **argv)
 {
-    // Initialise the configuration
-    config->site = NULL;                // Site configuration
-    config->camera = NULL;              // Camera configuration
-    config->recipe = NULL;              // Recipe configuration
-    config->arguments = NULL;           // The command-line arguments
-    config->database = NULL;            // Database handle
-
     // XXX - this should be split into a function to parse argc,argv
     //       and a second to read the config files.
Index: /trunk/ppImage/src/ppImageData.c
===================================================================
--- /trunk/ppImage/src/ppImageData.c	(revision 6260)
+++ /trunk/ppImage/src/ppImageData.c	(revision 6260)
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include "pslib.h"
+#include "ppImageData.h"
+
+static void imageDataFree(ppImageData *data)
+{
+    psFree(data->input);
+    psFree(data->mask);
+    psFree(data->bias);
+    psFree(data->dark);
+    psFree(data->flat);
+    psFree(data->fringe);
+    if (data->output) {
+        psFitsClose(data->output);
+    }
+}
+
+ppImageData *ppImageDataAlloc(void)
+{
+    ppImageData *data = psAlloc(sizeof(ppImageData));
+    psMemSetDeallocator(data, (psFreeFunc)imageDataFree);
+
+    data->input = NULL;
+    data->mask = NULL;
+    data->bias = NULL;
+    data->dark = NULL;
+    data->flat = NULL;
+    data->fringe = NULL;
+    data->output = NULL;
+
+    return data;
+}
Index: /trunk/ppImage/src/ppImageData.h
===================================================================
--- /trunk/ppImage/src/ppImageData.h	(revision 6260)
+++ /trunk/ppImage/src/ppImageData.h	(revision 6260)
@@ -0,0 +1,19 @@
+#ifndef PP_IMAGE_DATA_H
+#define PP_IMAGE_DATA_H
+
+#include "ppFile.h"
+
+// The data to be processed
+typedef struct {
+    ppFile *input;                      // The input, to be operated upon
+    ppFile *mask;                       // The bad pixel mask image
+    ppFile *bias;                       // The bias correction image
+    ppFile *dark;                       // The dark correction image
+    ppFile *flat;                       // The flat-field correction image
+    ppFile *fringe;                     // The fringe correction image
+    psFits *output;                     // The output file
+} ppImageData;
+
+ppImageData *ppImageDataAlloc(void);
+
+#endif
Index: /trunk/ppImage/src/ppImageDetrend.h
===================================================================
--- /trunk/ppImage/src/ppImageDetrend.h	(revision 6260)
+++ /trunk/ppImage/src/ppImageDetrend.h	(revision 6260)
@@ -0,0 +1,28 @@
+#ifndef PP_IMAGE_DETREND_H
+#define PP_IMAGE_DETREND_H
+
+#include "pslib.h"
+#include "pmFPA.h"
+#include "ppConfig.h"
+#include "ppImageOptions.h"
+
+// Cells to be used in the detrend
+typedef struct {
+    pmCell *input;                      // The input cell, to be operated upon
+    pmCell *mask;                       // The bad pixel mask
+    pmCell *bias;                       // The bias correction
+    pmCell *dark;                       // The dark correction
+    pmCell *flat;                       // The flat-field correction
+} ppImageDetrend;
+
+
+bool ppImageDetrendCell(ppImageDetrend *detrend, ppImageOptions *options, ppConfig *config);
+bool ppImageDetrendMask(pmCell *cell, pmReadout *input, pmReadout *mask);
+bool ppImageDetrendNonLinear(pmCell *cell, pmReadout *input, ppImageOptions *options);
+bool ppImageDetrendNonLinearLookup(pmReadout *input, psMetadataItem *dataItem);
+bool ppImageDetrendNonLinearPolynomial(pmReadout *input, psMetadataItem *dataItem);
+bool ppImageDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppImageOptions *options);
+pmReadout* ppImageDetrendSelectFirst(pmCell *cell, char *name, bool doThis);
+
+
+#endif
Index: /trunk/ppImage/src/ppImageDetrendBias.c
===================================================================
--- /trunk/ppImage/src/ppImageDetrendBias.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageDetrendBias.c	(revision 6260)
@@ -1,5 +1,9 @@
-#include "ppImage.h"
+#include <stdio.h>
+#include "pslib.h"
+#include "pmFPA.h"
+#include "ppImageOptions.h"
+#include "ppImageDetrend.h"
 
-bool ppDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppOptions *options)
+bool ppImageDetrendBias(pmReadout *inputReadout, pmReadout *bias, pmReadout *dark, ppImageOptions *options)
 {
     psTrace(__func__, 1, "Commencing bias processing....\n");
Index: /trunk/ppImage/src/ppImageDetrendCell.c
===================================================================
--- /trunk/ppImage/src/ppImageDetrendCell.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageDetrendCell.c	(revision 6260)
@@ -1,8 +1,11 @@
-# include "ppImage.h"
+#include <stdio.h>
+#include "pslib.h"
 #include "pmFPA.h"
+#include "pmFlatField.h"
+#include "ppImageDetrend.h"
 
 // mask, bias, dark, flat are defined per Cell
 
-pmReadout *ppDetrendSelectFirst(pmCell *cell, char *name, bool doThis)
+pmReadout *ppImageDetrendSelectFirst(pmCell *cell, char *name, bool doThis)
 {
     if (!doThis) {
@@ -19,12 +22,12 @@
 }
 
-bool ppDetrendCell(ppDetrend *detrend, ppOptions *options, ppConfig *config)
+bool ppImageDetrendCell(ppImageDetrend *detrend, ppImageOptions *options, ppConfig *config)
 {
     pmCellSetWeights(detrend->input);
 
-    pmReadout *mask = ppDetrendSelectFirst(detrend->mask, "mask", options->doMask);
-    pmReadout *bias = ppDetrendSelectFirst(detrend->bias, "bias", options->doBias);
-    pmReadout *dark = ppDetrendSelectFirst(detrend->dark, "dark", options->doDark);
-    pmReadout *flat = ppDetrendSelectFirst(detrend->flat, "flat", options->doFlat);
+    pmReadout *mask = ppImageDetrendSelectFirst(detrend->mask, "mask", options->doMask);
+    pmReadout *bias = ppImageDetrendSelectFirst(detrend->bias, "bias", options->doBias);
+    pmReadout *dark = ppImageDetrendSelectFirst(detrend->dark, "dark", options->doDark);
+    pmReadout *flat = ppImageDetrendSelectFirst(detrend->flat, "flat", options->doFlat);
 
 #if 0
@@ -39,14 +42,14 @@
         // Mask bad pixels
         if (options->doMask) {
-            ppDetrendMask(detrend->input, input, mask);
+            ppImageDetrendMask(detrend->input, input, mask);
         }
 
         // Non-linearity correction
         if (options->doNonLin) {
-            ppDetrendNonLinear(detrend->input, input, options);
+            ppImageDetrendNonLinear(detrend->input, input, options);
         }
 
         // Bias, dark and overscan subtraction are all merged.
-        ppDetrendBias(input, bias, dark, options);
+        ppImageDetrendBias(input, bias, dark, options);
 
         // Flat-field correction (no options used?)
Index: /trunk/ppImage/src/ppImageDetrendMask.c
===================================================================
--- /trunk/ppImage/src/ppImageDetrendMask.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageDetrendMask.c	(revision 6260)
@@ -1,3 +1,6 @@
-# include "ppImage.h"
+#include <stdio.h>
+#include "pmFPA.h"
+#include "pmMaskBadPixels.h"
+#include "ppImageDetrend.h"
 
 # define MASK_MODE (PM_MASK_TRAP | PM_MASK_BADCOL | PM_MASK_SAT)
@@ -5,5 +8,5 @@
 // XXX pass 'concepts' not 'cell' to this function?
 
-bool ppDetrendMask (pmCell *cell, pmReadout *input, pmReadout *mask) {
+bool ppImageDetrendMask(pmCell *cell, pmReadout *input, pmReadout *mask) {
 
     float saturation = psMetadataLookupF32(NULL, cell->concepts, "CELL.SATURATION");
Index: /trunk/ppImage/src/ppImageDetrendNonLinear.c
===================================================================
--- /trunk/ppImage/src/ppImageDetrendNonLinear.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageDetrendNonLinear.c	(revision 6260)
@@ -1,5 +1,9 @@
-# include "ppImage.h"
+#include <stdio.h>
+#include "pslib.h"
+#include "pmFPA.h"
+#include "pmNonLinear.h"
+#include "ppImageDetrend.h"
 
-bool ppDetrendNonLinearPolynomial (pmReadout *input, psMetadataItem *dataItem) {
+bool ppImageDetrendNonLinearPolynomial(pmReadout *input, psMetadataItem *dataItem) {
 
     // These are the polynomial coefficients
@@ -19,5 +23,5 @@
 }
 
-bool ppDetrendNonLinearLookup (pmReadout *input, psMetadataItem *dataItem) {
+bool ppImageDetrendNonLinearLookup(pmReadout *input, psMetadataItem *dataItem) {
 
     // This is a filename: lookup table
@@ -40,5 +44,5 @@
 }
 
-bool ppDetrendNonLinear (pmCell *cell, pmReadout *input, ppOptions *options) {
+bool ppImageDetrendNonLinear(pmCell *cell, pmReadout *input, ppImageOptions *options) {
 
     psMetadataItem *concept;
@@ -46,9 +50,9 @@
     switch (options->nonLinearType) {
       case PS_DATA_VECTOR:
-        ppDetrendNonLinearPolynomial (input, options->nonLinearData);
+        ppImageDetrendNonLinearPolynomial (input, options->nonLinearData);
         return true;
 
       case PS_DATA_STRING:
-        ppDetrendNonLinearLookup (input, options->nonLinearData);
+        ppImageDetrendNonLinearLookup (input, options->nonLinearData);
         return true;
 
@@ -91,8 +95,8 @@
         switch (optionItem->type) {
           case PS_DATA_VECTOR:
-            ppDetrendNonLinearPolynomial (input, optionItem);
+            ppImageDetrendNonLinearPolynomial (input, optionItem);
             return true;
           case PS_DATA_STRING:
-            ppDetrendNonLinearLookup (input, optionItem);
+            ppImageDetrendNonLinearLookup (input, optionItem);
             return true;
           default:
Index: /trunk/ppImage/src/ppImageLoop.c
===================================================================
--- /trunk/ppImage/src/ppImageLoop.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageLoop.c	(revision 6260)
@@ -1,16 +1,12 @@
-# include "ppImage.h"
+#include <stdio.h>
+#include "pslib.h"
+#include "pmFPA.h"
+#include "pmFPARead.h"
+#include "pmChipMosaic.h"
+#include "pmFPAWrite.h"
+#include "ppImageDetrend.h"
+#include "ppImage.h"
 
 #define MEM_LEAKS 1
-
-psMemId ppMemPrint(const psMemBlock *ptr)
-{
-    psLogMsg(__func__, PS_LOG_INFO,
-             "Memory block %d (%ld):\n"
-             "\tFile %s, line %d, size %d\n"
-             "\tPosts: %lx %lx %lx\n",
-             ptr->id, ptr->refCounter, ptr->file, ptr->lineno, ptr->userMemorySize, ptr->startblock,
-             ptr->endblock, *(void**)((int8_t *)(ptr + 1) + ptr->userMemorySize));
-    return 0;
-}
 
 // Read the entire FPA
@@ -46,7 +42,7 @@
 
 
-bool ppImageLoop(ppData *data, ppOptions *options, ppConfig *config)
+bool ppImageLoop(ppImageData *data, ppImageOptions *options, ppConfig *config)
 {
-    ppDetrend detrend;
+    ppImageDetrend detrend;
 
     int processChip = psMetadataLookupS32(NULL, config->arguments, "-chip"); // Chip number to process or -1
@@ -83,6 +79,4 @@
         pmChip *flatChip  = data->flat->fpa->chips->data[i];
 
-        ppMemPrint((psMemBlock*)inputChip-1);
-
         psArray *cells = inputChip->cells;
         for (int j = 0; j < cells->n; j++) {
@@ -104,5 +98,5 @@
             }
 
-            ppDetrendCell(&detrend, options, config);
+            ppImageDetrendCell(&detrend, options, config);
 
             // Need to free detrend cells here so we have enough memory to do other stuff
@@ -130,5 +124,4 @@
 #ifndef MEM_LEAKS
         pmChipFreeCells(inputChip);
-        ppMemPrint((psMemBlock*)chips->data[i]-1);
 #endif
     }
Index: /trunk/ppImage/src/ppImageOptions.c
===================================================================
--- /trunk/ppImage/src/ppImageOptions.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageOptions.c	(revision 6260)
@@ -1,7 +1,32 @@
-#include "ppImage.h"
+#include <stdio.h>
+#include "pslib.h"
+#include "ppConfig.h"
+#include "ppImageData.h"
+#include "ppImageOptions.h"
+
+static void imageOptionsFree(ppImageOptions *options)
+{
+    psFree(options->overscan);
+    psFree(options->nonLinearData);
+    psFree(options->nonLinearSource);
+}
+
+ppImageOptions *ppImageOptionsAlloc(void)
+{
+    ppImageOptions *options = psAlloc(sizeof(ppImageOptions));
+    psMemSetDeallocator(options, (psFreeFunc)imageOptionsFree);
+
+    // Initialise options
+    options->overscan = NULL;
+    options->nonLinearData = NULL;
+    options->nonLinearSource = NULL;
+
+    return options;
+}
+
 
 // XXX EAM : this needs signficant work to choose the detrend images based on the detrend database
 
-bool ppImageOptions(ppData *data, ppOptions *options, ppConfig *config)
+bool ppImageOptionsParse(ppImageData *data, ppImageOptions *options, ppConfig *config)
 {
 
Index: /trunk/ppImage/src/ppImageOptions.h
===================================================================
--- /trunk/ppImage/src/ppImageOptions.h	(revision 6260)
+++ /trunk/ppImage/src/ppImageOptions.h	(revision 6260)
@@ -0,0 +1,43 @@
+#ifndef PP_IMAGE_OPTIONS_H
+#define PP_IMAGE_OPTIONS_H
+
+#include "pslib.h"
+#include "pmSubtractBias.h"
+#include "ppImageData.h"
+#include "ppConfig.h"
+
+// How much of the FPA to load at a time
+typedef enum {
+    PP_LOAD_NONE,                       // Don't load anything
+    PP_LOAD_FPA,                        // Load the entire FPA at once
+    PP_LOAD_CHIP,                       // Load by chip
+    PP_LOAD_CELL,                       // Load by cell
+} ppImageLoadDepth;
+
+// Options for ppImage processing
+typedef struct {
+    bool doMask;                        // Mask bad pixels
+    bool doBias;                        // Bias subtraction
+    bool doDark;                        // Dark subtraction
+    bool doFlat;                        // Flat-field normalisation
+    bool doFringe;                      // Fringe subtraction
+    bool doSource;                      // Source identification and photometry
+    bool doAstrom;                      // Astrometry
+    bool doOverscan;                    // Overscan subtraction
+    pmOverscanOptions *overscan;        // Overscan options
+    bool doNonLin;                      // Non-linearity correction
+    psDataType nonLinearType;
+    psMetadataItem *nonLinearData;
+    void *nonLinearSource;
+    ppImageLoadDepth imageLoadDepth;    // How much of the FPA to load at once
+} ppImageOptions;
+
+ppImageOptions *ppImageOptionsAlloc(void);
+
+// Determine the processing options
+bool ppImageOptionsParse(ppImageData *data, // The data to be processed
+                         ppImageOptions *options, // Processing options
+                         ppConfig *config    // Configuration
+    );
+
+#endif
Index: /trunk/ppImage/src/ppImageParseCamera.c
===================================================================
--- /trunk/ppImage/src/ppImageParseCamera.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageParseCamera.c	(revision 6260)
@@ -1,5 +1,10 @@
+#include <stdio.h>
+#include "pslib.h"
+#include "pmFPA.h"
+#include "pmFPAConstruct.h"
+#include "pmConfig.h"
 #include "ppImage.h"
 
-bool ppImageParseCamera(ppData *data, ppConfig *config)
+bool ppImageParseCamera(ppImageData *data, ppConfig *config)
 {
     // Initialise the containers where the files will go
@@ -10,7 +15,4 @@
     data->flat    = ppFileAlloc();
     data->fringe  = ppFileAlloc();
-#if 0
-    data->process = ppFileAlloc();
-#endif
 
     data->input->filename = psMemIncrRefCounter(psMetadataLookupStr(NULL, config->arguments, "-input"));
Index: /trunk/ppImage/src/ppImageParseDetrend.c
===================================================================
--- /trunk/ppImage/src/ppImageParseDetrend.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageParseDetrend.c	(revision 6260)
@@ -1,3 +1,9 @@
-# include "ppImage.h"
+#include <stdio.h>
+#include "pslib.h"
+#include "pmConfig.h"
+#include "ppFile.h"
+#include "ppImageData.h"
+#include "ppImageOptions.h"
+#include "ppImage.h"
 
 // open all needed detrend files
@@ -25,5 +31,5 @@
 }
 
-bool ppImageParseDetrend (ppData *data, ppOptions *options, ppConfig *config) {
+bool ppImageParseDetrend(ppImageData *data, ppImageOptions *options, ppConfig *config) {
 
     ppFileOpen(data->mask, config->camera, "mask", options->doMask);
Index: /trunk/ppImage/src/ppImageWeights.c
===================================================================
--- /trunk/ppImage/src/ppImageWeights.c	(revision 6259)
+++ /trunk/ppImage/src/ppImageWeights.c	(revision 6260)
@@ -1,3 +1,6 @@
-# include "ppImage.h"
+#include <stdio.h>
+#include "pslib.h"
+#include "pmFPA.h"
+#include "ppImage.h"
 
 bool ppReadoutWeights (pmReadout *readout) {
@@ -10,5 +13,5 @@
     float rdnoise = 5.0;  // in electrons
     float gain = 2.0;     // in e/ADU
-    
+
     float rgain = 1.0 / gain;
     float rnoise = PS_SQR (rdnoise / gain);
@@ -19,8 +22,8 @@
 
     for (int j = 0; j < image->numRows; j++) {
-	for (int i = 0; i < image->numCols; i++) {
-	    vM[j][i] = 0;
-	    vW[j][i] = PS_MAX (rgain * vI[j][i] + rnoise, 0.0);
-	}
+        for (int i = 0; i < image->numCols; i++) {
+            vM[j][i] = 0;
+            vW[j][i] = PS_MAX (rgain * vI[j][i] + rnoise, 0.0);
+        }
     }
     return true;
Index: /trunk/ppImage/src/ppMem.c
===================================================================
--- /trunk/ppImage/src/ppMem.c	(revision 6260)
+++ /trunk/ppImage/src/ppMem.c	(revision 6260)
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include "pslib.h"
+#include "ppMem.h"
+
+#define LEAKS "leaks.dat"               // File to record leaks
+
+psMemId ppMemAlloc(const psMemBlock *ptr)
+{
+    fprintf(stderr, "Allocated ");
+    ppMemPrint(ptr);
+    return 0;
+}
+
+// Same as ppMemAlloc, except it says "Freed", and it subtracts one from the reference counter, because
+// psMemory.c doesn't do that until after the callback.
+psMemId ppMemFree(const psMemBlock *ptr)
+{
+    fprintf(stderr, "Freeing ");
+    ppMemPrint(ptr);
+    return 0;
+}
+
+void ppMemProblem(const psMemBlock *ptr)
+{
+    fprintf(stderr, "Problem with ");
+    ppMemPrint(ptr);
+}
+
+// Simply print a memory block
+void ppMemPrint(const psMemBlock *ptr)
+{
+    fprintf(stderr,
+            "Memory block %ld: %ld references\n"
+             "\tFile %s, line %d, size %d\n"
+             "\tPosts: %zx %zx %zx\n",
+             ptr->id, ptr->refCounter, ptr->file, ptr->lineno, ptr->userMemorySize, (size_t)ptr->startblock,
+             (size_t)ptr->endblock, (size_t)*(void**)((int8_t *)(ptr + 1) + ptr->userMemorySize));
+}
+
+
+// Check for memory problems
+void ppMemCheck(void)
+{
+    fprintf(stderr, "Checking for memory problems....\n");
+
+    (void)psMemProblemCallbackSet((psMemProblemCallback)ppMemProblem); // Set callback for corruption
+
+    FILE *leakFile = fopen(LEAKS, "w"); // File to write leaks to
+    if (leakFile == NULL) {
+        fprintf(stderr, "Unable to open leaks file, %s\n", LEAKS);
+        return;
+    }
+
+    psMemBlock **leaks = NULL;          // List of leaks
+    int nLeaks = psMemCheckLeaks(0, &leaks, leakFile, false); // Number of leaks
+    fprintf(stderr, "%d leaks found:\n", nLeaks);
+    for (int i = nLeaks - 1; i > 0; i--) {
+        ppMemPrint(leaks[i]);
+    }
+
+    int nCorrupted;                     // Number of corrupted memory blocks
+    nCorrupted = psMemCheckCorruption(false);
+    fprintf(stderr, "%d memory blocks corrupted.\n", nCorrupted);
+}
Index: /trunk/ppImage/src/ppMem.h
===================================================================
--- /trunk/ppImage/src/ppMem.h	(revision 6260)
+++ /trunk/ppImage/src/ppMem.h	(revision 6260)
@@ -0,0 +1,11 @@
+#ifndef PP_MEM_H
+#define PP_MEM_H
+
+#include "pslib.h"
+
+psMemId ppMemAlloc(const psMemBlock *ptr);
+psMemId ppMemFree(const psMemBlock *ptr);
+void ppMemPrint(const psMemBlock *ptr);
+void ppMemCheck(void);
+
+#endif
Index: /trunk/ppImage/src/ppTest.c
===================================================================
--- /trunk/ppImage/src/ppTest.c	(revision 6260)
+++ /trunk/ppImage/src/ppTest.c	(revision 6260)
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include "pslib.h"
+#include "pmConfig.h"
+#include "ppMem.h"
+
+int main(int argc, char *argv[])
+{
+#if 0
+    int numBadLines = 0;
+    psMetadata *config = psMetadataConfigParse(NULL, &numBadLines, "ipprc.config", true);
+    psFree(config);
+#endif
+
+    psMetadata *site = NULL;
+    psMetadata *camera = NULL;
+    psMetadata *recipe = NULL;
+    pmConfigRead(&site, &camera, &recipe, &argc, argv, "TEST");
+    psFree(site);
+    psFree(camera);
+    psFree(recipe);
+
+    ppMemCheck();
+}
