[comp.windows.x] PAX Format Package

daniel@mirsa.inria.fr (Daniel Dardailler) (02/22/89)

		PORTABLE PIXMAP DISTRIBUTION FORMAT PROPOSAL
		--------------------------------------------

Since the X window system do not propose a standard file format for pixmap
distribition, we at BULL Research have made one called the PAX (Ascii
PiXmap) format for our own use, and are releasing it in the public domain.
This format is space-consuming but portable and editable with any text
editor.

An example for a "foo" pixmap stored in PAX format:

 #define foo_paxformat 1	/* version # of the format, for extensions */
 #define foo_width 6		/* width in pixels */
 #define foo_height 3		/* height in pixels */
 #define foo_ncolors 4		/* number of colors needed */
 #define foo_chars_per_pixel 2	/* number of ascii chars per pixels */
 static  char * foo_colors[] = { /* colormap in symbolic form */
 "  " , "DarkSlateGrey",	 /* rgb database color name */
 ". " , "#A8A8A8",		 /* RGB value */
 "X " , "White",
 "o " , "#540054005400"  
 } ;
 static char * foo_pixels[] = {  /* the rows of pixels as C strings: */
 "  X X .     ",			/* foo_height rows of */
 "o o o X X . "			/* foo_chars_per_pixel * foo_width chars */
 };

We would like to hear comments about it, so that it can be proposed
to the MIT X-Consortium and become the PDF (Pixmap Distribution Format)
similarly to the BDF format for fonts.

We have patterned it along the standard X11 bitmap file format, and you wiil
find at the end of this posting our first (non-optimized) implementation on
top of Xlib of the three C primitives used to handle it, i.e:

  int XWritePaxmapFile(dpy, cmap, filename, pixmap, w, h)
  int XReadPaxmapFile(dpy, d, cmap, filename, w, h, depth, pixmap)
  Pixmap XCreatePaxmapFromData(dpy, d, cmap, w, h, depth, n, c, col, pix)

As you can see, these are similar to the ...Bitmap... calls, with the
addition of the colormap and depth parameters.

For now, the paxmap format is used in two of our products: the XFEDOR
font/bitmap/pixmap editor, to be posted soon on comp.sources.x and the GWM
window manager, selected on the OSF "catalog" and which should be on the
X11R4 tape.


Daniel  Dardailler		daniel@mirsa.inria.fr
Vania   Joloboff		vania@mirsa.inria.fr
Vincent Bouthors		vincent@mirsa.inria.fr
Colas   Nahaboo			colas@mirsa.inria.fr

BULL Research FRANCE -- Koala Project 
	INRIA - Sophia Antipolis, 
 	2004, route des Lucioles, 
	06565 Valbonne Cedex
	FRANCE
Voice phone: (33) 93.65.77.71, Fax: (33) 93 65 77 66, Telex: 97 00 50 F

