diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2015-06-05 02:19:56 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2015-06-05 02:19:56 +0000 |
commit | 5813a930b9134134b5b1951cb965df2d5e7fdc64 (patch) | |
tree | 151200b030c118015d2d2ffd432215600bbebd5f /converter/ppm/ppmtoicr.c | |
parent | e9908d12ac08cf61a200f9f57d5bbb48279b5997 (diff) | |
download | netpbm-mirror-5813a930b9134134b5b1951cb965df2d5e7fdc64.tar.gz netpbm-mirror-5813a930b9134134b5b1951cb965df2d5e7fdc64.tar.xz netpbm-mirror-5813a930b9134134b5b1951cb965df2d5e7fdc64.zip |
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2548 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/ppm/ppmtoicr.c')
-rw-r--r-- | converter/ppm/ppmtoicr.c | 421 |
1 files changed, 235 insertions, 186 deletions
diff --git a/converter/ppm/ppmtoicr.c b/converter/ppm/ppmtoicr.c index a2375101..3c8be421 100644 --- a/converter/ppm/ppmtoicr.c +++ b/converter/ppm/ppmtoicr.c @@ -10,206 +10,255 @@ ** implied warranty. */ +#include <stdbool.h> +#include <assert.h> #include "ppm.h" -#define MAXCOLORS 256 -#define CLUTCOLORS 768 +#define MAXCOLORCT 256 +#define CLUTCOLORCT 768 -static int colorstobpp ARGS(( int colors )); -static int GetPixel ARGS(( int x, int y )); -static pixel** pixels; -static colorhash_table cht; -static char* testimage; -int -main(argc, argv) -int argc; -char* argv[]; -{ - FILE* ifp; - int argn, rows, cols, colors, i, j, BitsPerPixel; - pixval maxval; - colorhist_vector chv; - char rgb[CLUTCOLORS]; - const char* windowname; - char* thischar; - register unsigned char c; - int display, expand; - int winflag; - const char* const usage = "[-windowname windowname] [-expand expand] [-display display] [ppmfile]"; - - - ppm_init( &argc, argv ); - - argn = 1; - windowname = "untitled"; - winflag = 0; - expand = 1; - display = 0; - - while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) - { - if ( pm_keymatch(argv[argn],"-windowname",2) && argn + 1 < argc ) - { - ++argn; - windowname = argv[argn]; - winflag = 1; - } - else if ( pm_keymatch(argv[argn],"-expand",2) && argn + 1 < argc ) - { - ++argn; - if ( sscanf( argv[argn], "%d",&expand ) != 1 ) - pm_usage( usage ); - } - else if ( pm_keymatch(argv[argn],"-display",2) && argn + 1 < argc ) - { - ++argn; - if ( sscanf( argv[argn], "%d",&display ) != 1 ) - pm_usage( usage ); - } - else - pm_usage( usage ); - } - - if ( argn < argc ) - { - ifp = pm_openr( argv[argn] ); - if ( ! winflag ) - windowname = argv[argn]; - ++argn; - } - else - ifp = stdin; - - if ( argn != argc ) - pm_usage( usage ); - - pixels = ppm_readppm( ifp, &cols, &rows, &maxval ); - - pm_close( ifp ); - - for (i = 0; i < CLUTCOLORS; i++) - rgb[i] = 0; - - /* Figure out the colormap. */ - pm_message("computing colormap..." ); - chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors); - if (chv == (colorhist_vector) 0) - pm_error( "too many colors - try doing a 'pnmquant %d'", MAXCOLORS ); - pm_message("%d colors found", colors ); - - /* Turn the ppm colormap into an ICR colormap. */ - if (maxval > 255) - pm_message( - "maxval is not 255 - automatically rescaling colors" ); - for (i = 0; i < colors; i++) - { - j = (3 * i); - if (maxval == 255) - { - rgb[j] = PPM_GETR(chv[i].color) ; - j++; - rgb[j] = PPM_GETG(chv[i].color) ; - j++; - rgb[j] = PPM_GETB(chv[i].color) ; - } - else - { - rgb[j] = (int) PPM_GETR(chv[i].color) * 255 / maxval; - j++; - rgb[j] = (int) PPM_GETG(chv[i].color) * 255 / maxval; - j++; - rgb[j] = (int) PPM_GETB(chv[i].color) * 255 / maxval; - } - } - BitsPerPixel = colorstobpp(colors); - - /* And make a hash table for fast lookup. */ - cht = ppm_colorhisttocolorhash(chv, colors); - ppm_freecolorhist(chv); - - - /************** Create a new window using ICR protocol *********/ - /* Format is "ESC^W;left;top;width;height;display;windowname" */ - - pm_message("creating window %s ...", windowname ); - (void)printf("\033^W;%d;%d;%d;%d;%d;%s^",0,0,cols*expand,rows*expand,display,windowname); - fflush(stdout); - - - /****************** Download the colormap. ********************/ - pm_message("downloading colormap for %s ...", windowname ); - - (void)printf("\033^M;%d;%d;%d;%s^",0,MAXCOLORS,CLUTCOLORS,windowname); - thischar = rgb; - for (j=0; j<CLUTCOLORS; j++) { - c = *thischar++; - if (c > 31 && c < 123 ) { /* printable ASCII */ - putchar(c); - } - else { - putchar((c>>6)+123); /* non-printable, so encode it */ - putchar((c & 0x3f) + 32); - } - } - fflush(stdout); - - /**************** send out picture *************************/ - - pm_message("sending picture data ..." ); - for (i = 0; i < rows; i++) { - (void)printf("\033^P;%d;%d;%d;%d;%s^",0,i*expand,expand,cols,windowname); - for (j = 0; j < cols; j++) { - c = GetPixel(j,i); +static void +makeIcrColormap(colorhist_vector const chv, + unsigned int const colorCt, + pixval const maxval, + char * const rgb) { + + unsigned int i; + + if (maxval > 255) + pm_message("Maxval is not 255 - automatically rescaling colors" ); + + for (i = 0; i < CLUTCOLORCT; ++i) + rgb[i] = 0; + + for (i = 0; i < colorCt; ++i) { + unsigned int j; + + j = (3 * i); + + if (maxval == 255) { + rgb[j++] = PPM_GETR(chv[i].color) ; + rgb[j++] = PPM_GETG(chv[i].color) ; + rgb[j++] = PPM_GETB(chv[i].color) ; + } else { + rgb[j++] = (unsigned int) PPM_GETR(chv[i].color) * 255 / maxval; + rgb[j++] = (unsigned int) PPM_GETG(chv[i].color) * 255 / maxval; + rgb[j++] = (unsigned int) PPM_GETB(chv[i].color) * 255 / maxval; + } + } +} + + + +static int +bppFromColorCt(unsigned int const colorCt) { + + unsigned int bpp; + + if (colorCt <= 2) + bpp = 1; + else if (colorCt <= 4) + bpp = 2; + else if (colorCt <= 8) + bpp = 3; + else if (colorCt <= 16) + bpp = 4; + else if (colorCt <= 32) + bpp = 5; + else if (colorCt <= 64) + bpp = 6; + else if (colorCt <= 128) + bpp = 7; + else if (colorCt <= 256) + bpp = 8; + else + assert(false); + + return bpp; +} + + + +static int +colorIndexAtPosition(unsigned int const x, + unsigned int const y, + pixel ** const pixels, + colorhash_table const cht) { + + int rc; + + rc = ppm_lookupcolor(cht, &pixels[y][x]); + + /* Every color in the image is in the palette */ + assert(rc >= 0); + + return rc; +} + + + +static void +downloadColormap(char const rgb[CLUTCOLORCT], + const char * const windowName) { + + unsigned int i; + + pm_message("Downloading colormap for %s ...", windowName); + + printf("\033^M;%d;%d;%d;%s^", + 0, MAXCOLORCT, CLUTCOLORCT, windowName); + + for (i = 0; i < CLUTCOLORCT; ++i) { + unsigned char const c = rgb[i]; + + if (c > 31 && c < 123) { + /* printable ASCII */ + putchar(c); + } else { + /* non-printable, so encode it */ + putchar((c >> 6) + 123); + putchar((c & 0x3f) + 32); + } + } + fflush(stdout); +} + + + +static void +sendOutPicture(pixel ** const pixels, + unsigned int const rows, + unsigned int const cols, + colorhash_table const cht, + int const expand, + const char * const windowName) { + + unsigned int row; + + pm_message("Sending picture data ..." ); + + for (row = 0; row < rows; ++row) { + unsigned int col; + printf("\033^P;%d;%d;%d;%d;%s^", + 0, row * expand, expand, cols, windowName); + for (col = 0; col < cols; ++col) { + unsigned char const c = + colorIndexAtPosition(col, row, pixels, cht); if (c > 31 && c < 123) { putchar(c); - } - else { - putchar((c>>6)+123); + } else { + putchar((c >> 6) + 123); putchar((c & 0x3f) + 32); } } } fflush(stdout); - exit(0); } -static int -colorstobpp(colors) -int colors; - { - int bpp; - - if (colors <= 2) - bpp = 1; - else if (colors <= 4) - bpp = 2; - else if (colors <= 8) - bpp = 3; - else if (colors <= 16) - bpp = 4; - else if (colors <= 32) - bpp = 5; - else if (colors <= 64) - bpp = 6; - else if (colors <= 128) - bpp = 7; - else if (colors <= 256) - bpp = 8; - else - pm_error("can't happen" ); - return bpp; - } -static int -GetPixel(x, y) -int x, y; - { - int color; - - color = ppm_lookupcolor(cht, &pixels[y][x]); - return color; - } + +int +main(int argc, const char ** const argv) { + + FILE * ifP; + int rows, cols; + int colorCt; + int argn; + unsigned int bitsPerPixel; + pixval maxval; + colorhist_vector chv; + char rgb[CLUTCOLORCT]; + const char * windowName; + int display, expand; + int winflag; + const char* const usage = "[-windowname windowname] [-expand expand] [-display display] [ppmfile]"; + pixel** pixels; + colorhash_table cht; + + pm_proginit(&argc, argv); + + argn = 1; + windowName = "untitled"; + winflag = 0; + expand = 1; + display = 0; + + while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) + { + if ( pm_keymatch(argv[argn],"-windowname",2) && argn + 1 < argc ) + { + ++argn; + windowName = argv[argn]; + winflag = 1; + } + else if ( pm_keymatch(argv[argn],"-expand",2) && argn + 1 < argc ) + { + ++argn; + if ( sscanf( argv[argn], "%d",&expand ) != 1 ) + pm_usage( usage ); + } + else if ( pm_keymatch(argv[argn],"-display",2) && argn + 1 < argc ) + { + ++argn; + if ( sscanf( argv[argn], "%d",&display ) != 1 ) + pm_usage( usage ); + } + else + pm_usage( usage ); + } + + if ( argn < argc ) + { + ifP = pm_openr( argv[argn] ); + if ( ! winflag ) + windowName = argv[argn]; + ++argn; + } + else + ifP = stdin; + + if ( argn != argc ) + pm_usage( usage ); + + pixels = ppm_readppm(ifP, &cols, &rows, &maxval); + + pm_close(ifP); + + /* Figure out the colormap. */ + pm_message("Computing colormap..." ); + chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORCT, &colorCt); + if (!chv) + pm_error("Too many colors - try doing a 'pnmquant %u'", MAXCOLORCT); + pm_message("%u colors found", colorCt ); + + makeIcrColormap(chv, colorCt, maxval, rgb); + + bitsPerPixel = bppFromColorCt(colorCt); + + /* And make a hash table for fast lookup. */ + cht = ppm_colorhisttocolorhash(chv, colorCt); + + ppm_freecolorhist(chv); + + /************** Create a new window using ICR protocol *********/ + /* Format is "ESC^W;left;top;width;height;display;windowname" */ + + pm_message("Creating window %s ...", windowName); + + printf("\033^W;%d;%d;%d;%d;%d;%s^", + 0, 0, cols * expand, rows * expand, display, windowName); + fflush(stdout); + + /****************** Download the colormap. ********************/ + + downloadColormap(rgb, windowName); + + sendOutPicture(pixels, rows, cols, cht, expand, windowName); + + return 0; +} + |