Index: /trunk/Ohana/src/kapa2/Makefile
===================================================================
--- /trunk/Ohana/src/kapa2/Makefile	(revision 16269)
+++ /trunk/Ohana/src/kapa2/Makefile	(revision 16270)
@@ -77,5 +77,5 @@
 $(SRC)/PSOverlay.$(ARCH).o                $(SRC)/SetChannel.$(ARCH).o         \
 $(SRC)/SetColorScale.$(ARCH).o            $(SRC)/ColorCube.$(ARCH).o          \
-$(SRC)/ColorHistogram.$(ARCH).o           
+$(SRC)/ColorHistogram.$(ARCH).o           $(SRC)/CreateWide.$(ARCH).o
 
 #$(SRC)/CreateZoom8.$(ARCH).o              $(SRC)/CreateZoom16.$(ARCH).o       \
Index: /trunk/Ohana/src/kapa2/include/prototypes.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/prototypes.h	(revision 16269)
+++ /trunk/Ohana/src/kapa2/include/prototypes.h	(revision 16270)
@@ -219,4 +219,5 @@
 void 	      CreateColorbar (KapaImageWidget *image, Graphic *graphic);
 void 	      CreateZoom (Graphic *graphic, KapaImageWidget *image);
+void 	      CreateWide (Graphic *graphic, KapaImageWidget *image);
 void 	      UpdateStatusBox (Graphic *graphic, KapaImageWidget *image, double x, double y, double z, int mode);
 
Index: /trunk/Ohana/src/kapa2/include/structures.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/structures.h	(revision 16269)
+++ /trunk/Ohana/src/kapa2/include/structures.h	(revision 16270)
@@ -95,4 +95,5 @@
   int      expand;	      // zoomscale
   double   X,  Y;	      // center of image in picture
+  char     flipx, flipy;      // parity (0 = +; 1 = -)
   XImage  *pix;
   char    *data;
Index: /trunk/Ohana/src/kapa2/src/ButtonFunctions.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/ButtonFunctions.c	(revision 16269)
+++ /trunk/Ohana/src/kapa2/src/ButtonFunctions.c	(revision 16270)
@@ -15,4 +15,5 @@
   Remap (graphic, image);
   CreateZoom (graphic, image); 
+  CreateWide (graphic, image); 
   Refresh ();
   XFlush (graphic[0].display);
@@ -26,4 +27,5 @@
   Remap (graphic, image);
   CreateZoom (graphic, image); 
+  CreateWide (graphic, image); 
   Refresh ();
   XFlush (graphic[0].display);
@@ -37,4 +39,5 @@
   Remap (graphic, image);
   CreateZoom (graphic, image); 
+  CreateWide (graphic, image); 
   Refresh ();
   XFlush (graphic[0].display);
