Index: trunk/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 40522)
+++ trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 40545)
@@ -113,4 +113,5 @@
 $(SRC)/ps.$(ARCH).o		\
 $(SRC)/print_vectors.$(ARCH).o 	\
+$(SRC)/mprint.$(ARCH).o 	\
 $(SRC)/queuedelete.$(ARCH).o	\
 $(SRC)/queuedrop.$(ARCH).o	\
Index: trunk/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/init.c	(revision 40522)
+++ trunk/Ohana/src/opihi/cmd.data/init.c	(revision 40545)
@@ -89,4 +89,5 @@
 int medimage_command PROTO((int, char **));
 int mset             PROTO((int, char **));
+int mprint           PROTO((int, char **));
 int needles          PROTO((int, char **));
 int nnet_command     PROTO((int, char **));
@@ -99,5 +100,5 @@
 int point            PROTO((int, char **));
 int ps               PROTO((int, char **));
-int print_vectors    PROTO((int, char **));
+int vprint           PROTO((int, char **));
 int queuelist        PROTO((int, char **));
 int queueload        PROTO((int, char **));
@@ -274,4 +275,5 @@
   {1, "mset",         mset,             "insert a vector in an image"},
   {1, "imset",        mset,             "insert a vector in an image"},
+  {1, "mprint",       mprint,           "print a region of an image"},
   {1, "needles",      needles,          "plot vectors needles"},
   {1, "nnet",         nnet_command,     "Neural Network commands"},
@@ -285,5 +287,6 @@
   {1, "ppm",          jpeg,             "convert display graphic to PPM"},
   {1, "ps",           ps,               "convert display to PostScript"},
-  {1, "print_vectors", print_vectors,   "print a set of vectors"},
+  {1, "print_vectors", vprint,          "print a set of vectors"},
+  {1, "vprint",       vprint,           "print a set of vectors"},
   {1, "queuedelete",  queuedelete,      "delete a queue"},
   {1, "queuedrop",    queuedrop,        "drop values from queue matching a key"},
