about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2014-09-16 02:49:34 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2014-09-16 02:49:34 +0000
commitb649804cfddd20cf31630f99fe6af4c710085a27 (patch)
tree179911c5f84975b4a9a063db6d0a7dd11f8a6811
parentcc8c48fb587dd5ae6e89b66ae96c8cfcefc5b44e (diff)
downloadnetpbm-mirror-b649804cfddd20cf31630f99fe6af4c710085a27.tar.gz
netpbm-mirror-b649804cfddd20cf31630f99fe6af4c710085a27.tar.xz
netpbm-mirror-b649804cfddd20cf31630f99fe6af4c710085a27.zip
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2281 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--converter/other/cameratopam/camera.c241
-rw-r--r--converter/other/cameratopam/camera.h95
-rw-r--r--converter/other/cameratopam/cameratopam.c1166
-rw-r--r--converter/other/cameratopam/cameratopam.h6
-rw-r--r--converter/other/cameratopam/canon.c6
-rw-r--r--converter/other/cameratopam/canon.h11
-rw-r--r--converter/other/cameratopam/foveon.c5
-rw-r--r--converter/other/cameratopam/foveon.h9
-rw-r--r--converter/other/cameratopam/global_variables.h1
-rw-r--r--converter/other/cameratopam/identify.c11
-rw-r--r--converter/other/cameratopam/identify.h4
-rw-r--r--converter/other/cameratopam/ljpeg.c5
-rw-r--r--converter/other/cameratopam/ljpeg.h5
13 files changed, 799 insertions, 766 deletions
diff --git a/converter/other/cameratopam/camera.c b/converter/other/cameratopam/camera.c
index 4008dbb2..14d208e3 100644
--- a/converter/other/cameratopam/camera.c
+++ b/converter/other/cameratopam/camera.c
@@ -17,6 +17,7 @@
 #include "mallocvar.h"
 
 #include "global_variables.h"
+#include "cameratopam.h"
 #include "util.h"
 #include "decode.h"
 #include "bayer.h"
@@ -55,67 +56,76 @@ merror (const void *ptr, const char *where)
 
 
 static void  
