Index: trunk/ppMerge/src/ppMergeScaleZero.c
===================================================================
--- trunk/ppMerge/src/ppMergeScaleZero.c	(revision 7263)
+++ trunk/ppMerge/src/ppMergeScaleZero.c	(revision 7355)
@@ -42,5 +42,14 @@
     )
 {
+    assert(data);
+    assert(options);
+    assert(config);
+
+    if (!options->scale && !options->zero) {
+        return true;                    // We did everything we were asked for
+    }
+
     assert(config->camera);             // Need the camera configuration
+    assert(config->arguments);          // Need the list of files
 
     psArray *filenames = psMetadataLookupPtr(NULL, config->arguments, "INPUT"); // The input file names
@@ -57,4 +66,94 @@
                                  (*zeros)->numRows == filenames->n));
 
+    // Allocate the outputs
+    if (options->scale) {
+        if (*scales) {
+            psFree(*scales);
+        }
+        *scales = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32);
+    }
+    if (options->zero) {
+        if (*zeros) {
+            psFree(*zeros);
+        }
+        *zeros = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32);
+    }
+
+    bool fromConcepts = false;          // Do we get the scale and zero points from the concepts
+    bool first = true;                  // Are we on the first cell (that sets the standard for the rest)?
+    bool done = false;                  // Are we done going through the list?
+    bool mdok = true;                   // Status of MD lookup
+    for (long i = 0; i < data->in->n && !done; i++) {
+        pmFPA *fpa = data->in->data[i]; // The FPA
+        if (!fpa) {
+            continue;
+        }
+        long cellNum = -1;              // Number of the cell
+        psArray *chips = fpa->chips;    // The array of chips
+        for (long j = 0; j < chips->n && !done; j++) {
+            pmChip *chip = chips->data[j]; // The chip
+            if (!chip) {
+                continue;
+            }
+            psArray *cells = chip->cells; // The array of cells
+            for (long k = 0; k < cells->n && !done; k++) {
+                pmCell *cell = cells->data[k]; // The cell
+                if (!cell) {
+                    continue;
+                }
+                cellNum++;
+
+                if (options->scale) {
+                    float scale = psMetadataLookupF32(&mdok, cell->concepts, "PPMERGE.SCALE"); // The scale
+                    if (mdok && !isnan(scale)) {
+                        if (!first && !fromConcepts) {
+                            psLogMsg(__func__, PS_LOG_WARN, "PPMERGE.SCALE and PPMERGE.ZERO have been set "
+                                     "for some, but not all cells --- we will re-measure it for all cells.");
+                            done = true;
+                            continue;
+                        }
+                        fromConcepts = true;
+                        (*scales)->data.F32[i][cellNum] = scale;
+                        psTrace(__func__, 9, "Scale for input %ld, chip %ld, cell %ld: %f\n", i, j, k, scale);
+                    } else if (!first && fromConcepts) {
+                        psLogMsg(__func__, PS_LOG_WARN, "PPMERGE.SCALE and PPMERGE.ZERO have been set "
+                                 "for some, but not all cells --- we will re-measure it for all cells.");
+                        fromConcepts = false;
+                        done = true;
+                        continue;
+                    }
+                }
+
+                if (options->zero) {
+                    float zero = psMetadataLookupF32(&mdok, cell->concepts, "PPMERGE.ZERO"); // The zero
+                    if (mdok && !isnan(zero)) {
+                        if (!first && !fromConcepts) {
+                            psLogMsg(__func__, PS_LOG_WARN, "PPMERGE.SCALE and PPMERGE.ZERO have been set "
+                                     "for some, but not all cells --- we will re-measure it for all cells.");
+                            done = true;
+                            continue;
+                        }
+                        fromConcepts = true;
+                        (*zeros)->data.F32[i][cellNum] = zero;
+                        psTrace(__func__, 9, "Zero for input %ld, chip %ld, cell %ld: %f\n", i, j, k, zero);
+                   } else if (!first && fromConcepts) {
+                        psLogMsg(__func__, PS_LOG_WARN, "PPMERGE.SCALE and PPMERGE.ZERO have been set "
+                                 "for some, but not all cells --- we will re-measure it for all cells.");
+                        fromConcepts = false;
+                        done = true;
+                        continue;
+                    }
+                }
+
+                first = false;
+            }
+        }
+    }
+
+    if (fromConcepts) {
+        // We've already done everything we need to
+        return true;
+    }
+
     psImage *background = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32); // Background measurements
     psImageInit(background, NAN);
@@ -108,5 +207,4 @@
                 // Normalising by the exposure time
                 if (options->exptime) {
-                    bool mdok = true;   // Status of MD lookup
                     exptime->data.F32[i][cellNum] = psMetadataLookupF32(&mdok, cell->concepts,
                                                                         "CELL.EXPOSURE");
@@ -203,5 +301,4 @@
         psFree(gains);
 
-        *scales = psImageCopy(*scales, background, PS_TYPE_F32);
         psImage *scalesDeref = *scales; // Dereference the pointer
 
@@ -217,7 +314,7 @@
         if (!options->scale) {
             // Copy over the exposure times
-            psImageCopy(*scales, exptime, PS_TYPE_F32);
+            *scales = psImageCopy(*scales, exptime, PS_TYPE_F32);
         } else {
-            psBinaryOp(*scales, *scales, "*", exptime);
+            *scales = (psImage*)psBinaryOp(*scales, *scales, "*", exptime);
         }
     }