-------------CUT HERE---------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  paxfile.c paxfile.h
# Wrapped by daniel@mirsa on Wed Feb 22 15:41:52 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'paxfile.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'paxfile.c'\"
else
echo shar: Extracting \"'paxfile.c'\" \(14658 characters\)
sed "s/^X//" >'paxfile.c' <<'END_OF_FILE'
X/**************************************************************************
X ****  Read/Write package for PAX file format (Ascii PiXmap) 
X ****
X ****  int    XWritePaxmapFile(dpy, cmap, filename, pixmap, w, h)
X ****  int    XReadPaxmapFile(dpy, d, cmap, filename, w, h, depth, pixmap)
X ****  Pixmap XCreatePaxmapFromData(dpy, d, cmap, w, h, depth, n, c, col, pix)
X ****
X ****  Daniel Dardailler - Bull RC (89/02/22) e-mail: daniel@mirsa.inria.fr
X **************************************************************************/
X
X/***************************************************************************
X **** Look of PAX file : .. something like X11 'C includable' format
X
X#define drunk_pax_format 1
X#define drunk_width 18
X#define drunk_height 21
X#define drunk_ncolors 4
X#define drunk_chars_per_pixel 2
Xstatic  char * drunk_colors[] = {
X"  " , "#FFFFFFFFFFFF",
X". " , "#A800A800A800",
X"X " , "White",
X"o " , "#540054005400"  
X} ;
Xstatic char * drunk_pixels[] = {
X"                                    ",
X"                                    ",
X"            . . . . . . .           ",
X"          X         . . . .         ",
X"        X     X       . . . .       ",
X"      o         X       . . .       ",
X"    o o     X           . . . .     ",
X"  o o o               . . . . .     ",
X"o o o               . . . . . .     ",
X"o o o                   . . . .     ",
X"  X                 X   . . .       ",
X"  X   X               . . . .       ",
X"    X               . . . .         ",
X"    X                 . .           ",
X"      X                   X X X     ",
X"        X X X               X   X   ",
X"              X           X X       ",
X"            X X X       X X         ",
X"          X       X X X             ",
X"      X X                           ",
X"                                    " 
X} ;
X
X
X*************************************************************************
X*  Version 1 can handle a variable number of chars per pixel
X*  - for each different color : n chars can represent the pixel value 
X*    and is associed with red, green and blue intensity or colorname.
X
X**************************************************************************/
X/*************************************************************************/
X
X#include <stdio.h>
X#include <X11/Xlib.h>
X
X#include "paxfile.h"      /* PaxmapOpenFailed, PixmapSuccess .. MAXPRINTABLE */
X
X
X/*----------------------------------------------------------------------*/
X/* 
X * Write a X Color Pixmap through a specified colormap
X * (THIS VERSION PRODUCE ONLY 2 CHARS PER PIXEL FORMAT : '_chars_per_pixel 2')
X */
Xint XWritePaxmapFile(display, colormap, filename, pixmap, width, height)
X/*------------------*/
X     Display * display;
X     Colormap  colormap ;
X     char *filename;
X     Pixmap pixmap;
X     unsigned int width, height;
X{
X   XImage *image;                /* client image */
X   
X   FILE *stream;
X   char *name, *stripname;     
X
X   int ncolors = 0 ;             /* number of different colors */
X
X   CmapEntry * cmap ;            /* indexed by ncolors, 
X				    dynamicaly allocated by width */
X
X   Cixel * Map ;                 /* should be [width][height] */
X   int i,j,p ;
X
X   XColor * colors ;
X
X   int MaxCixel ;               /* theorytical max */
X
X   if (!filename) return(PixmapOpenFailed);
X   stripname = (char *) malloc(strlen(filename));
X   if (stripname == NULL)
X     return PixmapNoMemory ;
X
X   strcpy(stripname,filename);           /* no more use of filename */
X
X   /* extract the short name of the pixmap */
X   if (!(name = (char *)rindex(stripname, '/')))
X     name = stripname;
X   else
X     name++;
X
X   if (!(stream = fopen(stripname, "w")))
X     return(PixmapOpenFailed);            
X
X   if (stripname = (char *)index(name, '.'))
X     *stripname = '\0' ;                  /* modify both name and stripname */
X   
X
X   /* Convert pixmap to an image in client memory */
X   image = XGetImage(display, pixmap, 0,0,width, height, AllPlanes, ZPixmap);
X
X   /* calcul of ncolors, cmap, Map in a while */
X   colors = (XColor *) malloc(width*sizeof(XColor));
X   cmap = (CmapEntry *) malloc(MAXPRINTABLE*sizeof(CmapEntry)); 
X   Map = (Cixel *) malloc(sizeof(Cixel)*width*height);
X
X   if ((colors == NULL) || (cmap == NULL) || (Map == NULL))
X     return PixmapNoMemory ;
X
X   MaxCixel = (MAXPRINTABLE*MAXPRINTABLE)-1 ;
X
X   for (j=0 ; j<height ; j++) {
X     for (i=0; i<width ; i++) colors[i].pixel = XGetPixel(image,i,j) ;
X     /* ask server for rgb values line by line */
X     XQueryColors(display,colormap,colors,width);  /* return : colors */
X     for (i=0; i<width ; i++) {
X       for (p=0; p<ncolors; p++)
X	 if ((colors[i].red   == cmap[p].red) &&
X	     (colors[i].green == cmap[p].green) &&
X	     (colors[i].blue  == cmap[p].blue)) {  /* already present */
X	   *(Map + j*width + i) = cmap[p].cixel ;
X	   break ;                     /* stop with p < ncolors */
X	 }
X       if (p == ncolors) {             /* new rgb value in cmap */
X	 cmap[ncolors].red = colors[i].red ;
X	 cmap[ncolors].green = colors[i].green ;
X	 cmap[ncolors].blue = colors[i].blue ;
X	 cmap[ncolors].cixel.c1 = printable[ncolors % MAXPRINTABLE];
X	 cmap[ncolors].cixel.c2 = printable[ncolors / MAXPRINTABLE];
X	 *(Map + j*width + i) = cmap[ncolors].cixel ;  
X	 if (ncolors < MaxCixel) ncolors++ ;
X	 if (ncolors % MAXPRINTABLE)          /*  => much memory for cmap */
X	   cmap = (CmapEntry *) realloc((char*)cmap,
X				(ncolors+MAXPRINTABLE)*sizeof(CmapEntry)); 
X	   if (cmap == NULL)
X	     return PixmapNoMemory ;
X       }
X     }
X   }       
X
X   /* Write out standard header */
X   fprintf(stream, "#define %s_paxformat %d\n",name,PAX_FORMAT);
X   fprintf(stream, "#define %s_width %d\n",name,width);
X   fprintf(stream, "#define %s_height %d\n",name,height);
X   fprintf(stream, "#define %s_ncolors %d\n",name,ncolors);
X   fprintf(stream, "#define %s_chars_per_pixel %d\n",name,2);
X
X   fprintf(stream, "static char * %s_colors[] = {\n",name);
X
X   for (i=0; i<ncolors ; i++) {
X     fprintf(stream, "\"%c%c\" , \"#%X%X%X\"",
X	     cmap[i].cixel.c1,cmap[i].cixel.c2,
X	     cmap[i].red,cmap[i].green,cmap[i].blue);
X     if (i != (ncolors - 1)) fprintf(stream,",\n"); else
X                            fprintf(stream,"\n"); 
X   }     
X   fprintf(stream, "} ;\n");
X   fprintf(stream, "static char * %s_pixels[] = {\n",name);
X
X   for (j=0; j<height ; j++) {
X     fprintf(stream, "\"");
X     for (i=0; i<width ; i++) 
X       fprintf(stream, "%c%c", (*(Map + j*width + i)).c1,
X	       (*(Map + j*width + i)).c2);
X     if (j != (height - 1)) fprintf(stream,"\",\n"); else
X                            fprintf(stream,"\n"); 
X   }
X
X   fprintf(stream, "} ;\n");
X
X   free(colors);
X   free(cmap);
X   free(Map) ;
X   XDestroyImage(image);
X
X   fclose(stream);
X   return PixmapSuccess ;
X}
X
X
X/*------------------------------------------------------------*/
X/*------------------------------------------------------------*/
X/* following routines are used in XReadPaxmapFile() function */
X/*------------------------------------------------------------*/
X
X/*
X * read the next line and jump blank lines 
X */
Xstatic char *
Xgetline(s,pF)
X     char * s ;
X     FILE * pF ;
X{
X    s = fgets(s,256,pF);
X
X    while (s) {
X	int len = strlen(s);
X	if (len && s[len-1] == '\015')
X	    s[--len] = '\0';
X	if (len==0) s = fgets(s,256,pF);
X	else break;
X    }
X    return(s);
X}
X	    
X
X/*
X * fatal message : return code, no exit 
X */
Xstatic int fatal(msg, p1, p2, p3, p4)
X    char *msg;
X{
X    fprintf(stderr,"\n");
X    fprintf(stderr, msg, p1, p2, p3, p4);
X    fprintf(stderr,"\n");
X    return PixmapFileInvalid ;
X}
X
X
X
X/*
X *  Read a Pixmap file in a X Pixmap with specified depth and colormap
X * (THIS VERSION READ ONLY 2 CHARS PER PIXEL FORMAT : '_chars_per_pixel 2')
X */
Xint XReadPaxmapFile (display,d,colormap,filename,width,height,depth,pixmap)
X/*-----------------*/
X     Display *display;
X     Drawable d;
X     Colormap colormap ;
X     char *filename;
X     unsigned int *width, *height;       /* RETURNED */
X     int depth ;   
X     Pixmap *pixmap;                     /* RETURNED */
X{
X  GC Gc ;
X  XGCValues xgcv;
X
X  FILE *fstream;			/* handle on file  */
X  char linebuf[256] ;
X  char namebuf[256];
X  char type[256];
X  char name[256];
X
X  int ncolors ;
X
X  CmapEntry * cmap ;           
X  int * Tpixel ;
X
X  char c1, c2, c;
X  int red, green, blue ;
X  XColor xcolor ;
X  int i,j,p;
X
X  
X  if ((fstream = fopen(filename, "r")) == NULL) {
X    return PixmapOpenFailed;
X  }
X
X  getline(linebuf,fstream);
X  if ((sscanf(linebuf, "#define %[^_]%s %d", namebuf, type, &p) != 3) 
X      || (strcmp("_paxformat",type)) 
X      || (p != PAX_FORMAT)) 
X    return fatal("bad '#define NAME_paxformat 1'"); 
X  else strcpy(name,namebuf);
X
X  getline(linebuf,fstream);
X  if ((sscanf(linebuf, "#define %[^_]%s %d", namebuf, type, width) != 3)
X      || (strcmp(name,namebuf)) 
X      || (strcmp("_width",type))) 
X	return fatal("bad '#define NAME_width w'");
X
X  getline(linebuf,fstream);
X  if ((sscanf(linebuf, "#define %[^_]%s %d", namebuf, type, height) != 3)
X      || (strcmp(name,namebuf)) 
X      || (strcmp("_height",type))) 
X	return fatal("bad '#define NAME_height w'");
X
X  getline(linebuf,fstream);
X  if ((sscanf(linebuf, "#define %[^_]%s %d", namebuf, type, &ncolors) != 3)
X      || (strcmp(name,namebuf)) 
X      || (strcmp("_ncolors",type))) 
X	return fatal("bad '#define NAME_ncolors w'");
X
X  if (ncolors > (MAXPRINTABLE*MAXPRINTABLE)) 
X    return fatal("Too many different colors, version 1");
X
X  getline(linebuf,fstream);
X  if ((sscanf(linebuf, "#define %[^_]%s %d", namebuf, type, &p) != 3)
X      || (strcmp(name,namebuf)) || (p != 2)
X      || (strcmp("_chars_per_pixel",type)))
X	return fatal("bad '#define NAME_chars_per_pixel 2'");
X
X  getline(linebuf,fstream);
X  if ((sscanf(linebuf, "static char * %[^_]%s = {",namebuf,type) != 2)
X      || (strcmp(name,namebuf))
X      || (strcmp("_colors[]",type))) 
X	return fatal("bad 'static char * NAME_colors[] = {'");
X
X  cmap = (CmapEntry *) malloc(ncolors*sizeof(CmapEntry)) ;
X  Tpixel = (int *) malloc(ncolors*sizeof(int)) ;
X  if ((cmap == NULL) || (Tpixel == NULL))
X    return PixmapNoMemory ;
X
X  getline(linebuf,fstream);
X  for (i=0; i<ncolors ; i++) {
X    if (sscanf(linebuf, "\"%c%c\" , \"%[^\"]%s",
X	       &c1,&c2,
X	       namebuf,type) != 4)
X      return fatal("bad colormap entry : must be '\"cC\" , \"colordef\",'"); 
X    if ((strchr(printable,c1)) &&
X	(strchr(printable,c2))) {
X      cmap[i].cixel.c1 = c1 ;
X      cmap[i].cixel.c2 = c2 ;
X      if (!XParseColor(display,colormap,namebuf,&xcolor))
X	return fatal("bad colordef specification : #RGB or colorname");
X      XAllocColor(display,colormap,&xcolor);
X      Tpixel[i] = xcolor.pixel ;
X    } else
X      return fatal("bad cixel value : must be printable");
X    
X    getline(linebuf,fstream);
X  }
X
X  if (strncmp(linebuf, "} ;",3))
X    return fatal("missing '} ;'");
X
X  getline(linebuf,fstream);
X  if ((sscanf(linebuf, "static char * %[^_]%s = {",namebuf,type) != 2)
X      || (strcmp(name,namebuf))
X      || (strcmp("_pixels[]",type))) 
X	return fatal("bad 'static char * NAME_pixels[] = {'");
X
X  *pixmap = XCreatePixmap(display,d,*width,*height,depth);
X  Gc = XCreateGC(display,*pixmap,0,&xgcv);
X  
X  getline(linebuf,fstream);
X  j = 0 ;
X  while((j < *height) && strncmp(linebuf, "} ;",3)) {  
X    if (strlen(linebuf) < (2*(*width)+2)) 
X      return fatal("bad pixmap line length %d",strlen(linebuf));
X    for (i=1; i<(2*(*width)) ; i+=2) {
X      c1 = linebuf[i] ;
X      c2 = linebuf[i+1] ;
X      for (p = 0 ; p < ncolors ; p++)
X	if ((cmap[p].cixel.c1 == c1)&&(cmap[p].cixel.c2 == c2)) break ;
X      if (p != ncolors)
X	XSetForeground(display,Gc,Tpixel[p]);
X      else 
X	return fatal("cixel %c%c not in previous colormap",c1,c2);
X      XDrawPoint(display,*pixmap,Gc,i/2,j) ;
X    }
X    j++ ;
X    getline(linebuf,fstream);    
X  }
X
X  if (strncmp(linebuf, "} ;",3))
X    return fatal("missing '} ;'");
X
X  if (j != *height)
X    return fatal("%d too few pixmap line", *height - j);
X
X  free(cmap) ;
X  free(Tpixel) ;
X  fclose(fstream) ;
X  return PixmapSuccess ;
X}
X
X
X
X  
X/*
X *  This function allows you to include in your C program (using #include)
X *  a pixmap file in PAX format that was written by XWritePaxmapFile
X * (THIS VERSION MANAGE ONLY 2 CHARS PER PIXEL FORMAT : '_chars_per_pixel 2')
X */
XPixmap XCreatePaxmapFromData(display, d, colormap, width, height, depth, 
X			      ncolors, chars_per_pixel, colors, pixels)
X/*-------------------------*/
X     Display *display;
X     Drawable d;
X     Colormap colormap ;
X     unsigned int width, height;       
X     int depth ;   
X     unsigned int ncolors ;
X     unsigned int chars_per_pixel ;
X     char ** colors ;           /* array of colormap entries  "cc","#RRGGBB" */
X     char ** pixels ;           /* array of pixels lines    "cc..cc00cccc.." */
X{
X  Pixmap pixmap ;
X  GC Gc ;
X  XGCValues xgcv;
X
X  CmapEntry * cmap ;           
X  int * Tpixel ;
X
X  char c1, c2, c;
X  int red, green, blue ;
X  XColor xcolor ;
X  int i,j,p;
X  
X  if (ncolors > (MAXPRINTABLE*MAXPRINTABLE)) 
X    return fatal("Too many different colors, version 1");
X
X  if (chars_per_pixel != 2) 
X    return fatal("version 1 handle only 2 chars_per_pixel");
X
X  /* now we construct cmap and Tpixel from colors array parameter */
X  cmap = (CmapEntry *) malloc(ncolors*sizeof(CmapEntry)) ;
X  Tpixel = (int *) malloc(ncolors*sizeof(int)) ;
X  if ((cmap == NULL) || (Tpixel == NULL))
X    return PixmapNoMemory ;
X
X  if (!colors) return fatal("colors not defined");
X
X  for (i=0; i<2*ncolors ; i+=2) {
X    if (sscanf(colors[i],"%c%c", &c1,&c2) != 2)
X      return fatal("bad colormap entry : must be '\"cC\" , \"colordef\",'"); 
X    if ((strchr(printable,c1)) &&
X	(strchr(printable,c2))) {
X      cmap[i/2].cixel.c1 = c1 ;
X      cmap[i/2].cixel.c2 = c2 ;
X      if (!XParseColor(display,colormap,colors[i+1],&xcolor))
X	return fatal("bad colordef specification : #RGB or colorname");
X      XAllocColor(display,colormap,&xcolor);
X      Tpixel[i] = xcolor.pixel ;
X    } else
X      return fatal("bad cixel value : must be printable");
X  }
X
X  pixmap = XCreatePixmap(display,d,width,height,depth);
X  Gc = XCreateGC(display,pixmap,0,&xgcv);
X
X  if (!pixels) return fatal("pixels not defined");
X  j = 0 ;
X  while (j < height) {  
X    if (strlen(pixels[j]) != (2*width))
X      return fatal("bad pixmap line length %d",strlen(pixels[j]));
X    for (i=0; i< (2*width) ; i+=2) {
X      c1 = pixels[j][i] ;
X      c2 = pixels[j][i+1] ;
X      for (p = 0 ; p < ncolors ; p++)
X	if ((cmap[p].cixel.c1 == c1)&&(cmap[p].cixel.c2 == c2)) break ;
X      if (p != ncolors)
X	XSetForeground(display,Gc,Tpixel[p]);
X      else 
X	return fatal("cixel %c%c not in previous colormap",c1,c2);
X      XDrawPoint(display,pixmap,Gc,i/2,j) ;
X    }
X    j++ ;
X  }
X
X  free(cmap) ;
X  free(Tpixel) ;
X  return pixmap ;
X
X}
END_OF_FILE
if test 14658 -ne `wc -c <'paxfile.c'`; then
    echo shar: \"'paxfile.c'\" unpacked with wrong size!
