update rad read from rad5R1

hopefully the new radiance code will be more robust
This commit is contained in:
John Cupitt 2018-07-22 13:04:46 +01:00
parent 0077017ad8
commit 927f92a8bb
1 changed files with 174 additions and 146 deletions

View File

@ -21,6 +21,8 @@
* - use dbuf for buffer output * - use dbuf for buffer output
* 4/4/17 * 4/4/17
* - reduce stack use to help musl * - reduce stack use to help musl
* 22/7/18
* - update code from radiance ... pasted in from rad5R1
*/ */
/* /*
@ -150,43 +152,24 @@
#include "pforeign.h" #include "pforeign.h"
/* Begin copy-paste from Radiance sources. /* Begin copy-paste from Radiance sources.
*
* To update:
*
* 1. Download and unpack latest stable radiance
* 2. ray/src/common has the files we need ... copy in this order:
* colour.h
* resolu.h
* rtio.h
* fputword.c
* colour.c
* resolu.c
* header.c
* 3. trim each one down, removing extern decls
* 4. make all functions static
* 5. reorder to remove forward refs
* 6. remove unused funcs, mostly related to HDR write
*/ */
/* flags for scanline ordering */
#define XDECR 1
#define YDECR 2
#define YMAJOR 4
/* standard scanline ordering */
#define PIXSTANDARD (YMAJOR|YDECR)
#define PIXSTDFMT "-Y %d +X %d\n"
/* structure for image dimensions */
typedef struct {
int rt; /* orientation (from flags above) */
int xr, yr; /* x and y resolution */
} RESOLU;
/* macros to get scanline length and number */
#define scanlen(rs) ((rs)->rt & YMAJOR ? (rs)->xr : (rs)->yr)
#define numscans(rs) ((rs)->rt & YMAJOR ? (rs)->yr : (rs)->xr)
/* resolution string buffer and its size */
#define RESOLU_BUFLEN 32
/* macros for reading/writing resolution struct */
#define fputsresolu(rs,fp) fputs(resolu2str(resolu_buf,rs),fp)
#define fgetsresolu(rs,fp) str2resolu(rs, \
fgets(resolu_buf,RESOLU_BUFLEN,fp))
/* reading/writing of standard ordering */
#define fprtresolu(sl,ns,fp) fprintf(fp,PIXSTDFMT,ns,sl)
#define fscnresolu(sl,ns,fp) (fscanf(fp,PIXSTDFMT,ns,sl)==2)
/* defined in resolu.c */
typedef int gethfunc(char *s, void *p); /* callback to process header lines */
#define RED 0 #define RED 0
#define GRN 1 #define GRN 1
#define BLU 2 #define BLU 2
@ -197,10 +180,10 @@ typedef int gethfunc(char *s, void *p); /* callback to process header lines */
#define COLXS 128 /* excess used for exponent */ #define COLXS 128 /* excess used for exponent */
#define WHT 3 /* used for RGBPRIMS type */ #define WHT 3 /* used for RGBPRIMS type */
#undef BYTE #undef uby8
#define BYTE unsigned char /* 8-bit unsigned integer */ #define uby8 unsigned char /* 8-bit unsigned integer */
typedef BYTE COLR[4]; /* red, green, blue (or X,Y,Z), exponent */ typedef uby8 COLR[4]; /* red, green, blue (or X,Y,Z), exponent */
typedef float COLORV; typedef float COLORV;
typedef COLORV COLOR[3]; /* red, green, blue (or X,Y,Z) */ typedef COLORV COLOR[3]; /* red, green, blue (or X,Y,Z) */
@ -232,8 +215,8 @@ typedef float COLORMAT[3][3]; /* color coordinate conversion matrix */
#define CIE_y_g 0.710 #define CIE_y_g 0.710
#define CIE_x_b 0.140 #define CIE_x_b 0.140
#define CIE_y_b 0.080 #define CIE_y_b 0.080
#define CIE_x_w 0.3333 /* use true white */ #define CIE_x_w (1./3.) /* use true white */
#define CIE_y_w 0.3333 #define CIE_y_w (1./3.)
#else #else
#define CIE_x_r 0.640 /* nominal CRT primaries */ #define CIE_x_r 0.640 /* nominal CRT primaries */
#define CIE_y_r 0.330 #define CIE_y_r 0.330
@ -241,8 +224,8 @@ typedef float COLORMAT[3][3]; /* color coordinate conversion matrix */
#define CIE_y_g 0.600 #define CIE_y_g 0.600
#define CIE_x_b 0.150 #define CIE_x_b 0.150
#define CIE_y_b 0.060 #define CIE_y_b 0.060
#define CIE_x_w 0.3333 /* use true white */ #define CIE_x_w (1./3.) /* use true white */
#define CIE_y_w 0.3333 #define CIE_y_w (1./3.)
#endif #endif
#define STDPRIMS {{CIE_x_r,CIE_y_r},{CIE_x_g,CIE_y_g}, \ #define STDPRIMS {{CIE_x_r,CIE_y_r},{CIE_x_g,CIE_y_g}, \
@ -327,12 +310,12 @@ typedef float COLORMAT[3][3]; /* color coordinate conversion matrix */
#define PRIMARYSTR "PRIMARIES=" #define PRIMARYSTR "PRIMARIES="
#define LPRIMARYSTR 10 #define LPRIMARYSTR 10
#define isprims(hl) (!strncmp(hl,PRIMARYSTR,LPRIMARYSTR)) #define isprims(hl) (!strncmp(hl,PRIMARYSTR,LPRIMARYSTR))
#define primsval(p,hl) sscanf(hl+LPRIMARYSTR, \ #define primsval(p,hl) (sscanf((hl)+LPRIMARYSTR, \
"%f %f %f %f %f %f %f %f", \ "%f %f %f %f %f %f %f %f", \
&(p)[RED][CIEX],&(p)[RED][CIEY], \ &(p)[RED][CIEX],&(p)[RED][CIEY], \
&(p)[GRN][CIEX],&(p)[GRN][CIEY], \ &(p)[GRN][CIEX],&(p)[GRN][CIEY], \
&(p)[BLU][CIEX],&(p)[BLU][CIEY], \ &(p)[BLU][CIEX],&(p)[BLU][CIEY], \
&(p)[WHT][CIEX],&(p)[WHT][CIEY]) &(p)[WHT][CIEX],&(p)[WHT][CIEY]) == 8)
#define fputprims(p,fp) fprintf(fp, \ #define fputprims(p,fp) fprintf(fp, \
"%s %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",\ "%s %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",\
PRIMARYSTR, \ PRIMARYSTR, \
@ -345,11 +328,22 @@ typedef float COLORMAT[3][3]; /* color coordinate conversion matrix */
#define COLCORSTR "COLORCORR=" #define COLCORSTR "COLORCORR="
#define LCOLCORSTR 10 #define LCOLCORSTR 10
#define iscolcor(hl) (!strncmp(hl,COLCORSTR,LCOLCORSTR)) #define iscolcor(hl) (!strncmp(hl,COLCORSTR,LCOLCORSTR))
#define colcorval(cc,hl) sscanf(hl+LCOLCORSTR,"%f %f %f", \ #define colcorval(cc,hl) sscanf((hl)+LCOLCORSTR,"%f %f %f", \
&(cc)[RED],&(cc)[GRN],&(cc)[BLU]) &(cc)[RED],&(cc)[GRN],&(cc)[BLU])
#define fputcolcor(cc,fp) fprintf(fp,"%s %f %f %f\n",COLCORSTR, \ #define fputcolcor(cc,fp) fprintf(fp,"%s %f %f %f\n",COLCORSTR, \
(cc)[RED],(cc)[GRN],(cc)[BLU]) (cc)[RED],(cc)[GRN],(cc)[BLU])
/*
* Conversions to and from XYZ space generally don't apply WHTEFFICACY.
* If you need Y to be luminance (cd/m^2), this must be applied when
* converting from radiance (watts/sr/m^2).
*/
extern RGBPRIMS stdprims; /* standard primary chromaticities */
extern COLORMAT rgb2xyzmat; /* RGB to XYZ conversion matrix */
extern COLORMAT xyz2rgbmat; /* XYZ to RGB conversion matrix */
extern COLOR cblack, cwhite; /* black (0,0,0) and white (1,1,1) */
#define CGAMUT_LOWER 01 #define CGAMUT_LOWER 01
#define CGAMUT_UPPER 02 #define CGAMUT_UPPER 02
#define CGAMUT (CGAMUT_LOWER|CGAMUT_UPPER) #define CGAMUT (CGAMUT_LOWER|CGAMUT_UPPER)
@ -358,28 +352,134 @@ typedef float COLORMAT[3][3]; /* color coordinate conversion matrix */
#define cpcolormat(md,ms) memcpy((void *)md,(void *)ms,sizeof(COLORMAT)) #define cpcolormat(md,ms) memcpy((void *)md,(void *)ms,sizeof(COLORMAT))
#ifdef getc_unlocked /* avoid horrendous overhead of flockfile */
#undef getc
#undef putc
#define getc getc_unlocked
#define putc putc_unlocked
#endif
#define MINELEN 8 /* minimum scanline length for encoding */
#define MAXELEN 0x7fff /* maximum scanline length for encoding */
#define MINRUN 4 /* minimum run length */
/* flags for scanline ordering */
#define XDECR 1
#define YDECR 2
#define YMAJOR 4
/* standard scanline ordering */
#define PIXSTANDARD (YMAJOR|YDECR)
#define PIXSTDFMT "-Y %d +X %d\n"
/* structure for image dimensions */
typedef struct {
int rt; /* orientation (from flags above) */
int xr, yr; /* x and y resolution */
} RESOLU;
/* macros to get scanline length and number */
#define scanlen(rs) ((rs)->rt & YMAJOR ? (rs)->xr : (rs)->yr)
#define numscans(rs) ((rs)->rt & YMAJOR ? (rs)->yr : (rs)->xr)
/* resolution string buffer and its size */
#define RESOLU_BUFLEN 32
/* macros for reading/writing resolution struct */
#define fputsresolu(rs,fp) fputs(resolu2str(resolu_buf,rs),fp)
#define fgetsresolu(rs,fp) str2resolu(rs, \
fgets(resolu_buf,RESOLU_BUFLEN,fp))
/* reading/writing of standard ordering */
#define fprtresolu(sl,ns,fp) fprintf(fp,PIXSTDFMT,ns,sl)
#define fscnresolu(sl,ns,fp) (fscanf(fp,PIXSTDFMT,ns,sl)==2)
/* identify header lines */
#define isheadid(s) headidval(NULL,s)
#define isformat(s) formatval(NULL,s)
#define isdate(s) dateval(NULL,s)
#define isgmt(s) gmtval(NULL,s)
#define LATLONSTR "LATLONG="
#define LLATLONSTR 8
#define islatlon(hl) (!strncmp(hl,LATLONSTR,LLATLONSTR))
#define latlonval(ll,hl) sscanf((hl)+LLATLONSTR, "%f %f", \
&(ll)[0],&(ll)[1])
#define fputlatlon(lat,lon,fp) fprintf(fp,"%s %.6f %.6f\n",LATLONSTR,lat,lon)
typedef int gethfunc(char *s, void *p); /* callback to process header lines */
#ifdef getc_unlocked /* avoid horrendous overhead of flockfile */
#undef getc
#undef putc
#define getc getc_unlocked
#define putc putc_unlocked
#endif
static char resolu_buf[RESOLU_BUFLEN]; /* resolution line buffer */
#define MAXLINE 512 static char *
resolu2str(buf, rp) /* convert resolution struct to line */
char *buf;
register RESOLU *rp;
{
if (rp->rt&YMAJOR)
sprintf(buf, "%cY %d %cX %d\n",
rp->rt&YDECR ? '-' : '+', rp->yr,
rp->rt&XDECR ? '-' : '+', rp->xr);
else
sprintf(buf, "%cX %d %cY %d\n",
rp->rt&XDECR ? '-' : '+', rp->xr,
rp->rt&YDECR ? '-' : '+', rp->yr);
return(buf);
}
char HDRSTR[] = "#?"; /* information header magic number */
char FMTSTR[] = "FORMAT="; /* format identifier */ static int
str2resolu(rp, buf) /* convert resolution line to struct */
register RESOLU *rp;
char *buf;
{
register char *xndx, *yndx;
register char *cp;
if (buf == NULL)
return(0);
xndx = yndx = NULL;
for (cp = buf; *cp; cp++)
if (*cp == 'X')
xndx = cp;
else if (*cp == 'Y')
yndx = cp;
if (xndx == NULL || yndx == NULL)
return(0);
rp->rt = 0;
if (xndx > yndx) rp->rt |= YMAJOR;
if (xndx[-1] == '-') rp->rt |= XDECR;
if (yndx[-1] == '-') rp->rt |= YDECR;
if ((rp->xr = atoi(xndx+1)) <= 0)
return(0);
if ((rp->yr = atoi(yndx+1)) <= 0)
return(0);
return(1);
}
#define MAXLINE 2048
static const char FMTSTR[] = "FORMAT="; /* format identifier */
char TMSTR[] = "CAPDATE="; /* capture date identifier */
static gethfunc mycheck; static gethfunc mycheck;
static int static int
formatval( /* get format value (return true if format) */ formatval( /* get format value (return true if format) */
register char *r, char *r,
register char *s const char *s
) )
{ {
register char *cp = FMTSTR; const char *cp = FMTSTR;
while (*cp) if (*cp++ != *s++) return(0); while (*cp) if (*cp++ != *s++) return(0);
while (isspace(*s)) s++; while (isspace(*s)) s++;
@ -387,22 +487,24 @@ formatval( /* get format value (return true if format) */
if (r == NULL) return(1); if (r == NULL) return(1);
do do
*r++ = *s++; *r++ = *s++;
while(*s && !isspace(*s)); while (*s && !isspace(*s));
*r = '\0'; *r = '\0';
return(1); return(1);
} }
static int static void
isformat( /* is line a format line? */ fputformat( /* put out a format value */
char *s const char *s,
FILE *fp
) )
{ {
return(formatval(NULL, s)); fputs(FMTSTR, fp);
fputs(s, fp);
putc('\n', fp);
} }
static int static int
getheader( /* get header from file */ getheader( /* get header from file */
FILE *fp, FILE *fp,
@ -410,30 +512,24 @@ getheader( /* get header from file */
void *p void *p
) )
{ {
int rtotal = 0;
char buf[MAXLINE]; char buf[MAXLINE];
int n;
/* give up if there are more than 1,000 lines of header, prevents for ( ; ; ) {
* us scanning entire files when testing for israd */ int rval = 0;
for (n = 0; n < 1000; n++) {
buf[MAXLINE-2] = '\n'; buf[MAXLINE-2] = '\n';
if (fgets(buf, MAXLINE, fp) == NULL) if (fgets(buf, MAXLINE, fp) == NULL)
return(-1); return(-1);
if (buf[0] == '\n') if (buf[buf[0]=='\r'] == '\n')
return(0); return(rtotal);
#ifdef MSDOS
if (buf[0] == '\r' && buf[1] == '\n')
return(0);
#endif
if (buf[MAXLINE-2] != '\n') { if (buf[MAXLINE-2] != '\n') {
ungetc(buf[MAXLINE-2], fp); /* prevent false end */ ungetc(buf[MAXLINE-2], fp); /* prevent false end */
buf[MAXLINE-2] = '\0'; buf[MAXLINE-2] = '\0';
} }
if (f != NULL && (*f)(buf, p) < 0) if (f != NULL && (rval = (*f)(buf, p)) < 0)
return(-1); return(-1);
rtotal += rval;
} }
return(0);
} }
@ -459,8 +555,8 @@ mycheck( /* check a header line for format info. */
static int static int
globmatch( /* check for match of s against pattern p */ globmatch( /* check for match of s against pattern p */
register char *p, const char *p,
register char *s const char *s
) )
{ {
int setmatch; int setmatch;
@ -474,7 +570,7 @@ globmatch( /* check for match of s against pattern p */
case '*': /* match any string */ case '*': /* match any string */
while (p[1] == '*') p++; while (p[1] == '*') p++;
do do
if ( (p[1]=='?' || p[1]==*s) && if ( (p[1]=='?') | (p[1]==*s) &&
globmatch(p+1,s) ) globmatch(p+1,s) )
return(1); return(1);
while (*s++); while (*s++);
@ -487,11 +583,11 @@ globmatch( /* check for match of s against pattern p */
if (!*p) if (!*p)
return(0); return(0);
if (*p == '-') { if (*p == '-') {
setmatch += p[-1] <= *s && *s <= p[1]; setmatch += (p[-1] <= *s && *s <= p[1]);
if (!*++p) if (!*++p)
break; break;
} else } else
setmatch += *p == *s; setmatch += (*p == *s);
} }
if (!setmatch) if (!setmatch)
return(0); return(0);
@ -533,7 +629,7 @@ checkheader(
) )
{ {
struct check cdat; struct check cdat;
register char *cp; char *cp;
cdat.fp = fout; cdat.fp = fout;
cdat.fs[0] = '\0'; cdat.fs[0] = '\0';
@ -552,74 +648,6 @@ checkheader(
return(strcmp(fmt, cdat.fs) ? -1 : 1); /* literal match */ return(strcmp(fmt, cdat.fs) ? -1 : 1); /* literal match */
} }
static char resolu_buf[RESOLU_BUFLEN]; /* resolution line buffer */
static int
str2resolu(RESOLU *rp, char *buf) /* convert resolution line to struct */
{
register char *xndx, *yndx;
register char *cp;
if (buf == NULL)
return(0);
xndx = yndx = NULL;
for (cp = buf; *cp; cp++)
if (*cp == 'X')
xndx = cp;
else if (*cp == 'Y')
yndx = cp;
if (xndx == NULL || yndx == NULL)
return(0);
rp->rt = 0;
if (xndx > yndx) rp->rt |= YMAJOR;
if (xndx[-1] == '-') rp->rt |= XDECR;
if (yndx[-1] == '-') rp->rt |= YDECR;
if ((rp->xr = atoi(xndx+1)) <= 0)
return(0);
if ((rp->yr = atoi(yndx+1)) <= 0)
return(0);
return(1);
}
#ifdef getc_unlocked /* avoid horrendous overhead of flockfile */
#undef getc
#undef putc
#define getc getc_unlocked
#define putc putc_unlocked
#endif
#define MINELEN 8 /* minimum scanline length for encoding */
#define MAXELEN 0x7fff /* maximum scanline length for encoding */
#define MINRUN 4 /* minimum run length */
static void
fputformat( /* put out a format value */
char *s,
FILE *fp
)
{
fputs(FMTSTR, fp);
fputs(s, fp);
putc('\n', fp);
}
char *
resolu2str(char *buf, RESOLU *rp) /* convert resolution struct to line */
{
if (rp->rt&YMAJOR)
sprintf(buf, "%cY %d %cX %d\n",
rp->rt&YDECR ? '-' : '+', rp->yr,
rp->rt&XDECR ? '-' : '+', rp->xr);
else
sprintf(buf, "%cX %d %cY %d\n",
rp->rt&XDECR ? '-' : '+', rp->xr,
rp->rt&YDECR ? '-' : '+', rp->yr);
return(buf);
}
/* End copy-paste from Radiance sources. /* End copy-paste from Radiance sources.
*/ */