-adobe_copy_pixel (int row, int col, unsigned short **rp, bool use_secondary)
-{
-  unsigned r=row, c=col;
-
-  if (fuji_secondary && use_secondary) (*rp)++;
-  if (filters) {
-    if (fuji_width) {
-      r = row + fuji_width - 1 - (col >> 1);
-      c = row + ((col+1) >> 1);
-    }
-    if (r < height && c < width)
-      BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp;
-    *rp += 1 + fuji_secondary;
-  } else
-    for (c=0; c < tiff_samples; c++) {
-      image[row*width+col][c] = **rp < 0x1000 ? curve[**rp] : **rp;
-      (*rp)++;
+adobeCopyPixel(Image             const image,
+               unsigned int      const row,
+               unsigned int      const col,
+               unsigned short ** const rp,
+               bool              const useSecondary) {
+
+    unsigned r=row, c=col;
+
+    if (fuji_secondary && useSecondary)
+        ++(*rp);
+    if (filters) {
+        if (fuji_width) {
+            r = row + fuji_width - 1 - (col >> 1);
+            c = row + ((col+1) >> 1);
+        }
+        if (r < height && c < width)
+            BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp;
+        *rp += 1 + fuji_secondary;
+    } else {
+        unsigned int c;
+        for (c = 0; c < tiff_samples; ++c) {
+            image[row*width+col][c] = **rp < 0x1000 ? curve[**rp] : **rp;
+            ++(*rp);
+        }
     }
-  if (fuji_secondary && use_secondary) (*rp)--;
+    if (fuji_secondary && useSecondary)
+        --(*rp);
 }
 
 void
-adobe_dng_load_raw_lj()
-{
-  int save, twide, trow=0, tcol=0, jrow, jcol;
-  struct jhead jh;
-  unsigned short *rp;
+adobe_dng_load_raw_lj(Image const image) {
 
-  while (1) {
-    save = ftell(ifp);
-    fseek (ifp, get4(ifp), SEEK_SET);
-    if (!ljpeg_start (ifp, &jh)) break;
-    if (trow >= raw_height) break;
-    if (jh.high > raw_height-trow)
-    jh.high = raw_height-trow;
-    twide = jh.wide;
-    if (filters) twide *= jh.clrs;
-    else         colors = jh.clrs;
-    if (fuji_secondary) twide /= 2;
-    if (twide > raw_width-tcol)
-    twide = raw_width-tcol;
-
-    for (jrow=0; jrow < jh.high; jrow++) {
-      ljpeg_row (&jh);
-      for (rp=jh.row, jcol=0; jcol < twide; jcol++)
-    adobe_copy_pixel (trow+jrow, tcol+jcol, &rp, use_secondary);
-    }
-    fseek (ifp, save+4, SEEK_SET);
-    if ((tcol += twide) >= raw_width) {
-      tcol = 0;
-      trow += jh.high;
+    int save, twide, trow=0, tcol=0, jrow, jcol;
+    struct jhead jh;
+    unsigned short *rp;
+
+    while (1) {
+        save = ftell(ifp);
+        fseek (ifp, get4(ifp), SEEK_SET);
+        if (!ljpeg_start (ifp, &jh)) break;
+        if (trow >= raw_height) break;
+        if (jh.high > raw_height-trow)
+            jh.high = raw_height-trow;
+        twide = jh.wide;
+        if (filters) twide *= jh.clrs;
+        else         colors = jh.clrs;
+        if (fuji_secondary) twide /= 2;
+        if (twide > raw_width-tcol)
+            twide = raw_width-tcol;
+
+        for (jrow=0; jrow < jh.high; jrow++) {
+            ljpeg_row (&jh);
+            for (rp=jh.row, jcol=0; jcol < twide; jcol++)
+                adobeCopyPixel(image,
+                               trow+jrow, tcol+jcol, &rp, use_secondary);
+        }
+        fseek (ifp, save+4, SEEK_SET);
+        if ((tcol += twide) >= raw_width) {
+            tcol = 0;
+            trow += jh.high;
+        }
+        free (jh.row);
     }
-    free (jh.row);
-  }
 }
 
 
 
 void
-adobe_dng_load_raw_nc()
-{
+adobe_dng_load_raw_nc(Image const image) {
+
     unsigned short *pixel, *rp;
     int row, col;
 
@@ -124,7 +134,7 @@ adobe_dng_load_raw_nc()
     for (row=0; row < raw_height; row++) {
         read_shorts (ifp, pixel, raw_width * tiff_samples);
         for (rp=pixel, col=0; col < raw_width; col++)
-            adobe_copy_pixel (row, col, &rp, use_secondary);
+            adobeCopyPixel(image, row, col, &rp, use_secondary);
     }
     free (pixel);
 }
@@ -134,8 +144,8 @@ adobe_dng_load_raw_nc()
 static int nikon_curve_offset;
 
 void
-nikon_compressed_load_raw(void)
-{
+nikon_compressed_load_raw(Image const image) {
+
     static const unsigned char nikon_tree[] = {
         0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,
         5,4,3,6,2,7,1,0,8,9,11,10,12
@@ -176,8 +186,8 @@ nikon_compressed_load_raw(void)
 }
 
 void
-nikon_load_raw()
-{
+nikon_load_raw(Image const image) {
+
   int irow, row, col, i;
 
   getbits(ifp, -1);
@@ -294,8 +304,8 @@ minolta_z2()
 }
 
 void
-nikon_e2100_load_raw()
-{
+nikon_e2100_load_raw(Image const image) {
+        
   unsigned char   data[3432], *dp;
   unsigned short pixel[2288], *pix;
   int row, col;
@@ -322,8 +332,8 @@ nikon_e2100_load_raw()
 }
 
 void
-nikon_e950_load_raw()
-{
+nikon_e950_load_raw(Image const image) {
+
   int irow, row, col;
 
   getbits(ifp, -1);
@@ -341,8 +351,7 @@ nikon_e950_load_raw()
    The Fuji Super CCD is just a Bayer grid rotated 45 degrees.
  */
 void
-fuji_s2_load_raw()
-{
+fuji_s2_load_raw(Image const image) {
   unsigned short pixel[2944];
   int row, col, r, c;
 
@@ -358,8 +367,7 @@ fuji_s2_load_raw()
 }
 
 void
-fuji_s3_load_raw()
-{
+fuji_s3_load_raw(Image const image) {
   unsigned short pixel[4352];
   int row, col, r, c;
 
@@ -374,42 +382,52 @@ fuji_s3_load_raw()
   }
 }
 
-static void  fuji_common_load_raw (int ncol, int icol, int nrow)
-{
-  unsigned short pixel[2048];
-  int row, col, r, c;
-
-  for (row=0; row < nrow; row++) {
-    read_shorts(ifp, pixel, ncol);
-    for (col=0; col <= icol; col++) {
-      r = icol - col + (row >> 1);
-      c = col + ((row+1) >> 1);
-      BAYER(r,c) = pixel[col];
+static void 
+fuji_common_load_raw(Image        const image,
+                     unsigned int const ncol,
+                     unsigned int const icol,
+                     unsigned int const nrow) {
+
+    unsigned short pixel[2048];
+    unsigned int row;
+
+    for (row = 0; row < nrow; ++row) {
+        unsigned int col;
+        read_shorts(ifp, pixel, ncol);
+        for (col = 0; col <= icol; ++col) {
+            int const r = icol - col + (row >> 1);
+            int const c = col + ((row+1) >> 1);
+            BAYER(r,c) = pixel[col];
+        }
     }
-  }
 }
 
+
+
 void
-fuji_s5000_load_raw()
-{
+fuji_s5000_load_raw(Image const image) {
+
   fseek (ifp, (1472*4+24)*2, SEEK_CUR);
-  fuji_common_load_raw (1472, 1423, 2152);
+  fuji_common_load_raw(image, 1472, 1423, 2152);
 }
 
+
+
 void
-fuji_s7000_load_raw()
-{
-  fuji_common_load_raw (2048, 2047, 3080);
+fuji_s7000_load_raw(Image const image) {
+
+    fuji_common_load_raw(image, 2048, 2047, 3080);
 }
 
+
+
 /*
    The Fuji Super CCD SR has two photodiodes for each pixel.
    The secondary has about 1/16 the sensitivity of the primary,
    but this ratio may vary.
  */
 void
-fuji_f700_load_raw()
-{
+fuji_f700_load_raw(Image const image) {
   unsigned short pixel[2944];
   int row, col, r, c, val;
 
@@ -425,8 +443,7 @@ fuji_f700_load_raw()
 }
 
 void
-rollei_load_raw()
-{
+rollei_load_raw(Image const image) {
   unsigned char pixel[10];
   unsigned iten=0, isix, i, buffer=0, row, col, todo[16];
 
@@ -452,8 +469,7 @@ rollei_load_raw()
 }
 
 void
-phase_one_load_raw()
-{
+phase_one_load_raw(Image const image) {
   int row, col, a, b;
   unsigned short *pixel, akey, bkey;
 
@@ -479,8 +495,7 @@ phase_one_load_raw()
 }
 
 void
-ixpress_load_raw()
-{
+ixpress_load_raw(Image const image) {
   unsigned short pixel[4090];
   int row, col;
 
@@ -494,8 +509,7 @@ ixpress_load_raw()
 }
 
 void
-leaf_load_raw()
-{
+leaf_load_raw(Image const image) {
   unsigned short *pixel;
   int r, c, row, col;
 
@@ -514,8 +528,7 @@ leaf_load_raw()
    For this function only, raw_width is in bytes, not pixels!
  */
 void
-packed_12_load_raw()
-{
+packed_12_load_raw(Image const image) {
   int row, col;
 
   getbits(ifp, -1);
@@ -528,8 +541,7 @@ packed_12_load_raw()
 }
 
 void
-unpacked_load_raw()
-{
+unpacked_load_raw(Image const image) {
   unsigned short *pixel;
   int row, col;
 
@@ -544,8 +556,7 @@ unpacked_load_raw()
 }
 
 void
-olympus_e300_load_raw()
-{
+olympus_e300_load_raw(Image const image) {
   unsigned char  *data,  *dp;
   unsigned short *pixel, *pix;
   int dwide, row, col;
@@ -568,8 +579,7 @@ olympus_e300_load_raw()
 }
 
 void
-olympus_cseries_load_raw()
-{
+olympus_cseries_load_raw(Image const image) {
   int irow, row, col;
 
   for (irow=0; irow < height; irow++) {
@@ -584,8 +594,7 @@ olympus_cseries_load_raw()
 }
 
 void
-eight_bit_load_raw()
-{
+eight_bit_load_raw(Image const image) {
   unsigned char *pixel;
   int row, col;
 
@@ -601,8 +610,7 @@ eight_bit_load_raw()
 }
 
 void
-casio_qv5700_load_raw()
-{
+casio_qv5700_load_raw(Image const image) {
   unsigned char  data[3232],  *dp;
   unsigned short pixel[2576], *pix;
   int row, col;
@@ -622,8 +630,7 @@ casio_qv5700_load_raw()
 }
 
 void
-nucore_load_raw()
-{
+nucore_load_raw(Image const image) {
   unsigned short *pixel;
   int irow, row, col;
 
@@ -685,8 +692,7 @@ static int  radc_token (int tree)
 : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4)
 
 void
-kodak_radc_load_raw()
-{
+kodak_radc_load_raw(Image const image) {
     int row, col, tree, nreps, rep, step, c, s, r, x, y, val;
     unsigned int i;
     short last[3] = { 16,16,16 }, mul[3], buf[3][3][386];
@@ -765,7 +771,8 @@ kodak_radc_load_raw()
 #undef PREDICTOR
 
 #ifndef HAVE_JPEG
-void kodak_jpeg_load_raw() {}
+void
+kodak_jpeg_load_raw(Image const Image) {}
 #else
 
 static bool
@@ -782,7 +789,7 @@ fill_input_buffer (j_decompress_ptr cinfo)
 }
 
 void
-kodak_jpeg_load_raw()
+kodak_jpeg_load_raw(Image const image)
 {
   struct jpeg_decompress_struct cinfo;
   struct jpeg_error_mgr jerr;
@@ -823,7 +830,7 @@ kodak_jpeg_load_raw()
 #endif
 
 void
-kodak_dc120_load_raw()
+kodak_dc120_load_raw(Image const image)
 {
   static const int mul[4] = { 162, 192, 187,  92 };
   static const int add[4] = {   0, 636, 424, 212 };
@@ -859,7 +866,7 @@ kodak_dc20_coeff (float const juice)
 }
 
 void
-kodak_easy_load_raw()
+kodak_easy_load_raw(Image const image)
 {
   unsigned char *pixel;
   unsigned row, col, icol;
@@ -887,7 +894,7 @@ kodak_easy_load_raw()
 }
 
 void
-kodak_compressed_load_raw()
+kodak_compressed_load_raw(Image const image)
 {
   unsigned char c, blen[256];
   unsigned short raw[6];
@@ -951,7 +958,7 @@ kodak_compressed_load_raw()
 }
 
 void
-kodak_yuv_load_raw()
+kodak_yuv_load_raw(Image const image)
 {
   unsigned char c, blen[384];
   unsigned row, col, len, bits=0;
@@ -1042,7 +1049,7 @@ static void  sony_decrypt (unsigned *data, int len, int start, int key)
 }
 
 void
-sony_load_raw()
+sony_load_raw(Image const image)
 {
   unsigned char head[40];
   struct pixel {
@@ -1310,12 +1317,6 @@ parse_mos(FILE * const ifp,
         fread (data, 1, 40, ifp);
         skip = get4(ifp);
         from = ftell(ifp);
-#ifdef USE_LCMS
-        if (!strcmp(data,"icc_camera_profile")) {
-            profile_length = skip;
-            profile_offset = from;
-        }
-#endif
         if (!strcmp(data,"NeutObj_neutrals")) {
             for (i=0; i < 4; i++)
                 fscanf (ifp, "%d", neut+i);
diff --git a/converter/other/cameratopam/camera.h b/converter/other/cameratopam/camera.h
index a1e884cf..02c3f2af 100644
--- a/converter/other/cameratopam/camera.h
+++ b/converter/other/cameratopam/camera.h
@@ -1,5 +1,10 @@
+#ifndef CAMERA_H_INCLUDED
+#define CAMERA_H_INCLUDED
+
 #include <stdio.h>
 
+#include "cameratopam.h"
+
 void 
 parse_ciff(FILE * const ifp,
            int    const offset,
@@ -21,20 +26,18 @@ void
 parse_mos(FILE * const ifp,
           int    const offset);
 
-void
-adobe_dng_load_raw_lj(void);
+typedef void LoadRawFn(Image const image);
 
-void
-adobe_dng_load_raw_nc(void);
+LoadRawFn adobe_dng_load_raw_lj;
+
+LoadRawFn adobe_dng_load_raw_nc;
 
 int
 nikon_is_compressed(void);
 
-void
-nikon_compressed_load_raw(void);
+LoadRawFn nikon_compressed_load_raw;
 
-void
-nikon_e950_load_raw(void);
+LoadRawFn nikon_e950_load_raw;
 
 void
 nikon_e950_coeff(void);
@@ -45,87 +48,63 @@ nikon_e990(void);
 int
 nikon_e2100(void);
 
-void
-nikon_e2100_load_raw(void);
+LoadRawFn nikon_e2100_load_raw;
 
 int
 minolta_z2(void);
 
-void
-fuji_s2_load_raw(void);
+LoadRawFn fuji_s2_load_raw;
 
-void
-fuji_s3_load_raw(void);
+LoadRawFn fuji_s3_load_raw;
 
-void
-fuji_s5000_load_raw(void);
+LoadRawFn fuji_s5000_load_raw;
 
-void
-unpacked_load_raw(void);
+LoadRawFn unpacked_load_raw;
 
-void
-fuji_s7000_load_raw(void);
+LoadRawFn fuji_s7000_load_raw;
 
-void
-fuji_f700_load_raw(void);
+LoadRawFn fuji_f700_load_raw;
 
-void
-packed_12_load_raw(void);
+LoadRawFn packed_12_load_raw;
 
-void
-eight_bit_load_raw(void);
+LoadRawFn eight_bit_load_raw;
 
-void
-phase_one_load_raw(void);
+LoadRawFn phase_one_load_raw;
 
-void
-ixpress_load_raw(void);
+LoadRawFn ixpress_load_raw;
 
-void
-leaf_load_raw(void);
+LoadRawFn leaf_load_raw;
 
-void
-olympus_e300_load_raw(void);
+LoadRawFn olympus_e300_load_raw;
 
-void
-olympus_cseries_load_raw(void);
+LoadRawFn olympus_cseries_load_raw;
 
-void
-sony_load_raw(void);
+LoadRawFn sony_load_raw;
 
-void
-kodak_easy_load_raw(void);
+LoadRawFn kodak_easy_load_raw;
 
-void
-kodak_compressed_load_raw(void);
+LoadRawFn kodak_compressed_load_raw;
 
-void
-kodak_yuv_load_raw(void);
+LoadRawFn kodak_yuv_load_raw;
 
 void
 kodak_dc20_coeff (float const juice);
 
-void
-kodak_radc_load_raw(void);
+LoadRawFn kodak_radc_load_raw;
 
-void
-kodak_jpeg_load_raw(void);
+LoadRawFn kodak_jpeg_load_raw;
 
-void
-kodak_dc120_load_raw(void);
+LoadRawFn kodak_dc120_load_raw;
 
-void
-rollei_load_raw(void);
+LoadRawFn rollei_load_raw;
 
-void
-casio_qv5700_load_raw(void);
+LoadRawFn casio_qv5700_load_raw;
 
-void
-nucore_load_raw(void);
+LoadRawFn nucore_load_raw;
 
-void
-nikon_load_raw(void);
+LoadRawFn nikon_load_raw;
 
 int
 pentax_optio33(void);
 
+#endif
diff --git a/converter/other/cameratopam/cameratopam.c b/converter/other/cameratopam/cameratopam.c
index 0a25686a..cd8093ee 100644
--- a/converter/other/cameratopam/cameratopam.c
+++ b/converter/other/cameratopam/cameratopam.c
@@ -39,6 +39,7 @@
 #include "pam.h"
 
 #include "global_variables.h"
+#include "cameratopam.h"
 #include "util.h"
 #include "decode.h"
 #include "identify.h"
@@ -65,7 +66,8 @@ int is_dng, is_canon, is_foveon, use_coeff, use_gamma;
 int trim, flip, xmag, ymag;
 int zero_after_ff;
 unsigned filters;
-unsigned short (*image)[4], white[8][8], curve[0x1000];
+unsigned short  white[8][8];
+unsigned short  curve[0x1000];
 int fuji_secondary;
 float cam_mul[4], pre_mul[4], coeff[3][4];
 int histogram[3][0x2000];
@@ -73,11 +75,6 @@ jmp_buf failure;
 int use_secondary;
 bool verbose;
 
-#ifdef USE_LCMS
-#include <lcms.h>
-int profile_offset, profile_length;
-#endif
-
 #define CLASS
 
 #define FORC3 for (c=0; c < 3; c++)
@@ -192,610 +189,660 @@ parseCommandLine(int argc, char ** argv,
 }
 
   
-/*
-   Seach from the current directory up to the root looking for
-   a ".badpixels" file, and fix those pixels now.
- */
-static void CLASS bad_pixels()
-{
-  FILE *fp=NULL;
-  char *fname, *cp, line[128];
-  int len, time, row, col, r, c, rad, tot, n, fixed=0;
-
-  if (!filters) return;
-  for (len=16 ; ; len *= 2) {
-    fname = malloc (len);
-    if (!fname) return;
-    if (getcwd (fname, len-12)) break;
-    free (fname);
-    if (errno != ERANGE) return;
-  }
+
+static void CLASS
+fixBadPixels(Image const image) {
+/*----------------------------------------------------------------------------
+  Search from the current directory up to the root looking for
+  a ".badpixels" file, and fix those pixels now.
+-----------------------------------------------------------------------------*/
+    FILE *fp=NULL;
+    char *fname, *cp, line[128];
+    int len, time, row, col, r, c, rad, tot, n, fixed=0;
+
+    if (!filters) return;
+    for (len=16 ; ; len *= 2) {
+        fname = malloc (len);
+        if (!fname) return;
+        if (getcwd (fname, len-12)) break;
+        free (fname);
+        if (errno != ERANGE) return;
+    }
 #if MSVCRT
-  if (fname[1] == ':')
-    memmove (fname, fname+2, len-2);
-  for (cp=fname; *cp; cp++)
-    if (*cp == '\\') *cp = '/';
+    if (fname[1] == ':')
+        memmove (fname, fname+2, len-2);
+    for (cp=fname; *cp; cp++)
+        if (*cp == '\\') *cp = '/';
 #endif
-  cp = fname + strlen(fname);
-  if (cp[-1] == '/') cp--;
-  while (*fname == '/') {
-    strcpy (cp, "/.badpixels");
-    if ((fp = fopen (fname, "r"))) break;
-    if (cp == fname) break;
-    while (*--cp != '/');
-  }
-  free (fname);
-  if (!fp) return;
-  while (fgets (line, 128, fp)) {
-    cp = strchr (line, '#');
-    if (cp) *cp = 0;
-    if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
-    if ((unsigned) col >= width || (unsigned) row >= height) continue;
-    if (time > timestamp) continue;
-    for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
-      for (r = row-rad; r <= row+rad; r++)
-    for (c = col-rad; c <= col+rad; c++)
-      if ((unsigned) r < height && (unsigned) c < width &&
-        (r != row || c != col) && FC(r,c) == FC(row,col)) {
-        tot += BAYER(r,c);
-        n++;
-      }
-    BAYER(row,col) = tot/n;
-    if (cmdline.verbose) {
-      if (!fixed++)
-          pm_message ("Fixed bad pixels at: %d,%d", col, row);
+    cp = fname + strlen(fname);
+    if (cp[-1] == '/') cp--;
+    while (*fname == '/') {
+        strcpy (cp, "/.badpixels");
+        if ((fp = fopen (fname, "r"))) break;
+        if (cp == fname) break;
+        while (*--cp != '/');
     }
-  }
-  fclose (fp);
-}
-
-static void CLASS scale_colors()
-{
-  int row, col, c, val, shift=0;
-  int min[4], max[4], count[4];
-  double sum[4], dmin;
-
-  maximum -= black;
-  if (cmdline.use_auto_wb || (cmdline.use_camera_wb && camera_red == -1)) {
-    FORC4 min[c] = INT_MAX;
-    FORC4 max[c] = count[c] = sum[c] = 0;
-    for (row=0; row < height; row++)
-      for (col=0; col < width; col++)
-    FORC4 {
-      val = image[row*width+col][c];
-      if (!val) continue;
-      if (min[c] > val) min[c] = val;
-      if (max[c] < val) max[c] = val;
-      val -= black;
-      if (val > maximum-25) continue;
-      if (val < 0) val = 0;
-      sum[c] += val;
-      count[c]++;
+    free (fname);
+    if (!fp) return;
+    while (fgets (line, 128, fp)) {
+        cp = strchr (line, '#');
+        if (cp) *cp = 0;
+        if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
+        if ((unsigned) col >= width || (unsigned) row >= height) continue;
+        if (time > timestamp) continue;
+        for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
+            for (r = row-rad; r <= row+rad; r++)
+                for (c = col-rad; c <= col+rad; c++)
+                    if ((unsigned) r < height && (unsigned) c < width &&
+                        (r != row || c != col) && FC(r,c) == FC(row,col)) {
+                        tot += BAYER(r,c);
+                        n++;
+                    }
+        BAYER(row,col) = tot/n;
+        if (cmdline.verbose) {
+            if (!fixed++)
+                pm_message ("Fixed bad pixels at: %d,%d", col, row);
+        }
     }
-    FORC4 pre_mul[c] = count[c] / sum[c];
-  }
-  if (cmdline.use_camera_wb && camera_red != -1) {
-    FORC4 count[c] = sum[c] = 0;
-    for (row=0; row < 8; row++)
-      for (col=0; col < 8; col++) {
-    c = FC(row,col);
-    if ((val = white[row][col] - black) > 0)
-      sum[c] += val;
-    count[c]++;
-      }
-    val = 1;
-    FORC4 if (sum[c] == 0) val = 0;
-    if (val)
-      FORC4 pre_mul[c] = count[c] / sum[c];
-    else if (camera_red && camera_blue)
-      memcpy (pre_mul, cam_mul, sizeof pre_mul);
-    else
-      pm_message ("Cannot use camera white balance.");
-  }
-  if (!use_coeff) {
-    pre_mul[0] *= cmdline.red_scale;
-    pre_mul[2] *= cmdline.blue_scale;
-  }
-  dmin = DBL_MAX;
-  FORC4 if (dmin > pre_mul[c])
-        dmin = pre_mul[c];
-  FORC4 pre_mul[c] /= dmin;
-
-  while (maximum << shift < 0x8000) shift++;
-  FORC4 pre_mul[c] *= 1 << shift;
-  maximum <<= shift;
-
-  if (cmdline.linear || cmdline.bright < 1) {
-      maximum *= cmdline.bright;
-      if (maximum > 0xffff)
-          maximum = 0xffff;
-      FORC4 pre_mul[c] *= cmdline.bright;
-  }
-  if (cmdline.verbose) {
-    fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black);
-    FORC4 fprintf (stderr, " %f", pre_mul[c]);
-    fputc ('\n', stderr);
-  }
-  clip_max = cmdline.no_clip_color ? 0xffff : maximum;
-  for (row=0; row < height; row++)
-    for (col=0; col < width; col++)
-      FORC4 {
-    val = image[row*width+col][c];
-    if (!val) continue;
-    val -= black;
-    val *= pre_mul[c];
-    if (val < 0) val = 0;
-    if (val > clip_max) val = clip_max;
-    image[row*width+col][c] = val;
-      }
+    fclose (fp);
 }
 
-/*
-   This algorithm is officially called:
-
-   "Interpolation using a Threshold-based variable number of gradients"
 
-   described in http://www-ise.stanford.edu/~tingchen/algodep/vargra.html
 
-   I've extended the basic idea to work with non-Bayer filter arrays.
-   Gradients are numbered clockwise from NW=0 to W=7.
- */
-static void CLASS vng_interpolate()
-{
-  static const signed char *cp, terms[] = {
-    -2,-2,+0,-1,0,(char)0x01, -2,-2,+0,+0,1,(char)0x01, -2,-1,-1,+0,0,(char)0x01,
-    -2,-1,+0,-1,0,(char)0x02, -2,-1,+0,+0,0,(char)0x03, -2,-1,+0,+1,1,(char)0x01,
-    -2,+0,+0,-1,0,(char)0x06, -2,+0,+0,+0,1,(char)0x02, -2,+0,+0,+1,0,(char)0x03,
-    -2,+1,-1,+0,0,(char)0x04, -2,+1,+0,-1,1,(char)0x04, -2,+1,+0,+0,0,(char)0x06,
-    -2,+1,+0,+1,0,(char)0x02, -2,+2,+0,+0,1,(char)0x04, -2,+2,+0,+1,0,(char)0x04,
-    -1,-2,-1,+0,0,(char)0x80, -1,-2,+0,-1,0,(char)0x01, -1,-2,+1,-1,0,(char)0x01,
-    -1,-2,+1,+0,1,(char)0x01, -1,-1,-1,+1,0,(char)0x88, -1,-1,+1,-2,0,(char)0x40,
-    -1,-1,+1,-1,0,(char)0x22, -1,-1,+1,+0,0,(char)0x33, -1,-1,+1,+1,1,(char)0x11,
-    -1,+0,-1,+2,0,(char)0x08, -1,+0,+0,-1,0,(char)0x44, -1,+0,+0,+1,0,(char)0x11,
-    -1,+0,+1,-2,1,(char)0x40, -1,+0,+1,-1,0,(char)0x66, -1,+0,+1,+0,1,(char)0x22,
-    -1,+0,+1,+1,0,(char)0x33, -1,+0,+1,+2,1,(char)0x10, -1,+1,+1,-1,1,(char)0x44,
-    -1,+1,+1,+0,0,(char)0x66, -1,+1,+1,+1,0,(char)0x22, -1,+1,+1,+2,0,(char)0x10,
-    -1,+2,+0,+1,0,(char)0x04, -1,+2,+1,+0,1,(char)0x04, -1,+2,+1,+1,0,(char)0x04,
-    +0,-2,+0,+0,1,(char)0x80, +0,-1,+0,+1,1,(char)0x88, +0,-1,+1,-2,0,(char)0x40,
-    +0,-1,+1,+0,0,(char)0x11, +0,-1,+2,-2,0,(char)0x40, +0,-1,+2,-1,0,(char)0x20,
-    +0,-1,+2,+0,0,(char)0x30, +0,-1,+2,+1,1,(char)0x10, +0,+0,+0,+2,1,(char)0x08,
-    +0,+0,+2,-2,1,(char)0x40, +0,+0,+2,-1,0,(char)0x60, +0,+0,+2,+0,1,(char)0x20,
-    +0,+0,+2,+1,0,(char)0x30, +0,+0,+2,+2,1,(char)0x10, +0,+1,+1,+0,0,(char)0x44,
-    +0,+1,+1,+2,0,(char)0x10, +0,+1,+2,-1,1,(char)0x40, +0,+1,+2,+0,0,(char)0x60,
-    +0,+1,+2,+1,0,(char)0x20, +0,+1,+2,+2,0,(char)0x10, +1,-2,+1,+0,0,(char)0x80,
-    +1,-1,+1,+1,0,(char)0x88, +1,+0,+1,+2,0,(char)0x08, +1,+0,+2,-1,0,(char)0x40,
-    +1,+0,+2,+1,0,(char)0x10
-  }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
-  unsigned short (*brow[5])[4], *pix;
-  int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4];
-  int row, col, shift, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
-  int g, diff, thold, num, c;
-
-  for (row=0; row < 8; row++) {     /* Precalculate for bilinear */
-    for (col=1; col < 3; col++) {
-      ip = code[row][col & 1];
-      memset (sum, 0, sizeof sum);
-      for (y=-1; y <= 1; y++)
-    for (x=-1; x <= 1; x++) {
-      shift = (y==0) + (x==0);
-      if (shift == 2) continue;
-      color = FC(row+y,col+x);
-      *ip++ = (width*y + x)*4 + color;
-      *ip++ = shift;
-      *ip++ = color;
-      sum[color] += 1 << shift;
+static void CLASS
+scaleColors(Image const image) {
+
+    int row;
+    int c;
+    int val;
+    int shift;
+    int min[4], max[4], count[4];
+    double sum[4], dmin;
+
+    shift = 0;  /* initial value */
+
+    maximum -= black;
+    if (cmdline.use_auto_wb || (cmdline.use_camera_wb && camera_red == -1)) {
+        unsigned int row;
+        FORC4 min[c] = INT_MAX;
+        FORC4 max[c] = count[c] = sum[c] = 0;
+        for (row = 0; row < height; ++row) {
+            unsigned int col;
+            for (col = 0; col < width; ++col) {
+                FORC4 {
+                    int val;
+                    val = image[row*width+col][c];
+                    if (!val)
+                        continue;
+                    if (min[c] > val)
+                        min[c] = val;
+                    if (max[c] < val)
+                        max[c] = val;
+                    val -= black;
+                    if (val > maximum-25)
+                        continue;
+                    if (val < 0)
+                        val = 0;
+                    sum[c] += val;
+                    ++count[c];
+                }
+            }
+        }
+        FORC4 pre_mul[c] = count[c] / sum[c];
     }
-      FORC4
-    if (c != FC(row,col)) {
-      *ip++ = c;
-      *ip++ = sum[c];
+    if (cmdline.use_camera_wb && camera_red != -1) {
+        unsigned int row;
+        FORC4 count[c] = sum[c] = 0;
+        for (row = 0; row < 8; ++row) {
+            unsigned int col;
+            for (col = 0; col < 8; ++col) {
+                c = FC(row,col);
+                if ((val = white[row][col] - black) > 0)
+                    sum[c] += val;
+                ++count[c];
+            }
+        }
+        val = 1;
+        FORC4 if (sum[c] == 0) val = 0;
+        if (val)
+            FORC4 pre_mul[c] = count[c] / sum[c];
+        else if (camera_red && camera_blue)
+            memcpy(pre_mul, cam_mul, sizeof pre_mul);
+        else
+            pm_message ("Cannot use camera white balance.");
     }
+    if (!use_coeff) {
+        pre_mul[0] *= cmdline.red_scale;
+        pre_mul[2] *= cmdline.blue_scale;
     }
-  }
-  for (row=1; row < height-1; row++) {  /* Do bilinear interpolation */
-    for (col=1; col < width-1; col++) {
-      pix = image[row*width+col];
-      ip = code[row & 7][col & 1];
-      memset (sum, 0, sizeof sum);
-      for (g=8; g--; ) {
-    diff = pix[*ip++];
-    diff <<= *ip++;
-    sum[*ip++] += diff;
-      }
-      for (g=colors; --g; ) {
-    c = *ip++;
-    pix[c] = sum[c] / *ip++;
-      }
+    dmin = DBL_MAX;
+    FORC4 if (dmin > pre_mul[c])
+        dmin = pre_mul[c];
+    FORC4 pre_mul[c] /= dmin;
+
+    while (maximum << shift < 0x8000)
+        ++shift;
+    FORC4 pre_mul[c] *= 1 << shift;
+    maximum <<= shift;
+
+    if (cmdline.linear || cmdline.bright < 1) {
+        maximum *= cmdline.bright;
+        if (maximum > 0xffff)
+            maximum = 0xffff;
+        FORC4 pre_mul[c] *= cmdline.bright;
     }
-  }
-  if (cmdline.quick_interpolate)
-    return;
-
-  for (row=0; row < 8; row++) {     /* Precalculate for VNG */
-    for (col=0; col < 2; col++) {
-      ip = code[row][col];
-      for (cp=terms, t=0; t < 64; t++) {
-    y1 = *cp++;  x1 = *cp++;
-    y2 = *cp++;  x2 = *cp++;
-    weight = *cp++;
-    grads = *cp++;
-    color = FC(row+y1,col+x1);
-    if (FC(row+y2,col+x2) != color) continue;
-    diag = (FC(row,col+1) == color && FC(row+1,col) == color) ? 2:1;
-    if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
-    *ip++ = (y1*width + x1)*4 + color;
-    *ip++ = (y2*width + x2)*4 + color;
-    *ip++ = weight;
-    for (g=0; g < 8; g++)
-      if (grads & 1<<g) *ip++ = g;
-    *ip++ = -1;
-      }
-      *ip++ = INT_MAX;
-      for (cp=chood, g=0; g < 8; g++) {
-    y = *cp++;  x = *cp++;
-    *ip++ = (y*width + x) * 4;
-    color = FC(row,col);
-    if (FC(row+y,col+x) != color && FC(row+y*2,col+x*2) == color)
-      *ip++ = (y*width + x) * 8 + color;
-    else
-      *ip++ = 0;
-      }
+    if (cmdline.verbose) {
+        fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black);
+        FORC4 fprintf (stderr, " %f", pre_mul[c]);
+        fputc ('\n', stderr);
     }
-  }
-  brow[4] = calloc (width*3, sizeof **brow);
-  merror (brow[4], "vng_interpolate()");
-  for (row=0; row < 3; row++)
-    brow[row] = brow[4] + row*width;
-  for (row=2; row < height-2; row++) {      /* Do VNG interpolation */
-    for (col=2; col < width-2; col++) {
-      pix = image[row*width+col];
-      ip = code[row & 7][col & 1];
-      memset (gval, 0, sizeof gval);
-      while ((g = ip[0]) != INT_MAX) {      /* Calculate gradients */
-    num = (diff = pix[g] - pix[ip[1]]) >> 31;
-    gval[ip[3]] += (diff = ((diff ^ num) - num) << ip[2]);
-    ip += 5;
-    if ((g = ip[-1]) == -1) continue;
-    gval[g] += diff;
-    while ((g = *ip++) != -1)
-      gval[g] += diff;
-      }
-      ip++;
-      gmin = gmax = gval[0];            /* Choose a threshold */
-      for (g=1; g < 8; g++) {
-    if (gmin > gval[g]) gmin = gval[g];
-    if (gmax < gval[g]) gmax = gval[g];
-      }
-      if (gmax == 0) {
-    memcpy (brow[2][col], pix, sizeof *image);
-    continue;
-      }
-      thold = gmin + (gmax >> 1);
-      memset (sum, 0, sizeof sum);
-      color = FC(row,col);
-      for (num=g=0; g < 8; g++,ip+=2) {     /* Average the neighbors */
-    if (gval[g] <= thold) {
-      FORC4
-        if (c == color && ip[1])
-          sum[c] += (pix[c] + pix[ip[1]]) >> 1;
-        else
-          sum[c] += pix[ip[0] + c];
-      num++;
+    clip_max = cmdline.no_clip_color ? 0xffff : maximum;
+    for (row = 0; row < height; ++row) {
+        unsigned int col;
+        for (col = 0; col < width; ++col) {
+            FORC4 {
+                int val;
+                val = image[row*width+col][c];
+                if (!val)
+                    continue;
+                val -= black;
+                val *= pre_mul[c];
+                if (val < 0)
+                    val = 0;
+                if (val > clip_max)
+                    val = clip_max;
+                image[row*width+col][c] = val;
+            }
+        }
     }
-      }
-      FORC4 {                   /* Save to buffer */
-    t = pix[color];
-    if (c != color) {
-      t += (sum[c] - sum[color])/num;
-      if (t < 0) t = 0;
-      if (t > clip_max) t = clip_max;
+}
+
+
+
+static void CLASS
+vngInterpolate(Image const image) {
+
+    /*
+      This algorithm is officially called "Interpolation using a
+      Threshold-based variable number of gradients," described in
+      http://www-ise.stanford.edu/~tingchen/algodep/vargra.html
+
+      I've extended the basic idea to work with non-Bayer filter arrays.
+      Gradients are numbered clockwise from NW=0 to W=7.
+    */
+
+    static const signed char *cp, terms[] = {
+  -2,-2,+0,-1,0,(char)0x01, -2,-2,+0,+0,1,(char)0x01, -2,-1,-1,+0,0,(char)0x01,
+  -2,-1,+0,-1,0,(char)0x02, -2,-1,+0,+0,0,(char)0x03, -2,-1,+0,+1,1,(char)0x01,
+  -2,+0,+0,-1,0,(char)0x06, -2,+0,+0,+0,1,(char)0x02, -2,+0,+0,+1,0,(char)0x03,
+  -2,+1,-1,+0,0,(char)0x04, -2,+1,+0,-1,1,(char)0x04, -2,+1,+0,+0,0,(char)0x06,
+  -2,+1,+0,+1,0,(char)0x02, -2,+2,+0,+0,1,(char)0x04, -2,+2,+0,+1,0,(char)0x04,
+  -1,-2,-1,+0,0,(char)0x80, -1,-2,+0,-1,0,(char)0x01, -1,-2,+1,-1,0,(char)0x01,
+  -1,-2,+1,+0,1,(char)0x01, -1,-1,-1,+1,0,(char)0x88, -1,-1,+1,-2,0,(char)0x40,
+  -1,-1,+1,-1,0,(char)0x22, -1,-1,+1,+0,0,(char)0x33, -1,-1,+1,+1,1,(char)0x11,
+  -1,+0,-1,+2,0,(char)0x08, -1,+0,+0,-1,0,(char)0x44, -1,+0,+0,+1,0,(char)0x11,
+  -1,+0,+1,-2,1,(char)0x40, -1,+0,+1,-1,0,(char)0x66, -1,+0,+1,+0,1,(char)0x22,
+  -1,+0,+1,+1,0,(char)0x33, -1,+0,+1,+2,1,(char)0x10, -1,+1,+1,-1,1,(char)0x44,
+  -1,+1,+1,+0,0,(char)0x66, -1,+1,+1,+1,0,(char)0x22, -1,+1,+1,+2,0,(char)0x10,
+  -1,+2,+0,+1,0,(char)0x04, -1,+2,+1,+0,1,(char)0x04, -1,+2,+1,+1,0,(char)0x04,
+  +0,-2,+0,+0,1,(char)0x80, +0,-1,+0,+1,1,(char)0x88, +0,-1,+1,-2,0,(char)0x40,
+  +0,-1,+1,+0,0,(char)0x11, +0,-1,+2,-2,0,(char)0x40, +0,-1,+2,-1,0,(char)0x20,
+  +0,-1,+2,+0,0,(char)0x30, +0,-1,+2,+1,1,(char)0x10, +0,+0,+0,+2,1,(char)0x08,
+  +0,+0,+2,-2,1,(char)0x40, +0,+0,+2,-1,0,(char)0x60, +0,+0,+2,+0,1,(char)0x20,
+  +0,+0,+2,+1,0,(char)0x30, +0,+0,+2,+2,1,(char)0x10, +0,+1,+1,+0,0,(char)0x44,
+  +0,+1,+1,+2,0,(char)0x10, +0,+1,+2,-1,1,(char)0x40, +0,+1,+2,+0,0,(char)0x60,
+  +0,+1,+2,+1,0,(char)0x20, +0,+1,+2,+2,0,(char)0x10, +1,-2,+1,+0,0,(char)0x80,
+  +1,-1,+1,+1,0,(char)0x88, +1,+0,+1,+2,0,(char)0x08, +1,+0,+2,-1,0,(char)0x40,
+  +1,+0,+2,+1,0,(char)0x10
+    }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
+    unsigned short (*brow[5])[4], *pix;
+    int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4];
+    int row, col, shift, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
+    int g, diff, thold, num, c;
+
+    for (row=0; row < 8; row++) {     /* Precalculate for bilinear */
+        for (col=1; col < 3; col++) {
+            ip = code[row][col & 1];
+            memset (sum, 0, sizeof sum);
+            for (y=-1; y <= 1; y++)
+                for (x=-1; x <= 1; x++) {
+                    shift = (y==0) + (x==0);
+                    if (shift == 2) continue;
+                    color = FC(row+y,col+x);
+                    *ip++ = (width*y + x)*4 + color;
+                    *ip++ = shift;
+                    *ip++ = color;
+                    sum[color] += 1 << shift;
+                }
+            FORC4
+                if (c != FC(row,col)) {
+                    *ip++ = c;
+                    *ip++ = sum[c];
+                }
+        }
     }
-    brow[2][col][c] = t;
-      }
+    for (row=1; row < height-1; row++) {  /* Do bilinear interpolation */
+        for (col=1; col < width-1; col++) {
+            pix = image[row*width+col];
+            ip = code[row & 7][col & 1];
+            memset (sum, 0, sizeof sum);
+            for (g=8; g--; ) {
+                diff = pix[*ip++];
+                diff <<= *ip++;
+                sum[*ip++] += diff;
+            }
+            for (g=colors; --g; ) {
+                c = *ip++;
+                pix[c] = sum[c] / *ip++;
+            }
+        }
+    }
+    if (cmdline.quick_interpolate)
+        return;
+
+    for (row=0; row < 8; row++) {     /* Precalculate for VNG */
+        for (col=0; col < 2; col++) {
+            ip = code[row][col];
+            for (cp=terms, t=0; t < 64; t++) {
+                y1 = *cp++;  x1 = *cp++;
+                y2 = *cp++;  x2 = *cp++;
+                weight = *cp++;
+                grads = *cp++;
+                color = FC(row+y1,col+x1);
+                if (FC(row+y2,col+x2) != color) continue;
+                diag =
+                    (FC(row,col+1) == color && FC(row+1,col) == color) ? 2:1;
+                if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
+                *ip++ = (y1*width + x1)*4 + color;
+                *ip++ = (y2*width + x2)*4 + color;
+                *ip++ = weight;
+                for (g=0; g < 8; g++)
+                    if (grads & 1<<g) *ip++ = g;
+                *ip++ = -1;
+            }
+            *ip++ = INT_MAX;
+            for (cp=chood, g=0; g < 8; g++) {
+                y = *cp++;  x = *cp++;
+                *ip++ = (y*width + x) * 4;
+                color = FC(row,col);
+                if (FC(row+y,col+x) != color && FC(row+y*2,col+x*2) == color)
+                    *ip++ = (y*width + x) * 8 + color;
+                else
+                    *ip++ = 0;
+            }
+        }
+    }
+    brow[4] = calloc (width*3, sizeof **brow);
+    merror (brow[4], "vngInterpolate()");
+    for (row=0; row < 3; row++)
+        brow[row] = brow[4] + row*width;
+    for (row=2; row < height-2; row++) {      /* Do VNG interpolation */
+        for (col=2; col < width-2; col++) {
+            pix = image[row*width+col];
+            ip = code[row & 7][col & 1];
+            memset (gval, 0, sizeof gval);
+            while ((g = ip[0]) != INT_MAX) {      /* Calculate gradients */
+                num = (diff = pix[g] - pix[ip[1]]) >> 31;
+                gval[ip[3]] += (diff = ((diff ^ num) - num) << ip[2]);
+                ip += 5;
+                if ((g = ip[-1]) == -1) continue;
+                gval[g] += diff;
+                while ((g = *ip++) != -1)
+                    gval[g] += diff;
+            }
+            ip++;
+            gmin = gmax = gval[0];            /* Choose a threshold */
+            for (g=1; g < 8; g++) {
+                if (gmin > gval[g]) gmin = gval[g];
+                if (gmax < gval[g]) gmax = gval[g];
+            }
+            if (gmax == 0) {
+                memcpy (brow[2][col], pix, sizeof *image);
+                continue;
+            }
+            thold = gmin + (gmax >> 1);
+            memset (sum, 0, sizeof sum);
+            color = FC(row,col);
+            for (num=g=0; g < 8; g++,ip+=2) {     /* Average the neighbors */
+                if (gval[g] <= thold) {
+                    FORC4
+                        if (c == color && ip[1])
+                            sum[c] += (pix[c] + pix[ip[1]]) >> 1;
+                        else
+                            sum[c] += pix[ip[0] + c];
+                    num++;
+                }
+            }
+            FORC4 {                   /* Save to buffer */
+                t = pix[color];
+                if (c != color) {
+                    t += (sum[c] - sum[color])/num;
+                    if (t < 0) t = 0;
+                    if (t > clip_max) t = clip_max;
+                }
+                brow[2][col][c] = t;
+            }
+        }
+        if (row > 3)                /* Write buffer to image */
+            memcpy(image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
+        for (g=0; g < 4; g++)
+            brow[(g-1) & 3] = brow[g];
     }
-    if (row > 3)                /* Write buffer to image */
-      memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
-    for (g=0; g < 4; g++)
-      brow[(g-1) & 3] = brow[g];
-  }
-  memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
-  memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
-  free (brow[4]);
+    memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image);
+    memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image);
+    free (brow[4]);
 }
 
-#ifdef USE_LCMS
-static void 
-apply_profile(FILE *       const ifP,
-              const char * const pfname)
-{
-  char *prof;
-  cmsHPROFILE hInProfile=NULL, hOutProfile;
-  cmsHTRANSFORM hTransform;
-
-  if (pfname)
-    hInProfile = cmsOpenProfileFromFile (pfname, "r");
-  else if (profile_length) {
-    prof = malloc (profile_length);
-    merror (prof, "apply_profile()");
-    fseek (ifP, profile_offset, SEEK_SET);
-    fread (prof, 1, profile_length, ifP);
-    hInProfile = cmsOpenProfileFromMem (prof, profile_length);
-    free (prof);
-  }
-  if (!hInProfile) return;
-  if (cmdline.verbose)
-      pm_message( "Applying color profile...");
-  maximum = 0xffff;
-  use_gamma = use_coeff = 0;
-
-  hOutProfile = cmsCreate_sRGBProfile();
-  hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
-    hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
-  cmsDoTransform (hTransform, image, image, width*height);
-
-  cmsDeleteTransform (hTransform);
-  cmsCloseProfile (hInProfile);
-  cmsCloseProfile (hOutProfile);
-}
-#else
-static void 
-apply_profile(FILE *       const ifP,
-              const char * const pfname)
-{
-}
-#endif
 
-/*
+
+static void CLASS
+convertToRgb(Image const image) {
+/*----------------------------------------------------------------------------
    Convert the entire image to RGB colorspace and build a histogram.
- */
-static void CLASS convert_to_rgb()
-{
-  int row, col, r, g, c=0;
-  unsigned short *img;
-  float rgb[3];
-
-  if (cmdline.document_mode)
-    colors = 1;
-  memset (histogram, 0, sizeof histogram);
-  for (row = trim; row < height-trim; row++)
-    for (col = trim; col < width-trim; col++) {
-      img = image[row*width+col];
-      if (cmdline.document_mode)
-    c = FC(row,col);
-      if (colors == 4 && !use_coeff)    /* Recombine the greens */
-    img[1] = (img[1] + img[3]) >> 1;
-      if (colors == 1)          /* RGB from grayscale */
-    for (r=0; r < 3; r++)
-      rgb[r] = img[c];
-      else if (use_coeff) {     /* RGB via coeff[][] */
-    for (r=0; r < 3; r++)
-      for (rgb[r]=g=0; g < colors; g++)
-        rgb[r] += img[g] * coeff[r][g];
-      } else                /* RGB from RGB (easy) */
-    goto norgb;
-      for (r=0; r < 3; r++) {
-    if (rgb[r] < 0)        rgb[r] = 0;
-    if (rgb[r] > clip_max) rgb[r] = clip_max;
-    img[r] = rgb[r];
-      }
-norgb:
-      for (r=0; r < 3; r++)
-    histogram[r][img[r] >> 3]++;
+-----------------------------------------------------------------------------*/
+    unsigned int row;
+    int r;
+    int g;
+    int c;
+    unsigned short *img;
+    float rgb[3];
+
+    c = 0;  /* initial value */
+
+    if (cmdline.document_mode)
+        colors = 1;
+
+    memset (histogram, 0, sizeof histogram);
+
+    for (row = trim; row < height-trim; ++row) {
+        unsigned int col;
+        for (col = trim; col < width-trim; ++col) {
+            img = image[row*width+col];
+            if (cmdline.document_mode)
+                c = FC(row,col);
+            if (colors == 4 && !use_coeff)    /* Recombine the greens */
+                img[1] = (img[1] + img[3]) >> 1;
+            if (colors == 1) {
+                /* RGB from grayscale */
+                for (r = 0; r < 3; ++r)
+                    rgb[r] = img[c];
+            } else if (use_coeff) {     /* RGB via coeff[][] */
+                for (r = 0; r < 3; ++r) {
+                    for (rgb[r]=g=0; g < colors; g++)
+                        rgb[r] += img[g] * coeff[r][g];
+                }
+            } else                /* RGB from RGB (easy) */
+                goto norgb;
+            for (r = 0; r < 3; ++r) {
+                if (rgb[r] < 0)        rgb[r] = 0;
+                if (rgb[r] > clip_max) rgb[r] = clip_max;
+                img[r] = rgb[r];
+            }
+        norgb:
+            for (r = 0; r < 3; ++r)
+                ++histogram[r][img[r] >> 3];
+        }
     }
 }
 
-static void CLASS fuji_rotate()
-{
-  int i, wide, high, row, col;
-  double step;
-  float r, c, fr, fc;
-  unsigned ur, uc;
-  unsigned short (*img)[4], (*pix)[4];
-
-  if (!fuji_width) return;
-  if (cmdline.verbose)
-    pm_message ("Rotating image 45 degrees...");
-  fuji_width = (fuji_width + shrink) >> shrink;
-  step = sqrt(0.5);
-  wide = fuji_width / step;
-  high = (height - fuji_width) / step;
-  img = calloc (wide*high, sizeof *img);
-  merror (img, "fuji_rotate()");
-
-  for (row=0; row < high; row++)
-    for (col=0; col < wide; col++) {
-      ur = r = fuji_width + (row-col)*step;
-      uc = c = (row+col)*step;
-      if (ur > height-2 || uc > width-2) continue;
-      fr = r - ur;
-      fc = c - uc;
-      pix = image + ur*width + uc;
-      for (i=0; i < colors; i++)
-    img[row*wide+col][i] =
-      (pix[    0][i]*(1-fc) + pix[      1][i]*fc) * (1-fr) +
-      (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
+
+
+static void CLASS
+fujiRotate(Image * const imageP) {
+
+    int wide;
+    int high;
+    unsigned int row;
+    double step;
+    float r, c, fr, fc;
+    unsigned short (*newImage)[4];
+    unsigned short (*pix)[4];
+
+    if (fuji_width > 0) {
+        if (cmdline.verbose)
+            pm_message ("Rotating image 45 degrees...");
+
+        fuji_width = (fuji_width + shrink) >> shrink;
+        step = sqrt(0.5);
+        wide = fuji_width / step;
+        high = (height - fuji_width) / step;
+        newImage = calloc (wide*high, sizeof *newImage);
+        merror (newImage, "fujiRotate()");
+
+        for (row = 0; row < high; ++row) {
+            unsigned int col;
+            for (col = 0; col < wide; ++col) {
+                unsigned int ur = r = fuji_width + (row-col)*step;
+                unsigned int uc = c = (row+col)*step;
+
+                unsigned int i;
+
+                if (ur > height-2 || uc > width-2)
+                    continue;
+
+                fr = r - ur;
+                fc = c - uc;
+                pix = (*imageP) + ur * width + uc;
+
+                for (i = 0; i < colors; ++i) {
+                    newImage[row*wide+col][i] =
+                        (pix[    0][i]*(1-fc) + pix[      1][i]*fc) * (1-fr) +
+                        (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr;
+                } 
+            }
+        }        
+        free(*imageP);
+        width  = wide;
+        height = high;
+        *imageP  = newImage;
+        fuji_width = 0;
     }
-  free (image);
-  width  = wide;
-  height = high;
-  image  = img;
-  fuji_width = 0;
 }
 
-static void CLASS flip_image()
-{
+
+
+static void CLASS
+flipImage(Image const image) {
+
     unsigned *flag;
-    int size, base, dest, next, row, col, temp;
+    int size, base, dest;
 
     struct imageCell {
         unsigned char contents[8];
     };
     struct imageCell * img;
-    struct imageCell hold;
 
     switch ((flip+3600) % 360) {
-    case 270:  flip = 5;  break;
-    case 180:  flip = 3;  break;
-    case  90:  flip = 6;
+    case 270:  flip = 0x5;  break;
+    case 180:  flip = 0x3;  break;
+    case  90:  flip = 0x6;
     }
     img = (struct imageCell *) image;
     size = height * width;
     flag = calloc ((size+31) >> 5, sizeof *flag);
-    merror (flag, "flip_image()");
-    for (base = 0; base < size; base++) {
-        if (flag[base >> 5] & (1 << (base & 31)))
-            continue;
-        dest = base;
-        hold = img[base];
-        while (1) {
-            if (flip & 4) {
-                row = dest % height;
-                col = dest / height;
-            } else {
-                row = dest / width;
-                col = dest % width;
+    merror (flag, "flipImage()");
+    for (base = 0; base < size; ++base) {
+        if (flag[base >> 5] & (1 << (base & 31))) {
+            /* nothing */
+        } else {
+            struct imageCell const hold = img[base];
+            dest = base;
+            while (true) {
+                unsigned int col;
+                unsigned int row;
+                int next;
+                if (flip & 0x4) {
+                    row = dest % height;
+                    col = dest / height;
+                } else {
+                    row = dest / width;
+                    col = dest % width;
+                }
+                if (flip & 0x2)
+                    row = height - 1 - row;
+                if (flip & 1)
+                    col = width - 1 - col;
+                next = row * width + col;
+                if (next == base)
+                    break;
+                flag[next >> 5] |= 1 << (next & 31);
+                img[dest] = img[next];
+                dest = next;
             }
-            if (flip & 2)
-                row = height - 1 - row;
-            if (flip & 1)
-                col = width - 1 - col;
-            next = row * width + col;
-            if (next == base) break;
-            flag[next >> 5] |= 1 << (next & 31);
-            img[dest] = img[next];
-            dest = next;
+            img[dest] = hold;
         }
-        img[dest] = hold;
     }
     free (flag);
-    if (flip & 4) {
-        temp = height;
+    if (flip & 0x4) {
+        int const oldHeight = height;
+        int const oldYmag = ymag;
+
         height = width;
-        width = temp;
-        temp = ymag;
+        width = oldHeight;
         ymag = xmag;
-        xmag = temp;
+        xmag = oldYmag;
     }
 }
 
-/*
-   Write the image as an RGB PAM image
- */
-static void CLASS write_pam_nonlinear (FILE *ofp)
-{
-  unsigned char lut[0x10000];
-  int perc, c, val, total, i, row, col;
-  float white=0, r;
-  struct pam pam;
-  tuple * tuplerow;
-
-  pam.size   = sizeof(pam);
-  pam.len    = PAM_STRUCT_SIZE(tuple_type);
-  pam.file   = ofp;
-  pam.width  = xmag*(width-trim*2);
-  pam.height = ymag*(height-trim*2);
-  pam.depth  = 3;
-  pam.format = PAM_FORMAT;
-  pam.maxval = 255;
-  strcpy(pam.tuple_type, "RGB");
-
-  pnm_writepaminit(&pam);
-
-  tuplerow = pnm_allocpamrow(&pam);
-
-  perc = width * height * 0.01;     /* 99th percentile white point */
-  if (fuji_width) perc /= 2;
-  FORC3 {
-    for (val=0x2000, total=0; --val > 32; )
-      if ((total += histogram[c][val]) > perc) break;
-    if (white < val) white = val;
-  }
-  white *= 8 / cmdline.bright;
-  for (i=0; i < 0x10000; i++) {
-    r = i / white;
-    val = 256 * ( !use_gamma ? r :
-    r <= 0.018 ? r*4.5 : pow(r,0.45)*1.099-0.099 );
-    if (val > 255) val = 255;
-    lut[i] = val;
-  }
-  for (row=trim; row < height-trim; row++) {
-      for (col=trim; col < width-trim; col++) {
-          unsigned int plane;
-          for (plane=0; plane < pam.depth; ++plane) {
-              unsigned int copy;
-              for (copy=0; copy < xmag; ++copy) {
-                  unsigned int const pamcol = xmag*(col-trim)+copy;
-                  tuplerow[pamcol][plane] = lut[image[row*width+col][plane]];
-              }
-          }
-      }
-      {
-          unsigned int copy;
-          for (copy=0; copy < ymag; ++copy)
-              pnm_writepamrow(&pam, tuplerow);
-      }
-  }
-  pnm_freepamrow(tuplerow);
+
+
+static void CLASS
+writePamLinear(FILE * const ofP,
+               Image  const image) {
+/*----------------------------------------------------------------------------
+   Write the image 'image' to a 16-bit PAM file with linear color space
+-----------------------------------------------------------------------------*/
+    unsigned int row;
+
+    struct pam pam;
+    tuple * tuplerow;
+
+    if (maximum < 256)
+        maximum = 256;
+
+    pam.size   = sizeof(pam);
+    pam.len    = PAM_STRUCT_SIZE(tuple_type);
+    pam.file   = ofP;
+    pam.width  = width-trim*2;
+    pam.height = height-trim*2;
+    pam.depth  = 3;
+    pam.format = PAM_FORMAT;
+    pam.maxval = MAX(maximum, 256);
+    strcpy(pam.tuple_type, "RGB");
+
+    pnm_writepaminit(&pam);
+
+    tuplerow = pnm_allocpamrow(&pam);
+
+    for (row = trim; row < height-trim; row++) {
+        unsigned int col;
+        for (col = trim; col < width-trim; col++) {
+            unsigned int const pamCol = col - trim;
+            unsigned int plane;
+            for (plane = 0; plane < 3; ++plane)
+                tuplerow[pamCol][plane] = image[row*width+col][plane];
+        }
+        pnm_writepamrow(&pam, tuplerow);
+    }
+    pnm_freepamrow(tuplerow);
 }
 
-/*
-   Write the image to a 16-bit PAM file with linear color space
- */
-static void CLASS write_pam_linear (FILE *ofp)
-{
-  int row;
-
-  struct pam pam;
-  tuple * tuplerow;
-
-  if (maximum < 256) maximum = 256;
-
-  pam.size   = sizeof(pam);
-  pam.len    = PAM_STRUCT_SIZE(tuple_type);
-  pam.file   = ofp;
-  pam.width  = width-trim*2;
-  pam.height = height-trim*2;
-  pam.depth  = 3;
-  pam.format = PAM_FORMAT;
-  pam.maxval = MAX(maximum, 256);
-  strcpy(pam.tuple_type, "RGB");
-
-  pnm_writepaminit(&pam);
-
-  tuplerow = pnm_allocpamrow(&pam);
-
-  for (row = trim; row < height-trim; row++) {
-      unsigned int col;
-      for (col = trim; col < width-trim; col++) {
-          unsigned int const pamCol = col - trim;
-          unsigned int plane;
-          for (plane = 0; plane < 3; ++plane)
-              tuplerow[pamCol][plane] = image[row*width+col][plane];
-      }
-      pnm_writepamrow(&pam, tuplerow);
-  }
-  pnm_freepamrow(tuplerow);
+
+
+static void CLASS
+writePamNonlinear(FILE * const ofP,
+                  Image  const image) {
+/*----------------------------------------------------------------------------
+  Write the image 'image' as an RGB PAM image
+-----------------------------------------------------------------------------*/
+    unsigned char lut[0x10000];
+    int perc;
+    int c;
+    int total;
+    int i;
+    unsigned int row;
+    float white;
+    float r;
+    struct pam pam;
+    tuple * tuplerow;
+
+    white = 0;  /* initial value */
+
+    pam.size   = sizeof(pam);
+    pam.len    = PAM_STRUCT_SIZE(tuple_type);
+    pam.file   = ofP;
+    pam.width  = xmag*(width-trim*2);
+    pam.height = ymag*(height-trim*2);
+    pam.depth  = 3;
+    pam.format = PAM_FORMAT;
+    pam.maxval = 255;
+    strcpy(pam.tuple_type, "RGB");
+
+    pnm_writepaminit(&pam);
+
+    tuplerow = pnm_allocpamrow(&pam);
+
+    perc = width * height * 0.01;     /* 99th percentile white point */
+    if (fuji_width) perc /= 2;
+    FORC3 {
+        int val;
+        for (val=0x2000, total=0; --val > 32; )
+            if ((total += histogram[c][val]) > perc) break;
+        if (white < val)
+            white = val;
+    }
+    white *= 8 / cmdline.bright;
+    for (i=0; i < 0x10000; ++i) {
+        int val;
+        r = i / white;
+        val = 256 * ( !use_gamma ? r :
+                      r <= 0.018 ? r*4.5 : pow(r,0.45)*1.099-0.099 );
+        if (val > 255)
+            val = 255;
+        lut[i] = val;
+    }
+    for (row = trim; row < height - trim; ++row) {
+        unsigned int col;
+        for (col = trim; col < width - trim; ++col) {
+            unsigned int plane;
+            for (plane=0; plane < pam.depth; ++plane) {
+                unsigned int copy;
+                for (copy=0; copy < xmag; ++copy) {
+                    unsigned int const pamcol = xmag*(col-trim)+copy;
+                    tuplerow[pamcol][plane] = lut[image[row*width+col][plane]];
+                }
+            }
+        }
+        {
+            unsigned int copy;
+            for (copy = 0; copy < ymag; ++copy)
+                pnm_writepamrow(&pam, tuplerow);
+        }
+    }
+    pnm_freepamrow(tuplerow);
 }
 
 
 
 static void CLASS
 writePam(FILE * const ofP,
+         Image  const image,
          bool   const linear) {
 
     if (linear)
-        write_pam_linear(ofP);
+        writePamLinear(ofP, image);
     else
-        write_pam_nonlinear(ofP);
+        writePamNonlinear(ofP, image);
 }
 
 
 
-
 static void CLASS
-convertIt(FILE *    const ifP,
-          FILE *    const ofP,
-          loadRawFn const load_raw) {
+convertIt(FILE *      const ifP,
+          FILE *      const ofP,
+          LoadRawFn * const load_raw) {
+
+    Image image;
 
     shrink = cmdline.half_size && filters;
     iheight = (height + shrink) >> shrink;
@@ -810,16 +857,16 @@ convertIt(FILE *    const ifP,
 
     ifp = ifP;  /* Set global variable for (*load_raw)() */
 
-    load_raw();
-    bad_pixels();
+    load_raw(image);
+    fixBadPixels(image);
     height = iheight;
     width  = iwidth;
     if (is_foveon) {
         if (cmdline.verbose)
             pm_message ("Foveon interpolation...");
-        foveon_interpolate(coeff);
+        foveon_interpolate(image, coeff);
     } else {
-        scale_colors();
+        scaleColors(image);
     }
     if (shrink) filters = 0;
     trim = 0;
@@ -828,25 +875,27 @@ convertIt(FILE *    const ifP,
         if (cmdline.verbose)
             pm_message ("%s interpolation...",
                         cmdline.quick_interpolate ? "Bilinear":"VNG");
-        vng_interpolate();
+        vngInterpolate(image);
     }
-    fuji_rotate();
-    apply_profile(ifP, cmdline.profile);
+    fujiRotate(&image);
     if (cmdline.verbose)
         pm_message ("Converting to RGB colorspace...");
-    convert_to_rgb();
+    convertToRgb(image);
 
     if (flip) {
         if (cmdline.verbose)
             pm_message ("Flipping image %c:%c:%c...",
                         flip & 1 ? 'H':'0', flip & 2 ? 'V':'0', 
                         flip & 4 ? 'T':'0');
-        flip_image();
+        flipImage(image);
     }
-    writePam(ofP, cmdline.linear);
+    writePam(ofP, image, cmdline.linear);
+
+    free(image);
 }
 
 
+
 int 
 main (int argc, char **argv) {
 
@@ -854,7 +903,7 @@ main (int argc, char **argv) {
 
     FILE * ifP;
     int rc;
-    loadRawFn load_raw;
+    LoadRawFn * load_raw;
 
     pnm_init(&argc, argv);
 
@@ -864,8 +913,6 @@ main (int argc, char **argv) {
 
     ifP = pm_openr(cmdline.inputFileName);
 
-    image = NULL;
-    
     rc = identify(ifP,
                   cmdline.use_secondary, cmdline.use_camera_rgb,
                   cmdline.red_scale, cmdline.blue_scale,
@@ -884,7 +931,6 @@ main (int argc, char **argv) {
     }
     pm_close(ifP);
     pm_close(ofP);
-    free(image);
 
     return 0;
 }
diff --git a/converter/other/cameratopam/cameratopam.h b/converter/other/cameratopam/cameratopam.h
new file mode 100644
index 00000000..9ff33cb3
--- /dev/null
+++ b/converter/other/cameratopam/cameratopam.h
@@ -0,0 +1,6 @@
+#ifndef CAMERATOPAM_H_INCLUDED
+#define CAMERATOPAM_H_INCLUDED
+
+typedef unsigned short (*Image)[4];
+
+#endif
diff --git a/converter/other/cameratopam/canon.c b/converter/other/cameratopam/canon.c
index a34771d0..96a6210b 100644
--- a/converter/other/cameratopam/canon.c
+++ b/converter/other/cameratopam/canon.c
@@ -9,7 +9,7 @@
 
 
 void 
-canon_600_load_raw(void) {
+canon_600_load_raw(Image const image) {
     unsigned char  data[1120], *dp;
     unsigned short pixel[896], *pix;
     int irow, orow, col;
@@ -42,7 +42,7 @@ canon_600_load_raw(void) {
 
 
 void
-canon_a5_load_raw(void) {
+canon_a5_load_raw(Image const image) {
     unsigned char  data[1940], *dp;
     unsigned short pixel[1552], *pix;
     int row, col;
@@ -97,7 +97,7 @@ canon_has_lowbits()
 
 
 void 
-canon_compressed_load_raw(void) {
+canon_compressed_load_raw(Image const image) {
     unsigned short *pixel, *prow;
     int lowbits, i, row, r, col, save, val;
     unsigned irow, icol;
diff --git a/converter/other/cameratopam/canon.h b/converter/other/cameratopam/canon.h
index 041cdc4d..fe6a5a08 100644
--- a/converter/other/cameratopam/canon.h
+++ b/converter/other/cameratopam/canon.h
@@ -1,13 +1,12 @@
 #ifndef CANON_H_INCLUDED
 #define CANON_H_INCLUDED
 
-void 
-canon_600_load_raw(void);
+#include "camera.h"
 
-void
-canon_a5_load_raw(void);
+LoadRawFn canon_600_load_raw;
 
-void 
-canon_compressed_load_raw(void);
+LoadRawFn canon_a5_load_raw;
+
+LoadRawFn canon_compressed_load_raw;
 
 #endif
diff --git a/converter/other/cameratopam/foveon.c b/converter/other/cameratopam/foveon.c
index f439bd52..a3e5449a 100644
--- a/converter/other/cameratopam/foveon.c
+++ b/converter/other/cameratopam/foveon.c
@@ -211,7 +211,7 @@ foveon_load_camf() {
 
 
 void  
-foveon_load_raw() {
+foveon_load_raw(Image const image) {
 
     struct decode *dindex;
     short diff[1024], pred[3];
@@ -391,7 +391,8 @@ static int  foveon_apply_curve (short *curve, int i)
 }
 
 void  
-foveon_interpolate(float coeff[3][4]) {
+foveon_interpolate(Image const image,
+                   float coeff[3][4]) {
 
     static const short hood[] = { 
         -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
diff --git a/converter/other/cameratopam/foveon.h b/converter/other/cameratopam/foveon.h
index f3177e50..c9bf48a8 100644
--- a/converter/other/cameratopam/foveon.h
+++ b/converter/other/cameratopam/foveon.h
@@ -1,13 +1,16 @@
 #include "pm.h"
 
+#include "cameratopam.h"
+#include "camera.h"
+
 void 
 parse_foveon(FILE * const ifp);
 
 void  
-foveon_interpolate(float coeff[3][4]);
+foveon_interpolate(Image const image,
+                   float coeff[3][4]);
 
-void 
-foveon_load_raw(void);
+LoadRawFn foveon_load_raw;
 
 void  
 foveon_coeff(int * const useCoeffP,
diff --git a/converter/other/cameratopam/global_variables.h b/converter/other/cameratopam/global_variables.h
index c8732d5a..2bfc08c9 100644
--- a/converter/other/cameratopam/global_variables.h
+++ b/converter/other/cameratopam/global_variables.h
@@ -23,7 +23,6 @@ extern time_t timestamp;
 extern int is_foveon;
 extern int is_dng;
 extern int is_canon;
-extern unsigned short (*image)[4];
 extern int maximum;
 extern int clip_max;
 extern short order;
diff --git a/converter/other/cameratopam/identify.c b/converter/other/cameratopam/identify.c
index b99496b7..cc6a2d8e 100644
--- a/converter/other/cameratopam/identify.c
+++ b/converter/other/cameratopam/identify.c
@@ -21,7 +21,6 @@ static bool const have64BitArithmetic = false;
 #endif
 
 
-static loadRawFn load_raw;
 
 /* This does the same as the function of the same name in the GNU C library */
 static const char *memmem_internal (const char *haystack, size_t haystacklen,
@@ -264,7 +263,7 @@ identify(FILE *       const ifp,
          float        const blue_scale,
          unsigned int const four_color_rgb,
          const char * const inputFileName,
-         loadRawFn *  const loadRawFnP)
+         LoadRawFn ** const loadRawFnP)
 {
     char head[32];
     char * c;
@@ -299,6 +298,7 @@ identify(FILE *       const ifp,
         { "Canon", "NIKON", "EPSON", "Kodak", "OLYMPUS", "PENTAX",
           "MINOLTA", "Minolta", "Konica", "CASIO" };
     float tmp;
+    LoadRawFn * load_raw;
 
     /*  What format is this file?  Set make[] if we recognize it. */
 
@@ -317,9 +317,6 @@ identify(FILE *       const ifp,
     colors = 3;
     for (i=0; i < 0x1000; i++) curve[i] = i;
     maximum = 0xfff;
-#ifdef USE_LCMS
-    profile_length = 0;
-#endif
 
     order = get2(ifp);
     hlen = get4(ifp);
@@ -449,7 +446,7 @@ identify(FILE *       const ifp,
         goto dng_skip;
     }
 
-/*  We'll try to decode anything from Canon or Nikon. */
+    /*  We'll try to decode anything from Canon or Nikon. */
 
     if (!filters) filters = 0x94949494;
     if ((is_canon = !strcmp(make,"Canon")))
@@ -459,7 +456,7 @@ identify(FILE *       const ifp,
         load_raw = nikon_is_compressed() ?
             nikon_compressed_load_raw : nikon_load_raw;
 
-/* Set parameters based on camera name (for non-DNG files). */
+    /* Set parameters based on camera name (for non-DNG files). */
 
     if (is_foveon) {
         if (!have64BitArithmetic)
diff --git a/converter/other/cameratopam/identify.h b/converter/other/cameratopam/identify.h
index 012b807c..62c9aae5 100644
--- a/converter/other/cameratopam/identify.h
+++ b/converter/other/cameratopam/identify.h
@@ -1,4 +1,4 @@
-typedef void (*loadRawFn)();
+#include "camera.h"
 
 int
 identify(FILE *       const ifp,
@@ -8,4 +8,4 @@ identify(FILE *       const ifp,
          float        const blue_scale,
          unsigned int const four_color_rgb,
          const char * const inputFileName,
-         loadRawFn *  const loadRawFnP);
+         LoadRawFn ** const loadRawFnP);
diff --git a/converter/other/cameratopam/ljpeg.c b/converter/other/cameratopam/ljpeg.c
index 18423f4f..29e4ff98 100644
--- a/converter/other/cameratopam/ljpeg.c
+++ b/converter/other/cameratopam/ljpeg.c
@@ -87,9 +87,10 @@ ljpeg_row (struct jhead *jh)
     }
 }
 
+
 void  
-lossless_jpeg_load_raw(void)
-{
+lossless_jpeg_load_raw(Image const image) {
+
   int jwide, jrow, jcol, val, jidx, i, row, col;
   struct jhead jh;
   int min=INT_MAX;
diff --git a/converter/other/cameratopam/ljpeg.h b/converter/other/cameratopam/ljpeg.h
index 60832a3d..cfd68eb4 100644
--- a/converter/other/cameratopam/ljpeg.h
+++ b/converter/other/cameratopam/ljpeg.h
@@ -1,11 +1,12 @@
+#include "camera.h"
+
 struct jhead {
   int bits, high, wide, clrs, vpred[4];
   struct decode *huff[4];
   unsigned short *row;
 };
 
-void  
-lossless_jpeg_load_raw(void);
+LoadRawFn lossless_jpeg_load_raw;
 
 int  
 ljpeg_start (FILE * ifp, struct jhead *jh);