Index: /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/Makefile
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/Makefile	(revision 42426)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/Makefile	(revision 42427)
@@ -11,4 +11,7 @@
 INC	=	$(HOME)/include
 include ../../Makefile.Common
+
+%.c : %.c.in
+	sed "s|@DATADIR@|$(DATA)|" $< > $@
 
 # programs may add their own internal requirements here
@@ -100,8 +103,8 @@
 $(SRC)/CheckButtons.$(ARCH).o             $(SRC)/InvertButton.$(ARCH).o       \
 $(SRC)/UpdatePointer.$(ARCH).o            $(SRC)/JPEGit24.$(ARCH).o           \
-$(SRC)/ButtonFunctions.$(ARCH).o    \
-$(SRC)/SetChannel.$(ARCH).o         \
+$(SRC)/ButtonFunctions.$(ARCH).o          $(SRC)/FindColormap.$(ARCH).o       \
 $(SRC)/SetColorScale.$(ARCH).o            $(SRC)/ColorCube.$(ARCH).o          \
-$(SRC)/ColorHistogram.$(ARCH).o           $(SRC)/CreateWide.$(ARCH).o
+$(SRC)/ColorHistogram.$(ARCH).o           $(SRC)/CreateWide.$(ARCH).o         \
+$(SRC)/SetChannel.$(ARCH).o
 
 OBJ  =  $(KAPA) $(PDF) $(BDRAW) $(PSFILES)
@@ -116,2 +119,4 @@
 
 $(BIN)/kapa.$(ARCH): $(OBJ)
+
+.PRECIOUS: $(SRC)/FindColormap.c
Index: /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/include/constants.h
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/include/constants.h	(revision 42426)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/include/constants.h	(revision 42427)
@@ -54,4 +54,13 @@
 } KapaChannels;
 
+typedef enum {
+  KAPA_CM_RAW,
+  KAPA_CM_CSV,
+  KAPA_CM_CET,
+  KAPA_CM_CET_REV,
+  KAPA_CM_LEGACY,
+  KAPA_CM_STATIC,
+} KapaColorMapMode;
+
 // use an enum to identify the 3 dimensions:
 typedef enum {
Index: /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/include/prototypes.h
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/include/prototypes.h	(revision 42426)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/include/prototypes.h	(revision 42427)
@@ -328,2 +328,7 @@
 int ResizeByImage (int sock);
 
+char *ParseColormapName (char *name, KapaColorMapMode *mode);
+int CheckFileAccess (char *name);
+char *FindColormap (char *name);
+
+
Index: /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/src/FindColormap.c.in
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/src/FindColormap.c.in	(revision 42427)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/src/FindColormap.c.in	(revision 42427)
@@ -0,0 +1,76 @@
+# include "Ximage.h"
+
+// look for the colormap files in the local directory first, then
+// in the directory given by @DATADIR@
+// XXX : probably need to check the input name length
+
+char *ParseColormapName (char *name, KapaColorMapMode *mode) {
+
+  *mode = KAPA_CM_STATIC;
+
+  if (!strncmp (name, "file:", 5)) *mode = KAPA_CM_RAW;
+  if (!strncmp (name, "lgcy:", 5)) *mode = KAPA_CM_LEGACY;
+  if (!strncmp (name, "cetf:", 5)) *mode = KAPA_CM_CET;
+  if (!strncmp (name, "cetr:", 5)) *mode = KAPA_CM_CET_REV;
+  if (!strncmp (name, "csvf:", 5)) *mode = KAPA_CM_CSV;
+  
+  // the output name needs to be allocated so it can be freed above
+  if (*mode == KAPA_CM_STATIC) return (strcreate (name));
+
+  return (strcreate (&name[5]));
+}
+
+int CheckFileAccess (char *name) {
+  
+  static int gotIDs = FALSE;
+  struct stat filestat;
+  static uid_t uid;
+  static gid_t gid;
+  int status;
+  
+  // only do this once, should not change while program is running
+  if (!gotIDs) {
+    uid = getuid();
+    gid = getgid();
+    gotIDs = TRUE;
+  }
+
+  /* check permission to exec file */
+  status = stat (name, &filestat);
+  if (status == 0) { /* file exists, are permissions OK? */
+    if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP)) || 
+	(                            (filestat.st_mode & S_IROTH))) {
+      return (TRUE);
+    } else {
+      return (FALSE);
+    }
+  }
+}
+
+// returns the name of an existing file
+char *FindColormap (char *name) {
+
+  static char *datadir = "@DATADIR@";
+
+  char *filename;
+  int Nbytes;
+
+  // make a copy of the file name if it is found locally
+  if (CheckFileAccess (name)) {
+    return (strcreate (name));
+  }
+
+  // name is like
+  Nbytes = strlen(datadir) + strlen(name) + 2;
+  ALLOCATE (filename, char, Nbytes);
+  snprintf (filename, Nbytes, "%s/%s", datadir, name);
+    
+  // make a copy of the file name if it is found locally
+  if (CheckFileAccess (filename)) {
+    return (strcreate (filename));
+  }
+
+  return NULL;
+}
+
Index: /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/src/SetColormap.c
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/src/SetColormap.c	(revision 42426)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/kapa2/src/SetColormap.c	(revision 42427)
@@ -214,107 +214,112 @@
 
   /* anuenue */
