Index: trunk/Ohana/src/kapa2/doc/communication.txt
===================================================================
--- trunk/Ohana/src/kapa2/doc/communication.txt	(revision 26891)
+++ trunk/Ohana/src/kapa2/doc/communication.txt	(revision 26891)
@@ -0,0 +1,119 @@
+
+These are the allowed commands from the pipe, and their required additional messages:
+
+NCUR : end cursor interaction (only valid if already in active cursor mode)
+     NONE
+QUIT : quit kapa
+     NONE
+CURS : turn on active cursor
+     NONE
+PSIT : create PS file
+  KiiSendMessage (fd, "%s", filename);
+PNGF : create PNG file
+  KiiSendMessage (fd, "%s", filename);
+PPMF : create PPM file
+  KiiSendMessage (fd, "%s", filename);
+DBOX : 
+  KiiSendMessage (fd, "%12.6g %12.6g %12.6g %12.6g", graphdata[0].xmin, graphdata[0].xmax, graphdata[0].ymin, graphdata[0].ymax);
+  KiiSendMessage (fd, "%lf %d", graphdata[0].lweight, graphdata[0].color);
+  KiiSendMessage (fd, "%s %s %s", graphdata[0].axis, graphdata[0].labels, graphdata[0].ticks);
+PLOT : 
+  KiiSendMessage (fd, "%8d %8d %d %d %d %d %d %f %f", Npts, data[0].style, data[0].ptype, data[0].ltype, data[0].etype, data[0].ebar, data[0].color, data[0].lweight, data[0].size);
+  KiiSendMessage (fd, "%g %g %g %g", data[0].xmin, data[0].xmax, data[0].ymin, data[0].ymax);
+LABL : 
+  KiiSendMessage (fd, "%6d", mode);
+  KiiSendData (fd, string, strlen(string));
+PTXT : 
+  KiiSendMessage (fd, "%f %f %f", x, y, angle);
+  KiiSendData (fd, string, strlen(string));
+RSIZ : 
+  KiiSendMessage (fd, "%d %d", Nx, Ny); 
+CHAN : 
+  KiiSendMessage (fd, "%1d", channel);
+CMAP : 
+  KiiSendMessage (fd, "%s", colormap);
+CSVE : 
+  KiiSendMessage (fd, "FILE: %d %s", n, file);
+DSEC : 
+  KiiSendMessage (fd, "%s %6.3f %6.3f %6.3f %6.3f", section[0].name, section[0].x, section[0].y, section[0].dx, section[0].dy);
+ERSC : 
+     NONE
+ERSI : 
+     NONE
+ERSO : 
+  KiiSendCommand (fd, 16, "OVERLAY %7d ", n);
+ERSP : 
+     NONE
+ERSS : 
+     NONE
+FONT : 
+  KiiSendCommand (fd, 16, "%s", name);
+  KiiSendCommand (fd, 16, "%d", size);
+GIMC : 
+  KiiScanMessage (fd, "%f %f %f %f", &coords[0].pc1_1, &coords[0].pc2_2, &coords[0].pc1_2, &coords[0].pc2_1); 
+  KiiScanMessage (fd, "%s", coords[0].ctype);
+  KiiScanMessage (fd, "%lf %lf %f %f %f %f", &coords[0].crval1, &coords[0].crval2, &coords[0].crpix1, &coords[0].crpix2, &coords[0].cdelt1, &coords[0].cdelt2);
+GIMD : 
+  KiiScanMessage (fd, "%lf %lf %s %s", &data[0].zero, &data[0].range, data[0].name, data[0].file);
+GIMR : 
+  KiiScanMessage (fd, "%lf %lf %lf %lf", Xmin, Xmax, Ymin, Ymax);
+GLIM : 
+  KiiScanMessage (fd, "%f %f", dx, dy); 
+GSTY : 
+  /* send kapa the plot details */
+  KiiScanMessage (fd, "%d %d %d %d %d %d %lf %lf", &data[0].style, &data[0].ptype, &data[0].ltype, &data[0].etype, &data[0].ebar, &data[0].color, &data[0].lweight, &data[0].size);
+  KiiScanMessage (fd, "%lf %lf %lf %lf", &data[0].xmin, &data[0].xmax, &data[0].ymin, &data[0].ymax);
+  KiiScanMessage (fd, "%f %f %f %f", &data[0].coords.pc1_1, &data[0].coords.pc2_2, &data[0].coords.pc1_2, &data[0].coords.pc2_1);
+  KiiScanMessage (fd, "%d %d %s", &data[0].flipeast, &data[0].flipnorth, data[0].coords.ctype);
+  KiiScanMessage (fd, "%lf %lf %f %f %f %f", &data[0].coords.crval1, &data[0].coords.crval2, &data[0].coords.crpix1, &data[0].coords.crpix2, &data[0].coords.cdelt1, &data[0].coords.cdelt2);
+LOAD : (eac write follewed by 'DONE')
+  KiiSendMessage (fd, "%d %d %d %d", overnum, Noverlay, Ntext, Ntextdata);
+  write (fd, buffer, Noverlay*sizeof(KiiOverlayBase)); 
+  write (fd, textdata, Ntextdata);
+LSEC : 
+  KiiSendMessage (fd, "%s", name);
+MOVE : 
+  KiiSendMessage (fd, "%d %d", x, y); 
+MSEC : 
+  KiiSendMessage (fd, "%s %s", name, direction);
+READ : 
+  KiiScanMessage (fd, "%d", &Ncolors);
+  KiiSendMessage (fd, "%8d %8d", image[0].Nx, image[0].Ny);
+  KiiSendMessage (fd, "%f %f %s %s", data[0].zero, data[0].range, data[0].name, data[0].file);
+  KiiSendMessage (fd, "%f %f %d ", min, max, size);
+  KiiSendMessage (fd, "%f %f %g %g %g ", coords[0].crval1, coords[0].crpix1, coords[0].cdelt1, coords[0].pc1_1, coords[0].pc1_2);
+  KiiSendMessage (fd, "%f %f %g %g %g ", coords[0].crval2, coords[0].crpix2, coords[0].cdelt2, coords[0].pc2_1, coords[0].pc2_2);
+  KiiSendMessage (fd, "%s", coords[0].ctype);
+  write (fd, image[0].data1d, size);
+  (note that 1D, 2D, and 1D_8bit have the same messaging)
+SAVE : 
+  KiiSendMessage (fd, "FILE: %d %s", n, file);
+SIMC : 
+  KiiSendMessage (fd, "%g %g %g %g", coords[0].pc1_1, coords[0].pc2_2, coords[0].pc1_2, coords[0].pc2_1);
+  KiiSendMessage (fd, "%s", coords[0].ctype);
+  KiiSendMessage (fd, "%g %g %g %g %g %g", coords[0].crval1, coords[0].crval2, coords[0].crpix1, coords[0].crpix2, coords[0].cdelt1, coords[0].cdelt2);
+SIMD : 
+  KiiSendMessage (fd, "%g %g %s %s", data[0].zero, data[0].range, data[0].name, data[0].file);
+SLIM : 
+  KiiSendMessage (fd, "%g %g %g %g ", data[0].xmin, data[0].xmax, data[0].ymin, data[0].ymax);
+SSEC : 
+  KiiSendMessage (fd, "%s", name);
+SSTY : 
+  KiiSendMessage (fd, "%8d %d %d %d %d %d %f %f", data[0].style, data[0].ptype, data[0].ltype, data[0].etype, data[0].ebar, data[0].color, data[0].lweight, data[0].size);
+  KiiSendMessage (fd, "%g %g %g %g", data[0].xmin, data[0].xmax, data[0].ymin, data[0].ymax);
+  KiiSendMessage (fd, "%g %g %g %g", data[0].coords.pc1_1, data[0].coords.pc2_2, data[0].coords.pc1_2, data[0].coords.pc2_1);
+  KiiSendMessage (fd, "%d %d %s", data[0].flipeast, data[0].flipnorth, data[0].coords.ctype);
+  KiiSendMessage (fd, "%g %g %g %g %g %g", data[0].coords.crval1, data[0].coords.crval2, data[0].coords.crpix1, data[0].coords.crpix2, data[0].coords.cdelt1, data[0].coords.cdelt2);
+TOOL : 
+  KiiSendMessage (fd, "%d", location); 
+JPEG : create JPEG file
+  KiiSendMessage (fd, "%s", filename);
+CENT : 
+  KiiSendMessage (fd, "%8.3f %8.3f %8d ", x, y, zoom);
+PARI : 
+  KiiSendMessage (fd, "%2d %2d ", xflip, yflip);
+PLOB :
+  KiiSendMessage (fd, "%s %d %d %d", type, Npts, Nbytes, swap); 
+  write (fd, values, Nbytes);
+
+NPIX : ?? deprecated?
Index: trunk/Ohana/src/kapa2/include/constants.h
===================================================================
--- trunk/Ohana/src/kapa2/include/constants.h	(revision 25978)
+++ trunk/Ohana/src/kapa2/include/constants.h	(revision 26891)
@@ -11,8 +11,8 @@
 
 # define NCHANNELS 3
