about summary refs log tree commit diff
path: root/converter/other
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2017-06-30 03:27:10 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2017-06-30 03:27:10 +0000
commit08d938dc6fc6b30e5da6733b52c97169c0d24f8a (patch)
tree92673cd6a5755fc209078cc6b6a42602defc0212 /converter/other
parente21f4e95d897c93a4779bf78c71f1341d164a222 (diff)
downloadnetpbm-mirror-08d938dc6fc6b30e5da6733b52c97169c0d24f8a.tar.gz
netpbm-mirror-08d938dc6fc6b30e5da6733b52c97169c0d24f8a.tar.xz
netpbm-mirror-08d938dc6fc6b30e5da6733b52c97169c0d24f8a.zip
Copy Development as new Advanced
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@3018 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other')
-rw-r--r--converter/other/bmptopnm.c6
-rw-r--r--converter/other/cameratopam/camera.c6
-rw-r--r--converter/other/cameratopam/foveon.c2
-rw-r--r--converter/other/fiasco/codec/approx.c563
-rw-r--r--converter/other/pamtosvg/vector.c2
-rw-r--r--converter/other/pamtotiff.c81
-rw-r--r--converter/other/svgtopam.c253
-rw-r--r--converter/other/tifftopnm.c2
8 files changed, 483 insertions, 432 deletions
diff --git a/converter/other/bmptopnm.c b/converter/other/bmptopnm.c
index 49e730fd..018b8326 100644
--- a/converter/other/bmptopnm.c
+++ b/converter/other/bmptopnm.c
@@ -1400,8 +1400,8 @@ isValidBmpBpp(unsigned int const cBitCount) {
 static void
 readBmp(FILE *               const ifP, 
         unsigned char ***    const bmpRasterP, 
-        int *                const colsP, 
-        int *                const rowsP,
+        unsigned int *       const colsP, 
+        unsigned int *       const rowsP,
         bool *               const grayPresentP, 
         bool *               const colorPresentP,
         unsigned int *       const cBitCountP, 
@@ -1566,7 +1566,7 @@ main(int argc, const char ** argv) {
            black and white and whether it has colors other than black, white,
            and gray.
         */
-    int cols, rows;
+    unsigned int cols, rows;
     unsigned char ** bmpRaster;
         /* The raster part of the BMP image, as a row x column array, with
            each element being a raw byte from the BMP raster.  Note that
diff --git a/converter/other/cameratopam/camera.c b/converter/other/cameratopam/camera.c
index 503551f1..f6196777 100644
--- a/converter/other/cameratopam/camera.c
+++ b/converter/other/cameratopam/camera.c
@@ -1023,6 +1023,7 @@ static void  sony_decrypt (unsigned *data, int len, int start, int key)
 {
   static uint32_t pad[128];
   unsigned int p;
+  unsigned int i;
 
   if (start) {
     for (p=0; p < 4; p++)
@@ -1047,8 +1048,9 @@ static void  sony_decrypt (unsigned *data, int len, int start, int key)
         pad[p] = u.word;
     }
   }
-  while (len--)
-    *data++ ^= pad[p++ & 0x7f] = pad[(p+1) & 0x7f] ^ pad[(p+65) & 0x7f];
+  for (i = 0, p = 0; i < len; ++i, ++p) {
+    *data++ ^= pad[p & 0x7f] = pad[(p+1) & 0x7f] ^ pad[(p+65) & 0x7f];
+  }
 }
 
 void
diff --git a/converter/other/cameratopam/foveon.c b/converter/other/cameratopam/foveon.c
index a3e5449a..992f3883 100644
--- a/converter/other/cameratopam/foveon.c
+++ b/converter/other/cameratopam/foveon.c
@@ -1,6 +1,6 @@
 /* This code is licensed to the public by its copyright owners under GPL. */
 
-#define _XOPEN_SOURCE   /* get M_PI */
+#define _XOPEN_SOURCE 500  /* get M_PI in math.h */
 
 #include <stdio.h>
 #include <assert.h>
diff --git a/converter/other/fiasco/codec/approx.c b/converter/other/fiasco/codec/approx.c
index d47bac62..d8fefcaa 100644
--- a/converter/other/fiasco/codec/approx.c
+++ b/converter/other/fiasco/codec/approx.c
@@ -294,9 +294,9 @@ static bool_t used [MAXSTATES];
 
 static void 
 matching_pursuit (mp_t *mp, bool_t full_search, real_t price,
-          unsigned max_edges, int y_state, const range_t *range,
-          const domain_pool_t *domain_pool, const coeff_t *coeff,
-          const wfa_t *wfa, const coding_t *c)
+                  unsigned max_edges, int y_state, const range_t *range,
+                  const domain_pool_t *domain_pool, const coeff_t *coeff,
+                  const wfa_t *wfa, const coding_t *c)
 /*
  *  Find an approximation of the current 'range' with a linear
  *  combination of vectors of the 'domain_pool'. The linear
@@ -320,303 +320,310 @@ matching_pursuit (mp_t *mp, bool_t full_search, real_t price,
  *  vectors, factors, rate, distortion and costs are stored in 'mp'
  */
 {
-   unsigned  n;         /* current vector of the OB */
-   int       index;         /* best fitting domain image */
-   unsigned  domain;        /* counter */
-   real_t    norm;          /* norm of range image */
-   real_t    additional_bits;   /* bits for mc, nd, and tree */
-   word_t   *domain_blocks;     /* current set of domain images */
-   const real_t  min_norm = 2e-3;   /* lower bound of norm */
-   unsigned      best_n   = 0;
-   unsigned  size     = size_of_level (range->level);
+    unsigned  n;         /* current vector of the OB */
+    int       index;         /* best fitting domain image */
+    unsigned  domain;        /* counter */
+    real_t    norm;          /* norm of range image */
+    real_t    additional_bits;   /* bits for mc, nd, and tree */
+    word_t   *domain_blocks;     /* current set of domain images */
+    const real_t  min_norm = 2e-3;   /* lower bound of norm */
+    unsigned      best_n   = 0;
+    unsigned  size     = size_of_level (range->level);
  
-   /*
-    *  Initialize domain pool and inner product arrays
-    */
-   domain_blocks = domain_pool->generate (range->level, y_state, wfa,
-                      domain_pool->model);
-   for (domain = 0; domain_blocks [domain] >= 0; domain++)
-   {
-      used [domain] = NO;
-      rem_denominator [domain]      /* norm of domain */
-     = get_ip_state_state (domain_blocks [domain], domain_blocks [domain],
-                   range->level, c);
-      if (rem_denominator [domain] / size < min_norm)
-     used [domain] = YES;       /* don't use domains with small norm */
-      else
-     rem_numerator [domain]     /* inner product <s_domain, b> */
-        = get_ip_image_state (range->image, range->address,
-                  range->level, domain_blocks [domain], c);
-      if (!used [domain] && fabs (rem_numerator [domain]) < min_norm)
-     used [domain] = YES;
-   }
+    /*
+     *  Initialize domain pool and inner product arrays
+     */
+    domain_blocks = domain_pool->generate (range->level, y_state, wfa,
+                                           domain_pool->model);
+    for (domain = 0; domain_blocks [domain] >= 0; domain++)
+    {
+        used [domain] = NO;
+        rem_denominator [domain] =     /* norm of domain */
+            get_ip_state_state (domain_blocks [domain], domain_blocks [domain],
+                                range->level, c);
+        if (rem_denominator [domain] / size < min_norm)
+            used [domain] = YES;       /* don't use domains with small norm */
+        else
+            rem_numerator [domain]     /* inner product <s_domain, b> */
+                = get_ip_image_state (range->image, range->address,
+                                      range->level, domain_blocks [domain], c);
+        if (!used [domain] && fabs (rem_numerator [domain]) < min_norm)
+            used [domain] = YES;
+    }
 
-   /*
-    *  Exclude all domain blocks given in array 'mp->exclude'
-    */
-   for (n = 0; isdomain (mp->exclude [n]); n++)
-      used [mp->exclude [n]] = YES;
+    /*
+     *  Exclude all domain blocks given in array 'mp->exclude'
+     */
+    for (n = 0; isdomain (mp->exclude [n]); n++)
+        used [mp->exclude [n]] = YES;
 
-   /*
-    *  Compute the approximation costs if 'range' is approximated with
-    *  no linear combination, i.e. the error is equal to the square
-    *  of the image norm and the size of the automaton is determined by
-    *  storing only zero elements in the current matrix row
-    */
-   for (norm = 0, n = 0; n < size; n++)
-      norm += square (c->pixels [range->address * size + n]);
-
-   additional_bits = range->tree_bits + range->mv_tree_bits
-             + range->mv_coord_bits + range->nd_tree_bits
-             + range->nd_weights_bits;
-
-   mp->err          = norm;
-   mp->weights_bits = 0;
-   mp->matrix_bits  = domain_pool->bits (domain_blocks, NULL, range->level,
-                     y_state, wfa, domain_pool->model);
-   mp->costs        = (mp->matrix_bits + mp->weights_bits
-               + additional_bits) * price + mp->err;
-
-   n = 0;
-   do 
-   {
-      /*
-       *  Current approximation is: b = d_0 o_0 + ... + d_(n-1) o_(n-1)
-       *  with corresponding costs 'range->err + range->bits * p'.
-       *  For all remaining state images s_i (used[s_i] == NO) set
-       *  o_n : = s_i - \sum(k = 0, ... , n-1) {(<s_i, o_k> / ||o_k||^2) o_k}
-       *  and try to beat current costs.
-       *  Choose that vector for the next orthogonalization step,
-       *  which has minimal costs: s_index.
-       *  (No progress is indicated by index == -1)
-       */
-      
-      real_t min_matrix_bits  = 0;
-      real_t min_weights_bits = 0;
-      real_t min_error        = 0;
-      real_t min_weight [MAXEDGES];
-      real_t min_costs = full_search ? MAXCOSTS : mp->costs;
-      
-      for (index = -1, domain = 0; domain_blocks [domain] >= 0; domain++) 
-     if (!used [domain]) 
-     {
-        real_t    matrix_bits, weights_bits;
+    /*
+     *  Compute the approximation costs if 'range' is approximated with
+     *  no linear combination, i.e. the error is equal to the square
+     *  of the image norm and the size of the automaton is determined by
+     *  storing only zero elements in the current matrix row
+     */
+    for (norm = 0, n = 0; n < size; n++)
+        norm += square (c->pixels [range->address * size + n]);
+
+    additional_bits = range->tree_bits + range->mv_tree_bits
+        + range->mv_coord_bits + range->nd_tree_bits
+        + range->nd_weights_bits;
+
+    mp->err          = norm;
+    mp->weights_bits = 0;
+    mp->matrix_bits  = domain_pool->bits (domain_blocks, NULL, range->level,
+                                          y_state, wfa, domain_pool->model);
+    mp->costs        = (mp->matrix_bits + mp->weights_bits
+                        + additional_bits) * price + mp->err;
+
+    n = 0;
+    do 
+    {
         /*
-         *  To speed up the search through the domain images,
-         *  the costs of using domain image 'domain' as next vector
-         *  can be approximated in a first step:
-         *  improvement of image quality
-         *    <= square (rem_numerator[domain]) / rem_denominator[domain]
+         *  Current approximation is: b = d_0 o_0 + ... + d_(n-1) o_(n-1)
+         *  with corresponding costs 'range->err + range->bits * p'.
+         *  For all remaining state images s_i (used[s_i] == NO) set
+         *  o_n : = s_i - \sum(k = 0, ... , n-1) {(<s_i, o_k> / ||o_k||^2) o_k}
+         *  and try to beat current costs.
+         *  Choose that vector for the next orthogonalization step,
+         *  which has minimal costs: s_index.
+         *  (No progress is indicated by index == -1)
          */
-        {
-          word_t   vectors [MAXEDGES + 1];
-          word_t   states [MAXEDGES + 1];
-          real_t   weights [MAXEDGES + 1];
-          unsigned i, k;
+      
+        real_t min_matrix_bits  = 0;
+        real_t min_weights_bits = 0;
+        real_t min_error        = 0;
+        real_t min_weight [MAXEDGES];
+        real_t min_costs = full_search ? MAXCOSTS : mp->costs;
+      
+        for (index = -1, domain = 0; domain_blocks [domain] >= 0; domain++) 
+            if (!used [domain]) 
+            {
+                real_t    matrix_bits, weights_bits;
+                /*
+                 *  To speed up the search through the domain images,
+                 *  the costs of using domain image 'domain' as next vector
+                 *  can be approximated in a first step:
+                 *  improvement of image quality
+                 *  <= square (rem_numerator[domain]) / rem_denominator[domain]
+                 */
+                {
+                    word_t   vectors [MAXEDGES + 1];
+                    word_t   states [MAXEDGES + 1];
+                    real_t   weights [MAXEDGES + 1];
+                    unsigned i, k;
           
-          for (i = 0, k = 0; k < n; k++)
-             if (mp->weight [k] != 0)
-             {
-            vectors [i] = mp->indices [k];
-            states [i]  = domain_blocks [vectors [i]];
-            weights [i] = mp->weight [k];
-            i++;
-             }
-          vectors [i]     = domain;
-          states [i]      = domain_blocks [domain];
-          weights [i]     = 0.5;
-          vectors [i + 1] = -1;
-          states [i + 1]  = -1;
-
-          weights_bits = coeff->bits (weights, states, range->level,
-                          coeff);
-          matrix_bits = domain_pool->bits (domain_blocks, vectors,
-                           range->level, y_state,
-                           wfa, domain_pool->model);
-        }
-        if (((matrix_bits + weights_bits + additional_bits) * price +
-         mp->err -
-         square (rem_numerator [domain]) / rem_denominator [domain])
-        < min_costs)
-        {
-           /*
-        *  1.) Compute the weights (linear factors) c_i of the
-        *  linear combination
-        *  b = c_0 v_0 + ... + c_(n-1) v_(n-1) + c_n v_'domain'
-        *  Use backward substitution to obtain c_i from the linear
-        *  factors of the lin. comb. b = d_0 o_0 + ... + d_n o_n
-        *  of the corresponding orthogonal vectors {o_0, ..., o_n}.
-        *  Vector o_n of the orthogonal basis is obtained by using
-        *  vector 'v_domain' in step n of the Gram Schmidt
-        *  orthogonalization (see above for definition of o_n).
-        *  Recursive formula for the coefficients c_i:
-        *  c_n := <b, o_n> / ||o_n||^2
-        *  for i = n - 1, ... , 0:
-        *  c_i := <b, o_i> / ||o_i||^2 +
-        *          \sum (k = i + 1, ... , n){ c_k <v_k, o_i>
-        *                   / ||o_i||^2 }
-        *  2.) Because linear factors are stored with reduced precision
-        *  factor c_i is rounded with the given precision in step i
-        *  of the recursive formula. 
-        */
-
-           unsigned k;      /* counter */
-           int      l;      /* counter */
-           real_t   m_bits;     /* number of matrix bits to store */
-           real_t   w_bits;     /* number of weights bits to store */
-           real_t   r [MAXEDGES];   /* rounded linear factors */
-           real_t   f [MAXEDGES];   /* linear factors */
-           int      v [MAXEDGES];   /* mapping of domains to vectors */
-           real_t   costs;      /* current approximation costs */
-           real_t   m_err;      /* current approximation error */
-
-           f [n] = rem_numerator [domain] / rem_denominator [domain];
-           v [n] = domain;      /* corresponding mapping */
-           for (k = 0; k < n; k++)
-           {
-          f [k] = ip_image_ortho_vector [k] / norm_ortho_vector [k];
-          v [k] = mp->indices [k];
-           }
+                    for (i = 0, k = 0; k < n; k++)
+                        if (mp->weight [k] != 0)
+                        {
+                            vectors [i] = mp->indices [k];
+                            states [i]  = domain_blocks [vectors [i]];
+                            weights [i] = mp->weight [k];
+                            i++;
+                        }
+                    vectors [i]     = domain;
+                    states [i]      = domain_blocks [domain];
+                    weights [i]     = 0.5;
+                    vectors [i + 1] = -1;
+                    states [i + 1]  = -1;
+
+                    weights_bits = coeff->bits (weights, states, range->level,
+                                                coeff);
+                    matrix_bits = domain_pool->bits (domain_blocks, vectors,
+                                                     range->level, y_state,
+                                                     wfa, domain_pool->model);
+                }
+                if (((matrix_bits + weights_bits + additional_bits) * price +
+                     mp->err -
+                     square (rem_numerator[domain]) / rem_denominator[domain])
+                    < min_costs)
+                {
+                    /*
+                     *  1.) Compute the weights (linear factors) c_i of the
+                     *  linear combination
+                     *  b = c_0 v_0 + ... + c_(n-1) v_(n-1) + c_n v_'domain'
+                     *  Use backward substitution to obtain c_i from the linear
+                     *  factors of the lin. comb. b = d_0 o_0 + ... + d_n o_n
+                     *  of the corresponding orthogonal vectors {o_0, ..., o_n}.
+                     *  Vector o_n of the orthogonal basis is obtained by using
+                     *  vector 'v_domain' in step n of the Gram Schmidt
+                     *  orthogonalization (see above for definition of o_n).
+                     *  Recursive formula for the coefficients c_i:
+                     *  c_n := <b, o_n> / ||o_n||^2
+                     *  for i = n - 1, ... , 0:
+                     *  c_i := <b, o_i> / ||o_i||^2 +
+                     *          \sum (k = i + 1, ... , n){ c_k <v_k, o_i>
+                     *                   / ||o_i||^2 }
+                     *  2.) Because linear factors are stored with reduced
+                     *  precision factor c_i is rounded with the given
+                     *  precision in step i of the recursive formula.
+                     */
+
+                    unsigned k;      /* counter */
+                    int      l;      /* counter */
+                    real_t   m_bits;     /* number of matrix bits to store */
+                    real_t   w_bits;     /* number of weights bits to store */
+                    real_t   r [MAXEDGES];   /* rounded linear factors */
+                    real_t   f [MAXEDGES];   /* linear factors */
+                    int      v [MAXEDGES];   /* mapping of domains to vectors*/
+                    real_t   costs;      /* current approximation costs */
+                    real_t   m_err;      /* current approximation error */
+
+                    f [n] = rem_numerator [domain] / rem_denominator [domain];
+                    v [n] = domain;      /* corresponding mapping */
+                    for (k = 0; k < n; k++)
+                    {
+                        f[k] = ip_image_ortho_vector[k] / norm_ortho_vector[k];
+                        v [k] = mp->indices [k];
+                    }
         
-           for (l = n; l >= 0; l--) 
-           {
-          rpf_t *rpf = domain_blocks [v [l]]
-                   ? coeff->rpf : coeff->dc_rpf;
+                    for (l = n; l >= 0; --l) {
+                        rpf_t * const rpf = domain_blocks[v[l]]
+                            ? coeff->rpf : coeff->dc_rpf;
+
+                        unsigned int k;
 
-          r [l] = f [l] = btor (rtob (f [l], rpf), rpf);
+                        r[l] = f[l] = btor(rtob(f[l], rpf), rpf);
+
+                        {
+                            real_t const fl = f[l];
              
-          for (k = 0; k < (unsigned) l; k++)
-             f [k] -= f [l] * ip_domain_ortho_vector [v [l]][k]
-                  / norm_ortho_vector [k] ;
-           } 
-
-           /*
-        *  Compute the number of output bits of the linear combination
-        *  and store the weights with reduced precision. The
-        *  resulting linear combination is
-        *  b = r_0 v_0 + ... + r_(n-1) v_(n-1) + r_n v_'domain'
-        */
-           {
-          word_t vectors [MAXEDGES + 1];
-          word_t states [MAXEDGES + 1];
-          real_t weights [MAXEDGES + 1];
-          int    i;
+                            for (k = 0; k < l; ++k) {
+                                f[k] -= fl * ip_domain_ortho_vector[v[l]][k]
+                                    / norm_ortho_vector[k];
+                            }
+                        }
+                    } 
+
+                    /*
+                     *  Compute the number of output bits of the linear
+                     *  combination and store the weights with reduced
+                     *  precision. The resulting linear combination is
+                     *  b = r_0 v_0 + ... + r_(n-1) v_(n-1) + r_n v_'domain'
+                     */
+                    {
+                        word_t vectors [MAXEDGES + 1];
+                        word_t states [MAXEDGES + 1];
+                        real_t weights [MAXEDGES + 1];
+                        int    i;
           
-          for (i = 0, k = 0; k <= n; k++)
-             if (f [k] != 0)
-             {
-            vectors [i] = v [k];
-            states [i]  = domain_blocks [v [k]];
-            weights [i] = f [k];
-            i++;
-             }
-          vectors [i] = -1;
-          states [i]  = -1;
-
-          w_bits = coeff->bits (weights, states, range->level, coeff);
-          m_bits = domain_pool->bits (domain_blocks, vectors,
-                          range->level, y_state,
-                          wfa, domain_pool->model);
-           }
+                        for (i = 0, k = 0; k <= n; k++)
+                            if (f [k] != 0)
+                            {
+                                vectors [i] = v [k];
+                                states [i]  = domain_blocks [v [k]];
+                                weights [i] = f [k];
+                                i++;
+                            }
+                        vectors [i] = -1;
+                        states [i]  = -1;
+
+                        w_bits =
+                            coeff->bits(weights, states, range->level, coeff);
+                        m_bits = domain_pool->bits (domain_blocks, vectors,
+                                                    range->level, y_state,
+                                                    wfa, domain_pool->model);
+                    }
            
-           /*
-        *  To compute the approximation error, the corresponding
-        *  linear factors of the linear combination 
-        *  b = r_0 o_0 + ... + r_(n-1) o_(n-1) + r_n o_'domain'
-        *  with orthogonal vectors must be computed with following
-        *  formula:
-        *  r_i := r_i +
-        *          \sum (k = i + 1, ... , n) { r_k <v_k, o_i>
-        *                   / ||o_i||^2 }
-        */
-           for (l = 0; (unsigned) l <= n; l++)
-           {
-          /*
-           *  compute <v_n, o_n>
-           */
-          real_t a;
-
-          a = get_ip_state_state (domain_blocks [v [l]],
-                      domain_blocks [domain],
-                      range->level, c);
-          for (k = 0; k < n; k++) 
-             a -= ip_domain_ortho_vector [v [l]][k]
-              / norm_ortho_vector [k]
-              * ip_domain_ortho_vector [domain][k];
-          ip_domain_ortho_vector [v [l]][n] = a;
-           }
-           norm_ortho_vector [n]     = rem_denominator [domain];
-           ip_image_ortho_vector [n] = rem_numerator [domain];
+                    /*
+                     *  To compute the approximation error, the corresponding
+                     *  linear factors of the linear combination 
+                     *  b = r_0 o_0 + ... + r_(n-1) o_(n-1) + r_n o_'domain'
+                     *  with orthogonal vectors must be computed with following
+                     *  formula:
+                     *  r_i := r_i +
+                     *          \sum (k = i + 1, ... , n) { r_k <v_k, o_i>
+                     *                   / ||o_i||^2 }
+                     */
+                    for (l = 0; (unsigned) l <= n; l++)
+                    {
+                        /*
+                         *  compute <v_n, o_n>
+                         */
+                        real_t a;
+
+                        a = get_ip_state_state (domain_blocks [v [l]],
+                                                domain_blocks [domain],
+                                                range->level, c);
+                        for (k = 0; k < n; k++) 
+                            a -= ip_domain_ortho_vector [v [l]][k]
+                                / norm_ortho_vector [k]
+                                * ip_domain_ortho_vector [domain][k];
+                        ip_domain_ortho_vector [v [l]][n] = a;
+                    }
+                    norm_ortho_vector [n]     = rem_denominator [domain];
+                    ip_image_ortho_vector [n] = rem_numerator [domain];
         
-           for (k = 0; k <= n; k++)
-          for (l = k + 1; (unsigned) l <= n; l++)
-             r [k] += ip_domain_ortho_vector [v [l]][k] * r [l]
-                  / norm_ortho_vector [k];
-           /*
-        *  Compute approximation error:
-        *  error := ||b||^2 +
-        *  \sum (k = 0, ... , n){r_k^2 ||o_k||^2 - 2 r_k <b, o_k>}
-        */
-           m_err = norm;
-           for (k = 0; k <= n; k++)
-          m_err += square (r [k]) * norm_ortho_vector [k]
-             - 2 * r [k] * ip_image_ortho_vector [k];
-           if (m_err < 0)       /* TODO: return MAXCOSTS */
-          warning ("Negative image norm: %f"
-               " (current domain: %d, level = %d)",
-               (double) m_err, domain, range->level);
-
-           costs = (m_bits + w_bits + additional_bits) * price + m_err;
-           if (costs < min_costs)   /* found a better approximation */
-           {
-          index            = domain;
-          min_costs        = costs;
-          min_matrix_bits  = m_bits;
-          min_weights_bits = w_bits;
-          min_error        = m_err;
-          for (k = 0; k <= n; k++)
-             min_weight [k] = f [k];
-           }
-        }
-     }
+                    for (k = 0; k <= n; k++)
+                        for (l = k + 1; (unsigned) l <= n; l++)
+                            r [k] += ip_domain_ortho_vector [v [l]][k] * r [l]
+                                / norm_ortho_vector [k];
+                    /*
+                     *  Compute approximation error:
+                     *  error := ||b||^2 +
+                     *  \sum (k = 0, ... , n){r_k^2 ||o_k||^2 - 2 r_k <b, o_k>}
+                     */
+                    m_err = norm;
+                    for (k = 0; k <= n; k++)
+                        m_err += square (r [k]) * norm_ortho_vector [k]
+                            - 2 * r [k] * ip_image_ortho_vector [k];
+                    if (m_err < 0)       /* TODO: return MAXCOSTS */
+                        warning ("Negative image norm: %f"
+                                 " (current domain: %d, level = %d)",
+                                 (double) m_err, domain, range->level);
+
+                    costs = (m_bits + w_bits + additional_bits) * price + m_err;
+                    if (costs < min_costs)   /* found a better approximation */
+                    {
+                        index            = domain;
+                        min_costs        = costs;
+                        min_matrix_bits  = m_bits;
+                        min_weights_bits = w_bits;
+                        min_error        = m_err;
+                        for (k = 0; k <= n; k++)
+                            min_weight [k] = f [k];
+                    }
+                }
+            }
       
-      if (index >= 0)           /* found a better approximation */
-      {
-     if (min_costs < mp->costs)
-     {
-        unsigned k;
+        if (index >= 0)           /* found a better approximation */
+        {
+            if (min_costs < mp->costs)
+            {
+                unsigned k;
         
-        mp->costs        = min_costs;
-        mp->err          = min_error;
-        mp->matrix_bits  = min_matrix_bits;
-        mp->weights_bits = min_weights_bits;
+                mp->costs        = min_costs;
+                mp->err          = min_error;
+                mp->matrix_bits  = min_matrix_bits;
+                mp->weights_bits = min_weights_bits;
         
-        for (k = 0; k <= n; k++)
-           mp->weight [k] = min_weight [k];
+                for (k = 0; k <= n; k++)
+                    mp->weight [k] = min_weight [k];
 
-        best_n = n + 1;
-     }
+                best_n = n + 1;
+            }
      
-     mp->indices [n] = index;
-     mp->into [n]    = domain_blocks [index];
+            mp->indices [n] = index;
+            mp->into [n]    = domain_blocks [index];
 
-     used [index] = YES;
+            used [index] = YES;
 
-     /* 
-      *  Gram-Schmidt orthogonalization step n 
-      */
-     orthogonalize (index, n, range->level, min_norm, domain_blocks, c);
-     n++;
-      } 
-   } 
-   while (n < max_edges && index >= 0);
+            /* 
+             *  Gram-Schmidt orthogonalization step n 
+             */
+            orthogonalize (index, n, range->level, min_norm, domain_blocks, c);
+            n++;
+        } 
+    } 
+    while (n < max_edges && index >= 0);
 
-   mp->indices [best_n] = NO_EDGE;
+    mp->indices [best_n] = NO_EDGE;
    
-   mp->costs = (mp->matrix_bits + mp->weights_bits + additional_bits) * price
-           + mp->err;
+    mp->costs = (mp->matrix_bits + mp->weights_bits + additional_bits) * price
+        + mp->err;
 
-   Free (domain_blocks);
+    Free (domain_blocks);
 }
 
 static void
diff --git a/converter/other/pamtosvg/vector.c b/converter/other/pamtosvg/vector.c
index 0a5ef3a9..771e5f27 100644
--- a/converter/other/pamtosvg/vector.c
+++ b/converter/other/pamtosvg/vector.c
@@ -1,6 +1,6 @@
 /* vector.c: vector/point operations. */
 
-#define _XOPEN_SOURCE   /* Make sure M_PI is in <math.h> */
+#define _XOPEN_SOURCE 500  /* get M_PI in math.h */
 #include <math.h>
 #include <errno.h>
 #include <assert.h>
diff --git a/converter/other/pamtotiff.c b/converter/other/pamtotiff.c
index 32057e55..139b1fd7 100644
--- a/converter/other/pamtotiff.c
+++ b/converter/other/pamtotiff.c
@@ -136,6 +136,44 @@ validateTagList(struct optNameValue const taglist[]) {
 
 
 static void
+parseIndexbits(bool          const indexbitsSpec,
+               char **       const indexbits,
+               CmdlineInfo * const cmdlineP) {
+
+    if (indexbitsSpec) {
+        unsigned int i;
+
+        /* Set initial values */
+        cmdlineP->indexsizeAllowed.b1 = FALSE;
+        cmdlineP->indexsizeAllowed.b2 = FALSE;
+        cmdlineP->indexsizeAllowed.b4 = FALSE;
+        cmdlineP->indexsizeAllowed.b8 = FALSE;
+
+        for (i = 0; indexbits[i]; ++i) {
+            const char * const thisItem = indexbits[i];
+            if (streq(thisItem, "1"))
+                cmdlineP->indexsizeAllowed.b1 = TRUE;
+            else if (streq(thisItem, "2"))
+                cmdlineP->indexsizeAllowed.b2 = TRUE;
+            else if (streq(thisItem, "4"))
+                cmdlineP->indexsizeAllowed.b4 = TRUE;
+            else if (streq(thisItem, "8"))
+                cmdlineP->indexsizeAllowed.b8 = TRUE;
+            else
+                pm_error("Invalid item in -indexbits list: '%s'.  "
+                         "We recognize only 1, 2, 4, and 8", thisItem);
+        }           
+    } else {
+        cmdlineP->indexsizeAllowed.b1 = FALSE;
+        cmdlineP->indexsizeAllowed.b2 = FALSE;
+        cmdlineP->indexsizeAllowed.b4 = FALSE;
+        cmdlineP->indexsizeAllowed.b8 = TRUE;
+    }
+}
+
+
+
+static void
 parseCommandLine(int                 argc,
                  const char ** const argv,
                  CmdlineInfo * const cmdlineP) {
@@ -149,7 +187,7 @@ parseCommandLine(int                 argc,
 
     unsigned int none, packbits, lzw, g3, g4, msb2lsb, lsb2msb, opt_2d, fill;
     unsigned int flate, adobeflate;
-    char * indexbits;
+    char ** indexbits;
     char * resolutionunit;
 
     unsigned int appendSpec, outputSpec, predictorSpec, rowsperstripSpec,
@@ -192,7 +230,7 @@ parseCommandLine(int                 argc,
             &yresolutionSpec,  0);
     OPTENT3(0, "resolutionunit", OPT_STRING, &resolutionunit,
             &resolutionunitSpec,    0);
-    OPTENT3(0, "indexbits",    OPT_STRING,   &indexbits,
+    OPTENT3(0, "indexbits",    OPT_STRINGLIST, &indexbits,
             &indexbitsSpec,    0);
     OPTENT3(0, "tag",          OPT_NAMELIST, &cmdlineP->taglist, &tagSpec, 0);
 
@@ -302,35 +340,16 @@ parseCommandLine(int                 argc,
     } else
         cmdlineP->resolutionunit = RESUNIT_INCH;
 
-    if (indexbitsSpec) {
-        if (strstr(indexbits, "1"))
-            cmdlineP->indexsizeAllowed.b1 = TRUE;
-        else
-            cmdlineP->indexsizeAllowed.b1 = FALSE;
-        if (strstr(indexbits, "2"))
-            cmdlineP->indexsizeAllowed.b2 = TRUE;
-        else
-            cmdlineP->indexsizeAllowed.b2 = FALSE;
-        if (strstr(indexbits, "4"))
-            cmdlineP->indexsizeAllowed.b4 = TRUE;
-        else
-            cmdlineP->indexsizeAllowed.b4 = FALSE;
-        if (strstr(indexbits, "8"))
-            cmdlineP->indexsizeAllowed.b8 = TRUE;
-        else
-            cmdlineP->indexsizeAllowed.b8 = FALSE;
-    } else {
-        cmdlineP->indexsizeAllowed.b1 = FALSE;
-        cmdlineP->indexsizeAllowed.b2 = FALSE;
-        cmdlineP->indexsizeAllowed.b4 = FALSE;
-        cmdlineP->indexsizeAllowed.b8 = TRUE;
-    }
+    parseIndexbits(indexbitsSpec, indexbits, cmdlineP);
+
+    if (indexbitsSpec)
+        free(indexbits);
 
     if (tagSpec)
         validateTagList(cmdlineP->taglist);
     else {
         MALLOCARRAY_NOFAIL(cmdlineP->taglist, 1);
-        cmdlineP->taglist[0].name = NULL;
+        cmdlineP->taglist[0].name  = NULL;
         cmdlineP->taglist[0].value = NULL;
     }
 
@@ -346,6 +365,14 @@ parseCommandLine(int                 argc,
 
 
 static void
+freeCmdline(CmdlineInfo const cmdline) {
+
+    pm_optDestroyNameValueList(cmdline.taglist);
+}
+
+
+
+static void
 fillRowOfSubBytePixels(struct pam *    const pamP,
                        const tuple *   const tuplerow,
                        unsigned char * const buf,
@@ -1280,6 +1307,8 @@ main(int argc, const char *argv[]) {
     closeTiffGenerator(cmdline.writeMethod, tifP, ofd);
     pm_close(ifP);
 
+    freeCmdline(cmdline);
+
     return 0;
 }
 
diff --git a/converter/other/svgtopam.c b/converter/other/svgtopam.c
index 09e3a24e..ca6f4dc7 100644
--- a/converter/other/svgtopam.c
+++ b/converter/other/svgtopam.c
@@ -147,36 +147,36 @@ typedef struct {
     unsigned int height;
     pixel ** pixels;
     pixval maxval;
-} canvas;
+} Canvas;
 
 typedef struct {
     pixel fillColor;
-} style;
+} Style;
 
 
 
 typedef struct {
     const char * pathText;
         /* This is e.g. "M0 0 L1 1 L9 8 Z" */
-    style        style;
+    Style        style;
         /* This is the style as given by a 'style' attribute of <path> */
     unsigned int pathTextLength;
         /* This is the length in characters of 'pathText'.  It's redundant
            with 'pathText' and exists for convenience.
         */
-} path;
+} Path;
 
 static void
 createPath(const char * const pathText,
-           style        const style,
-           path **      const pathPP) {
+           Style        const style,
+           Path **      const pathPP) {
 /*----------------------------------------------------------------------------
    Create a path as described by a <path> element whose "style" attribute
    indicates style 'style' and whose "d" attribute indicates path data
    'pathText'.
 -----------------------------------------------------------------------------*/
     bool error;
-    path * pathP;
+    Path * pathP;
     
     MALLOCVAR(pathP);
     if (pathP == NULL)
@@ -204,7 +204,7 @@ createPath(const char * const pathText,
 
 
 static void
-destroyPath(path * const pathP) {
+destroyPath(Path * const pathP) {
     
     assert(pathP->pathTextLength == strlen(pathP->pathText));
 
@@ -218,13 +218,13 @@ destroyPath(path * const pathP) {
 typedef struct {
     unsigned int x;
     unsigned int y;
-} point;
+} Point;
 
-static point
+static Point
 makePoint(unsigned int const x,
           unsigned int const y) {
 
-    point p;
+    Point p;
     
     p.x = x;
     p.y = y;
@@ -233,7 +233,7 @@ makePoint(unsigned int const x,
 }
 
 static ppmd_point
-makePpmdPoint(point const arg) {
+makePpmdPoint(Point const arg) {
 
     ppmd_point p;
 
@@ -248,16 +248,16 @@ typedef enum {
     PATH_LINETO,
     PATH_CLOSEPATH,
     PATH_CUBIC
-} pathCommandVerb;
+} PathCommandVerb;
 
 typedef struct {
-    point dest;
-} pathMovetoArgs;
+    Point dest;
+} PathMovetoArgs;
 
 typedef struct {
     /* Draw a line segment from current point to 'dest' */
-    point dest;
-} pathLinetoArgs;
+    Point dest;
+} PathLinetoArgs;
 
 typedef struct {
     /* Draw a cubic spline from current point to 'dest' with control points
@@ -272,19 +272,19 @@ typedef struct {
        A cubic curve is a plot of a polynomial equation of degree 3
        (or less, for our purposes).
     */
-    point dest;
-    point ctl1;
-    point ctl2;
-} pathCubicArgs;
+    Point dest;
+    Point ctl1;
+    Point ctl2;
+} PathCubicArgs;
 
 typedef struct {
-    pathCommandVerb verb;
+    PathCommandVerb verb;
     union {
-        pathMovetoArgs moveto;
-        pathLinetoArgs lineto;
-        pathCubicArgs  cubic;
+        PathMovetoArgs moveto;
+        PathLinetoArgs lineto;
+        PathCubicArgs  cubic;
     } args;
-} pathCommand;
+} PathCommand;
 
 
 
@@ -292,15 +292,15 @@ typedef struct {
 /*----------------------------------------------------------------------------
    This is an object for reading through a path from beginning to end.
 -----------------------------------------------------------------------------*/
-    path *       pathP;
+    Path *       pathP;
     unsigned int cursor;
-} pathReader;
+} PathReader;
 
 static void
-createPathReader(path *        const pathP,
-                 pathReader ** const pathReaderPP) {
+pathReader_create(Path *        const pathP,
+                  PathReader ** const pathReaderPP) {
 
-    pathReader * pathReaderP;
+    PathReader * pathReaderP;
 
     MALLOCVAR_NOFAIL(pathReaderP);
 
@@ -311,18 +311,31 @@ createPathReader(path *        const pathP,
 }
 
 static void
-destroyPathReader(pathReader * const pathReaderP) {
+pathReader_destroy(PathReader * const pathReaderP) {
     free(pathReaderP);
 }
 
 
 
+static const char *
+pathReader_context(PathReader * const pathReaderP) {
+
+    const char * retval;
+
+    pm_asprintf(&retval, "Character position %u (starting at 0) in '%s'",
+                pathReaderP->cursor, pathReaderP->pathP->pathText);
+
+    return retval;
+}
+
+
+
 static void
-skipWhiteSpace(pathReader * const pathReaderP) {
+pathReader_skipWhiteSpace(PathReader * const pathReaderP) {
 /*----------------------------------------------------------------------------
    Move the cursor over any white space where it now points.
 -----------------------------------------------------------------------------*/
-    const path * const pathP = pathReaderP->pathP;
+    const Path * const pathP = pathReaderP->pathP;
 
     while (isspace(pathP->pathText[pathReaderP->cursor]) &&
            pathReaderP->cursor < pathP->pathTextLength)
@@ -332,10 +345,10 @@ skipWhiteSpace(pathReader * const pathReaderP) {
 
 
 static void
-getNumber(pathReader *   const pathReaderP,
-          unsigned int * const numberP) {
+pathReader_getNumber(PathReader *   const pathReaderP,
+                     unsigned int * const numberP) {
 
-    const path * const pathP          = pathReaderP->pathP;
+    const Path * const pathP          = pathReaderP->pathP;
     const char * const pathText       = pathP->pathText;
     size_t       const pathTextLength = pathP->pathTextLength;
 
@@ -343,7 +356,10 @@ getNumber(pathReader *   const pathReaderP,
 
     if (pathReaderP->cursor >= pathTextLength)
         pm_error("Path description ends where a number was expected.");
-    else {
+    else if (!isdigit(pathText[pathReaderP->cursor])) {
+        pm_error("Character '%c' instead of a digit where number expected",
+                 pathText[pathReaderP->cursor]);
+    } else {
         unsigned int number;
 
         number = 0;  /* initial value */
@@ -353,6 +369,10 @@ getNumber(pathReader *   const pathReaderP,
             number = 10 * number + (pathText[pathReaderP->cursor] - '0');
             ++pathReaderP->cursor;
         }
+        if (pathText[pathReaderP->cursor] == '.')
+            pm_error("Number contains decimal point.  This program does not "
+                     "know how to deal with fractional positions");
+
         *numberP = number;
     }
 }
@@ -360,15 +380,15 @@ getNumber(pathReader *   const pathReaderP,
 
 
 static void
-getNextCommand(pathReader *  const pathReaderP,
-               pathCommand * const pathCommandP,
-               bool *        const endOfPathP) {
+pathReader_getNextCommand(PathReader *  const pathReaderP,
+                          PathCommand * const pathCommandP,
+                          bool *        const endOfPathP) {
 
-    const path * const pathP          = pathReaderP->pathP;
+    const Path * const pathP          = pathReaderP->pathP;
     const char * const pathText       = pathP->pathText;
     size_t       const pathTextLength = pathP->pathTextLength;
 
-    skipWhiteSpace(pathReaderP);
+    pathReader_skipWhiteSpace(pathReaderP);
 
     if (pathReaderP->cursor >= pathTextLength)
         *endOfPathP = true;
@@ -376,67 +396,79 @@ getNextCommand(pathReader *  const pathReaderP,
         switch (pathText[pathReaderP->cursor++]) {
         case 'M':
             pathCommandP->verb = PATH_MOVETO;
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.moveto.dest.x);
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.moveto.dest.y);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP,
+                                 &pathCommandP->args.moveto.dest.x);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP,
+                                 &pathCommandP->args.moveto.dest.y);
             break;
         case 'L':
             pathCommandP->verb = PATH_LINETO;
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.lineto.dest.x);
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.lineto.dest.y);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP,
+                                 &pathCommandP->args.lineto.dest.x);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP,
+                                 &pathCommandP->args.lineto.dest.y);
             break;
         case 'C':
             pathCommandP->verb = PATH_CUBIC;
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.cubic.ctl1.x);
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.cubic.ctl1.y);
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.cubic.ctl2.x);
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.cubic.ctl2.y);
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.cubic.dest.x);
-            skipWhiteSpace(pathReaderP);
-            getNumber(pathReaderP, &pathCommandP->args.cubic.dest.y);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.ctl1.x);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.ctl1.y);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.ctl2.x);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.ctl2.y);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.dest.x);
+            pathReader_skipWhiteSpace(pathReaderP);
+            pathReader_getNumber(pathReaderP, &pathCommandP->args.cubic.dest.y);
             break;
         case 'z':
             pathCommandP->verb = PATH_CLOSEPATH;
             break;
-        default:
-            pm_error("Unrecognized command in <path>: '%c'",
-                     pathText[pathReaderP->cursor++]);
+        default: {
+            const char * const context = pathReader_context(pathReaderP);
+            
+            pm_errormsg("Unrecognized command in <path>: '%c'.  %s",
+                        pathText[pathReaderP->cursor++], context);
+
+            pm_strfree(context);
+
+            pm_longjmp();
+        }
         }
     }
 }
 
 