fi
# end of 'paxfile.c'
fi
if test -f 'paxfile.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'paxfile.h'\"
else
echo shar: Extracting \"'paxfile.h'\" \(1541 characters\)
sed "s/^X//" >'paxfile.h' <<'END_OF_FILE'
X/**************************************************************************
X ****  Constant used in paxfile library functions :
X ****
X ****  int XWritePaxmapFile(dpy, cmap, filename, pixmap, w, h)
X ****  int XReadPaxmapFile(dpy, d, cmap, filename, w, h, depth, pixmap)
X ****  Pixmap XCreatePaxmapFromData(dpy, d, cmap, w, h, depth, n, c, col, pix)
X ****
X ****  Daniel Dardailler - Bull RC (89/02/22) e-mail: daniel@mirsa.inria.fr
X **************************************************************************/
X
X#define PAX_FORMAT 1
X
X/* we keep the same codes as for Bitmap management */
X#ifndef _XUTIL_H_
X#include <X11/Xutil.h>
X#endif
X#define PixmapSuccess        BitmapSuccess 
X#define PixmapOpenFailed     BitmapOpenFailed
X#define PixmapFileInvalid    BitmapFileInvalid
X#define PixmapNoMemory       BitmapNoMemory
X
X
Xtypedef struct _Cixel {
X     char c1,c2 ;
X   } Cixel ;                    /* 2 chars for one pixel value */
X
Xtypedef struct _CmapEntry {
X     Cixel cixel ;               
X     int red,green,blue ;
X   } CmapEntry ;                    
X
X
X#define MAXPRINTABLE 93             /* number of printable ascii chars 
X				       minus \ and " for string compat. */
X
Xstatic char * printable = " .XoO+@#$%&*=-;:?>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|" ;
X           /* printable begin with a space, so in most case, due to
X	      my algorythm, when the number of different colors is
X	      less than MAXPRINTABLE, it will give a char follow by 
X	      "nothing" (a space) in the readable pax file */
X
END_OF_FILE
if test 1541 -ne `wc -c <'paxfile.h'`; then
    echo shar: \"'paxfile.h'\" unpacked with wrong size!
