about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2014-09-20 02:04:58 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2014-09-20 02:04:58 +0000
commit09bc6b2a4c9f354d27449d9d39faaa42f88071d4 (patch)
treeb23833aeb967821453c55b1815d0cdb1c089c320
parent9e08489fef2b106a05f983f76fa5f7731dfebba1 (diff)
downloadnetpbm-mirror-09bc6b2a4c9f354d27449d9d39faaa42f88071d4.tar.gz
netpbm-mirror-09bc6b2a4c9f354d27449d9d39faaa42f88071d4.tar.xz
netpbm-mirror-09bc6b2a4c9f354d27449d9d39faaa42f88071d4.zip
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2284 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--converter/other/cameratopam/cameratopam.c326
-rw-r--r--converter/other/cameratopam/dng.c151
-rw-r--r--converter/other/cameratopam/dng.h4
-rw-r--r--converter/other/cameratopam/identify.c68
4 files changed, 320 insertions, 229 deletions
diff --git a/converter/other/cameratopam/cameratopam.c b/converter/other/cameratopam/cameratopam.c
index cd8093ee..40d8207f 100644
--- a/converter/other/cameratopam/cameratopam.c
+++ b/converter/other/cameratopam/cameratopam.c
@@ -63,13 +63,14 @@ int height, width, fuji_width, colors, tiff_samples;
 int black, maximum, clip_max;
 int iheight, iwidth, shrink;
 int is_dng, is_canon, is_foveon, use_coeff, use_gamma;
-int trim, flip, xmag, ymag;
+int flip, xmag, ymag;
 int zero_after_ff;
 unsigned filters;
 unsigned short  white[8][8];
 unsigned short  curve[0x1000];
 int fuji_secondary;
-float cam_mul[4], pre_mul[4], coeff[3][4];
+float cam_mul[4], coeff[3][4];
+float pre_mul[4];
 int histogram[3][0x2000];
 jmp_buf failure;
 int use_secondary;
@@ -86,7 +87,7 @@ static void CLASS merror (const void *ptr, const char *where)
         pm_error ("Out of memory in %s", where);
 }
 
-struct cmdlineInfo {
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
@@ -110,11 +111,11 @@ struct cmdlineInfo {
 };
 
 
-static struct cmdlineInfo cmdline;
+static struct CmdlineInfo cmdline;
 
 static void
 parseCommandLine(int argc, char ** argv,
-                 struct cmdlineInfo *cmdlineP) {
+                 struct CmdlineInfo *cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that many of the strings that this function returns in the
    *cmdlineP structure are actually in the supplied argv array.  And
@@ -196,55 +197,74 @@ 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 (filters) {
+        FILE *fp;
+        char *fname, *cp, line[128];
+        int len, time, row, col, rad, tot, n, fixed=0;
+
+        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++;
+        cp = fname + strlen(fname);
+        if (cp[-1] == '/')
+            --cp;
+        fp = NULL; /* initial value */
+        while (*fname == '/') {
+            strcpy (cp, "/.badpixels");
+            fp = fopen (fname, "r");
+            if (fp)
+                break;
+            if (cp == fname)
+                break;
+            while (*--cp != '/');
+        }
+        free (fname);
+        if (fp) {
+            while (fgets (line, 128, fp)) {
+                char * cp;
+                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++) {
+                    unsigned int r;
+                    for (r = row-rad; r <= row+rad; ++r) {
+                        unsigned int c;
+                        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);
+                }
+                BAYER(row,col) = tot/n;
+                if (cmdline.verbose) {
+                    if (!fixed++)
+                        pm_message ("Fixed bad pixels at: %d,%d", col, row);
+                }
+            }
+            fclose (fp);
         }
     }
-    fclose (fp);
 }
 
 