-# define NPIXELS_DYNAMIC 4600
+# define NPIXELS_DYNAMIC 128
 
 // XXX for the moment, this is set to match the values in SetColorScale3D_CC
-# define NPIXELS_STATIC 4600
+# define NPIXELS_STATIC 128
 
 # define PAD1  3
Index: trunk/Ohana/src/kapa2/src/ColorHistogram.c
===================================================================
--- trunk/Ohana/src/kapa2/src/ColorHistogram.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/ColorHistogram.c	(revision 26891)
@@ -174,5 +174,5 @@
     node->pixel = current[0];
     current[0] ++;
-    assert (current[0] <= Npixels);
+    assert (current[0] < Npixels);
     return TRUE;
   }
Index: trunk/Ohana/src/kapa2/src/EraseOverlay.c
===================================================================
--- trunk/Ohana/src/kapa2/src/EraseOverlay.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/EraseOverlay.c	(revision 26891)
@@ -8,10 +8,11 @@
   KapaImageWidget *image;
 
+  // We have to accept the incoming message even if we cannot perform the action
+  KiiScanCommand (sock, 16, "%*s %d", &N);
+
   graphic = GetGraphic();
   section = GetActiveSection();
   image = section->image;
   if (image == NULL) return (TRUE);
-
-  KiiScanCommand (sock, 16, "%*s %d", &N);
 
   if (N > NOVERLAYS) {
Index: trunk/Ohana/src/kapa2/src/LoadPicture.c
===================================================================
--- trunk/Ohana/src/kapa2/src/LoadPicture.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/LoadPicture.c	(revision 26891)
@@ -73,4 +73,5 @@
     if (status == 0) {  /* No more pipe */
       fprintf (stderr, "error: pipe closed\n");
+      fcntl (sock, F_SETFL, !O_NONBLOCK);  
       return (FALSE);
     }
@@ -92,6 +93,4 @@
   SetColorScale (graphic, image);
 
-  SetColorScale (graphic, image);
-
   if (!USE_XWINDOW) return (TRUE);
 
Index: trunk/Ohana/src/kapa2/src/PNGit.c
===================================================================
--- trunk/Ohana/src/kapa2/src/PNGit.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/PNGit.c	(revision 26891)
@@ -16,9 +16,5 @@
 
   /* expect a line telling the number of bytes and a filename */
-  status = read (sock, filename, 16);
-  filename[16] = 0;
-  sscanf (filename, "%*s %d", &Nbytes);
-  status = read (sock, filename, Nbytes);
-  filename[status] = 0; /* make the string easy to parse */
+  KiiScanMessage (sock, "%s", filename);
 
   f = fopen (filename, "w");
Index: trunk/Ohana/src/kapa2/src/PPMit.c
===================================================================
--- trunk/Ohana/src/kapa2/src/PPMit.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/PPMit.c	(revision 26891)
@@ -13,9 +13,5 @@
 
   /* expect a line telling the number of bytes and a filename */
-  status = read (sock, filename, 16);
-  filename[16] = 0;
-  sscanf (filename, "%*s %d", &Nbytes);
-  status = read (sock, filename, Nbytes);
-  filename[status] = 0; /* make the string easy to parse */
+  KiiScanMessage (sock, "%s", filename);
 
   f = fopen (filename, "w");
Index: trunk/Ohana/src/kapa2/src/Resize.c
===================================================================
--- trunk/Ohana/src/kapa2/src/Resize.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/Resize.c	(revision 26891)
@@ -11,4 +11,5 @@
   graphic = GetGraphic();
 
+  // must scan the message before possible return
   KiiScanMessage (sock, "%d %d", &NX, &NY);
 
Index: trunk/Ohana/src/kapa2/src/SaveOverlay.c
===================================================================
--- trunk/Ohana/src/kapa2/src/SaveOverlay.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/SaveOverlay.c	(revision 26891)
@@ -9,10 +9,10 @@
   KapaImageWidget *image;
 
+  KiiScanMessage (sock, "%*s %d %s", &N, filename);
+  
   section = GetActiveSection();
   image   = section->image;
   if (image == NULL) return (TRUE);
 
-  KiiScanMessage (sock, "%*s %d %s", &N, filename);
-  
   f = fopen (filename, "w");
   if (f == NULL) {
Index: trunk/Ohana/src/kapa2/src/SetColorScale.c
===================================================================
--- trunk/Ohana/src/kapa2/src/SetColorScale.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/SetColorScale.c	(revision 26891)
@@ -34,12 +34,13 @@
   float slope;
   float start;
-  unsigned short MaxValue;
+  unsigned short MaxValue, NANValue;
   Matrix *matrix;
 
   // define the color transform parameters
-  MaxValue = graphic[0].Npixels - 1;
+  NANValue = graphic[0].Npixels - 1;
+  MaxValue = graphic[0].Npixels - 2;
   if (image[0].image[0].range != 0.0) {
-    slope = graphic[0].Npixels / image[0].image[0].range;
-    start = graphic[0].Npixels * image[0].image[0].zero / image[0].image[0].range;
+    slope = (graphic[0].Npixels - 1) / image[0].image[0].range;
+    start = slope * image[0].image[0].zero;
   } else {
     slope = 1.0;
@@ -63,7 +64,17 @@
   // convert pixel data values to pixel index values (0 - Npixel)
   for (i = 0; i < nPixels; i++, iData++, oData++) {
+    if (isnan(*iData) || isinf(*iData)) {
+      *oData = NANValue;
+      continue;
+    }
     value = *iData * slope - start;
-    if (value < 0) value = 0;
-    if (value > MaxValue) value = MaxValue;
+    if (value < 0) {
+      *oData = 0;
+      continue;
+    }
+    if (value > MaxValue) {
+      *oData = MaxValue;
+      continue;
+    }
     *oData = value;
   }
@@ -169,4 +180,13 @@
   if (DX != image[0].channel[KAPA_CHANNEL_BLUE].matrix.Naxis[0]) return FALSE;
   if (DY != image[0].channel[KAPA_CHANNEL_BLUE].matrix.Naxis[1]) return FALSE;
+
+  // XXX a bit bogus: we are going to store a special color at Npixels-1 for 
+  // marking the NAN pixels.  
+  { 
+      // XXX set pure green for now
+      graphic[0].cmap[graphic[0].Npixels-1].red = 0;
+      graphic[0].cmap[graphic[0].Npixels-1].green = 0xffff;
+      graphic[0].cmap[graphic[0].Npixels-1].blue = 0;
+  }  
 
   // create the top-level cube
@@ -214,5 +234,5 @@
   // convert histogram 3D values to cmap colors
   Npixels = 0;
-  CCNodeSetColorMap (cube, graphic[0].cmap, graphic[0].Npixels, &Npixels);
+  CCNodeSetColorMap (cube, graphic[0].cmap, graphic[0].Npixels - 1, &Npixels);
 
   // store the colors
Index: trunk/Ohana/src/kapa2/src/SetColormap.c
===================================================================
--- trunk/Ohana/src/kapa2/src/SetColormap.c	(revision 25978)
+++ trunk/Ohana/src/kapa2/src/SetColormap.c	(revision 26891)
@@ -10,4 +10,9 @@
     VAR = tmp; \
   } }   
+
+// the image arrives from the client program as an array of floats, stored in image->matrix.
+// whenever we load a new image or change tv channels, we need to map the currently active
+// image from float to pixel index (image->pixmap).  When we actually display (or change the
+// display of) an image, we simply remap the lit pixels (in Remap32.c, etc).
 
 int SetColormap (char *name) {
@@ -26,9 +31,18 @@
   }
 
+  // XXX a bit bogus: we are going to store a special color at Npixels-1 for 
+  // marking the NAN pixels.  
+  { 
+      // XXX set pure green for now
+      graphic[0].cmap[graphic[0].Npixels-1].red = 0;
+      graphic[0].cmap[graphic[0].Npixels-1].green = 0xffff;
+      graphic[0].cmap[graphic[0].Npixels-1].blue = 0;
+  }  
+
   // very simple color model: evenly spaced cube 
   if (!strcasecmp (name, "ruffcolor")) {
       graphic[0].nRed  = pow (graphic[0].Npixels, 0.333);
       graphic[0].nBlue = pow (graphic[0].Npixels, 0.333);
-      graphic[0].nGreen = graphic[0].Npixels / (graphic[0].nRed * graphic[0].nBlue);
+      graphic[0].nGreen = (graphic[0].Npixels - 1) / (graphic[0].nRed * graphic[0].nBlue);
 
       // red,green,blue are values in range 0x0000 to 0xffff
@@ -48,4 +62,5 @@
 	  }
       }
