Index: /branches/eam_branches/ipp-20130306/Ohana/src/addstar/src/ExternImageIDs.c
===================================================================
--- /branches/eam_branches/ipp-20130306/Ohana/src/addstar/src/ExternImageIDs.c	(revision 35253)
+++ /branches/eam_branches/ipp-20130306/Ohana/src/addstar/src/ExternImageIDs.c	(revision 35254)
@@ -1,3 +1,88 @@
 # include "addstar.h"
+
+typedef struct {
+  off_t Nimage;
+  off_t minID;
+  off_t maxID;
+  off_t range;
+  off_t *value;
+  char *found;
+} ExtID_Index;
+
+ExtID_Index *ExtID_Load (char *filename) {
+
+  int i, Ncol;
+  off_t Nrow;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  ExtID_Index *extID = NULL;
+  ALLOCATE (extID, ExtID_Index, 1);
+
+  FILE *f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file %s\n", filename);
+    return NULL;
+  }
+
+  /* load in PHU segment (ignore) */
+  if (!gfits_fread_header (f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset header\n");
+    fclose (f);
+    return NULL;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset matrix\n");
+    gfits_free_header (&header);
+    fclose (f);
+    return NULL;
+  }
+
+  ftable.header = &theader;
+
+  // load data for this header 
+  if (!gfits_load_header (f, &theader)) {
+    fclose (f);
+    return NULL;
+  }
+
+  // read the fits table bytes
+  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) {
+    fclose (f);
+    return (NULL);
+  }
+  fclose (f);
+
+  // a bit annoying : we read the entire block of data, then extract the columns, then set the image structure values.
+  // this means I need 3 copies in memory at some point.  ugh.
+
+  char type[16];
+
+  extID->value = gfits_get_bintable_column_data (&theader, &ftable, "EXTERN_ID", type, &Nrow, &Ncol);
+  myAssert (!strcmp(type, "int"), "wrong column type");
+
+  extID->Nimage = Nrow;
+
+  extID->minID = -1;
+  extID->maxID = -1;
+  for (i = 0; i < extID->Nimage; i++) {
+    if (extID->minID == -1) extID->minID = extID->value[i];
+    extID->minID = MIN(extID->minID, extID->value[i]);
+    extID->maxID = MAX(extID->maxID, extID->value[i]);
+  }
+  extID->range = extID->maxID- extID->minID + 1;
+  
+  ALLOCATE (extID->found, char, extID->range);
+  for (i = 0; i < extID->range; i++) extID->found[i] = FALSE;
+
+  for (i = 0; i < extID->Nimage; i++) {
+    off_t N = extID->value[i] - extID->minID;
+    extID->found[N] = TRUE
+  }
+
+  return extID;
+}
 
 int CheckDuplicateImageIDs (Image *images, off_t Nimages) {
@@ -6,15 +91,19 @@
   char filename[DVO_MAX_PATH];
   snprintf (filename, DVO_MAX_PATH, "%s/ExternImageIDs.fits", CATDIR);
-  ExternImageIDs *imageIDs = ExternImageIDsLoad (filename);
+
+  ExtID_Index *extID = ExtID_Load (filename);
 
   for (i = 0; i < Nimages; i++) {
-    off_t extID = images[i].externID;
-    if (extID == 0) continue;
+    off_t ID = images[i].externID;
+    if (ID == 0) continue;
 
-    if (extID < imageIDs.minID) continue;
-    if (extID > imageIDs.maxID) continue;
+    if (ID < extID->minID) continue;
+    if (ID > extID->maxID) continue;
 
-    extIDoff = extID - imageIDs.min;
-    if (imageIDs.value[extIDoff] == -1) continue;
+    offset = ID - extID->minID;
+    myAssert (offset >= 0, "offset out of range?");
+    myAssert (offset <= extID->range, "offset out of range?");
+
+    if (!extID->found[offset]) continue;
     fprintf (stderr, "duplicate external image ID "OFF_T_FMT" found, exiting\n", extID);
     exit (1);
@@ -27,5 +116,5 @@
 
   // do this as an 'extend' operation
-  ExternImageIDsSave (filename, imageIDs);
+  ExtID_Save (filename, extID);
   return TRUE;
 }