@@ -258,33 +278,32 @@ scaleColors(Image const image) {
     int shift;
     int min[4], max[4], count[4];
     double sum[4], dmin;
+    int scaleMax;
 
-    shift = 0;  /* initial value */
-
-    maximum -= black;
+    scaleMax = maximum - black;  /* initial value */
     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;
+        FORC4 min  [c] = INT_MAX;
+        FORC4 max  [c] = 0;
+        FORC4 count[c] = 0;
+        FORC4 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];
+                    if (val != 0) {
+                        if (min[c] > val)
+                            min[c] = val;
+                        if (max[c] < val)
+                            max[c] = val;
+                        val -= black;
+                        if (val <= scaleMax-25) {
+                            sum  [c] += MAX(0, val);
+                            count[c] += 1;
+                        }
+                    }
                 }
             }
         }
@@ -320,38 +339,34 @@ scaleColors(Image const image) {
         dmin = pre_mul[c];
     FORC4 pre_mul[c] /= dmin;
 
-    while (maximum << shift < 0x8000)
-        ++shift;
+    for (shift = 0; scaleMax << shift < 0x8000; ++shift);
+
     FORC4 pre_mul[c] *= 1 << shift;
-    maximum <<= shift;
+    scaleMax <<= shift;
 
     if (cmdline.linear || cmdline.bright < 1) {
-        maximum *= cmdline.bright;
-        if (maximum > 0xffff)
-            maximum = 0xffff;
+        scaleMax = MIN(0xffff, scaleMax * cmdline.bright);
         FORC4 pre_mul[c] *= cmdline.bright;
     }
     if (cmdline.verbose) {
-        fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black);
+        fprintf(stderr, "Scaling with black=%d, ", black);
+        fprintf(stderr, "pre_mul[] = ");
         FORC4 fprintf (stderr, " %f", pre_mul[c]);
-        fputc ('\n', stderr);
+        fprintf(stderr, "\n");
     }
-    clip_max = cmdline.no_clip_color ? 0xffff : maximum;
+    clip_max = cmdline.no_clip_color ? 0xffff : scaleMax;
     for (row = 0; row < height; ++row) {
         unsigned int col;
         for (col = 0; col < width; ++col) {
-            FORC4 {
+            unsigned int c;
+            for (c = 0; c < colors; ++c) {
                 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;
+                if (val != 0) {
+                    val -= black;
+                    val *= pre_mul[c];
+                    image[row*width+col][c] = MAX(0, MIN(clip_max, val));
+                }
             }
         }
     }
@@ -536,51 +551,65 @@ vngInterpolate(Image const image) {
 
 
 static void CLASS
-convertToRgb(Image const image) {
+convertToRgb(Image        const image,
+             unsigned int const trim) {
 /*----------------------------------------------------------------------------
    Convert the entire image to RGB colorspace and build a histogram.
+
+   We modify 'image' to change it from whatever it is now to RGB.
 -----------------------------------------------------------------------------*/
     unsigned int row;
-    int r;
-    int g;
-    int c;
-    unsigned short *img;
-    float rgb[3];
+    unsigned int c;
+    float rgb[3];  /* { red, green, blue } */
 
     c = 0;  /* initial value */
 
     if (cmdline.document_mode)
         colors = 1;
 
-    memset (histogram, 0, sizeof histogram);
+    memset(histogram, 0, sizeof histogram);
 
-    for (row = trim; row < height-trim; ++row) {
+    for (row = 0 + trim; row < height - trim; ++row) {
         unsigned int col;
-        for (col = trim; col < width-trim; ++col) {
-            img = image[row*width+col];
+        for (col = 0 + trim; col < width - trim; ++col) {
+            unsigned short * const 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 == 4 && !use_coeff)
+                /* Recombine the greens */
+                img[1] = (img[1] + img[3]) / 2;
+
             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];
+                unsigned int i;
+                for (i = 0; i < 3; ++i)
+                    rgb[i] = img[c];
+            } else if (use_coeff) {
+                /* RGB via coeff[][] */
+                unsigned int i;
+                for (i = 0; i < 3; ++i) {
+                    unsigned int j;
+                    for (j = 0, rgb[i]= 0; j < colors; ++j)
+                        rgb[i] += img[j] * coeff[i][j];
                 }
-            } 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];
+            } else {
+                /* RGB from RGB (easy) */
+                unsigned int i;
+                for (i = 0; i < 3; ++i)
+                    rgb[i] = img[i];
+            }
+            {
+                unsigned int i;
+                for (i = 0; i < 3; ++i)
+                    img[i] = MIN(clip_max, MAX(0, rgb[i]));
+            }
+            {
+                unsigned int i;
+                for (i = 0; i < 3; ++i)
+                    ++histogram[i][img[i] >> 3];
             }
-        norgb:
-            for (r = 0; r < 3; ++r)
-                ++histogram[r][img[r] >> 3];
         }
     }
 }
