Back to index

radiance  4R0+20100331
lamps.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: lamps.c,v 2.10 2008/02/18 23:35:51 greg Exp $";
00003 #endif
00004 /*
00005  * Load lamp data.
00006  */
00007 
00008 #include "copyright.h"
00009 
00010 #include  <stdio.h>
00011 #include  <stdlib.h>
00012 #include  <ctype.h>
00013 
00014 #include  "standard.h"
00015 #include  "color.h"
00016 
00017 extern char   *eindex(), *expsave();
00018 
00019 typedef struct lamp {
00020        char   *pattern;                   /* search pattern */
00021        float  *color;                            /* pointer to lamp value */
00022        struct lamp   *next;               /* next lamp in list */
00023 } LAMP;                                   /* a lamp entry */
00024 
00025 static LAMP   *lamps = NULL;              /* lamp list */
00026 
00027 
00028 float *
00029 matchlamp(                         /* see if string matches any lamp */
00030 char   *s
00031 )
00032 {
00033        register LAMP *lp;
00034 
00035        for (lp = lamps; lp != NULL; lp = lp->next) {
00036               expset(lp->pattern);
00037               if (eindex(s) != NULL)
00038                      return(lp->color);
00039        }
00040        return(NULL);
00041 }
00042 
00043 
00044 int
00045 loadlamps(                                /* load lamp type file */
00046 char   *file
00047 )
00048 {
00049        LAMP   *lastp;
00050        register LAMP *lp;
00051        FILE   *fp;
00052        float  xyz[3];
00053        char   buf[128], str[128];
00054        register char *cp1, *cp2;
00055 
00056        if ((fp = frlibopen(file)) == NULL)
00057               return(0);
00058        lastp = NULL;
00059        while (fgets(buf, sizeof(buf), fp) != NULL) {
00060                                    /* work on a copy of buffer */
00061               strcpy(str, buf);
00062                                    /* get pattern for this entry */
00063               for (cp1 = str; isspace(*cp1); cp1++)
00064                      ;
00065               if (!*cp1 || *cp1 == '#')
00066                      continue;
00067               for (cp2 = cp1+1; *cp2; cp2++)
00068                      if (*cp2 == *cp1 && cp2[-1] != '\\')
00069                             break;
00070               if (!*cp2) {
00071                      cp1 = "unclosed pattern";
00072                      goto fmterr;
00073               }
00074               cp1++; *cp2++ = '\0';
00075               if (ecompile(cp1, 1, 0) < 0) {
00076                      cp1 = "bad regular expression";
00077                      goto fmterr;
00078               }
00079               if ((lp = (LAMP *)malloc(sizeof(LAMP))) == NULL)
00080                      goto memerr;
00081               if ((lp->pattern = expsave()) == NULL)
00082                      goto memerr;
00083                                           /* get specification */
00084               for (cp1 = cp2; isspace(*cp1); cp1++)
00085                      ;
00086               if (!isdigit(*cp1) && *cp1 != '.' && *cp1 != '(') {
00087                      cp1 = "missing lamp specification";
00088                      goto fmterr;
00089               }
00090               if (*cp1 == '(') {          /* find alias */
00091                      for (cp2 = ++cp1; *cp2; cp2++)
00092                             if (*cp2 == ')' && cp2[-1] != '\\')
00093                                    break;
00094                      *cp2 = '\0';
00095                      if ((lp->color = matchlamp(cp1)) == NULL) {
00096                             cp1 = "unmatched alias";
00097                             goto fmterr;
00098                      }
00099               } else {                    /* or read specificaion */
00100                      if ((lp->color=(float *)malloc(6*sizeof(float)))==NULL)
00101                             goto memerr;
00102                      if (sscanf(cp1, "%f %f %f", &lp->color[3], &
00103                                    lp->color[4], &lp->color[5]) != 3) {
00104                             cp1 = "bad lamp data";
00105                             goto fmterr;
00106                      }
00107                                           /* convert xyY to XYZ */
00108                      xyz[1] = lp->color[5];
00109                      xyz[0] = lp->color[3]/lp->color[4] * xyz[1];
00110                      xyz[2] = xyz[1]*(1./lp->color[4] - 1.) - xyz[0];
00111                                           /* XYZ to RGB */
00112                      cie_rgb(lp->color, xyz);
00113               }
00114               if (lastp == NULL)
00115                      lamps = lp;
00116               else
00117                      lastp->next = lp;
00118               lp->next = NULL;
00119               lastp = lp;
00120        }
00121        fclose(fp);
00122        return(lastp != NULL);
00123 memerr:
00124        fputs("Out of memory in loadlamps\n", stderr);
00125        return(-1);
00126 fmterr:
00127        fputs(buf, stderr);
00128        fprintf(stderr, "%s: %s\n", file, cp1);
00129        return(-1);
00130 }
00131 
00132 
00133 void
00134 freelamps(void)                    /* free our lamps list */
00135 {
00136        register LAMP *lp1, *lp2;
00137        
00138        for (lp1 = lamps; lp1 != NULL; lp1 = lp2) {
00139               free(lp1->pattern);
00140               if (lp1->color != NULL) {
00141                      for (lp2 = lp1->next; lp2 != NULL; lp2 = lp2->next)
00142                             if (lp2->color == lp1->color)
00143                                    lp2->color = NULL;
00144                      free((void *)lp1->color);
00145               }
00146               lp2 = lp1->next;
00147               free((void *)lp1);
00148        }
00149        lamps = NULL;
00150 }