void save(Image im, string filename) { assert(im.channels == 3, "Can't save HDR image with <> 3 channels.\n"); assert(im.frames == 1, "Can't save a multi-frame HDR image\n"); FILE *f = fopen(filename.c_str(), "wb"); assert(f, "Could not write output file %s\n", filename.c_str()); // Write trivial hdr header fprintf(f,"#?RADIANCE\n"); fprintf(f,"\n"); fprintf(f,"-Y %d +X %d\n", im.height, im.width); // Read image vector<float> scanline(im.width*3); for (int y = 0; y < im.height; y++) { for (int x = 0; x < im.width; x++) { scanline[x*3+0] = im(x, y, 0); scanline[x*3+1] = im(x, y, 1); scanline[x*3+2] = im(x, y, 2); } fwritescan((COLOR *)&scanline[0], im.width, f); } fclose(f); }
static void ppm2ra2( /* convert 2-byte Pixmap to Radiance picture */ colorscanf_t *getscan ) { COLOR *scanout; double mult; int y; register int x; /* allocate scanline */ scanout = (COLOR *)malloc(xmax*sizeof(COLOR)); if (scanout == NULL) quiterr("out of memory in ppm2ra2"); if (bradj) mult = pow(2., (double)bradj); /* convert image */ for (y = ymax-1; y >= 0; y--) { if ((*getscan)(scanout, xmax, stdin) < 0) quiterr("error reading Pixmap"); for (x = (gamcor>1.01)|(gamcor<0.99)?xmax:0; x--; ) { colval(scanout[x],RED) = pow(colval(scanout[x],RED), gamcor); colval(scanout[x],GRN) = pow(colval(scanout[x],GRN), gamcor); colval(scanout[x],BLU) = pow(colval(scanout[x],BLU), gamcor); } for (x = bradj?xmax:0; x--; ) scalecolor(scanout[x], mult); if (fwritescan(scanout, xmax, stdout) < 0) quiterr("error writing Radiance picture"); } /* free scanline */ free((void *)scanout); }
/* write out matrix to file (precede by resolution string if picture) */ int cm_write(const CMATRIX *cm, int dtype, FILE *fp) { static const char tabEOL[2] = {'\t','\n'}; const COLORV *mp = cm->cmem; int r, c; switch (dtype) { case DTascii: for (r = 0; r < cm->nrows; r++) for (c = 0; c < cm->ncols; c++, mp += 3) fprintf(fp, "%.6e %.6e %.6e%c", mp[0], mp[1], mp[2], tabEOL[c >= cm->ncols-1]); break; case DTfloat: case DTdouble: if (sizeof(COLOR) == cm_elem_size[dtype]) { r = cm->ncols*cm->nrows; while (r > 0) { c = putbinary(mp, sizeof(COLOR), r, fp); if (c <= 0) return(0); mp += 3*c; r -= c; } } else if (dtype == DTdouble) { double dc[3]; r = cm->ncols*cm->nrows; while (r--) { copycolor(dc, mp); if (putbinary(dc, sizeof(double), 3, fp) != 3) return(0); mp += 3; } } else /* dtype == DTfloat */ { float fc[3]; r = cm->ncols*cm->nrows; while (r--) { copycolor(fc, mp); if (putbinary(fc, sizeof(float), 3, fp) != 3) return(0); mp += 3; } } break; case DTrgbe: case DTxyze: fprtresolu(cm->ncols, cm->nrows, fp); for (r = 0; r < cm->nrows; r++, mp += 3*cm->ncols) if (fwritescan((COLOR *)mp, cm->ncols, fp) < 0) return(0); break; default: fputs("Unsupported data type in cm_write()!\n", stderr); return(0); } return(fflush(fp) == 0); }
static void combine(void) /* combine pictures */ { EPNODE *coldef[3], *brtdef; COLOR *scanout; double d; register int i, j; /* check defined variables */ for (j = 0; j < 3; j++) { if (vardefined(vcolout[j])) coldef[j] = eparse(vcolout[j]); else coldef[j] = NULL; } if (vardefined(vbrtout)) brtdef = eparse(vbrtout); else brtdef = NULL; /* allocate scanline */ scanout = (COLOR *)emalloc(xres*sizeof(COLOR)); /* set input position */ yscan = ymax+MIDSCN; /* combine files */ for (ypos = yres-1; ypos >= 0; ypos--) { advance(); varset(vypos, '=', (double)ypos); for (xpos = 0; xpos < xres; xpos++) { xscan = (xpos+.5)*xmax/xres; varset(vxpos, '=', (double)xpos); eclock++; if (brtdef != NULL) { d = evalue(brtdef); if (d < 0.0) d = 0.0; setcolor(scanout[xpos], d, d, d); } else { for (j = 0; j < 3; j++) { if (coldef[j] != NULL) { d = evalue(coldef[j]); } else { d = 0.0; for (i = 0; i < nfiles; i++) d += colval(input[i].scan[MIDSCN][xscan],j); } if (d < 0.0) d = 0.0; colval(scanout[xpos],j) = d; } } } if (fwritescan(scanout, xres, stdout) < 0) { perror("write error"); quit(1); } } efree((char *)scanout); }
static void picdebug(void) /* put out debugging picture */ { static COLOR blkcol = BLKCOLOR; COLOR *scan; int y, i; register int x, rg; if (fseek(stdin, 0L, 0) == EOF) { fprintf(stderr, "%s: cannot seek on input picture\n", progname); exit(1); } getheader(stdin, NULL, NULL); /* skip input header */ fgetresolu(&xmax, &ymax, stdin); /* allocate scanline */ scan = (COLOR *)malloc(xmax*sizeof(COLOR)); if (scan == NULL) { perror(progname); exit(1); } /* finish debug header */ fputformat(COLRFMT, debugfp); putc('\n', debugfp); fprtresolu(xmax, ymax, debugfp); /* write debug picture */ for (y = ymax-1; y >= 0; y--) { if (freadscan(scan, xmax, stdin) < 0) { fprintf(stderr, "%s: error rereading input picture\n", progname); exit(1); } for (x = 0; x < xmax; x++) { rg = chartndx(x, y, &i); if (rg == RG_CENT) { if (!(1L<<i & gmtflags) || (x+y)&07) { copycolor(scan[x], mbRGB[i]); clipgamut(scan[x], bright(scan[x]), CGAMUT, colmin, colmax); } else copycolor(scan[x], blkcol); } else if (rg == RG_CORR) cvtcolor(scan[x], scan[x]); else if (rg != RG_ORIG) copycolor(scan[x], blkcol); } if (fwritescan(scan, xmax, debugfp) < 0) { fprintf(stderr, "%s: error writing debugging picture\n", progname); exit(1); } } /* clean up */ fclose(debugfp); free((void *)scan); }
static void valtopix(void) /* convert values to a pixel file */ { int dogamma; register COLOR *scanln; 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; set_io(); for (y = 0; y < numscans(&picres); y++) { for (x = 0; x < scanlen(&picres); x++) { if (!dataonly) { fscanf(fin, "%*d %*d"); if (fin2 != NULL) { fscanf(fin2, "%*d %*d"); fscanf(fin3, "%*d %*d"); } } if ((*getval)(scanln[x]) < 0) { fprintf(stderr, "%s: read error\n", progname); quit(1); } if (dogamma) setcolor(scanln[x], pow(colval(scanln[x],RED), gamcor), pow(colval(scanln[x],GRN), gamcor), pow(colval(scanln[x],BLU), gamcor)); if (doexposure) multcolor(scanln[x], exposure); } if (fwritescan(scanln, scanlen(&picres), stdout) < 0) { fprintf(stderr, "%s: write error\n", progname); quit(1); } } free((void *)scanln); }
static int rmx_write_rgbe(const RMATRIX *rm, FILE *fp) { COLOR *scan = (COLOR *)malloc(sizeof(COLOR)*rm->ncols); int i, j; if (scan == NULL) return(0); for (i = 0; i < rm->nrows; i++) { for (j = rm->ncols; j--; ) setcolor(scan[j], rmx_lval(rm,i,j,0), rmx_lval(rm,i,j,1), rmx_lval(rm,i,j,2) ); if (fwritescan(scan, rm->ncols, fp) < 0) { free(scan); return(0); } } free(scan); return(1); }
static void mapimage(void) /* map picture and send to stdout */ { COLOR *scan; comphist(); /* generate adaptation histogram */ check2do(); /* modify what2do flags */ if (what2do&DO_VEIL) compveil(); /* compute veil image */ if (!(what2do&DO_LINEAR)) if (mkbrmap() < 0) /* make tone map */ what2do |= DO_LINEAR; /* failed! -- use linear */ #if ADJ_VEIL else if (what2do&DO_VEIL) adjveil(); /* else adjust veil image */ #endif if (what2do&DO_LINEAR) { if (scalef <= FTINY) { if (what2do&DO_HSENS) scalef = htcontrs(Lb(0.5*(Bldmax+Bldmin))) / htcontrs(Lb(bwavg)); else scalef = Lb(0.5*(Bldmax+Bldmin)) / Lb(bwavg); scalef *= WHTEFFICACY/(inpexp*ldmax); } fputexpos(inpexp*scalef, stdout); /* record exposure */ if (lumf == cielum) scalef /= WHTEFFICACY; } fputformat(COLRFMT, stdout); /* complete header */ putchar('\n'); fputsresolu(&inpres, stdout); /* resolution doesn't change */ /* condition our image */ for (scan = firstscan(); scan != NULL; scan = nextscan()) if (fwritescan(scan, scanlen(&inpres), stdout) < 0) { fprintf(stderr, "%s: scanline write error\n", progname); exit(1); } }