about summary refs log tree commit diff
path: root/converter/other/pnmtopalm/palmcolormap.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other/pnmtopalm/palmcolormap.c')
-rw-r--r--converter/other/pnmtopalm/palmcolormap.c134
1 files changed, 82 insertions, 52 deletions
diff --git a/converter/other/pnmtopalm/palmcolormap.c b/converter/other/pnmtopalm/palmcolormap.c
index 0f47558c..1341ca2b 100644
--- a/converter/other/pnmtopalm/palmcolormap.c
+++ b/converter/other/pnmtopalm/palmcolormap.c
@@ -4,18 +4,46 @@
 #include "pm_c_util.h"
 #include "mallocvar.h"
 #include "pnm.h"
-
 #include "palm.h"
 
+#include "palmcolormap.h"
+
+
+
+static pixval
+scaleSample(pixval const arg,
+            pixval const oldMaxval,
+            pixval const newMaxval) {
+
+    return (arg * newMaxval + oldMaxval/2) / oldMaxval;
+}
+
+
+
+ColormapEntry
+palmcolor_mapEntryColorFmPixel(pixel  const color,
+                               pixval const maxval,
+                               pixval const newMaxval) {
+
+
+    return
+        0
+        | (scaleSample(PPM_GETR(color), maxval, newMaxval) << 16) 
+        | (scaleSample(PPM_GETG(color), maxval, newMaxval) <<  8)
+        | (scaleSample(PPM_GETB(color), maxval, newMaxval) <<  0);
+}
+
+
+
 int
 palmcolor_compare_indices(const void * const p1,
                           const void * const p2) {
 /*----------------------------------------------------------------------------
    This is a 'qsort' collation function.
 -----------------------------------------------------------------------------*/
-    if ((*((Color) p1) & 0xFF000000) < (*((Color) p2) & 0xFF000000))
+    if ((*((ColormapEntry *) p1) & 0xFF000000) < (*((ColormapEntry *) p2) & 0xFF000000))
         return -1;
-    else if ((*((Color) p1) & 0xFF000000) > (*((Color) p2) & 0xFF000000))
+    else if ((*((ColormapEntry *) p1) & 0xFF000000) > (*((ColormapEntry *) p2) & 0xFF000000))
         return 1;
     else
         return 0;
@@ -165,86 +193,88 @@ static int PalmPalette8bpp[256][3] =
 
 
 
-Colormap
+Colormap *
 palmcolor_build_default_8bit_colormap(void) {
 
     unsigned int i;
 
-    Colormap cm;
+    Colormap * cmP;
 
-    MALLOCVAR_NOFAIL(cm);
-    cm->nentries = 232;
-    MALLOCARRAY_NOFAIL(cm->color_entries, cm->nentries);
+    MALLOCVAR_NOFAIL(cmP);
+    cmP->nentries = 232;
+    MALLOCARRAY_NOFAIL(cmP->color_entries, cmP->nentries);
 
     /* Fill in the colors */
     for (i = 0; i < 231; ++i) {
-        cm->color_entries[i] = ((i << 24) |
+        cmP->color_entries[i] = ((i << 24) |
                                 (PalmPalette8bpp[i][0] << 16) |
                                 (PalmPalette8bpp[i][1] << 8) |
                                 (PalmPalette8bpp[i][2]));
     }
-    cm->color_entries[231] = 0xFF000000;
-    cm->ncolors = 232;
+    cmP->color_entries[231] = 0xFF000000;
+    cmP->ncolors = 232;
 
     /* now sort the table */
-    qsort (cm->color_entries, cm->ncolors, sizeof(Color_s), 
-           palmcolor_compare_colors);
-    return cm;
+    qsort(cmP->color_entries, cmP->ncolors, sizeof(ColormapEntry), 
+          palmcolor_compare_colors);
+    return cmP;
 }
 
 
 
-Colormap
-palmcolor_build_custom_8bit_colormap(unsigned int const rows,
+Colormap *
+palmcolor_build_custom_8bit_colormap(pixel **     const pixels,
+                                     unsigned int const rows,
                                      unsigned int const cols,
-                                     pixel **     const pixels) {
+                                     pixval       const maxval) {
+
     unsigned int row;
-    Colormap colormap;
+    Colormap * colormapP;
 
-    MALLOCVAR_NOFAIL(colormap);
-    colormap->nentries = 256;
-    MALLOCARRAY_NOFAIL(colormap->color_entries, colormap->nentries);
-    colormap->ncolors = 0;  /* initial value */
+    MALLOCVAR_NOFAIL(colormapP);
+    colormapP->nentries = 256;
+    MALLOCARRAY_NOFAIL(colormapP->color_entries, colormapP->nentries);
+    colormapP->ncolors = 0;  /* initial value */
     
     for (row = 0; row < rows; ++row) {
         unsigned int col;
         for (col = 0; col < cols; ++col) {
-            Color found;
-            Color_s temp;
-
-            temp = ((PPM_GETR(pixels[row][col]) << 16) |
-                    (PPM_GETG(pixels[row][col]) << 8) |
-                    PPM_GETB(pixels[row][col]));
-            found = (bsearch (&temp,
-                              colormap->color_entries, colormap->ncolors,
-                              sizeof(Color_s), palmcolor_compare_colors));
-            if (!found) {
-                if (colormap->ncolors >= colormap->nentries)
+            ColormapEntry * foundEntryP;
+            ColormapEntry const searchTarget =
+                palmcolor_mapEntryColorFmPixel(pixels[row][col], maxval, 255);
+
+            foundEntryP =
+                bsearch(&searchTarget,
+                        colormapP->color_entries, colormapP->ncolors,
+                        sizeof(ColormapEntry), palmcolor_compare_colors);
+            if (!foundEntryP) {
+                if (colormapP->ncolors >= colormapP->nentries)
                     pm_error("Too many colors for custom colormap "
-                             "(max 256).  "
+                             "(max %u).  "
                              "Try using pnmquant to reduce the number "
-                             "of colors.");
+                             "of colors.", colormapP->nentries);
                 else {
                     /* add the new color, and re-sort */
-                    temp |= ((colormap->ncolors) << 24);
-                    colormap->color_entries[colormap->ncolors] = temp;
-                    colormap->ncolors += 1;
-                    qsort(colormap->color_entries, colormap->ncolors, 
-                          sizeof(Color_s), palmcolor_compare_colors);
+                    unsigned int const colorIndex = colormapP->ncolors++;
+                    ColormapEntry const newEntry =
+                        searchTarget | (colorIndex << 24);
+                    colormapP->color_entries[colorIndex] = newEntry;
+                    qsort(colormapP->color_entries, colormapP->ncolors, 
+                          sizeof(ColormapEntry), palmcolor_compare_colors);
                 }
             }
         }
     }
-    return colormap;
+    return colormapP;
 }
 
 
 
-Colormap
+Colormap *
 palmcolor_read_colormap (FILE * const ifP) {
 
     unsigned short ncolors;
-    Colormap retval;
+    Colormap * retval;
     int rc;
     
     rc = pm_readbigshort(ifP, (short *) &ncolors);
@@ -252,13 +282,13 @@ palmcolor_read_colormap (FILE * const ifP) {
         retval = NULL;
     else {
         long colorentry;
-        Colormap colormap;
+        Colormap * colormapP;
         unsigned int i;
         bool error;
 
-        MALLOCVAR_NOFAIL(colormap);
-        colormap->nentries = ncolors;
-        MALLOCARRAY_NOFAIL(colormap->color_entries, colormap->nentries);
+        MALLOCVAR_NOFAIL(colormapP);
+        colormapP->nentries = ncolors;
+        MALLOCARRAY_NOFAIL(colormapP->color_entries, colormapP->nentries);
         
         for (i = 0, error = FALSE;  i < ncolors && !error;  ++i) {
             int rc;
@@ -266,15 +296,15 @@ palmcolor_read_colormap (FILE * const ifP) {
             if (rc != 0)
                 error = TRUE;
             else
-                colormap->color_entries[i] = (colorentry & 0xFFFFFFFF);
+                colormapP->color_entries[i] = (colorentry & 0xFFFFFFFF);
         }
         if (error) {
-            free (colormap->color_entries);
-            free (colormap);
+            free (colormapP->color_entries);
+            free (colormapP);
             retval = NULL;
         } else {
-            colormap->ncolors = ncolors;
-            retval = colormap;
+            colormapP->ncolors = ncolors;
+            retval = colormapP;
         }
     }
     return retval;