fi
# end of 'paxfile.h'
fi
echo shar: End of shell archive.
exit 0
-- 
   Daniel Dardailler                   |      Email : daniel@mirsa.inria.fr  
   BULL  Centre de Sophia Antipolis    |      Phone : (33) 93 65 77 71       
         2004, Route des Lucioles      |      Telex :      97 00 50 F        
         06565 Valbonne CEDEX  France  |      Fax   : (33) 93 65 77 66      

bzs@Encore.COM (Barry Shein) (02/24/89)

Good thing to bring up.

Although I see the desires of the design, which are good, it seems
like tying the colormap to, essentially, the ASCII printable character
set (probably less without contortions) is an artificial and probably
ultimately problematic limitation.

Personally I can't think of any easy way out of it other than using
some sort of numeric encoding (eg.  #C8 #04) of the colormap index
(perhaps a space can be used to separate if variable numbers of digits
are to be allowed rather than an additional escape char like "#".) I
*do* understand the original desire to use one char per pixel to
simplify editing/viewing, problem.

Any thoughts/reactions on this particular issue? I suspect the
designers agonized over it also.

	-Barry Shein, ||Encore||

markc@hpcvlx.HP.COM (Mark Cook) (02/24/89)

What's wrong the I/O file format already in use by xwd and xwud?  I realize
that they don't constitute a 'standard' format, but they are already in wide
use (via the MIT distribution).  The XImage they use also provides a very
tight format for datafile storage of a Pixmap of arbitrary depth, allows for
all the different vendor hardware configurations that X11 supports, and
allows for the integration of the existing XImage calls with any I/O calls
you might want to write.  One really only needs to write 3 additional calls
to provide full I/O functionality: XReadImageFile(), XWriteImageFile(), and
XConvertImageColormap().  The only thing that this format does not lend it-
self to that the PAX format does, is the editing of a data file by a text
editor.  Considering the potential size of any useful Pixmap file, I don't
consider that capability a very high priority.

By the way, the 3 calls I suggest writing above involve very little work
if one already has access to the source code of xwd and/or xwud.

	Mark F. Cook

USMail: User Interface Technical Support
	Hewlett-Packard - Corvallis Workstation Operation
	1000 NE Circle Blvd.  Corvallis, OR 97330

ARPA: markc%hpcvss@hplabs.HP.COM
UUCP: {cmcl2, harpo, hplabs, rice, tektronix}!hp-pcd!hpcvss!markc

"The opinions expressed herein are not necessarily those of my employer,
 not necessarily mine, and probably not necessary."

geoff@desint.UUCP (Geoff Kuenning) (02/24/89)

In article <133@mirsa.inria.fr> daniel@mirsa.inria.fr
(Daniel Dardailler) writes:

> Since the X window system do not propose a standard file format for pixmap
> distribition, we at BULL Research have made one called the PAX (Ascii
> PiXmap) format for our own use, and are releasing it in the public domain.

I haven't read the proposal yet, but how about calling it something other
than PAX?  That name has recently been preempted for a new portable
archiver (cf. comp.sources.unix in the past few weeks).
-- 
	Geoff Kuenning   geoff@ITcorp.com   uunet!desint!geoff

raveling@vaxb.isi.edu (Paul Raveling) (02/25/89)

In article <100920057@hpcvlx.HP.COM> markc@hpcvlx.HP.COM (Mark Cook) writes:
>
>What's wrong the I/O file format already in use by xwd and xwud?  I realize
>that they don't constitute a 'standard' format, but they are already in wide
>use (via the MIT distribution). ...

	There are a number of problems -- some are:

	1.  It doesn't include associated data for use by applications.
	    For example, our map images include scale & latitude/longitude
	    bounds as ascii text in the file header.
	
	2.  It DOES include a lot of things that are unneeded complexity
	    for most image users.  Some of the excess baggage relates
	    to views of the image (e.g., window geometry) rather than
	    the image itself.

	3.  It's not widely used.  Among all the sources of images
	    that I know of on the net, none supply images in XWD format.
	    More popular formats are GIF, Sun rasterfiles, TIFF,
	    and a cast of dozens more.


	We've learned a fair bit about requirements for simple
	image formats after more than a year of using our own format
	under X.  Some of the discussion at the image processing BOF at
	the X Conference backed up much of what we learned.  The
	bottom line is that none of the current file formats are
	entirely satisfactory;  some are close, but still no cigar.

	I think we should open the floor for nominations for a
	"simple image" format and matching support software.
	The combination should meet the requirements of virtually
	all "ordinary" image display -- being able to represent
	images for use as background tiles, icons, & such.  It
	need not support more sophisticated image display and image
	processing needs (e.g., wouldn't include data for gamma
	correction).  Above all, the file format and the associated
	processing functions should be "as simple as possible,
	but not simpler".

	Before Monday's done I'll post a nomination in the form
	of a file format spec, and I'd encourage others to do the
	same.   It would seem best to post to both comp.graphics
	and comp.windows.x  (& any others?); so far most of the
	attention to file formats has been in comp.graphics.


----------------
Paul Raveling
Raveling@isi.edu