@@ -79,4 +82,7 @@
 int ToggleDEG (Graphic *graphic, KapaImageWidget *image) {
 
+  image[0].picture.flipy = !image[0].picture.flipy;
+  image[0].zoom.flipy = !image[0].zoom.flipy;
+  image[0].wide.flipy = !image[0].wide.flipy;
   image[0].DecimalDegrees = image[0].DecimalDegrees ^ TRUE;
   StatusBox (graphic, image);
Index: /trunk/Ohana/src/kapa2/src/CreatePicture.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CreatePicture.c	(revision 16269)
+++ /trunk/Ohana/src/kapa2/src/CreatePicture.c	(revision 16270)
@@ -12,4 +12,6 @@
   switch (graphic[0].Nbits) {
   case 8:
+    REALLOCATE (image[0].wide.data,    char, image[0].wide.dx*image[0].wide.dy);
+    REALLOCATE (image[0].zoom.data,    char, image[0].zoom.dx*image[0].zoom.dy);
     REALLOCATE (image[0].picture.data, char, image[0].picture.dx*image[0].picture.dy);
     c = (unsigned char *) image[0].picture.data;
@@ -21,4 +23,6 @@
 
   case 16:
+    REALLOCATE (image[0].wide.data,    char, 2*image[0].wide.dx*image[0].wide.dy);
+    REALLOCATE (image[0].zoom.data,    char, 2*image[0].zoom.dx*image[0].zoom.dy);
     REALLOCATE (image[0].picture.data, char, 2*image[0].picture.dy*image[0].picture.dx);
     c = (unsigned char *) image[0].picture.data;
@@ -37,4 +41,6 @@
   case 24:
     extra = 4 - (image[0].picture.dx * 3) % 4;
+    REALLOCATE (image[0].wide.data, char, image[0].wide.dy*(3*image[0].wide.dx+extra));
+    REALLOCATE (image[0].zoom.data, char, image[0].zoom.dy*(3*image[0].zoom.dx+extra));
     REALLOCATE (image[0].picture.data, char, image[0].picture.dy*(3*image[0].picture.dx+extra));
     c = (unsigned char *) image[0].picture.data;
@@ -55,4 +61,5 @@
 
   case 32:
+    REALLOCATE (image[0].wide.data,    char, 4*image[0].wide.dx*image[0].wide.dy);
     REALLOCATE (image[0].zoom.data,    char, 4*image[0].zoom.dx*image[0].zoom.dy);
     REALLOCATE (image[0].picture.data, char, 4*image[0].picture.dx*image[0].picture.dy);
Index: /trunk/Ohana/src/kapa2/src/CreateWide.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CreateWide.c	(revision 16270)
+++ /trunk/Ohana/src/kapa2/src/CreateWide.c	(revision 16270)
@@ -0,0 +1,19 @@
+# include "Ximage.h"
+
+void CreateWide (Graphic *graphic, KapaImageWidget *image) {
+
+  switch (graphic[0].Nbits) {
+  case 8:
+    Remap8  (graphic, image, &image->wide, &image->image->matrix);
+    break;
+  case 16:
+    Remap16 (graphic, image, &image->wide, &image->image->matrix);
+    break;
+  case 24:
+    Remap24 (graphic, image, &image->wide, &image->image->matrix);
+    break;
+  case 32:
+    Remap32 (graphic, image, &image->wide, &image->image->matrix);
+    break;
+  }    
+}
Index: /trunk/Ohana/src/kapa2/src/CursorOps.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CursorOps.c	(revision 16269)
+++ /trunk/Ohana/src/kapa2/src/CursorOps.c	(revision 16270)
@@ -4,5 +4,5 @@
 void Picture_to_Image (double *x1, double *y1, double x2, double y2, Picture *picture) {
 
-  double expand;
+  double expand, dx, dy;
 
   expand = 1.0;
@@ -13,7 +13,11 @@
   }
   
+  // pixel coordinates in picture frame
+  dx = expand*(x2 - 0.5*picture[0].dx);
+  dy = expand*(y2 - 0.5*picture[0].dy);
+
   // picture[0].X,Y is the image coordinate in the center of the picture
-  *x1 = expand*(x2 - 0.5*picture[0].dx) + picture[0].X;
-  *y1 = expand*(y2 - 0.5*picture[0].dy) + picture[0].Y;
+  *x1 = picture[0].flipx ? picture[0].X - dx : picture[0].X + dx;
+  *y1 = picture[0].flipy ? picture[0].Y - dy : picture[0].Y + dy;
 }
 
@@ -32,5 +36,5 @@
 void Image_to_Picture (double *x1, double *y1, double x2, double y2, Picture *picture) {
 
-  double expand;
+  double expand, dx, dy;
 
   /* notice that here, expand is the reciprocal of the expand above */
@@ -43,6 +47,9 @@
   
   // pixel coordinates in picture frame
-  *x1 = expand*(x2 - picture[0].X) + 0.5*picture[0].dx;
-  *y1 = expand*(y2 - picture[0].Y) + 0.5*picture[0].dy;
+  dx = picture[0].flipx ? picture[0].X - x2 : x2 - picture[0].X;
+  dy = picture[0].flipy ? picture[0].Y - y2 : y2 - picture[0].Y;
+    
+  *x1 = expand*dx + 0.5*picture[0].dx;
+  *y1 = expand*dy + 0.5*picture[0].dy;
 }
 
@@ -70,7 +77,11 @@
   Iy = MIN (MAX (Iy, 0), matrix[0].Naxis[1]);
 
-  // round up to nearest pixel boundary
-  if (Ix > (int)(Ix)) Ix = (int)(Ix) + 1;
-  if (Iy > (int)(Iy)) Iy = (int)(Iy) + 1;
+  // round up (down) to nearest pixel boundary
+  if (Ix > (int)(Ix)) {
+    Ix = picture[0].flipx ? (int)(Ix) : (int)(Ix) + 1;
+  }
+  if (Iy > (int)(Iy)) {
+    Iy = picture[0].flipy ? (int)(Iy) : (int)(Iy) + 1;
+  }
 
   // Sx, Sy are the screen coordinates of the Ix,Iy pixel
@@ -94,7 +105,11 @@
   Iy = MIN (MAX (Iy, 0), matrix[0].Naxis[1]);
 
-  // round down to nearest pixel boundary
-  if (Ix > (int)(Ix)) Ix = (int)(Ix);
-  if (Iy > (int)(Iy)) Iy = (int)(Iy);
+  // round down (up) to nearest pixel boundary
+  if (Ix > (int)(Ix)) {
+    Ix = picture[0].flipx ? (int)(Ix) + 1 : (int)(Ix);
+  }
+  if (Iy > (int)(Iy)) {
+    Iy = picture[0].flipy ? (int)(Iy) + 1: (int)(Iy);
+  }
 
   // Sx, Sy are the screen coordinates of the Ix,Iy pixel
Index: /trunk/Ohana/src/kapa2/src/Image.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Image.c	(revision 16269)
+++ /trunk/Ohana/src/kapa2/src/Image.c	(revision 16270)
@@ -51,12 +51,18 @@
   image[0].picture.Y      = 0.0;
   image[0].picture.expand = 1;
+  image[0].picture.flipx  = FALSE;
+  image[0].picture.flipy  = FALSE;
 
   image[0].zoom.X      	  = 0.0;
   image[0].zoom.Y      	  = 0.0;
   image[0].zoom.expand 	  = +5;
+  image[0].zoom.flipx  	  = FALSE;
+  image[0].zoom.flipy  	  = FALSE;
 
   image[0].wide.X      	  = 0.0;
   image[0].wide.Y      	  = 0.0;
   image[0].wide.expand 	  = -5;
+  image[0].wide.flipx  	  = FALSE;
+  image[0].wide.flipy  	  = FALSE;
 
   image[0].location = 4;
@@ -67,4 +73,5 @@
   ALLOCATE (image[0].cmapbar.data, char, 1);   /* allocate so later free will not crash! */
   ALLOCATE (image[0].zoom.data, char, 1);      /* allocate so later free will not crash! */
+  ALLOCATE (image[0].wide.data, char, 1);      /* allocate so later free will not crash! */
 
   InitButtonSize (&image[0].PS_button, PS_width, PS_height, PS_bits);
@@ -147,4 +154,9 @@
 	       image[0].cmapbar.x, image[0].cmapbar.y, 
 	       image[0].cmapbar.dx, image[0].cmapbar.dy);