Index: trunk/Ohana/src/opihi/cmd.data/mprint.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/mprint.c	(revision 40545)
+++ trunk/Ohana/src/opihi/cmd.data/mprint.c	(revision 40545)
@@ -0,0 +1,128 @@
+# include "data.h"
+
+enum {OUTPUT_TEXT, OUTPUT_HTML, OUTPUT_LATEX};
+
+int mprint (int argc, char **argv) {
+
+  Buffer *buf;
+  int N;
+
+  int OUTPUT_FMT = OUTPUT_TEXT;
+  if ((N = get_argument (argc, argv, "-html"))) {
+    remove_argument (N, &argc, argv);
+    OUTPUT_FMT = OUTPUT_HTML;
+  }
+  if ((N = get_argument (argc, argv, "-latex"))) {
+    if (OUTPUT_FMT == OUTPUT_HTML) {
+      gprint (GP_ERR, "ERROR: only one of -html and -latex may be used for mprint\n");
+      return (FALSE);
+    }
+    remove_argument (N, &argc, argv);
+    OUTPUT_FMT = OUTPUT_LATEX;
+  }
+
+  char *format = NULL;
+  if ((N = get_argument (argc, argv, "-fmt"))) {
+    remove_argument (N, &argc, argv);
+    format = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if (!format) format = strcreate ("%f");
+
+  if (argc < 6) {
+    gprint (GP_ERR, "USAGE: mprint [-html | -latex] (buffer) [Xs] [Ys] [Nx] [Ny]\n");
+    return (FALSE);
+  }
+
+  if ((buf = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) return (FALSE);
+
+  int Xs = atoi(argv[2]);
+  int Ys = atoi(argv[3]);
+  int Nx = atoi(argv[4]);
+  int Ny = atoi(argv[5]);
+
+  // (silently?) truncate to valid region on the image
+  Xs = MIN (MAX (0, Xs), buf->matrix.Naxis[0]); // Xs : 0 to Nx-1
+  Ys = MIN (MAX (0, Ys), buf->matrix.Naxis[1]);
+
+  // if: Naxis[0] = 100, Xs = 50, Nx = 50, Nx -> 50
+  // if: Naxis[0] = 100, Xs = 100, Nx = 1, Nx -> 0
+  Nx = MIN (buf->matrix.Naxis[0] - Xs, MAX (0, Nx));
+  Ny = MIN (buf->matrix.Naxis[1] - Ys, MAX (0, Ny));
+
+  int NX = buf->matrix.Naxis[0];
+
+  float *bufValue = (float *) buf->matrix.buffer;
+
+  if (OUTPUT_FMT == OUTPUT_HTML) {
+    gprint (GP_LOG, " <table>\n");
+  }
+  if (OUTPUT_FMT == OUTPUT_LATEX) {
+    char tablespec[512];
+    strcpy (tablespec, "{ | l || ");
+    for (int ix = 0; ix < Nx; ix++) {
+      strcat (tablespec, "r | ");
+    }
+    strcat (tablespec, "}");
+    gprint (GP_LOG, "\\begin{tabular}%s\n", tablespec);
+    gprint (GP_LOG, "\\hline\n");
+  }
+
+  // top row (column labels)
+  if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, "<tr>");
+  if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, " <th> ");
+  gprint (GP_LOG, "%s", "Y X ");
+  if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, " </th> ");
+  if (OUTPUT_FMT == OUTPUT_LATEX) gprint (GP_LOG, " & ");
+
+  for (int ix = Xs; ix < Xs + Nx; ix++) {
+    if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, " <th> ");
+    gprint (GP_LOG, format, (float) ix);
+    if (OUTPUT_FMT == OUTPUT_TEXT) gprint (GP_LOG, " ");
+    if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, " </th> ");
+    if (OUTPUT_FMT == OUTPUT_LATEX) {
+      if (ix == Xs + Nx - 1) gprint (GP_LOG, " \\\\ ");
+      else gprint (GP_LOG, " & ");
+    }
+  }
+  if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, "</tr>");
+  gprint (GP_LOG, "\n");
+  if (OUTPUT_FMT == OUTPUT_LATEX) gprint (GP_LOG, "\\hline \\hline\n");
+
+  for (int iy = Ys; iy < Ys + Ny; iy++) {
+    if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, "<tr>");
+
+    // add row label 
+    if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, " <td> ");
+    gprint (GP_LOG, format, (float) iy);
+    if (OUTPUT_FMT == OUTPUT_LATEX) gprint (GP_LOG, " & ");
+    if (OUTPUT_FMT == OUTPUT_TEXT) gprint (GP_LOG, " ");
+    if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, " </td> ");
+    
+    for (int ix = Xs; ix < Xs + Nx; ix++) {
+      if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, " <td> ");
+      gprint (GP_LOG, format, bufValue[ix + iy*NX]);
+      if (OUTPUT_FMT == OUTPUT_TEXT) gprint (GP_LOG, " ");
+      if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, " </td> ");
+      if (OUTPUT_FMT == OUTPUT_LATEX) {
+	if (ix == Xs + Nx - 1) gprint (GP_LOG, " \\\\ ");
+	else gprint (GP_LOG, " & ");
+      }
+    }
+    if (OUTPUT_FMT == OUTPUT_HTML) gprint (GP_LOG, "</tr>");
+    gprint (GP_LOG, "\n");
+    if (OUTPUT_FMT == OUTPUT_LATEX) gprint (GP_LOG, "\\hline\n");
+  }
+
+  if (OUTPUT_FMT == OUTPUT_LATEX) {
+    gprint (GP_LOG, "\\end{tabular}\n");
+  }
+
+  if (OUTPUT_FMT == OUTPUT_HTML) {
+    gprint (GP_LOG, " </table>\n");
+  }
+
+  gprint (GP_LOG, "\n");
+
+  return (TRUE);
+}
Index: trunk/Ohana/src/opihi/cmd.data/print_vectors.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/print_vectors.c	(revision 40522)
+++ trunk/Ohana/src/opihi/cmd.data/print_vectors.c	(revision 40545)
@@ -1,5 +1,5 @@
 # include "data.h"
 
-int print_vectors (int argc, char **argv) {
+int vprint (int argc, char **argv) {
 
   Vector **vec;
@@ -21,5 +21,5 @@
 
   if (argc < 2) {
-    gprint (GP_ERR, "USAGE: print_vectors (vector)[,vector,...]\n");
+    gprint (GP_ERR, "USAGE: vprint (vector)[,vector,...] [-s start] [-e end]\n");
     return (FALSE);
   }