+
 static void
-outlineObject(path *           const pathP,
+outlineObject(Path *           const pathP,
               struct fillobj * const fillObjP) {
 /*----------------------------------------------------------------------------
   Create a fill object, which contains and outline of the object and
   can be used with ppmd_fill() to fill the figure.  The outline is as
   described by *pathP.
 -----------------------------------------------------------------------------*/
-    pathReader * pathReaderP;
+    PathReader * pathReaderP;
     bool endOfPath;
-    point currentPos;
-    point subpathStart;
+    Point currentPos;
+    Point subpathStart;
         /* Point at which the current subpath starts */
 
     endOfPath = false;
     subpathStart = makePoint(0,0);
     currentPos = subpathStart;
 
-    createPathReader(pathP, &pathReaderP);
+    pathReader_create(pathP, &pathReaderP);
 
     while (!endOfPath) {
-        pathCommand pathCommand;
-        getNextCommand(pathReaderP, &pathCommand, &endOfPath);
+        PathCommand pathCommand;
+        pathReader_getNextCommand(pathReaderP, &pathCommand, &endOfPath);
         if (!endOfPath) {
             switch (pathCommand.verb) {
             case PATH_MOVETO:
@@ -448,7 +480,7 @@ outlineObject(path *           const pathP,
                 currentPos = subpathStart;
                 break;
             case PATH_LINETO: {
-                point const dest = pathCommand.args.lineto.dest;
+                Point const dest = pathCommand.args.lineto.dest;
                 if (traceDraw)
                     pm_message("Lining to (%u, %u)", dest.x, dest.y);
                 ppmd_line(NULL, 0, 0, 0,
@@ -466,12 +498,14 @@ outlineObject(path *           const pathP,
                 currentPos = subpathStart;
                 break;
             case PATH_CUBIC: {
-                point const dest = pathCommand.args.cubic.dest;
-                point const ctl1 = pathCommand.args.cubic.ctl1;
-                point const ctl2 = pathCommand.args.cubic.ctl2;
+                Point const dest = pathCommand.args.cubic.dest;
+                Point const ctl1 = pathCommand.args.cubic.ctl1;
+                Point const ctl2 = pathCommand.args.cubic.ctl2;
                 if (traceDraw)
                     pm_message("Doing cubic spline to (%u, %u)",
                                dest.x, dest.y);
+                pm_error("SVG image contains a cubic spline path.  "
+                         "This program cannot process cubic splines.");
                 /* We need to write ppmd_spline4() */
                 ppmd_spline4p(NULL, 0, 0, 0,
                               makePpmdPoint(currentPos),
@@ -484,14 +518,14 @@ outlineObject(path *           const pathP,
             }
         }
     }
-    destroyPathReader(pathReaderP);
+    pathReader_destroy(pathReaderP);
 }
 
 
 
 static void
-drawPath(canvas * const canvasP,
-         path *   const pathP) {
+drawPath(Canvas * const canvasP,
+         Path *   const pathP) {
 /*----------------------------------------------------------------------------
    Draw the path 'pathP' on the canvas 'canvasP'.
 -----------------------------------------------------------------------------*/
@@ -518,10 +552,10 @@ drawPath(canvas * const canvasP,
 
 
 
-static style
+static Style
 interpretStyle(const char * const styleAttr) {
 
-    style style;
+    Style style;
 
     char * buffer;
 
@@ -582,7 +616,7 @@ interpretStyle(const char * const styleAttr) {
 
 static void
 getPathAttributes(xmlTextReaderPtr const xmlReaderP,
-                  style *          const styleP,
+                  Style *          const styleP,
                   const char **    const pathP) {
 
     const char * const style = getAttribute(xmlReaderP, "style");
@@ -628,11 +662,11 @@ processSubPathNode(xmlTextReaderPtr const xmlReaderP,
 
 static void
 processPathElement(xmlTextReaderPtr const xmlReaderP,
-                   canvas *         const canvasP) {
+                   Canvas *         const canvasP) {
 
-    style style;
+    Style style;
     const char * pathData;
-    path * pathP;
+    Path * pathP;
     bool endOfPath;
 
     assert(xmlTextReaderNodeType(xmlReaderP) == XML_READER_TYPE_ELEMENT);
@@ -670,29 +704,6 @@ processPathElement(xmlTextReaderPtr const xmlReaderP,
 
 
 static void
-stringToUint(const char *   const string,
-             unsigned int * const uintP,
-             const char **  const errorP) {
-
-    /* TODO: move this to nstring.c */
-
-    if (strlen(string) == 0)
-        pm_asprintf(errorP, "Value is a null string");
-    else {
-        char * tailptr;
-
-        *uintP = strtoul(string, &tailptr, 10);
-
-        if (*tailptr != '\0')
-            pm_asprintf(errorP, "Non-numeric crap in string: '%s'", tailptr);
-        else
-            *errorP = NULL;
-    }
-}
-
-
-
-static void
 getSvgAttributes(xmlTextReaderPtr const xmlReaderP,
                  unsigned int *   const colsP,
                  unsigned int *   const rowsP) {
@@ -702,14 +713,16 @@ getSvgAttributes(xmlTextReaderPtr const xmlReaderP,
 
     const char * error;
 
-    stringToUint(width, colsP, &error);
+    pm_string_to_uint(width, colsP, &error);
     if (error) {
-        pm_error("'width' attribute of <svg> has invalid value.  %s", error);
+        pm_error("'width' attribute of <svg> has invalid value '%s'.  %s",
+                 width, error);
         pm_strfree(error);
     }
-    stringToUint(height, rowsP, &error);
+    pm_string_to_uint(height, rowsP, &error);
     if (error) {
-        pm_error("'height' attribute of <svg> has invalid value.  %s", error);
+        pm_error("'height' attribute of <svg> has invalid value '%s'.  %s",
+                 height, error);
         pm_strfree(error);
     }
 }
@@ -718,7 +731,7 @@ getSvgAttributes(xmlTextReaderPtr const xmlReaderP,
 
 static void
 processSubSvgElement(xmlTextReaderPtr const xmlReaderP,
-                     canvas *         const canvasP) {
+                     Canvas *         const canvasP) {
 
     const char * const nodeName = currentNodeName(xmlReaderP);
 
@@ -735,7 +748,7 @@ processSubSvgElement(xmlTextReaderPtr const xmlReaderP,
 
 static void
 processSubSvgNode(xmlTextReaderPtr const xmlReaderP,
-                  canvas *         const canvasP,
+                  Canvas *         const canvasP,
                   bool *           const endOfSvgP) {
 
     xmlReaderTypes const nodeType = xmlTextReaderNodeType(xmlReaderP);
@@ -765,9 +778,9 @@ static void
 createCanvas(unsigned int const width,
              unsigned int const height,
              pixval       const maxval,
-             canvas **    const canvasPP) {
+             Canvas **    const canvasPP) {
 
-    canvas * canvasP;
+    Canvas * canvasP;
 
     MALLOCVAR_NOFAIL(canvasP);
 
@@ -782,7 +795,7 @@ createCanvas(unsigned int const width,
 
 
 static void
-destroyCanvas(canvas * const canvasP) {
+destroyCanvas(Canvas * const canvasP) {
 
     ppm_freearray(canvasP->pixels, canvasP->height);
 
@@ -793,7 +806,7 @@ destroyCanvas(canvas * const canvasP) {
 
 static void
 writePam(FILE *   const ofP,
-         canvas * const canvasP) {
+         Canvas * const canvasP) {
 
     unsigned int row;
     struct pam pam;
@@ -839,7 +852,7 @@ processSvgElement(xmlTextReaderPtr const xmlReaderP,
 
     unsigned int width, height;
     bool endOfSvg;
-    canvas * canvasP;
+    Canvas * canvasP;
 
     assert(xmlTextReaderNodeType(xmlReaderP) == XML_READER_TYPE_ELEMENT);
     assert(streq(currentNodeName(xmlReaderP), "svg"));
diff --git a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c
index e72aff5e..c1e7af85 100644
--- a/converter/other/tifftopnm.c
+++ b/converter/other/tifftopnm.c
@@ -191,7 +191,7 @@ getBps(TIFF *           const tif,
 
     if (bps < 1 || (bps > 8 && bps != 16 && bps != 32))
         pm_error("This program can process Tiff images with only "
-                 "1-8 or 16 bits per sample.  The input Tiff image "
+                 "1-8 or 16 or 32 bits per sample.  The input Tiff image "
                  "has %hu bits per sample.", bps);
     else
         *bpsP = bps;