+      fprintf (stderr, "ruff Npix: %d vs %d\n", i, graphic[0].Npixels);
 
       // all other modes are 1D: set the flag:
@@ -58,9 +73,9 @@
 
   // red,green,blue are values in range 0x0000 to 0xffff
-  scale = 0xffff / (graphic[0].Npixels - 1);
+  scale = 0xffff / (graphic[0].Npixels - 2);
 
   /* greyscale */
   if ((!strcasecmp (name, "grayscale")) || (!strcasecmp (name, "greyscale"))) {
-    for (i = 0; i < graphic[0].Npixels; i++) {  
+    for (i = 0; i < graphic[0].Npixels - 1; i++) {  
       SETVALUE (graphic[0].cmap[i].red,   0xffff - i*scale, 0, 0xffff);
       SETVALUE (graphic[0].cmap[i].green, 0xffff - i*scale, 0, 0xffff);
@@ -72,5 +87,5 @@
   /* -grayscale */
   if ((!strcasecmp (name, "-grayscale")) || (!strcasecmp (name, "-greyscale"))) {
-    for (i = 0; i < graphic[0].Npixels; i++) {  
+    for (i = 0; i < graphic[0].Npixels - 1; i++) {  
       SETVALUE (graphic[0].cmap[i].red,   i*scale, 0, 0xffff);
       SETVALUE (graphic[0].cmap[i].green, i*scale, 0, 0xffff);
@@ -102,5 +117,5 @@
       graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
     }
-    for (i = (int)(0.75*graphic[0].Npixels); i < graphic[0].Npixels; i++) {  
+    for (i = (int)(0.75*graphic[0].Npixels); i < graphic[0].Npixels - 1; i++) {  
       graphic[0].cmap[i].red   = 0xffff;
       graphic[0].cmap[i].green = 0xffff;
@@ -134,5 +149,5 @@
     }
     blueRef  = 0.75*graphic[0].Npixels*scale*4.0;
-    for (i = (int)(0.75*graphic[0].Npixels); i < graphic[0].Npixels; i++) {  
+    for (i = (int)(0.75*graphic[0].Npixels); i < graphic[0].Npixels - 1; i++) {  
       graphic[0].cmap[i].red   = 0xffff;
       graphic[0].cmap[i].green = 0xffff;