+
+    XPutImage (graphic[0].display, graphic[0].window, graphic[0].gc,
+	       image[0].wide.pix, 0, 0, 
+	       image[0].wide.x, image[0].wide.y, 
+	       image[0].wide.dx, image[0].wide.dy);
 
     CrossHairs (graphic, &image[0].zoom);
@@ -188,4 +200,5 @@
   free (image[0].cmapbar.data);
   free (image[0].zoom.data);
+  free (image[0].wide.data);
 
   free (image);
Index: /trunk/Ohana/src/kapa2/src/LoadPicture.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadPicture.c	(revision 16269)
+++ /trunk/Ohana/src/kapa2/src/LoadPicture.c	(revision 16270)
@@ -9,5 +9,5 @@
   KapaImageWidget *image;
   Graphic *graphic;
-  double Xoffset, Yoffset;
+  double Xoffset, Yoffset, wx;
 
   graphic = GetGraphic ();
@@ -46,4 +46,14 @@
   image[0].picture.Y = 0.5*header.Naxis[1] + Yoffset;
 
+  // choose expand for wide to guarantee we fit:
+  wx = MAX ((header.Naxis[0] / (float) image[0].wide.dx), (header.Naxis[1] / (float) image[0].wide.dy));
+  if (wx > 1.0) {
+    image[0].wide.expand = -wx;
+  } else {
+    image[0].wide.expand = 1.0 / wx;
+  }    
+  image[0].wide.X = 0.5*header.Naxis[0];
+  image[0].wide.Y = 0.5*header.Naxis[1];
+
   fcntl (sock, F_SETFL, O_NONBLOCK);  
 
