about summary refs log tree commit diff
path: root/converter/ppm/ppmtoterm.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2011-12-07 18:24:44 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2011-12-07 18:24:44 +0000
commit0535c050bcede50d817da4af439b685cebc15247 (patch)
treefc03861621c945bfe35c6860b58a425843bdca8a /converter/ppm/ppmtoterm.c
parent4f9c6d7728fdc4ede9b07dbd72a51c7dec9df4d5 (diff)
downloadnetpbm-mirror-0535c050bcede50d817da4af439b685cebc15247.tar.gz
netpbm-mirror-0535c050bcede50d817da4af439b685cebc15247.tar.xz
netpbm-mirror-0535c050bcede50d817da4af439b685cebc15247.zip
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1604 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/ppm/ppmtoterm.c')
-rw-r--r--converter/ppm/ppmtoterm.c156
1 files changed, 106 insertions, 50 deletions
diff --git a/converter/ppm/ppmtoterm.c b/converter/ppm/ppmtoterm.c
index 29b35a94..d388f77d 100644
--- a/converter/ppm/ppmtoterm.c
+++ b/converter/ppm/ppmtoterm.c
@@ -19,6 +19,7 @@
 **
 */
 
+#include <assert.h>
 #include <string.h>
 
 #include "pm_c_util.h"
