From 0535c050bcede50d817da4af439b685cebc15247 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Wed, 7 Dec 2011 18:24:44 +0000 Subject: cleanup git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1604 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/ppm/ppmtoterm.c | 156 +++++++++++++++++++++++++++++++--------------- 1 file changed, 106 insertions(+), 50 deletions(-) (limited to 'converter') 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 #include #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); -- cgit 1.4.1