@@ -78,4 +88,5 @@
   SetColorScale (graphic, image);
   Remap (graphic, image);
+  CreateWide (graphic, image);
   if (DEBUG) fprintf (stderr, "remapped image\n");
   Refresh ();
Index: /trunk/Ohana/src/kapa2/src/Remap32.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Remap32.c	(revision 16269)
+++ /trunk/Ohana/src/kapa2/src/Remap32.c	(revision 16270)
@@ -1,3 +1,7 @@
 # include "Ximage.h"
+
+# ifndef ISWAP
+# define ISWAP(X,Y) {int tmp=(X); (X) = (Y); (Y) = tmp;}
+# endif
 
 void Remap32 (Graphic *graphic, KapaImageWidget *image, Picture *picture, Matrix *matrix) {
@@ -5,5 +9,5 @@
   int i, j, ii, jj;
   int i_start, i_end, j_start, j_end;
-  int dropback;
+  int dropback, inDX, inDY;
   int dx, dy, DX, DY;
   double expand, Ix, Iy;
@@ -48,6 +52,19 @@
   Picture_Upper (&i_end, &j_end, matrix, picture);
 
+  if (i_end < i_start) ISWAP (i_start, i_end);
+  if (j_end < j_start) ISWAP (j_start, j_end);
+
   // Ix,Iy are the first displayed image pixel
   Picture_to_Image (&Ix, &Iy, i_start, j_start, picture);
+  Ix = MIN (MAX (0, Ix), DX - 1);
+  Iy = MIN (MAX (0, Iy), DY - 1);
+  // XXX not completely consistent with the i_start, i_end range...
+
+  // we need to offset because i_start points to the bottom edge of Ix
+  // if (picture[0].flipx) Ix -= 1.0;
+  // if (picture[0].flipy) Iy -= 1.0;
+
+  inDX = picture[0].flipx ? -1 : +1;
+  inDY = picture[0].flipy ? -1 : +1;
 
   dropback = expand_out - (i_end - i_start) % expand_out;
@@ -64,5 +81,5 @@
   }
   