@@ -72,9 +73,15 @@ parseCommandLine(int argc, const char ** argv,
 
 
 
-#define ESC         "\x1B\x5B"
-#define NUM_COLORS      128
-#define MAX_ANSI_STR_LEN    16
+#define ESC "\x1B\x5B"
+#define ANSI_BRIGHT_CMD_PAT ESC "%dm"
+#define ANSI_FGCOLOR_CMD_PAT ESC "3%dm"
+#define ANSI_BGCOLOR_CMD_PAT ESC "4%dm"
+#define MAX_ANSI_STR_LEN 16
+#define NUM_COLORS 128
+    /* 1 bit each RGB = 8 colors.
+       8 BG colors * 8 FG colors * 2 brightnesses
+    */
 
 
 
@@ -85,33 +92,97 @@ generatePalette(unsigned char        rgb[NUM_COLORS][3],
 /*----------------------------------------------------------------------------
   Generate some sort of color palette mixing the available colors as different
   values of background, foreground & brightness.
+
+  We return as rgb[I] the RGB triple for the color with palette index I.
+  Component intensities are in the range 0..255.  rgb[I][0] is red;
+  rgb[I][1] is green; rgb[I][2] is blue.
+
+  We return as ansiCode[I] the sequence you send to a terminal to generate
+  the color with palette index I.
 -----------------------------------------------------------------------------*/
-    unsigned int code;
-    unsigned int col;
-    unsigned int cd2;
-    
-    memset((void *)rgb, 0, NUM_COLORS*3);
-    memset((void *)ansiCode, 0, NUM_COLORS*MAX_ANSI_STR_LEN);
-
-    for( col = cd2 =0; cd2 < 8; ++cd2) {
-        unsigned int b;
-        for (b = 0; b < 2; ++b) {
-            for (code = 0; code < 8; ++code) {
-                unsigned int c;
-                for (c = 0; c < 3; ++c) {
-                    if ((code & (0x1 << c)) != 0)
-                        rgb[col][c] = (192 | (b ? 63 : 0));
-                    if ((cd2 & (0x1 << c)) != 0)
-                        rgb[col][c] |= 0x80;
+    unsigned int idx;
+        /* palette index of the color being considered */
+    unsigned int bgColorCode;
+        /* This is the ANSI color code for the background.  An ANSI color code
+           is a 3 bit code in which LSB means red; middle bit means green, and
+           MSB means blue.
+        */
+
+    /* We develop the palette backwards: consider every permutation of the
+       three terminal controls -- background, foreground, and brightness --
+       and for each figure out what RGB color it represents and fill in
+       that element of RGB[][]
+    */
+
+    for (bgColorCode = 0, idx = 0; bgColorCode < 8; ++bgColorCode) {
+        unsigned int brightness;  /* 0 = dim; 1 = bright */
+        for (brightness = 0; brightness < 2; ++brightness) {
+            unsigned int fgColorCode;
+                /* ANSI color code for the foreground.  See bgColorCode. */
+            for (fgColorCode = 0; fgColorCode < 8; ++fgColorCode) {
+                unsigned int rgbComp;
+                    /* 0 = red; 1 = green; 2 = blue */
+                for (rgbComp = 0; rgbComp < 3; ++rgbComp) {
+                    assert (idx < NUM_COLORS);
+                    rgb[idx][rgbComp] = 0x00;  /* initial value */
+                    if ((fgColorCode & (0x1 << rgbComp)) != 0) {
+                        rgb[idx][rgbComp] |= 0xC0;
+                        if (brightness == 1)
+                            rgb[idx][rgbComp] |= 0x3F;
+                    }
+                    if ((bgColorCode & (0x1 << rgbComp)) != 0)
+                        rgb[idx][rgbComp] |= 0x80;
                 }
-                sprintf(ansiCode[col],
-                        ESC"%dm"ESC"3%dm"ESC"4%dm",
-                        b, code, cd2);
-                ++col;
+                sprintf(ansiCode[idx],
+                        ANSI_BRIGHT_CMD_PAT
+                        ANSI_FGCOLOR_CMD_PAT
+                        ANSI_BGCOLOR_CMD_PAT,
+                        brightness, fgColorCode, bgColorCode);
+                ++idx;
             }
         }
     }
-    *paletteSizeP = col;
+    *paletteSizeP = idx;
+}
+
+
+
+static void
+lookupInPalette(pixel          const pixel,
+                pixval         const maxval,
+                unsigned char        rgb[NUM_COLORS][3], 
+                unsigned int   const palLen,
+                unsigned int * const paletteIdxP) {
+/*----------------------------------------------------------------------------
+   Look up the color 'pixel' (which has maxval 'maxval') in the palette
+   palette[], which has 'palLen' elements and uses maxval 255.  Return the
+   index into palette[] of the color that is closes to 'pixel' as
+   *paletteIdxP.
+-----------------------------------------------------------------------------*/
+    pixval const r = PPM_GETR(pixel) * 255 / maxval;
+    pixval const g = PPM_GETG(pixel) * 255 / maxval;
+    pixval const b = PPM_GETB(pixel) * 255 / maxval;
+
+    unsigned int paletteIdxSoFar;
+    unsigned int dist;
+    unsigned int i;
+            
+    /* The following loop calculates the index that corresponds to the
+       minimum color distance between the given RGB values and the
+       values available in the palette.
+    */
+    for (i = 0, dist = SQR(255)*3, paletteIdxSoFar = 0; i < palLen; ++i) {
+        pixval const pr=rgb[i][0];
+        pixval const pg=rgb[i][1];
+        pixval const pb=rgb[i][2];
+        unsigned int const j = SQR(r-pr) + SQR(b-pb) + SQR(g-pg);
+
+        if (j  < dist) {
+            dist = j;
+            paletteIdxSoFar = i;
+        }
+    }
+    *paletteIdxP = paletteIdxSoFar;
 }
 
 
@@ -119,8 +190,8 @@ generatePalette(unsigned char        rgb[NUM_COLORS][3],
 int
 main(int argc, const char ** argv) {
 
-    FILE            * ifP;
-    pixel           ** pixels;
+    FILE *          ifP;
+    pixel **        pixels;
     int             rows, cols;
     unsigned int    row;
     unsigned int    palLen;
@@ -144,31 +215,16 @@ main(int argc, const char ** argv) {
     for (row = 0; row < rows; ++row) {
         unsigned int col;
         for (col = 0; col < cols; ++col) {
-            pixval const r=(int)PPM_GETR(pixels[row][col])*255/maxval;
-            pixval const g=(int)PPM_GETG(pixels[row][col])*255/maxval;
-            pixval const b=(int)PPM_GETB(pixels[row][col])*255/maxval;
-            int val, dist;
-            unsigned int i;
-            
-            /* The following loop calculates the index that corresponds to the
-               minimum color distance between the given RGB values and the
-               values available in the palette.
-            */
-            for (i = 0, dist = SQR(255)*3, val = 0; i < palLen; ++i) {
-                pixval const pr=rgb[i][0];
-                pixval const pg=rgb[i][1];
-                pixval const pb=rgb[i][2];
-                unsigned int const j = SQR(r-pr) + SQR(b-pb) + SQR(g-pg);
-                if (j  < dist) {
-                    dist = j;
-                    val = i;
-                }
-            }
-            printf("%s%c", ansiCode[val], 0xB1);
+            unsigned int paletteIdx;
+
+            lookupInPalette(pixels[row][col], maxval, rgb, palLen,
+                            &paletteIdx);
+
+            printf("%s\xB1", ansiCode[paletteIdx]);
         }
-        printf(ESC"\x30m\n");
+        printf(ESC "\x30m\n");
     }
-    printf(ESC"\x30m");
+    printf(ESC "\x30m");
 
     ppm_freearray(pixels, rows);