about summary refs log tree commit diff
path: root/converter/ppm/ppmtoicr.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/ppm/ppmtoicr.c')
-rw-r--r--converter/ppm/ppmtoicr.c532
1 files changed, 238 insertions, 294 deletions
diff --git a/converter/ppm/ppmtoicr.c b/converter/ppm/ppmtoicr.c
index feca0c18..3c8be421 100644
--- a/converter/ppm/ppmtoicr.c
+++ b/converter/ppm/ppmtoicr.c
@@ -10,311 +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 int rleit ARGS(( char* buf, char* bufto, int len ));
 
-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, newxsize;
-	pixval maxval;
-	colorhist_vector chv;
-	char rgb[CLUTCOLORS];
-	const char* windowname;
-	char* thischar;
-	char* thisline;
-	char* space;
-	register unsigned char c;
-	register char* p;
-	int display, expand;
-	int rleflag, winflag;
-	const char* const usage = "[-windowname windowname] [-expand expand] [-display display] [-rle] [ppmfile]";
-
-
-	ppm_init( &argc, argv );
-
-	argn = 1;
-	windowname = "untitled";
-	winflag = 0;
-	expand = 1;
-	display = 0;
-	rleflag = 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 if ( pm_keymatch(argv[argn],"-rle",2) )
-		rleflag = 1;
-	    else if ( pm_keymatch(argv[argn],"-norle",2) )
-		rleflag = 0;
-	    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 *************************/
-	/* Protocol's RLE scheme is quicker but buggy              */
-
-	if (rleflag) {	
-		pm_message("sending run-length encoded picture data ..." );
-		testimage = (char*) malloc(rows*cols);
-		p = testimage;
-		for (i=0; i<rows; i++)
-			for (j=0; j<cols; j++) 
-			*p++ = GetPixel(j,i);
-		space = (char*) malloc(rows*3);
-		thisline = testimage;
-		for (i = 0; i < rows; i++) {
-			newxsize = rleit(thisline,space,cols);
-			thisline += cols;	/* increment to next line */
-		(void)printf("\033^R;%d;%d;%d;%d;%s^",0,i*expand,expand,newxsize,windowname);
-		thischar = space;
-		for (j=0; j< newxsize; j++) {
-			c= *thischar++;  /*get byte to send */
-			if (c>31 && c <123) {
-				putchar(c);
-				}
-			else {
-				putchar((c>>6) + 123);
-				putchar((c & 0x3f) + 32);
-				}
-			}
-			fflush(stdout);
-		}
-		free(space);
-		exit(0);
-		}
-
-	/* Otherwise, send out uncompressed pixel data via the slow method */
-
-		else {
-		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);
-				if (c > 31 && c < 123) {
-						putchar(c);
-						}
-				else		{
-						putchar((c>>6)+123);
-						putchar((c & 0x3f) + 32);
-						}
-				}
-			}
-		fflush(stdout);
-		exit(0);
-		}
-	}
+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
-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;
-	}
+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
-GetPixel(x, y)
-int x, y;
-	{
-	int color;
+colorIndexAtPosition(unsigned int    const x,
+                     unsigned int    const y,
+                     pixel **        const pixels,
+                     colorhash_table const cht) {
 
-	color = ppm_lookupcolor(cht, &pixels[y][x]);
-	return color;
-	}
+    int rc;
 
+    rc = ppm_lookupcolor(cht, &pixels[y][x]);
 
-/* rleit   compress with run length encoding as per NCSA's documentation */
+    /* Every color in the image is in the palette */
+    assert(rc >= 0);
 
-static int
-rleit(buf,bufto,len)
-	char* buf;
-	char* bufto;
-	int len;
-	{
-	register char* p;
-	register char* q;
-	register char* cfoll;
-	register char* clead;
-	char* begp;
-	int i;
-
-	p = buf;
-	cfoll = bufto;
-	clead = cfoll + 1;
-
-	begp = p;
-	while (len > 0 ) {		/* encode until gone */
-		
-		q = p + 1;
-		i = len-1;
-	while (*p == *q && i+120 > len && i) {
-		q++;
-		i--;
-	}
-
-	if (q > p +2) {			/* three in a row */
-		if (p > begp) {
-			*cfoll = p - begp;
-			cfoll = clead;
-		}
-		*cfoll++ = 128 | (q-p);		/*len of seq*/
-		*cfoll++ = *p;			/* char of seq */
-		len -= q-p;		/* subtract len of seq */
-		p = q;
-		clead = cfoll+1;
-		begp = p;
-	}
-	else {
-		*clead++ = *p++;	/* copy one char */
-		len--;
-		if (p>begp + 120) {
-			*cfoll = p - begp;
-			cfoll = clead++;
-			begp = p;
-		}
-	}
-	}
-
-/* fillin last bytecount */
-
-	if (p>begp)
-		*cfoll = (p - begp);
-	else
-		clead--;
-
-	return((int) (clead-bufto));	/*how many stored as encoded */
+    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);
+                putchar((c & 0x3f) + 32);
+            }
+        }
+    }
+    fflush(stdout);
+}
+
+
+
+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;
+}
+
+
+