[argyllcms] Re: Calibration of my colormunki

  • From: Graeme Gill <graeme@xxxxxxxxxxxxx>
  • To: argyllcms@xxxxxxxxxxxxx
  • Date: Thu, 29 Apr 2010 16:54:53 +1000

Richard Hughes wrote:
Legend, thanks. Any chance of a Argyll_dev_src.zip code drop at some
point please? Thanks.

Hi, attached is a patch for V1.1.1

        Graeme Gill.

--- i1pro_imp.old.c     2010-04-29 16:42:19.000000000 +1000
+++ i1pro_imp.c 2010-04-29 16:50:49.000000000 +1000
@@ -42,6 +42,8 @@
        See the Munki implementation for an approach to fix this ??
 */
 
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -108,6 +110,8 @@
 #define HIGHRES_LONG  750
 #define HIGHRES_WIDTH  (10.0/3.0) /* (The 3.3333 spacing and lanczos2 seems a 
good combination) */
 
+#define CALIBRATION_DIR "argyll"     /* Directory the instrument calibration 
files get stored */
+
 #include "i1pro.h"
 #include "i1pro_imp.h"
 
@@ -2237,14 +2241,118 @@
 }
 
 
+/* NOTE!! these two routines should be consolidates with the */
+/* very similar ones in munki_imp.c !! */
+
+/* Return the path to the calibration save/restore file. */
+/* Return NULL on error. */
+/* Free after used */
+static char *i1pro_cal_name(i1pro *p) {
+       i1proimp *m = (i1proimp *)p->m;
+       char *cal_dir3 = NULL;          /* Directory */
+       char *cal_dir2 = NULL;          /* Directory */
+       char *cal_dir1 = NULL;          /* Directory */
+       char cal_name[20+1];            /* Name */
+       char *cal_path = NULL;          /* Allocated overal path */
+       int cpl = 0;                    /* cal path length */
+
+       /* Create the file name */
+       sprintf(cal_name, ".i1p_%d.cal", m->serno);
+
+       if ((cal_dir3 = getenv("XDG_CACHE_HOME")) != NULL && cal_dir3[0] != 
'\000') {
+               cal_dir1 = CALIBRATION_DIR;
+       } else {
+               if ((cal_dir3 = getenv("HOME")) != NULL && cal_dir3[0] != 
'\000') {
+                       cal_dir2 = ".cache";
+                       cal_dir1 = CALIBRATION_DIR;
+               } else {
+                       cal_dir3 = NULL;
+               }
+       }
+       cpl += (cal_dir3 != NULL) ? strlen(cal_dir3) + 1 : 0;
+       cpl += (cal_dir2 != NULL) ? strlen(cal_dir2) + 1 : 0;
+       cpl += (cal_dir1 != NULL) ? strlen(cal_dir1) + 1 : 0;
+       cpl += strlen(cal_name) + 1;
+
+       if ((cal_path = malloc(cpl)) == NULL)
+               return NULL;
+
+       cal_path[0] = '\000';
+       if (cal_dir3 != NULL)
+               strcat(cal_path, cal_dir3);
+       if (cal_dir2 != NULL) {
+               if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/')
+                       strcat(cal_path, "/");
+               strcat(cal_path, cal_dir2);
+       }
+       if (cal_dir1 != NULL) {
+               if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/')
+                       strcat(cal_path, "/");
+               strcat(cal_path, cal_dir1);
+       }
+       if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/')
+               strcat(cal_path, "/");
+       strcat(cal_path, cal_name);
+
+       return cal_path;
+}
+
+/* Given the path to a file, ensure that all the parent directories */
+/* are created. return nz on error */
+static int i1pro_mkpdirs(char *path) {
+       char *pp = path;
+#if defined (UNIX)
+       struct stat sbuf;
+       mode_t mode = 0700;             /* Default directory mode */
+#else
+       struct _stat sbuf;
+#endif
+
+#if !defined (UNIX)
+       if (*pp != '\000'               /* Skip drive number */
+               && ((*pp >= 'a' && *pp <= 'z') || (*pp >= 'A' && *pp <= 'Z'))
+           && pp[1] == ':')
+               pp += 2;
+#endif
+       if (*pp == '/')
+               pp++;                   /* Skip root directory */
+       for (;pp != NULL && *pp != '\000';) {
+               if ((pp = strchr(pp, '/')) != NULL) {
+                       *pp = '\000';
+#if defined (UNIX)
+                       if (stat(path,&sbuf) != 0)
+#else
+                       if (_stat(path,&sbuf) != 0)
+#endif
+                       {
+#if defined (UNIX)
+                               if (mkdir(path, mode) != 0)
+#else
+                               if (_mkdir(path) != 0)
+#endif
+                               {
+                                       return 1;
+                               }
+                       }
+#if defined (UNIX)
+                       else
+                               mode = sbuf.st_mode;
+#endif
+                       *pp = '/';
+                       pp++;
+               }
+       }
+       return 0;
+} 
+
+
 i1pro_code i1pro_save_calibration(i1pro *p) {
        i1proimp *m = (i1proimp *)p->m;
        i1pro_code ev = I1PRO_OK;
        i1pro_state *s;
        int i, j;
-       char fname[MAXNAMEL+1];
        char nmode[10];
-       char *path;
+       char *cal_path;
        FILE *fp;
        i1pnonv x;
        int ss;
@@ -2254,18 +2362,19 @@
 #if defined(O_BINARY) || defined(_O_BINARY)
        strcat(nmode, "b");
 #endif
-       /* Use global exe_path setup by set_exe_path(argv[0]) */
-       /* to locate file in same directory as the executable. */
-       if ((strlen(exe_path) + 15) > MAXNAMEL) {
-               DBG((dbgo,"i1pro_save_calibration can't open cal file because 
path is too long\n"));
+
+       if ((cal_path = i1pro_cal_name(p)) == NULL)
                return I1PRO_INT_CAL_SAVE;
-       }
-       sprintf(fname, "%s.i1p_%d.cal", exe_path, m->serno);
 
-       DBG((dbgo,"i1pro_save_calibration saving to file '%s'\n",fname));
+       DBG((dbgo,"i1pro_save_calibration saving to file '%s'\n",cal_path));
+
+       if (i1pro_mkpdirs(cal_path)) {
+               return I1PRO_INT_CAL_SAVE;
+       }
 
-       if ((fp = fopen(fname, nmode)) == NULL) {
+       if ((fp = fopen(cal_path, nmode)) == NULL) {
                DBG((dbgo,"i1pro_save_calibration failed to open file for 
writing\n"));
+               free(cal_path);
                return I1PRO_INT_CAL_SAVE;
        }
        
@@ -2333,12 +2442,14 @@
 
        if (x.ef != 0) {
                DBG((dbgo,"Writing calibration file failed\n"))
+               return I1PRO_INT_CAL_SAVE;
                fclose(fp);
-               delete_file(fname);
+               delete_file(cal_path);
        } else {
                fclose(fp);
                DBG((dbgo,"Writing calibration file done\n"))
        }
+       free(cal_path);
 
        return ev;
 }
@@ -2349,9 +2460,8 @@
        i1pro_code ev = I1PRO_OK;
        i1pro_state *s, ts;
        int i, j;
-       char fname[MAXNAMEL+1];
        char nmode[10];
-       char *path;
+       char *cal_path;
        FILE *fp;
        i1pnonv x;
        int argyllversion;
@@ -2361,21 +2471,17 @@
 #if defined(O_BINARY) || defined(_O_BINARY)
        strcat(nmode, "b");
 #endif
-       /* Use global exe_path setup by set_exe_path(argv[0]) */
-       /* to locate file in same directory as the executable. */
-       if ((strlen(exe_path) + 15) > MAXNAMEL) {
-               DBG((dbgo,"i1pro_restore_calibration can't open cal file 
because path is too long\n"));
+       if ((cal_path = i1pro_cal_name(p)) == NULL)
                return I1PRO_INT_CAL_RESTORE;
-       }
-       sprintf(fname, "%s.i1p_%d.cal", exe_path, m->serno);
 
        DBG((dbgo,"i1pro_restore_calibration restoring from file 
'%s'\n",fname));
 
-       if ((fp = fopen(fname, nmode)) == NULL) {
+       if ((fp = fopen(cal_path, nmode)) == NULL) {
                DBG((dbgo,"i1pro_restore_calibration failed to open file for 
reading\n"));
+               free(cal_path);
                return I1PRO_INT_CAL_RESTORE;
        }
-       
+
        x.ef = 0;
        x.chsum = 0;
 
@@ -2628,6 +2734,7 @@
  reserr:;
 
        fclose(fp);
+       free(cal_path);
 
        return ev;
 }
--- munki_imp.old.c     2010-04-29 16:42:40.000000000 +1000
+++ munki_imp.c 2010-04-29 16:51:42.000000000 +1000
@@ -38,6 +38,8 @@
 
 */
 
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -120,6 +122,8 @@
 #define HIGHRES_LONG  750
 #define HIGHRES_WIDTH  (10.0/3.0) /* (The 3.3333 spacing and lanczos2 seems a 
good combination) */
 
+#define CALIBRATION_DIR "argyll"       /* Directory the instrument calibration 
files get stored */
+
 #include "munki.h"
 #include "munki_imp.h"
 
@@ -1967,15 +1971,115 @@
        }
 }
 
+/* NOTE!! these two routines should be consolidates with the */
+/* very similar ones in i1pro_imp.c !! */
+
+/* Return the path to the calibration save/restore file. */
+/* Return NULL on error. */
+/* Free after used */
+static char *munki_cal_name(munki *p) {
+       munkiimp *m = (munkiimp *)p->m;
+       char *cal_dir3 = NULL;          /* Directory */
+       char *cal_dir2 = NULL;          /* Directory */
+       char *cal_dir1 = NULL;          /* Directory */
+       char cal_name[20+1];            /* Name */
+       char *cal_path = NULL;          /* Allocated overal path */
+       int cpl = 0;                    /* cal path length */
+
+       /* Create the file name */
+       sprintf(cal_name, ".mk_%s.cal", m->serno);
+
+       if ((cal_dir3 = getenv("XDG_CACHE_HOME")) != NULL && cal_dir3[0] != 
'\000') {
+               cal_dir1 = CALIBRATION_DIR;
+       } else {
+               if ((cal_dir3 = getenv("HOME")) != NULL && cal_dir3[0] != 
'\000') {
+                       cal_dir2 = ".cache";
+                       cal_dir1 = CALIBRATION_DIR;
+               } else {
+                       cal_dir3 = NULL;
+               }
+       }
+       cpl += (cal_dir3 != NULL) ? strlen(cal_dir3) + 1 : 0;
+       cpl += (cal_dir2 != NULL) ? strlen(cal_dir2) + 1 : 0;
+       cpl += (cal_dir1 != NULL) ? strlen(cal_dir1) + 1 : 0;
+       cpl += strlen(cal_name) + 1;
+
+       if ((cal_path = malloc(cpl)) == NULL)
+               return NULL;
+
+       cal_path[0] = '\000';
+       if (cal_dir3 != NULL)
+               strcat(cal_path, cal_dir3);
+       if (cal_dir2 != NULL) {
+               if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/')
+                       strcat(cal_path, "/");
+               strcat(cal_path, cal_dir2);
+       }
+       if (cal_dir1 != NULL) {
+               if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/')
+                       strcat(cal_path, "/");
+               strcat(cal_path, cal_dir1);
+       }
+       if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/')
+               strcat(cal_path, "/");
+       strcat(cal_path, cal_name);
+
+       return cal_path;
+}
+
+/* Given the path to a file, ensure that all the parent directories */
+/* are created. return nz on error */
+static int munki_mkpdirs(char *path) {
+       char *pp = path;
+#if defined (UNIX)
+       struct stat sbuf;
+       mode_t mode = 0700;             /* Default directory mode */
+#else
+       struct _stat sbuf;
+#endif
+
+#if !defined (UNIX)
+       if (*pp != '\000'               /* Skip drive number */
+               && ((*pp >= 'a' && *pp <= 'z') || (*pp >= 'A' && *pp <= 'Z'))
+           && pp[1] == ':')
+               pp += 2;
+#endif
+       if (*pp == '/')
+               pp++;                   /* Skip root directory */
+       for (;pp != NULL && *pp != '\000';) {
+               if ((pp = strchr(pp, '/')) != NULL) {
+                       *pp = '\000';
+#if defined (UNIX)
+                       if (stat(path,&sbuf) != 0)
+#else
+                       if (_stat(path,&sbuf) != 0)
+#endif
+                       {
+#if defined (UNIX)
+                               if (mkdir(path, mode) != 0)
+#else
+                               if (_mkdir(path) != 0)
+#endif
+                                       return 1;
+                       }
+#if defined (UNIX)
+                       else
+                               mode = sbuf.st_mode;
+#endif
+                       *pp = '/';
+                       pp++;
+               }
+       }
+       return 0;
+} 
 
 munki_code munki_save_calibration(munki *p) {
        munkiimp *m = (munkiimp *)p->m;
        munki_code ev = MUNKI_OK;
        munki_state *s;
        int i, j;
-       char fname[MAXNAMEL+1];
        char nmode[10];
-       char *path;
+       char *cal_path = NULL;          /* Allocated overal path */
        FILE *fp;
        i1pnonv x;
        int ss;
@@ -1985,18 +2089,18 @@
 #if defined(O_BINARY) || defined(_O_BINARY)
        strcat(nmode, "b");
 #endif
-       /* Use global exe_path setup by set_exe_path(argv[0]) */
-       /* to locate file in same directory as the executable. */
-       if ((strlen(exe_path) + 15) > MAXNAMEL) {
-               DBG((dbgo,"munki_save_calibration can't open cal file because 
path is too long\n"));
+
+       if ((cal_path = munki_cal_name(p)) == NULL)
                return MUNKI_INT_CAL_SAVE;
-       }
-       sprintf(fname, "%s.mk_%s.cal", exe_path, m->serno);
 
-       DBG((dbgo,"munki_save_calibration saving to file '%s'\n",fname));
+       DBG((dbgo,"munki_save_calibration saving to file '%s'\n",cal_path));
 
-       if ((fp = fopen(fname, nmode)) == NULL) {
+       if (munki_mkpdirs(cal_path))
+               return MUNKI_INT_CAL_SAVE;
+
+       if ((fp = fopen(cal_path, nmode)) == NULL) {
                DBG((dbgo,"munki_save_calibration failed to open file for 
writing\n"));
+               free(cal_path);
                return MUNKI_INT_CAL_SAVE;
        }
        
@@ -2069,11 +2173,12 @@
        if (x.ef != 0) {
                DBG((dbgo,"Writing calibration file failed\n"))
                fclose(fp);
-               delete_file(fname);
+               delete_file(cal_path);
        } else {
                fclose(fp);
                DBG((dbgo,"Writing calibration file done\n"))
        }
+       free(cal_path);
 
        return ev;
 }
@@ -2084,9 +2189,8 @@
        munki_code ev = MUNKI_OK;
        munki_state *s, ts;
        int i, j;
-       char fname[MAXNAMEL+1];
        char nmode[10];
-       char *path;
+       char *cal_path;
        FILE *fp;
        i1pnonv x;
        int argyllversion;
@@ -2097,20 +2201,18 @@
 #if defined(O_BINARY) || defined(_O_BINARY)
        strcat(nmode, "b");
 #endif
-       /* Use global exe_path setup by set_exe_path(argv[0]) */
-       /* to locate file in same directory as the executable. */
-       if ((strlen(exe_path) + 15) > MAXNAMEL) {
-               DBG((dbgo,"munki_restore_calibration can't open cal file 
because path is too long\n"));
+
+       if ((cal_path = munki_cal_name(p)) == NULL)
                return MUNKI_INT_CAL_RESTORE;
-       }
-       sprintf(fname, "%s.mk_%s.cal", exe_path, m->serno);
 
-       DBG((dbgo,"munki_restore_calibration restoring from file 
'%s'\n",fname));
+       DBG((dbgo,"munki_restore_calibration restoring from file 
'%s'\n",cal_path));
 
-       if ((fp = fopen(fname, nmode)) == NULL) {
+       if ((fp = fopen(cal_path, nmode)) == NULL) {
                DBG((dbgo,"munki_restore_calibration failed to open file for 
reading\n"));
+               free(cal_path);
                return MUNKI_INT_CAL_RESTORE;
        }
+       free(cal_path);
        
        x.ef = 0;
        x.chsum = 0;

Other related posts: