Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/ImageSelection.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/ImageSelection.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/ImageSelection.c	(revision 28989)
@@ -38,5 +38,5 @@
 /* free loaded images */
 void FreeImageSelection () {
-  if (image != NULL) free (image);
+  if (image != NULL) FreeImages(image);
   if (subset != NULL) free (subset);
   image = NULL;
@@ -45,9 +45,13 @@
 }
 
-Image *MatchImage (unsigned int time, short int source) { 
+Image *MatchImage (unsigned int time, short int source, unsigned int imageID) { 
 
   int m;
 
-  m = match_image_subset (image, subset, Nsubset, time, source);
+  if ((imageID != 0) && (imageID < Nimage)) {
+    m = (int) imageID - 1;
+  } else {
+    m = match_image_subset (image, subset, Nsubset, time, source);
+  }
   if (m == -1) return (NULL);
   if (!FindMosaicForImage (image, Nimage, m)) return (NULL);
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/LoadImages.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/LoadImages.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/LoadImages.c	(revision 28989)
@@ -1,3 +1,13 @@
 # include "dvoshell.h"
+
+// XXX: Maybe make this a command line option
+int dvoUseImageCache = 1;
+
+static char *lastFilename = NULL;
+static time_t lastModified = 0;
+static Image *imageCache = NULL;
+static off_t cacheNimage = 0;
+
+static time_t getLastModified(char *filename);
 
 Image *LoadImages (off_t *Nimage) {
@@ -12,4 +22,21 @@
   catdir = GetCATDIR ();
   sprintf (filename, "%s/Images.dat", catdir);
+
+  if (lastFilename) {
+    if (dvoUseImageCache && !strcmp(lastFilename, filename)) {
+      // Make sure the file hasn't changed since we loaded it
+      if (getLastModified(filename) == lastModified) {
+        *Nimage = cacheNimage;
+        return  imageCache;
+      }
+    }
+    free(lastFilename);
+    lastFilename = NULL;
+    free(imageCache);
+    imageCache = NULL;
+    cacheNimage = 0;
+    lastModified = 0;
+  }
+
 
   gfits_db_init (&db);
@@ -40,6 +67,30 @@
   if (!image) {
     fprintf (stderr, "ERROR: failed to read images\n");
-    exit (2);
+    return (NULL);
+  }
+  if (dvoUseImageCache && image) {
+    cacheNimage = *Nimage;
+    imageCache = image;
+    lastFilename = strdup(filename);
+    lastModified = getLastModified(filename);
   }
   return (image);
 }
+
+static time_t getLastModified(char *filename) {
+  struct stat statbuf;
+  if (!stat(filename, &statbuf)) {
+    return statbuf.st_mtime;
+  } else {
+    return 0;
+  }
+}
+
+void FreeImages(Image *images) {
+  if (!dvoUseImageCache && (images != NULL)) {
+    free(images);
+  } else {
+    // defer free until next LoadImages with a different or modified Images.dat
+  }
+}
+
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/dbExtractMeasures.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/dbExtractMeasures.c	(revision 28989)
@@ -358,5 +358,5 @@
 	ra  = average[0].R - measure[0].dR / 3600.0;
 	dec = average[0].D - measure[0].dD / 3600.0;
-	image = MatchImage (measure[0].t, measure[0].photcode);
+	image = MatchImage (measure[0].t, measure[0].photcode, measure[0].imageID);
 	if (image == NULL) break;
 	RD_to_XY (&x, &y, ra, dec, &image[0].coords);
@@ -374,5 +374,5 @@
 	ra  = average[0].R - measure[0].dR / 3600.0;
 	dec = average[0].D - measure[0].dD / 3600.0;
-	image = MatchImage (measure[0].t, measure[0].photcode);
+	image = MatchImage (measure[0].t, measure[0].photcode, measure[0].imageID);
 	if (image == NULL) break;
 	RD_to_XY (&x, &y, ra, dec, &image[0].coords);
@@ -440,4 +440,12 @@
       value.Flt = measure[0].extNsigma;
       break;
+    case MEAS_EXTERN_ID: /* OK */
+      {
+	Image *image;
+	image = MatchImage (measure[0].t, measure[0].photcode, measure[0].imageID);
+	if (image == NULL) break;
+	value.Int = image->externID;
+      }
+      break;
 
       // add the star/galaxy sep -- 
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/dbFields.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/dbFields.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/dbFields.c	(revision 28989)
@@ -212,4 +212,5 @@
   if (!strcasecmp (fieldName, "SKY"))        	 ESCAPE (MEAS_SKY,            MAG_NONE, OPIHI_FLT);
   if (!strcasecmp (fieldName, "SKY_ERR"))    	 ESCAPE (MEAS_dSKY,           MAG_NONE, OPIHI_FLT);
+  if (!strcasecmp (fieldName, "externID"))    	 ESCAPE (MEAS_EXTERN_ID,      MAG_NONE, OPIHI_INT);
 
   // for words that don't parse, try a photcode
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/gimages.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/gimages.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/gimages.c	(revision 28989)
@@ -235,4 +235,6 @@
     sprintf (name, "IMAGEname:%d", Nfound);
     set_str_variable (name, image[i].name);
+    sprintf (name, "IMAGEphotcode:%d", Nfound);
+    set_int_variable (name, image[i].photcode);
     Nfound ++;
     free (date);
@@ -243,6 +245,7 @@
   set_int_variable ("IMAGEccd:n", Nfound);
   set_int_variable ("IMAGEname:n", Nfound);
-
-  free (image);
+  set_int_variable ("IMAGEphotcode:n", Nfound);
+
+  FreeImages (image);
   free (subset);
 
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/images.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/images.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/images.c	(revision 28989)
@@ -319,5 +319,5 @@
   free (Xvec.elements.Flt);
   free (Yvec.elements.Flt);
-  free (image);
+  FreeImages (image);
   return (TRUE);
 
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/imdense.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/imdense.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/imdense.c	(revision 28989)
@@ -70,5 +70,5 @@
   free (Xvec.elements.Flt);
   free (Yvec.elements.Flt);
-  free (image);
+  FreeImages (image);
   return (TRUE);
 
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/imextract.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/imextract.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/imextract.c	(revision 28989)
@@ -137,5 +137,5 @@
 
   // free (subset);
-  free (image);
+  FreeImages (image);
 
   if (vec) free (vec);
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/mextract.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/mextract.c	(revision 28989)
@@ -88,8 +88,9 @@
   mosaicMode = FALSE;
   for (i = 0; !loadImages && (i < Nfields); i++) {
-    if (fields[i].ID == MEAS_XCCD) loadImages = TRUE;
-    if (fields[i].ID == MEAS_YCCD) loadImages = TRUE;
+    if (fields[i].ID == MEAS_XCCD) loadImages = TRUE;   // Are these still needed? Xccd and Yccd are in measurement
+    if (fields[i].ID == MEAS_YCCD) loadImages = TRUE;   // and dbExtractMeasures doesn't look at the image for these
     if (fields[i].ID == MEAS_XMOSAIC) loadImages = mosaicMode = TRUE;
     if (fields[i].ID == MEAS_YMOSAIC) loadImages = mosaicMode = TRUE;
+    if (fields[i].ID == MEAS_EXTERN_ID) loadImages = mosaicMode = TRUE;
   }
   if (loadImages && !SetImageSelection (mosaicMode, selection)) goto escape;
@@ -305,4 +306,5 @@
     gprint (GP_ERR, "  catID : catalog ID (32 bit)\n");
     gprint (GP_ERR, "  imageID : ID of source image (32 bit)\n");
+    gprint (GP_ERR, "  externID : externID of source image (32 bit)\n");
     return (FALSE);
   }
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/photometry.c
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/photometry.c	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/dvo/photometry.c	(revision 28989)
@@ -1178,5 +1178,5 @@
       ra  = average[0].R - measure[0].dR / 3600.0;
       dec = average[0].D - measure[0].dD / 3600.0;
-      image = MatchImage (measure[0].t, measure[0].photcode);
+      image = MatchImage (measure[0].t, measure[0].photcode, measure[0].imageID);
       if (image == NULL) break;
       RD_to_XY (&x, &y, ra, dec, &image[0].coords);
@@ -1191,5 +1191,5 @@
       ra  = average[0].R - measure[0].dR / 3600.0;
       dec = average[0].D - measure[0].dD / 3600.0;
-      image = MatchImage (measure[0].t, measure[0].photcode);
+      image = MatchImage (measure[0].t, measure[0].photcode, measure[0].imageID);
       if (image == NULL) break;
       RD_to_XY (&x, &y, ra, dec, &image[0].coords);
Index: branches/eam_branches/ipp-20100621/Ohana/src/opihi/include/dvoshell.h
===================================================================
--- branches/eam_branches/ipp-20100621/Ohana/src/opihi/include/dvoshell.h	(revision 28988)
+++ branches/eam_branches/ipp-20100621/Ohana/src/opihi/include/dvoshell.h	(revision 28989)
@@ -121,4 +121,5 @@
       MEAS_CR_NSIGMA, 
       MEAS_EXT_NSIGMA, 
+      MEAS_EXTERN_ID,
 };
 
@@ -301,5 +302,6 @@
 int           InitPhotcodes         PROTO((void));
 Image        *LoadImages            PROTO((off_t *Nimage));
-Image        *MatchImage            PROTO((unsigned int time, short int source));
+void          FreeImages            PROTO((Image *images));
+Image        *MatchImage            PROTO((unsigned int time, short int source, unsigned int imageID));
 Coords       *MatchMosaic           PROTO((unsigned int time, short int source));
 int           Quality               PROTO((Measure *measure, int IsDophot));