-  for (j = j_start; j < j_end; j+= expand_out, out_pix+=(expand_out-1)*dx, in_pix += expand_in*DX) {
+  for (j = j_start; j < j_end; j+= expand_out, out_pix+=(expand_out-1)*dx, in_pix += inDY*expand_in*DX) {
 
     /**** fill in area to the left of the picture ****/
@@ -78,9 +95,9 @@
     in_pix2 = in_pix;
     if (expand_out == 1) {
-      for (i = i_start; i < i_end; i++, in_pix2+= expand_in, out_pix++) {
+      for (i = i_start; i < i_end; i++, in_pix2 += inDX*expand_in, out_pix++) {
 	*out_pix = pixel[*in_pix2];
       }
     } else {
-      for (i = i_start; i < i_end; i+= expand_out, in_pix2++, out_pix+= expand_out) { 
+      for (i = i_start; i < i_end; i+= expand_out, in_pix2 += inDX, out_pix+= expand_out) { 
 	pixvalue = pixel[*in_pix2];
 	out_pix2 = out_pix;
@@ -94,4 +111,9 @@
     out_pix -= dropback;
     
+    // assert (in_pix2 - image[0].pixmap <= DX*DY);
+    // assert (in_pix2 - image[0].pixmap >= 0);
+    // assert (in_pix - image[0].pixmap <= DX*DY);
+    // assert (in_pix - image[0].pixmap >= 0);
+
     /**** fill in area to the right of the picture ****/
     for (jj = 0; jj < expand_out; jj++) {
@@ -102,4 +124,6 @@
     }
     out_pix += (dx - i_end);
+    // assert (out_pix - (unsigned int *)picture[0].data <= dx*dy);
+    // assert (out_pix - (unsigned int *)picture[0].data >= 0);
   } 
   
@@ -107,4 +131,7 @@
     out_pix -= expand_out - (j_end - j_start) % expand_out;
   
+  // assert (out_pix - (unsigned int *)picture[0].data <= dx*dy);
+  // assert (out_pix - (unsigned int *)picture[0].data >= 0);
+
   /**** fill in top area ****/
   for (j = 0; (j < dx*(dy - j_end)) && (out_pix - (unsigned int *)picture[0].data < dx*dy); j++, out_pix++) { 
Index: /trunk/Ohana/src/kapa2/src/SetImageSize.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetImageSize.c	(revision 16269)
+++ /trunk/Ohana/src/kapa2/src/SetImageSize.c	(revision 16270)
@@ -109,4 +109,11 @@
       image[0].recenter_button.x = image[0].heat_button.x + image[0].heat_button.dx + PAD1;
       image[0].recenter_button.y = image[0].PS_button.y;
+
+      // XXX zoom should scale somewhat with the image? (with a min and a max)
+      // XXX actually, it is limited by the buttons and status region
+      image[0].wide.dx = ZOOM_X; 
+      image[0].wide.dy = ZOOM_Y;
+      image[0].wide.x = image[0].recenter_button.x + image[0].recenter_button.dx + PAD1;
+      image[0].wide.y = image[0].PS_button.y;
       break;
 
@@ -177,4 +184,11 @@
       image[0].recenter_button.x = image[0].heat_button.x + image[0].heat_button.dx + PAD1;
       image[0].recenter_button.y = image[0].PS_button.y;
+
+      // XXX zoom should scale somewhat with the image? (with a min and a max)
+      // XXX actually, it is limited by the buttons and status region
+      image[0].wide.dx = ZOOM_X; 
+      image[0].wide.dy = ZOOM_Y;
+      image[0].wide.x = image[0].PS_button.x;
+      image[0].wide.y = image[0].PS_button.y + BUTTON_HEIGHT + PAD1;
       break;
 
@@ -243,4 +257,11 @@
       image[0].recenter_button.x = image[0].heat_button.x + image[0].heat_button.dx + PAD1;
       image[0].recenter_button.y = image[0].PS_button.y;
+
+      // XXX zoom should scale somewhat with the image? (with a min and a max)
+      // XXX actually, it is limited by the buttons and status region
+      image[0].wide.dx = ZOOM_X; 
+      image[0].wide.dy = ZOOM_Y;
+      image[0].wide.x = image[0].recenter_button.x + image[0].recenter_button.dx + PAD1;
+      image[0].wide.y = image[0].PS_button.y;
       break;
 
@@ -309,4 +330,11 @@
       image[0].recenter_button.x = image[0].heat_button.x + image[0].heat_button.dx + PAD1;
       image[0].recenter_button.y = image[0].PS_button.y;
+
+      // XXX zoom should scale somewhat with the image? (with a min and a max)
+      // XXX actually, it is limited by the buttons and status region
+      image[0].wide.dx = ZOOM_X; 
+      image[0].wide.dy = ZOOM_Y;
+      image[0].wide.x = image[0].PS_button.x;
+      image[0].wide.y = image[0].PS_button.y + BUTTON_HEIGHT + PAD1;
       break;
 
@@ -320,4 +348,5 @@
     CreateColorbar (image, graphic);
     CreateZoom (graphic, image); 
+    CreateWide (graphic, image); 
   }
   Remap (graphic, image);
