Back to index

radiance  4R0+20100331
rhpict.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: rhpict.c,v 3.18 2004/06/08 19:48:30 greg Exp $";
00003 #endif
00004 /*
00005  * Radiance holodeck picture generator
00006  */
00007 
00008 #include <string.h>
00009 
00010 #include "platform.h"
00011 #include "rterror.h"
00012 #include "rholo.h"
00013 
00014 char   *progname;           /* our program name */
00015 char   *hdkfile;            /* holodeck file name */
00016 char   gargc;               /* global argc */
00017 char   **gargv;             /* global argv */
00018 
00019 VIEW   myview = STDVIEW;    /* current output view */
00020 int    xres = 512, yres = 512;     /* max. horizontal and vertical resolution */
00021 char   *outspec = NULL;     /* output file specification */
00022 double randfrac = -1.;             /* random resampling fraction */
00023 double pixaspect = 1.;             /* pixel aspect ratio */
00024 int    seqstart = 0;        /* sequence start frame */
00025 double expval = 1.;         /* exposure value */
00026 
00027 COLOR  *mypixel;            /* pixels being rendered */
00028 float  *myweight;           /* weights (used to compute final pixels) */
00029 float  *mydepth;            /* depth values (visibility culling) */
00030 int    hres, vres;          /* current horizontal and vertical res. */
00031 
00032 extern int    nowarn;              /* turn warnings off? */
00033 
00034 static void dopicture(int fn);
00035 static void render_frame(PACKHEAD *bl, int nb);
00036 static void startpicture(int fn);
00037 static int endpicture(void);
00038 static void initialize(void);
00039  /* from rhpict2.c */
00040 extern void pixFinish(double ransamp);
00041 extern void pixBeam(BEAM *bp, HDBEAMI *hb);
00042 
00043 
00044 int
00045 main(
00046 int    argc,
00047 char   *argv[]
00048 )
00049 {
00050        int    i, rval;
00051 
00052        gargc = argc; gargv = argv;
00053        progname = argv[0];                /* get arguments */
00054        for (i = 1; i < argc && argv[i][0] == '-'; i++) {
00055               rval = getviewopt(&myview, argc-i, argv+i);
00056               if (rval >= 0) {            /* view option */
00057                      i += rval;
00058                      continue;
00059               }
00060               switch (argv[i][1]) {
00061               case 'w':                   /* turn off warnings */
00062                      nowarn++;
00063                      break;
00064               case 'p':                   /* pixel aspect/exposure */
00065                      if (badarg(argc-i-1,argv+i+1,"f"))
00066                             goto userr;
00067                      if (argv[i][2] == 'a')
00068                             pixaspect = atof(argv[++i]);
00069                      else if (argv[i][2] == 'e') {
00070                             expval = atof(argv[++i]);
00071                             if ((argv[i][0] == '-') | (argv[i][0] == '+'))
00072                                    expval = pow(2., expval);
00073                      } else
00074                             goto userr;
00075                      break;
00076               case 'x':                   /* horizontal resolution */
00077                      if (badarg(argc-i-1,argv+i+1,"i"))
00078                             goto userr;
00079                      xres = atoi(argv[++i]);
00080                      break;
00081               case 'y':                   /* vertical resolution */
00082                      if (badarg(argc-i-1,argv+i+1,"i"))
00083                             goto userr;
00084                      yres = atoi(argv[++i]);
00085                      break;
00086               case 'o':                   /* output file specificaiton */
00087                      if (badarg(argc-i-1,argv+i+1,"s"))
00088                             goto userr;
00089                      outspec = argv[++i];
00090                      break;
00091               case 'r':                   /* random sampling */
00092                      if (badarg(argc-i-1,argv+i+1,"f"))
00093                             goto userr;
00094                      randfrac = atof(argv[++i]);
00095                      break;
00096               case 's':                   /* smooth sampling */
00097                      randfrac = -1.;
00098                      break;
00099               case 'S':                   /* sequence start */
00100                      if (badarg(argc-i-1,argv+i+1,"i"))
00101                             goto userr;
00102                      seqstart = atoi(argv[++i]);
00103                      break;
00104               case 'v':                   /* view file */
00105                      if (argv[i][2]!='f' || badarg(argc-i-1,argv+i+1,"s"))
00106                             goto userr;
00107                      rval = viewfile(argv[++i], &myview, NULL);
00108                      if (rval < 0) {
00109                             sprintf(errmsg, "cannot open view file \"%s\"",
00110                                           argv[i]);
00111                             error(SYSTEM, errmsg);
00112                      } else if (rval == 0) {
00113                             sprintf(errmsg, "bad view file \"%s\"",
00114                                           argv[i]);
00115                             error(USER, errmsg);
00116                      }
00117                      break;
00118               default:
00119                      goto userr;
00120               }
00121        }
00122                                           /* open holodeck file */
00123        if (i != argc-1)
00124               goto userr;
00125        hdkfile = argv[i];
00126        initialize();
00127                                           /* render picture(s) */
00128        if (seqstart <= 0)
00129               dopicture(0);
00130        else
00131               while (nextview(&myview, stdin) != EOF)
00132                      dopicture(seqstart++);
00133        quit(0);                           /* all done! */
00134 userr:
00135        fprintf(stderr,
00136 "Usage: %s [-w][-r rf][-pa pa][-pe ex][-x hr][-y vr][-S stfn][-o outp][view] input.hdk\n",
00137                      progname);
00138        quit(1);
00139        return 1;  /* pro forma return */
00140 }
00141 
00142 
00143 static void
00144 dopicture(                  /* render view from holodeck */
00145        int    fn
00146 )
00147 {
00148        char   *err;
00149        int    rval;
00150        BEAMLIST      blist;
00151 
00152        if ((err = setview(&myview)) != NULL) {
00153               sprintf(errmsg, "%s -- skipping frame %d", err, fn);
00154               error(WARNING, errmsg);
00155               return;
00156        }
00157        startpicture(fn);           /* open output picture */
00158                                    /* determine relevant beams */
00159        viewbeams(&myview, hres, vres, &blist);
00160                                    /* render image */
00161        if (blist.nb > 0) {
00162               render_frame(blist.bl, blist.nb);
00163               free((void *)blist.bl);
00164        } else {
00165               sprintf(errmsg, "no section visible in frame %d", fn);
00166               error(WARNING, errmsg);
00167        }
00168        rval = endpicture();        /* write pixel values */
00169        if (rval < 0) {
00170               sprintf(errmsg, "error writing frame %d", fn);
00171               error(SYSTEM, errmsg);
00172        }
00173 #ifdef DEBUG
00174        if (blist.nb > 0 & rval > 0) {
00175               sprintf(errmsg, "%d unrendered pixels in frame %d (%.1f%%)",
00176                             rval, fn, 100.*rval/(hres*vres));
00177               error(WARNING, errmsg);
00178        }
00179 #endif
00180 }
00181 
00182 
00183 static void
00184 render_frame(        /* render frame from beam values */
00185        register PACKHEAD    *bl,
00186        int    nb
00187 )
00188 {
00189        register HDBEAMI     *bil;
00190        register int  i;
00191 
00192        if (nb <= 0) return;
00193        if ((bil = (HDBEAMI *)malloc(nb*sizeof(HDBEAMI))) == NULL)
00194               error(SYSTEM, "out of memory in render_frame");
00195        for (i = nb; i--; ) {
00196               bil[i].h = hdlist[bl[i].hd];
00197               bil[i].b = bl[i].bi;
00198        }
00199        hdloadbeams(bil, nb, pixBeam);
00200        pixFinish(randfrac);
00201        free((void *)bil);
00202 }
00203 
00204 
00205 static void
00206 startpicture(        /* initialize picture for rendering & output */
00207        int    fn
00208 )
00209 {
00210        extern char   VersionID[];
00211        double pa = pixaspect;
00212        char   fname[256];
00213                             /* compute picture resolution */
00214        hres = xres; vres = yres;
00215        normaspect(viewaspect(&myview), &pa, &hres, &vres);
00216                             /* prepare output */
00217        if (outspec != NULL) {
00218               sprintf(fname, outspec, fn);
00219               if (freopen(fname, "w", stdout) == NULL) {
00220                      sprintf(errmsg, "cannot open output \"%s\"", fname);
00221                      error(SYSTEM, errmsg);
00222               }
00223        }
00224                             /* write header */
00225        newheader("RADIANCE", stdout);
00226        printf("SOFTWARE= %s\n", VersionID);
00227        printargs(gargc, gargv, stdout);
00228        if (fn)
00229               printf("FRAME=%d\n", fn);
00230        fputs(VIEWSTR, stdout);
00231        fprintview(&myview, stdout);
00232        fputc('\n', stdout);
00233        if ((pa < 0.99) | (pa > 1.01))
00234               fputaspect(pa, stdout);
00235        if ((expval < 0.99) | (expval > 1.01))
00236               fputexpos(expval, stdout);
00237        fputformat(COLRFMT, stdout);
00238        fputc('\n', stdout);
00239                             /* write resolution (standard order) */
00240        fprtresolu(hres, vres, stdout);
00241                             /* prepare image buffers */
00242        memset((char *)mypixel, '\0', hres*vres*sizeof(COLOR));
00243        memset((char *)myweight, '\0', hres*vres*sizeof(float));
00244        memset((char *)mydepth, '\0', hres*vres*sizeof(float));
00245 }
00246 
00247 
00248 static int
00249 endpicture(void)                   /* finish and write out pixels */
00250 {
00251        int    lastr = -1, nunrend = 0;
00252        int32  lastp, lastrp;
00253        register int32       p;
00254        register double      d;
00255                             /* compute final pixel values */
00256        for (p = hres*vres; p--; ) {
00257               if (myweight[p] <= FTINY) {
00258                      if (lastr >= 0) {
00259                             if (p/hres == lastp/hres)
00260                                    copycolor(mypixel[p], mypixel[lastp]);
00261                             else
00262                                    copycolor(mypixel[p], mypixel[lastrp]);
00263                      }
00264                      nunrend++;
00265                      continue;
00266               }
00267               d = expval/myweight[p];
00268               scalecolor(mypixel[p], d);
00269               if ((lastp=p)/hres != lastr)
00270                      lastr = (lastrp=p)/hres;
00271        }
00272                             /* write each scanline */
00273        for (p = vres; p--; )
00274               if (fwritescan(mypixel+p*hres, hres, stdout) < 0)
00275                      return(-1);
00276        if (fflush(stdout) == EOF)
00277               return(-1);
00278        return(nunrend);
00279 }
00280 
00281 
00282 static void
00283 initialize(void)                   /* initialize holodeck and buffers */
00284 {
00285        int    fd;
00286        FILE   *fp;
00287        int    n;
00288        int32  nextloc;
00289                                    /* open holodeck file */
00290        if ((fp = fopen(hdkfile, "r")) == NULL) {
00291               sprintf(errmsg, "cannot open \"%s\" for reading", hdkfile);
00292               error(SYSTEM, errmsg);
00293        }
00294                                    /* check header format */
00295        checkheader(fp, HOLOFMT, NULL);
00296                                    /* check magic number */
00297        if (getw(fp) != HOLOMAGIC) {
00298               sprintf(errmsg, "bad magic number in holodeck file \"%s\"",
00299                             hdkfile);
00300               error(USER, errmsg);
00301        }
00302        nextloc = ftell(fp);               /* get stdio position */
00303        fd = dup(fileno(fp));                     /* dup file descriptor */
00304        fclose(fp);                        /* done with stdio */
00305        for (n = 0; nextloc > 0L; n++) {   /* initialize each section */
00306               lseek(fd, (off_t)nextloc, SEEK_SET);
00307               read(fd, (char *)&nextloc, sizeof(nextloc));
00308               hdinit(fd, NULL);
00309        }
00310                                    /* allocate picture buffer */
00311        mypixel = (COLOR *)bmalloc(xres*yres*sizeof(COLOR));
00312        myweight = (float *)bmalloc(xres*yres*sizeof(float));
00313        mydepth = (float *)bmalloc(xres*yres*sizeof(float));
00314        if ((mypixel == NULL) | (myweight == NULL) | (mydepth == NULL))
00315               error(SYSTEM, "out of memory in initialize");
00316 }
00317 
00318 
00319 void
00320 eputs(s)                    /* put error message to stderr */
00321 register char  *s;
00322 {
00323        static int  midline = 0;
00324 
00325        if (!*s)
00326               return;
00327        if (!midline++) {    /* prepend line with program name */
00328               fputs(progname, stderr);
00329               fputs(": ", stderr);
00330        }
00331        fputs(s, stderr);
00332        if (s[strlen(s)-1] == '\n') {
00333               fflush(stderr);
00334               midline = 0;
00335        }
00336 }