Index: trunk/Ohana/src/kapa2/src/PNGit.c
===================================================================
--- trunk/Ohana/src/kapa2/src/PNGit.c	(revision 27599)
+++ trunk/Ohana/src/kapa2/src/PNGit.c	(revision 27600)
@@ -1,3 +1,12 @@
 # include "Ximage.h"
+
+/* I almost have PNG images + plots working.  I need to do a few more things:
+   1) decide on the dimensions of the output image/plot file -- like the jpeg covering the pixels? adjust the box to include the full plot box?
+   2) update bDraw to either write palette values (as now) or RGB values into the buffer
+   3) decision on output based on the existence of images or not
+*/
+
+bDrawBuffer *bDrawBufferCreate8bitRGB (int Nx, int Ny);
+int bDrawImage (bDrawBuffer *buffer, Graphic *graphic);
 
 int PNGit (int sock) {
@@ -6,9 +15,9 @@
   png_structp png_ptr;
   png_infop info_ptr;
-  png_color *palette;
   int Npalette;
   char filename[1024];
-  bDrawBuffer *buffer;
-  Graphic *graphic;
+  bDrawBuffer *buffer = NULL;
+  Graphic *graphic = NULL;
+  png_color *palette = NULL;
 
   graphic = GetGraphic();
@@ -48,12 +57,14 @@
 
   /* see docs for write-row-callback to provide progress info */
-
-  png_set_IHDR (png_ptr, info_ptr, graphic->dx, graphic->dy, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 
-
-  /* png_set_IHDR (png_ptr, info_ptr, graphic->dx, graphic->dy, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); */
-  /* png_set_IHDR (png_ptr, info_ptr, graphic->dx, graphic->dy, 16, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); */
-
-  /* For color images, I need to define the relationship between the drawing colors and the RGB values? */
-  /* instead of calling png_set_PLTE, call png_set_sRGB (png_ptr, info_ptr, PNG_sRGB_INTENT_ABSOLUTE); */
+# define PALETTE 1
+  if (PALETTE) {
+    png_set_IHDR (png_ptr, info_ptr, graphic->dx, graphic->dy, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 
+    palette = KapaPNGPalette (&Npalette);
+    png_set_PLTE (png_ptr, info_ptr, palette, Npalette); 
+  } else {
+    // png_set_IHDR (png_ptr, info_ptr, graphic->dx, graphic->dy, 16, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+    png_set_IHDR (png_ptr, info_ptr, graphic->dx, graphic->dy, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+    png_set_sRGB (png_ptr, info_ptr, PNG_sRGB_INTENT_ABSOLUTE);
+  }
 
   /* other useful calls here:
@@ -61,11 +72,13 @@
      png_set_text(png_ptr, info_ptr, text_ptr, num_text);
   */
-
-  palette = KapaPNGPalette (&Npalette);
-  png_set_PLTE (png_ptr, info_ptr, palette, Npalette); 
  
   png_write_info (png_ptr, info_ptr);
 
-  buffer = bDrawIt ();
+  if (PALETTE) {
+    buffer = bDrawIt ();
+  } else {
+    buffer = bDrawBufferCreate8bitRGB(graphic->dx, graphic->dy);
+    bDrawImage (buffer, graphic);
+  }
 
   png_write_image (png_ptr, buffer[0].pixels);
@@ -79,2 +92,210 @@
 
 }
+
+/* For color images, I need to define the relationship between the drawing colors and the RGB values? */
+
+
+bDrawBuffer *bDrawBufferCreate8bitRGB (int Nx, int Ny) {
+
+  int i, j;
+  bDrawBuffer *buffer;
+
+  ALLOCATE (buffer, bDrawBuffer, 1);
+  buffer[0].Nx = Nx;
+  buffer[0].Ny = Ny;
+
+  ALLOCATE (buffer[0].pixels, bDrawColor *, Ny);
+  for (i = 0; i < Ny; i++) {
+    ALLOCATE (buffer[0].pixels[i], bDrawColor, 3*Nx);
+    for (j = 0; j < 3*Nx; j+=3) {
+      buffer[0].pixels[i][j+0] = 0xff;
+      buffer[0].pixels[i][j+1] = 0xff;
+      buffer[0].pixels[i][j+2] = 0xff;
+    }
+  }
+  return (buffer);
+}
+
+# define WHITE_R 255
+# define WHITE_G 255
+# define WHITE_B 255
+# define MY_SWAP_INT(A,B) { int tmp; tmp = A; A = B; B = tmp; }
+
+int bDrawImage (bDrawBuffer *buffer, Graphic *graphic) {
+  
+  Section *section;
+  KapaImageWidget *image;
+
+  int ii, i, j;
+  int i_start, i_end, j_start, j_end;
+  int I_start, J_start;
+  int dropback;  /* this is a bit of a kludge... */
+  int dx, dy, DX, DY, inDX, inDY;
+  int expand_in, expand_out;
+  double expand, Ix, Iy;
+  unsigned char *out_pix;
+  unsigned short *in_pix, *in_pix_ref;
+  unsigned char *pixel1, *pixel2, *pixel3;
+
+  bDrawColor *line_buffer;
+
+  section = GetActiveSection();
+  image   = section->image;
+  if (image == NULL) return (TRUE);
+
+  ALLOCATE (pixel1, unsigned char, graphic[0].Npixels);
+  ALLOCATE (pixel2, unsigned char, graphic[0].Npixels);
+  ALLOCATE (pixel3, unsigned char, graphic[0].Npixels);
+
+  /** cmap[i].pixel must be defined even if X is not used **/
+  for (i = 0; i < graphic[0].Npixels; i++) { /* set up pixel array */
+    pixel1[i] = graphic[0].cmap[i].red >> 8;
+    pixel2[i] = graphic[0].cmap[i].green >> 8;
+    pixel3[i] = graphic[0].cmap[i].blue >> 8;
+  }
+
+  assert ((image[0].picture.expand >= 1) || (image[0].picture.expand <= -2));
+  expand = expand_in = expand_out = 1.0;
+  if (image[0].picture.expand > 0) {
+    expand = 1 / (1.0*image[0].picture.expand);
+    expand_out = image[0].picture.expand;
+    expand_in  = 1;
+  }
+  if (image[0].picture.expand < 0) {
+    expand = fabs((double)image[0].picture.expand);
+    expand_out = 1;
+    expand_in  = -image[0].picture.expand;
+  }
+
+  dx = image[0].picture.dx;
+  dy = image[0].picture.dy;
+  DX = image[0].image[0].matrix.Naxis[0];
+  DY = image[0].image[0].matrix.Naxis[1];
+
+  // i_start, j_start are the closest lit screen pixel to 0,0
+  // I_start, J_start are the image pixel corresponding to i_start, j_start
+  Picture_Lower (&i_start, &j_start, &I_start, &J_start, &image[0].image[0].matrix, &image[0].picture);
+
+  // i_end, j_end are the closest lit screen pixel to dx, dy
+  // I_end, J_end are the image pixel corresponding to i_end, j_end
+  Picture_Upper (&i_end, &j_end, i_start, j_start, &image[0].image[0].matrix, &image[0].picture);
+
+  assert (i_start <= i_end);
+  assert (j_start <= j_end);
+
+  Ix = image[0].picture.flipx ? I_start - 1 : I_start;
+  Iy = image[0].picture.flipy ? J_start - 1 : J_start;
+
+  inDX = image[0].picture.flipx ? -1 : +1;
+  inDY = image[0].picture.flipy ? -1 : +1;
+
+  dropback = expand_out - (i_end - i_start) % expand_out;
+  if ((i_end - i_start) % expand_out == 0) dropback = 0;
+
+  ALLOCATE (line_buffer, bDrawColor, 3*dx);
+
+  in_pix_ref  = &image[0].pixmap[DX*(int)MAX(Iy,0) + (int)MAX(Ix,0)];
+
+  /********** below we do the mapping from buffer pixels (in) to picture pixels (out) **********/
+
+  /**** fill in bottom area ****/
+  out_pix = line_buffer;
+  for (i = 0; i < dx; i++, out_pix+=3) {
+    out_pix[0] = WHITE_R;
+    out_pix[1] = WHITE_G;
+    out_pix[2] = WHITE_B;
+  }
+  for (j = 0; j < j_start; j++) {
+    memcpy (buffer[0].pixels[j], line_buffer, 3*dx);
+  }
+  
+  /*** fill in the image data region ***/
+  for (j = j_start; j < j_end; j+= expand_out, in_pix_ref += inDY*expand_in*DX) {
+    
+    /* create one output image line */
+    in_pix = in_pix_ref;
+    out_pix = line_buffer;
+
+    /**** fill in area to the left of the picture ****/
+    for (i = 0; i < i_start; i++, out_pix+=3) {
+      out_pix[0] = WHITE_R;
+      out_pix[1] = WHITE_G;
+      out_pix[2] = WHITE_B;
+    }
+    
+    /*** fill in the picture region ***/
+    for (i = i_start; i < i_end; i+=expand_out, in_pix += inDX*expand_in) {
+      for (ii = 0; ii < expand_out; ii++, out_pix+=3) {
+	out_pix[0] = pixel1[*in_pix];
+	out_pix[1] = pixel2[*in_pix];
+	out_pix[2] = pixel3[*in_pix];
+      }
+    }
+    
+    /**** fill in area to the right of the picture ****/
+    for (i = i_end; i < dx; i++, out_pix+=3) {
+      out_pix[0] = WHITE_R;
+      out_pix[1] = WHITE_G;
+      out_pix[2] = WHITE_B;
+    }
+
+    /* write out the image line expand_out times */
+    for (i = 0; i < expand_out; i++) {
+      memcpy (buffer[0].pixels[j + i], line_buffer, 3*dx);
+    }
+  }
+
+  /**** fill in top area ****/
+  out_pix = line_buffer;
+  for (i = 0; i < dx; i++, out_pix+=3) { 
+    out_pix[0] = WHITE_R;
+    out_pix[1] = WHITE_G;
+    out_pix[2] = WHITE_B;
+  }
+  for (j = j_end; j < dy; j++) {
+    memcpy (buffer[0].pixels[j], line_buffer, 3*dx);
+  }
+
+  free (pixel1);
+  free (pixel2);
+  free (pixel3);
+  free (line_buffer);
+
+  return (TRUE);
+}
+
+# if (0)
+
+  /* I need to write the overlay objects on the jpeg image.
+     if i can write / overwrite data in jpeg buffer, then do it here,
+     otherwise i need to create a temporary image buffer, then write the 
+     scanlines to that buffer */
+
+  {
+    int Npalette;
+    png_color *palette;
+    bDrawColor white, color;
+    bDrawBuffer *buffer;
+
+    palette = KapaPNGPalette (&Npalette);
+
+    buffer = bDrawBufferCreate (dx, dy);
+    bDrawSetBuffer (buffer);
+    for (i = 0; i < NOVERLAYS; i++) {
+      if (image[i].overlay[i].active) bDrawOverlay (image, i);
+    }
+
+    white = KapaColorByName ("white");
+    for (j = 0; j < dy; j++) {
+      for (i = 0; i < dx; i++) {
+	color = buffer[0].pixels[j][i];
+	if (color == white) continue;
+	image_buffer[j*3*dx + 3*i + 0] = palette[color].red;
+	image_buffer[j*3*dx + 3*i + 1] = palette[color].green;
+	image_buffer[j*3*dx + 3*i + 2] = palette[color].blue;
+      }
+    }
+    bDrawBufferFree (buffer);
+  }
+
+# endif