@@ -707,8 +736,9 @@ flipImage(Image const image) {
 
 
 static void CLASS
-writePamLinear(FILE * const ofP,
-               Image  const image) {
+writePamLinear(FILE *       const ofP,
+               Image        const image,
+               unsigned int const trim) {
 /*----------------------------------------------------------------------------
    Write the image 'image' to a 16-bit PAM file with linear color space
 -----------------------------------------------------------------------------*/
@@ -717,14 +747,11 @@ writePamLinear(FILE * const ofP,
     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.width  = width - trim - trim;
+    pam.height = height - trim - trim;
     pam.depth  = 3;
     pam.format = PAM_FORMAT;
     pam.maxval = MAX(maximum, 256);
@@ -734,9 +761,9 @@ writePamLinear(FILE * const ofP,
 
     tuplerow = pnm_allocpamrow(&pam);
 
-    for (row = trim; row < height-trim; row++) {
+    for (row = 0 + trim; row < height - trim; ++row) {
         unsigned int col;
-        for (col = trim; col < width-trim; col++) {
+        for (col = 0 + trim; col < width - trim; ++col) {
             unsigned int const pamCol = col - trim;
             unsigned int plane;
             for (plane = 0; plane < 3; ++plane)
@@ -750,8 +777,9 @@ writePamLinear(FILE * const ofP,
 
 
 static void CLASS
-writePamNonlinear(FILE * const ofP,
-                  Image  const image) {
+writePamNonlinear(FILE *       const ofP,
+                  Image        const image,
+                  unsigned int const trim) {
 /*----------------------------------------------------------------------------
   Write the image 'image' as an RGB PAM image
 -----------------------------------------------------------------------------*/
@@ -797,19 +825,19 @@ writePamNonlinear(FILE * const ofP,
         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;
+        lut[i] = MIN(255, val);
     }
-    for (row = trim; row < height - trim; ++row) {
+
+    for (row = 0 + trim; row < height - trim; ++row) {
         unsigned int col;
-        for (col = trim; col < width - trim; ++col) {
+        for (col = 0 + trim; col < width - trim; ++col) {
             unsigned int plane;
-            for (plane=0; plane < pam.depth; ++plane) {
+            for (plane = 0; plane < pam.depth; ++plane) {
+                sample const value = lut[image[row*width+col][plane]];
                 unsigned int copy;
-                for (copy=0; copy < xmag; ++copy) {
+                for (copy = 0; copy < xmag; ++copy) {
                     unsigned int const pamcol = xmag*(col-trim)+copy;
-                    tuplerow[pamcol][plane] = lut[image[row*width+col][plane]];
+                    tuplerow[pamcol][plane] = value;
                 }
             }
         }
@@ -825,29 +853,31 @@ writePamNonlinear(FILE * const ofP,
 
 
 static void CLASS
-writePam(FILE * const ofP,
-         Image  const image,
-         bool   const linear) {
+writePam(FILE *       const ofP,
+         Image        const image,
+         bool         const linear,
+         unsigned int const trim) {
 
     if (linear)
-        writePamLinear(ofP, image);
+        writePamLinear(ofP, image, trim);
     else
-        writePamNonlinear(ofP, image);
+        writePamNonlinear(ofP, image, trim);
 }
 
 
 
 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;
+    unsigned int trim;
 
     shrink = cmdline.half_size && filters;
     iheight = (height + shrink) >> shrink;
     iwidth  = (width  + shrink) >> shrink;
-    image = calloc (iheight*iwidth*sizeof *image + meta_length, 1);
+    image = calloc (iheight*iwidth*sizeof(*image) + meta_length, 1);
     merror (image, "main()");
     meta_data = (char *) (image + iheight*iwidth);
     if (cmdline.verbose)
@@ -868,19 +898,23 @@ convertIt(FILE *      const ifP,
     } else {
         scaleColors(image);
     }
-    if (shrink) filters = 0;
-    trim = 0;
+    if (shrink)
+        filters = 0;
+
     if (filters && !cmdline.document_mode) {
         trim = 1;
         if (cmdline.verbose)
             pm_message ("%s interpolation...",
                         cmdline.quick_interpolate ? "Bilinear":"VNG");
         vngInterpolate(image);
-    }
+    } else
+        trim = 0;
+
     fujiRotate(&image);
+
     if (cmdline.verbose)
         pm_message ("Converting to RGB colorspace...");
-    convertToRgb(image);
+    convertToRgb(image, trim);
 
     if (flip) {
         if (cmdline.verbose)
@@ -889,7 +923,7 @@ convertIt(FILE *      const ifP,
                         flip & 4 ? 'T':'0');
         flipImage(image);
     }
-    writePam(ofP, image, cmdline.linear);
+    writePam(ofP, image, cmdline.linear, trim);
 
     free(image);
 }
diff --git a/converter/other/cameratopam/dng.c b/converter/other/cameratopam/dng.c
index 44d45b02..bddfd9f4 100644
--- a/converter/other/cameratopam/dng.c
+++ b/converter/other/cameratopam/dng.c
@@ -4,70 +4,105 @@
 #include "dng.h"
 
 void 
-dng_coeff (double cc[4][4], double cm[4][3], double xyz[3])
-{
-  static const double rgb_xyz[3][3] = {     /* RGB from XYZ */
-    {  3.240479, -1.537150, -0.498535 },
-    { -0.969256,  1.875992,  0.041556 },
-    {  0.055648, -0.204043,  1.057311 } };
+dng_coeff (double cc[4][4],
+           double cm[4][3],
+           double xyz[3]) {
+    static const double rgb_xyz[3][3] = {     /* RGB from XYZ */
+        {  3.240479, -1.537150, -0.498535 },
+        { -0.969256,  1.875992,  0.041556 },
+        {  0.055648, -0.204043,  1.057311 } };
 #if 0
-  static const double xyz_rgb[3][3] = {     /* XYZ from RGB */
-    { 0.412453, 0.357580, 0.180423 },
-    { 0.212671, 0.715160, 0.072169 },
-    { 0.019334, 0.119193, 0.950227 } };
+    static const double xyz_rgb[3][3] = {     /* XYZ from RGB */
+        { 0.412453, 0.357580, 0.180423 },
+        { 0.212671, 0.715160, 0.072169 },
+        { 0.019334, 0.119193, 0.950227 } };
 #endif
-  double cam_xyz[4][3], xyz_cam[3][4], invert[3][6], num;
-  int i, j, k;
+    double cam_xyz[4][3], xyz_cam[3][4], invert[3][6];
+    unsigned int i;
 
-  memset (cam_xyz, 0, sizeof cam_xyz);
-  for (i=0; i < colors; i++)
-    for (j=0; j < 3; j++)
-      for (k=0; k < colors; k++)
-    cam_xyz[i][j] += cc[i][k] * cm[k][j] * xyz[j];
+    for (i = 0; i < colors; ++i) {
+        unsigned int j;
+        for (j = 0; j < 3; ++j) {
+            unsigned int k;
+            for (k = 0, cam_xyz[i][j] = 0.0; k < colors; ++k) {
+                cam_xyz[i][j] += cc[i][k] * cm[k][j] * xyz[j];
+            }
+        }
+    }
+    for (i = 0; i < colors; ++i) {
+        unsigned int j;
+        double camXyzSum;
+
+        for (j = 0, camXyzSum = 0.0; j < 3; ++j)
+            camXyzSum += cam_xyz[i][j];
 
-  for (i=0; i < colors; i++) {
-    for (num=j=0; j < 3; j++)
-      num += cam_xyz[i][j];
-    for (j=0; j < 3; j++)
-      cam_xyz[i][j] /= num;
-    pre_mul[i] = 1 / num;
-  }
-  for (i=0; i < 3; i++) {
-    for (j=0; j < 6; j++)
-      invert[i][j] = j == i+3;
-    for (j=0; j < 3; j++)
-      for (k=0; k < colors; k++)
-    invert[i][j] += cam_xyz[k][i] * cam_xyz[k][j];
-  }
-  for (i=0; i < 3; i++) {
-    num = invert[i][i];
-    for (j=0; j < 6; j++)       /* Normalize row i */
-      invert[i][j] /= num;
-    for (k=0; k < 3; k++) {     /* Subtract it from other rows */
-      if (k==i) continue;
-      num = invert[k][i];
-      for (j=0; j < 6; j++)
-    invert[k][j] -= invert[i][j] * num;
+        for (j = 0; j < 3; ++j)
+            cam_xyz[i][j] /= camXyzSum;
+
+        pre_mul[i] = 1 / camXyzSum;
+    }
+    for (i = 0; i < 3; ++i) {
+        unsigned int j;
+        for (j = 0; j < 6; ++j)
+            invert[i][j] = j == i+3;
+        for (j = 0; j < 3; ++j) {
+            unsigned int k;
+            for (k = 0; k < colors; ++k)
+                invert[i][j] += cam_xyz[k][i] * cam_xyz[k][j];
+        }
     }
-  }
-  memset (xyz_cam, 0, sizeof xyz_cam);
-  for (i=0; i < 3; i++)
-    for (j=0; j < colors; j++)
-      for (k=0; k < 3; k++)
-    xyz_cam[i][j] += invert[i][k+3] * cam_xyz[j][k];
+    for (i = 0; i < 3; ++i) {
+        double const num = invert[i][i];
+        unsigned int j;
+        unsigned int k;
+        for (j = 0; j < 6; ++j)       /* Normalize row i */
+            invert[i][j] /= num;
+        for (k = 0; k < 3; ++k) {     /* Subtract it from other rows */
+            if (k != i) {
+                double const num = invert[k][i];
+                unsigned int j;
+                for (j = 0; j < 6; ++j)
+                    invert[k][j] -= invert[i][j] * num;
+            }
+        }
+    }
+
+    memset(xyz_cam, 0, sizeof xyz_cam);
 
-  memset (coeff, 0, sizeof coeff);
-  for (i=0; i < 3; i++)
-    for (j=0; j < colors; j++)
-      for (k=0; k < 3; k++)
-    coeff[i][j] += rgb_xyz[i][k] * xyz_cam[k][j];
+    for (i = 0; i < 3; ++i) {
+        unsigned int j;
+        for (j = 0; j < colors; ++j) {
+            unsigned int k;
+            for (k = 0; k < 3; ++k)
+                xyz_cam[i][j] += invert[i][k+3] * cam_xyz[j][k];
+        }
+    }
+    memset (coeff, 0, sizeof coeff);
 
-  for (num=j=0; j < colors; j++)
-    num += coeff[1][j];
-  for (i=0; i < 3; i++) {
-    for (j=0; j < colors; j++)
-      coeff[i][j] /= num;
-  }
-  use_coeff = 1;
+    for (i = 0; i < 3; ++i) {
+        unsigned int j;
+        for (j = 0; j < colors; ++j) {
+            unsigned int k;
+            for (k = 0; k < 3; ++k)
+                coeff[i][j] += rgb_xyz[i][k] * xyz_cam[k][j];
+        }
+    }
+    {
+        double greenSum;
+        unsigned int j;
+        unsigned int i;
+
+        for (j = 0, greenSum = 0.0; j < colors; ++j)
+            greenSum += coeff[1][j];
+
+        for (i = 0; i < 3; ++i) {
+            unsigned int j;
+            for (j = 0; j < colors; ++j)
+                coeff[i][j] /= greenSum;
+        }
+    }
+    use_coeff = 1;
 }
 
+
+
diff --git a/converter/other/cameratopam/dng.h b/converter/other/cameratopam/dng.h
index 01e7e0a5..56293563 100644
--- a/converter/other/cameratopam/dng.h
+++ b/converter/other/cameratopam/dng.h
@@ -1,2 +1,4 @@
 void 
-dng_coeff (double cc[4][4], double cm[4][3], double xyz[3]);
+dng_coeff(double cc[4][4],
+          double cm[4][3],
+          double xyz[3]);
diff --git a/converter/other/cameratopam/identify.c b/converter/other/cameratopam/identify.c
index d9b96959..394ba0a7 100644
--- a/converter/other/cameratopam/identify.c
+++ b/converter/other/cameratopam/identify.c
@@ -2,6 +2,8 @@
 #include <string.h>
 
 #include "pm.h"
+#include "pm_c_util.h"
+#include "nstring.h"
 
 #include "global_variables.h"
 #include "util.h"
@@ -33,16 +35,20 @@ static const char *memmem_internal (const char *haystack, size_t haystacklen,
     return NULL;
 }
 
-/*
-  Thanks to Adobe for providing these excellent CAM -> XYZ matrices!
-*/
+
+
 static void 
-adobe_coeff()
-{
-    static const struct {
-        const char *prefix;
+adobeCoeff(const char * const make,
+           const char * const model) {
+    /*
+      Thanks to Adobe for providing these excellent CAM -> XYZ matrices!
+    */
+    struct CoeffTableEntry {
+        const char * prefix;
         short trans[12];
-    } table[] = {
+    }; 
+
+    static struct CoeffTableEntry const table[] = {
         { "Canon EOS D2000C",
           { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
         { "Canon EOS D30",
@@ -228,26 +234,33 @@ adobe_coeff()
     double cm[4][3];
     double xyz[] = { 1,1,1 };
     char name[130];
-    int i, j;
+    unsigned int i;
 
-    for (i=0; i < 4; i++)
-        for (j=0; j < 4; j++)
-            cc[i][j] = i == j;
+    /* Make an identity matrix (1's on the diagonal) */
+    for (i = 0; i < 4; ++i) {
+        unsigned int j;
+        for (j = 0; j < 4; ++j)
+            cc[i][j] = (i == j);
+    }
     sprintf (name, "%s %s", make, model);
-    for (i=0; i < sizeof table / sizeof *table; i++)
-        if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) {
+
+    for (i = 0; i < ARRAY_SIZE(table); ++i) {
+        const struct CoeffTableEntry * const entryP = &table[i];
+
+        if (strneq(name, entryP->prefix, strlen(entryP->prefix))) {
             unsigned int j;
-            for (j=0; j < 12; j++)
-                cm[j/4][j%4] = table[i].trans[j];
-            dng_coeff (cc, cm, xyz);
+            for (j = 0; j < 12; ++j)
+                cm[j/4][j%4] = entryP->trans[j];
+            dng_coeff(cc, cm, xyz);
+
             break;
         }
+    }
 }
 
-/*
-  Identify which camera created this file, and set global variables
-  accordingly.  Return nonzero if the file cannot be decoded.
-*/
+
+
+
 int
 identify(FILE *       const ifp,
          bool         const use_secondary,
@@ -256,8 +269,11 @@ identify(FILE *       const ifp,
          float        const blue_scale,
          unsigned int const four_color_rgb,
          const char * const inputFileName,
-         LoadRawFn ** const loadRawFnP)
-{
+         LoadRawFn ** const loadRawFnP) {
+/*----------------------------------------------------------------------------
+  Identify which camera created this file, and set global variables
+  accordingly.  Return nonzero if the file cannot be decoded.
+-----------------------------------------------------------------------------*/
     char head[32];
     char * c;
     unsigned hlen, fsize, i;
@@ -409,6 +425,9 @@ identify(FILE *       const ifp,
         memmove (model, model+i, 64-i);
     make[63] = model[63] = model2[63] = 0;
 
+    if (verbose)
+        fprintf(stderr, "Make = '%s', Model = '%s'\n", make, model);
+
     if (make[0] == 0) {
         pm_message ("unrecognized file format.");
         return 1;
@@ -1142,7 +1161,8 @@ identify(FILE *       const ifp,
             flip = 2;
         }
     }
-    if (!use_coeff) adobe_coeff();
+    if (!use_coeff)
+        adobeCoeff(make, model);
 dng_skip:
     if (!load_raw || !height) {
         pm_message ("This program cannot handle data from %s %s.",