-  if (!strncmp (graphic->colormapName, "file:", 5) || 
-      !strncmp (graphic->colormapName, "lgcy:", 5) || 
-      !strncmp (graphic->colormapName, "cetf:", 5) || 
-      !strncmp (graphic->colormapName, "cetr:", 5) || 
-      !strncmp (graphic->colormapName, "csvf:", 5)) {
-
-    FILE *f = fopen (&graphic->colormapName[5], "r");
-    if (!f) {
-      fprintf (stderr, "failed to open colormap file %s\n", &graphic->colormapName[5]);
+  KapaColorMapMode mode = KAPA_CM_STATIC;
+
+  char *basename = ParseColormapName (graphic->colormapName, &mode);
+  if (mode == KAPA_CM_STATIC) {
+    fprintf (stderr, "unknown static colormap name %s\n", &graphic->colormapName);
+    free (basename);
+    return FALSE;
+  }    
+
+  // look in local directory and installation directory
+  char *truename = FindColormap (basename);
+  FREE (basename);
+
+  if (!truename) {
+      fprintf (stderr, "cannot find colormap file %s\n", &graphic->colormapName[5]);
       return FALSE;
-    }
-    char line[1024];
-
-    int lastIndex = 0;
-    float lastRed = 0.0;
-    float lastBlue = 0.0;
-    float lastGreen = 0.0;
-
-    int isCSV = !strncmp (graphic->colormapName, "csvf:", 5);
-    int isCET = !strncmp (graphic->colormapName, "cetf:", 5);
-    int isCETRev = !strncmp (graphic->colormapName, "cetr:", 5);
-    int isLegacy = !strncmp (graphic->colormapName, "lgcy:", 5);
-
-    float fracIndex, fracRed, fracBlue, fracGreen;
-
-    if (isCET || isCETRev) fracIndex = 0.0;
-
-    while (scan_line_maxlen (f, line, 1024) != EOF) {
-      // file contains f R G B : f = 0.0 - 1.0, R,G,B = 0.0 - 1.0
-
-      int Nscan;
-      if (isCSV) {
-	Nscan = sscanf (line, "%f,%f,%f,%f", &fracIndex, &fracRed, &fracGreen, &fracBlue);
-	if (Nscan != 4) continue;
-      }
-      if (isCET || isCETRev) {
-	Nscan = sscanf (line, "%f,%f,%f", &fracRed, &fracGreen, &fracBlue);
-	fracIndex += 1.0 / 256.0;
-	if (Nscan != 3) continue;
-      }
-      if (isLegacy) {
-	Nscan = sscanf (line, "%f %f %f %f", &fracIndex, &fracRed, &fracBlue, &fracGreen);
-	if (Nscan != 4) continue;
-      }
-      if (!isCSV && !isLegacy && !isCET && !isCETRev) {
-	Nscan = sscanf (line, "%f %f %f %f", &fracIndex, &fracRed, &fracGreen, &fracBlue);
-	if (Nscan != 4) continue;
-      }
-
-      int nextIndex = fracIndex * MaxValue;
-      if (nextIndex <= lastIndex) {
-	lastRed = fracRed;
-	lastBlue = fracBlue;
-	lastGreen = fracGreen;
-	continue;
-      }
-      float dRdI = (fracRed   - lastRed)   / (float) (nextIndex - lastIndex);
-      float dBdI = (fracBlue  - lastBlue)  / (float) (nextIndex - lastIndex);
-      float dGdI = (fracGreen - lastGreen) / (float) (nextIndex - lastIndex);
-      for (i = lastIndex; i < nextIndex; i++) {
-	float redValue   = 0xffff * (dRdI * (i - lastIndex) + lastRed);
-	float blueValue  = 0xffff * (dBdI * (i - lastIndex) + lastBlue);
-	float greenValue = 0xffff * (dGdI * (i - lastIndex) + lastGreen);
-	SETVALUE (graphic[0].cmap[i].red,   redValue,   0, 0xffff);
-	SETVALUE (graphic[0].cmap[i].blue,  blueValue,  0, 0xffff);
-	SETVALUE (graphic[0].cmap[i].green, greenValue, 0, 0xffff);
-      }
+  }
+
+  FILE *f = fopen (truename, "r");
+  if (!f) {
+    fprintf (stderr, "failed to open colormap file %s\n", truename);
+    FREE (truename);
+    return FALSE;
+  }
+  FREE (truename);
+
+  char line[1024];
+  
+  int lastIndex = 0;
+  float lastRed = 0.0;
+  float lastBlue = 0.0;
+  float lastGreen = 0.0;
+  
+  float fracIndex, fracRed, fracBlue, fracGreen;
+
+  if (mode == KAPA_CM_CET || mode == KAPA_CM_CET_REV) fracIndex = 0.0;
+
+  while (scan_line_maxlen (f, line, 1024) != EOF) {
+    // file contains f R G B : f = 0.0 - 1.0, R,G,B = 0.0 - 1.0
+
+    int Nscan;
+    if (mode == KAPA_CM_CSV) {
+      Nscan = sscanf (line, "%f,%f,%f,%f", &fracIndex, &fracRed, &fracGreen, &fracBlue);
+      if (Nscan != 4) continue;
+    }
+    if ((mode == KAPA_CM_CET || mode == KAPA_CM_CET_REV)) {
+      Nscan = sscanf (line, "%f,%f,%f", &fracRed, &fracGreen, &fracBlue);
+      fracIndex += 1.0 / 256.0;
+      if (Nscan != 3) continue;
+    }
+    if (mode == KAPA_CM_LEGACY) {
+      Nscan = sscanf (line, "%f %f %f %f", &fracIndex, &fracRed, &fracBlue, &fracGreen);
+      if (Nscan != 4) continue;
+    }
+    if (mode == KAPA_CM_RAW) {
+      Nscan = sscanf (line, "%f %f %f %f", &fracIndex, &fracRed, &fracGreen, &fracBlue);
+      if (Nscan != 4) continue;
+    }
+    
+    int nextIndex = fracIndex * MaxValue;
+    if (nextIndex <= lastIndex) {
       lastRed = fracRed;
       lastBlue = fracBlue;
       lastGreen = fracGreen;
-      lastIndex = nextIndex;
-    }
-    fclose (f);
-
-    if ((int) (MaxValue*fracIndex) < MaxValue) {
-      float dRdI = (1.0 - lastRed)   / (float) (MaxValue - lastIndex);
-      float dBdI = (1.0 - lastBlue)  / (float) (MaxValue - lastIndex);
-      float dGdI = (1.0 - lastGreen) / (float) (MaxValue - lastIndex);
-      for (i = lastIndex; i < MaxValue; i++) {
-	float redValue   = 0xffff * (dRdI * (i - lastIndex) + lastRed);
-	float blueValue  = 0xffff * (dBdI * (i - lastIndex) + lastBlue);
-	float greenValue = 0xffff * (dGdI * (i - lastIndex) + lastGreen);
-	SETVALUE (graphic[0].cmap[i].red,   redValue,   0, 0xffff);
-	SETVALUE (graphic[0].cmap[i].blue,  blueValue,  0, 0xffff);
-	SETVALUE (graphic[0].cmap[i].green, greenValue, 0, 0xffff);
-      }
-    }
-
-    // reverse the color sequence:
-    if (isCETRev) {
-      for (i = 0; i < MaxValue / 2; i++) {  
-	unsigned short tmp;
-	// fprintf (stderr, "swap: %d %d\n", graphic[0].cmap[i].red, graphic[0].cmap[MaxValue - 1 - i].red);
-	tmp = graphic[0].cmap[i].red;   graphic[0].cmap[i].red   = graphic[0].cmap[MaxValue - 1 - i].red;   graphic[0].cmap[MaxValue - 1 - i].red   = tmp;
-	tmp = graphic[0].cmap[i].blue;  graphic[0].cmap[i].blue  = graphic[0].cmap[MaxValue - 1 - i].blue;  graphic[0].cmap[MaxValue - 1 - i].blue  = tmp;
-	tmp = graphic[0].cmap[i].green; graphic[0].cmap[i].green = graphic[0].cmap[MaxValue - 1 - i].green; graphic[0].cmap[MaxValue - 1 - i].green = tmp;
-      }
-    }
-
-    goto store_colors;
-  }
-
-  return (FALSE);
+      continue;
+    }
+    float dRdI = (fracRed   - lastRed)   / (float) (nextIndex - lastIndex);
+    float dBdI = (fracBlue  - lastBlue)  / (float) (nextIndex - lastIndex);
+    float dGdI = (fracGreen - lastGreen) / (float) (nextIndex - lastIndex);
+    for (i = lastIndex; i < nextIndex; i++) {
+      float redValue   = 0xffff * (dRdI * (i - lastIndex) + lastRed);
+      float blueValue  = 0xffff * (dBdI * (i - lastIndex) + lastBlue);
+      float greenValue = 0xffff * (dGdI * (i - lastIndex) + lastGreen);
+      SETVALUE (graphic[0].cmap[i].red,   redValue,   0, 0xffff);
+      SETVALUE (graphic[0].cmap[i].blue,  blueValue,  0, 0xffff);
+      SETVALUE (graphic[0].cmap[i].green, greenValue, 0, 0xffff);
+    }
+    lastRed = fracRed;
+    lastBlue = fracBlue;
+    lastGreen = fracGreen;
+    lastIndex = nextIndex;
+  }
+  fclose (f);
+
+  if ((int) (MaxValue*fracIndex) < MaxValue) {
+    float dRdI = (1.0 - lastRed)   / (float) (MaxValue - lastIndex);
+    float dBdI = (1.0 - lastBlue)  / (float) (MaxValue - lastIndex);
+    float dGdI = (1.0 - lastGreen) / (float) (MaxValue - lastIndex);
+    for (i = lastIndex; i < MaxValue; i++) {
+      float redValue   = 0xffff * (dRdI * (i - lastIndex) + lastRed);
+      float blueValue  = 0xffff * (dBdI * (i - lastIndex) + lastBlue);
+      float greenValue = 0xffff * (dGdI * (i - lastIndex) + lastGreen);
+      SETVALUE (graphic[0].cmap[i].red,   redValue,   0, 0xffff);
+      SETVALUE (graphic[0].cmap[i].blue,  blueValue,  0, 0xffff);
+      SETVALUE (graphic[0].cmap[i].green, greenValue, 0, 0xffff);
+    }
+  }
+
+  // reverse the color sequence:
+  if (mode == KAPA_CM_CET_REV) {
+    for (i = 0; i < MaxValue / 2; i++) {  
+      unsigned short tmp;
+      // fprintf (stderr, "swap: %d %d\n", graphic[0].cmap[i].red, graphic[0].cmap[MaxValue - 1 - i].red);
+      tmp = graphic[0].cmap[i].red;   graphic[0].cmap[i].red   = graphic[0].cmap[MaxValue - 1 - i].red;   graphic[0].cmap[MaxValue - 1 - i].red   = tmp;
+      tmp = graphic[0].cmap[i].blue;  graphic[0].cmap[i].blue  = graphic[0].cmap[MaxValue - 1 - i].blue;  graphic[0].cmap[MaxValue - 1 - i].blue  = tmp;
+      tmp = graphic[0].cmap[i].green; graphic[0].cmap[i].green = graphic[0].cmap[MaxValue - 1 - i].green; graphic[0].cmap[MaxValue - 1 - i].green = tmp;
+    }
+  }
 
  store_colors:
