static double l_psize(char *nm) /* compute pixel size in steradians */ { static unsigned long ltick[MAXINP]; static double psize[MAXINP]; FVECT dir0, org, dirx, diry; RREAL locx[2], locy[2]; double d; int fn; register int i; d = argument(1); if (d <= -0.5 || d >= nfiles+0.5) { errno = EDOM; return(0.0); } if (d < 0.5) return((double)nfiles); fn = d - 0.5; if (ltick[fn] != eclock) { /* need to compute? */ psize[fn] = 0.0; if (input[fn].vw.type == 0) errno = EDOM; else if (input[fn].vw.type != VT_PAR && funvalue(vray[6], 1, &d) >= -FTINY) { for (i = 0; i < 3; i++) dir0[i] = funvalue(vray[3+i], 1, &d); pix2loc(locx, &input[fn].rs, xscan+1, ymax-1-yscan); pix2loc(locy, &input[fn].rs, xscan, ymax-yscan); if (viewray(org, dirx, &input[fn].vw, locx[0], locx[1]) >= -FTINY && viewray(org, diry, &input[fn].vw, locy[0], locy[1]) >= -FTINY) { /* approximate solid angle */ for (i = 0; i < 3; i++) { dirx[i] -= dir0[i]; diry[i] -= dir0[i]; } fcross(dir0, dirx, diry); psize[fn] = VLEN(dir0); } } ltick[fn] = eclock; } return(psize[fn]); }
static double l_ray( /* return ray origin or direction */ register char *nam ) { static unsigned long ltick[MAXINP]; static FVECT lorg[MAXINP], ldir[MAXINP]; static double ldist[MAXINP]; RREAL loc[2]; double d; int fn; register int i; d = argument(1); if (d <= -0.5 || d >= nfiles+0.5) { errno = EDOM; return(0.0); } if (d < 0.5) return((double)nfiles); fn = d - 0.5; if (ltick[fn] != eclock) { /* need to compute? */ lorg[fn][0] = lorg[fn][1] = lorg[fn][2] = 0.0; ldir[fn][0] = ldir[fn][1] = ldir[fn][2] = 0.0; ldist[fn] = -1.0; if (input[fn].vw.type == 0) errno = EDOM; else { pix2loc(loc, &input[fn].rs, xscan, ymax-1-yscan); ldist[fn] = viewray(lorg[fn], ldir[fn], &input[fn].vw, loc[0], loc[1]); } ltick[fn] = eclock; } if (nam == vray[i=6]) return(ldist[fn]); while (i--) if (nam == vray[i]) return(i < 3 ? lorg[fn][i] : ldir[fn][i-3]); eputs("Bad call to l_ray()!\n"); quit(1); return 1; /* pro forma return */ }
static void pixtoval(void) /* convert picture to values */ { register COLOR *scanln; int dogamma; COLOR lastc; RREAL hv[2]; int startprim, endprim; long startpos; int y; register int x; scanln = (COLOR *)malloc(scanlen(&picres)*sizeof(COLOR)); if (scanln == NULL) { fprintf(stderr, "%s: out of memory\n", progname); quit(1); } dogamma = gamcor < .95 || gamcor > 1.05; if (putprim == ALL && !interleave) { startprim = RED; endprim = BLU; startpos = ftell(fin); } else { startprim = putprim; endprim = putprim; } for (putprim = startprim; putprim <= endprim; putprim++) { if (putprim != startprim && fseek(fin, startpos, 0)) { fprintf(stderr, "%s: seek error on input file\n", progname); quit(1); } set_io(); setcolor(lastc, 0.0, 0.0, 0.0); for (y = 0; y < numscans(&picres); y++) { if (freadscan(scanln, scanlen(&picres), fin) < 0) { fprintf(stderr, "%s: read error\n", progname); quit(1); } for (x = 0; x < scanlen(&picres); x++) { if (uniq) { if ( colval(scanln[x],RED) == colval(lastc,RED) && colval(scanln[x],GRN) == colval(lastc,GRN) && colval(scanln[x],BLU) == colval(lastc,BLU) ) continue; else copycolor(lastc, scanln[x]); } if (doexposure) multcolor(scanln[x], exposure); if (dogamma) setcolor(scanln[x], pow(colval(scanln[x],RED), 1.0/gamcor), pow(colval(scanln[x],GRN), 1.0/gamcor), pow(colval(scanln[x],BLU), 1.0/gamcor)); if (!dataonly) { pix2loc(hv, &picres, x, y); printf("%7d %7d ", (int)(hv[0]*picres.xr), (int)(hv[1]*picres.yr)); } if ((*putval)(scanln[x]) < 0) { fprintf(stderr, "%s: write error\n", progname); quit(1); } } } } free((void *)scanln); }
void addpicz( /* add a picture + depth-buffer */ char *pcf, char *zbf ) { FILE *pfp; int zfd; COLR *cscn; float *zscn; struct phead phd; int eshft; double emult; RESOLU prs; RREAL vl[2]; FVECT ro, rd; double aftd; COLOR ctmp; int j; register int i; /* open files */ if ((pfp = fopen(pcf, "r")) == NULL) { sprintf(errmsg, "cannot open picture file \"%s\"", pcf); error(SYSTEM, pcf); } if ((zfd = open(zbf, O_RDONLY)) < 0) { sprintf(errmsg, "cannot open depth file \"%s\"", zbf); error(SYSTEM, pcf); } /* load picture header */ phd.vw = stdview; phd.expos = 1.0; phd.badfmt = phd.gotview = phd.altprims = 0; if (getheader(pfp, picheadline, &phd) < 0 || phd.badfmt || !fgetsresolu(&prs, pfp)) { sprintf(errmsg, "bad format for picture file \"%s\"", pcf); error(USER, errmsg); } if (!phd.gotview || setview(&phd.vw) != NULL) { sprintf(errmsg, "missing/illegal view in picture \"%s\"", pcf); error(USER, errmsg); } if (phd.altprims) { sprintf(errmsg, "ignoring primary values in picture \"%s\"", pcf); error(WARNING, errmsg); } /* figure out what to do about exposure */ if ((phd.expos < 0.99) | (phd.expos > 1.01)) { emult = -log(phd.expos)/log(2.); eshft = emult >= 0. ? emult+.5 : emult-.5; emult -= (double)eshft; if ((emult <= 0.01) & (emult >= -0.01)) emult = -1.; else { emult = 1./phd.expos; eshft = 0; } } else { emult = -1.; eshft = 0; } /* allocate buffers */ cscn = (COLR *)malloc(scanlen(&prs)*sizeof(COLR)); zscn = (float *)malloc(scanlen(&prs)*sizeof(float)); if ((cscn == NULL) | (zscn == NULL)) error(SYSTEM, "out of memory in addpicz"); /* read and process each scanline */ for (j = 0; j < numscans(&prs); j++) { i = scanlen(&prs); /* read colrs */ if (freadcolrs(cscn, i, pfp) < 0) { sprintf(errmsg, "error reading picture \"%s\"", pcf); error(USER, errmsg); } if (eshft) /* shift exposure */ shiftcolrs(cscn, i, eshft); i *= sizeof(float); /* read depth */ if (read(zfd, (char *)zscn, i) != i) { sprintf(errmsg, "error reading depth file \"%s\"", zbf); error(USER, errmsg); } for (i = scanlen(&prs); i--; ) { /* do each pixel */ pix2loc(vl, &prs, i, j); aftd = viewray(ro, rd, &phd.vw, vl[0], vl[1]); if (aftd < -FTINY) continue; /* off view */ if (aftd > FTINY && zscn[i] > aftd) continue; /* aft clipped */ if (emult > 0.) { /* whatta pain */ colr_color(ctmp, cscn[i]); scalecolor(ctmp, emult); setcolr(cscn[i], colval(ctmp,RED), colval(ctmp,GRN), colval(ctmp,BLU)); } addray(ro, rd, (double)zscn[i], cscn[i]); } } /* write output and free beams */ hdflush(NULL); /* clean up */ free((void *)cscn); free((void *)zscn); fclose(pfp); close(zfd); }