[net.micro.amiga] DISPLAY.C program for viewing .IMG files

wecker@cookie.dec.com (DAVE TANSTAAFL WECKER) (10/14/86)

/***********************************************************************
 *
 *  DISPLAY package for .img files (DBW encoding)
 *
 *	File format:
 *	    MAXX MAXY MAXCOLORS			    - header
 *	    sixteen hex colors in descending usage  - colortable
 *	    Encoding of pixels: (all printable ASCII)
 *		@ - O	= Absolute color (low four bits) in color table
 *		P - _	= Relative color. Low four bits is new BLUE  value
 *		` - o	= Relative color. Low four bits is new RED   value
 *		p - DEL	= Relative color. Low four bits is new GREEN value
 *		' '- >	= Repeat introducer (next char - ' ' = repeat count)
 *		?       = Alternate encoding for <DEL>
 *		\r \n	= Ignored (end of line markers) (NOT scan line)
 *
 *	v1.0	860907	DBW
 *
 ***********************************************************************/

#include <stdio.h>
#include <strings.h>
#include <sys/file.h>
#include <X/Xlib.h>
#include <X/Xtext.h>

#define CHECK(x)	while (line[x] < ' ') {\
	if (fgets(line,128,fp) == NULL) error("Early EOF");\
	x = 0;\
	}

FILE		*fp;
unsigned char	line[128];
unsigned char	grey[] = "  ..,,::;;//**##";
unsigned char	map[6][6] = {
    {0,	0,  0,	0,  0,	0},
    {0,	1,  0,	0,  0,	0},
    {0,	1,  0,  1,  0,  0},
    {1,	0,  1,	0,  1,	0},
    {1,	1,  0,	1,  0,	1},
    {1,	1,  1,	0,  1,	1} };

unsigned char   buf1[1024],buf2[1024];
int		maxx,maxy,maxc;
int		colors[16];
int		cpix,cr,cg,cb,count,pos,doX;
Window		w;
Display		*dpy;
XEvent		rep;
Color		col[16],sav[16];

main(argc,argv)
int argc;
char *argv[];
    {
    char	    str[10];
    int		    i,j,k,x,y,val;

    doX = argc < 3 ? 1 : 0;

    /* open the display */
    if (doX) {
	dpy = XOpenDisplay("");
	if (dpy == 0) exit(-1);
	}

    /* set up the gray scale map */
    for (i=0; i<16; i++) {
	sav[i].pixel	= i;
	sprintf(str,"#%01x%01x%01x",15-i,15-i,15-i);
	if (doX) XParseColor(str,&col[i]);
	}
    if (doX) {
	XQueryColors(sav,16);
	XStoreColors(16,col);
	}

    if (argc < 2) fp = stdin;
    else	  fp = fopen(argv[1],"r");

    if (fp == NULL) error("can't open input file");
    if (fgets(line,128,fp) == NULL) error("can't read first line");
    if (sscanf(line,"%d %d %d\n",&maxx,&maxy,&maxc) != 3) error("bad header");
    if (maxc != 256) error("expecting 256 colors");
    for (i = 0; i < 16; i++) {
	if (fgets(line,128,fp) == NULL) error("can't read colors");
	if (i == 0 &&
	    sscanf(line,"%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
	     &colors[0],&colors[1],&colors[2],&colors[3],&colors[4],&colors[5],
	     &colors[6],&colors[7],&colors[8],&colors[9],&colors[10],&colors[11],
	     &colors[12],&colors[13],&colors[14],&colors[15]) != 16)
		error("didn't find 16 colors as expected");
	}

    /* now init the read buffer */
    line[0] = '\n';
    pos	    = 0;
    count   = 0;
    cr	    = 0;
    cg	    = 0;
    cb	    = 0;
    cpix    = '@';

    /* set up the window for display */
    printf("Maxx = %d, Maxy = %d\n",maxx,maxy);
    if (doX) {
	w = XCreateWindow(dpy->root,0,0,maxx*3,maxy*2,2,WhitePixmap,BlackPixmap);
	XSelectInput(w,KeyPressed|ButtonPressed);
	XMapWindow(w);
	}

    /* Read through the file and display the results */
    for (y = 0; y < maxy; y++) {
	for (x = 0; x < maxx; x++) {
	    getnext();
/*	    val  = (cr * 7 + cg * 4 + cb * 2)/2;    */
	    val  = (cr * 5 + cg * 4 + cb * 3)/2;
	    if (val > 89) val = 89;
	    i = val / 6;
	    j = val % 6;
	    buf1[(x*3)]	    = i + map[j][0];
	    buf1[(x*3)+1]   = i + map[j][1];
	    buf1[(x*3)+2]   = i + map[j][2];
	    buf2[(x*3)]	    = i + map[j][3];
	    buf2[(x*3)+1]   = i + map[j][4];
	    buf2[(x*3)+2]   = i + map[j][5];
	    if (doX == 0 && (y % 10) == 9 && (x % 4) == 3) 
		printf("%c",grey[i]);
	    }
	if (doX) {
	    XPixmapBitsPutZ(w,0,(y*2)  ,maxx*3,1,buf1,0,GXcopy,AllPlanes);
	    XPixmapBitsPutZ(w,0,(y*2)+1,maxx*3,1,buf2,0,GXcopy,AllPlanes);
	    }
	else {
	    if ((y % 10) == 9) printf("\n");
	    }
	}
    error(NULL);
    }

error(msg)
char *msg;
    {
    int	i;

    if (msg != NULL) {
	puts("ERROR: ");
	puts(msg);
	puts("\n");
	}
    fclose(fp);
    if (doX) {
	XFlush();
	XWindowEvent(w,(KeyPressed|ButtonPressed),&rep);
	XUnmapWindow(w);
	XStoreColors(16,sav);
	}
    if (msg == NULL) exit(0);
    else	     exit(-1);
    }

getnext() {
    int	scr,crgb;

    /* first see if we're in a repeat count */
    if (count-- > 0) return;

    /* now see if we need a new buffer */
    CHECK(pos);

    /* see if we got a repeat count */
    if (line[pos] < '?') {
	count = (line[pos] - ' ') * 94;
	++pos;
	CHECK(pos);
	count += line[pos++] - ' ';
	CHECK(pos);
	}
    else
	count = 1;

    /* now bring the character in */
    cpix = line[pos++];
    if (cpix == '?') cpix = 127;
    if (--count < 0) return;

    /* now set up all the associated variables */
    scr = (cpix >> 4) & 3;
    switch (scr) {
	case 0:	crgb = colors[cpix & 0xF];
		cr   = (crgb >> 8) & 0xF;
		cg   = (crgb >> 4) & 0xF;
		cb   = (crgb     ) & 0xF;
		break;
	case 1:	cb   = cpix & 0xF;
		break;
	case 2:	cr   = cpix & 0xF;
		break;
	case 3:	cg   = cpix & 0xF;
		break;
	}
    }