ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_bmp.c
Revision: 2.8
Committed: Tue Jul 20 03:08:42 2004 UTC (19 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +3 -9 lines
Log Message:
Eliminated unnecessary file chaecking in tmap2bmp()

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.8 static const char RCSid[] = "$Id: ra_bmp.c,v 2.7 2004/04/30 21:16:58 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * program to convert between RADIANCE and Windows BMP file
6     */
7    
8     #include <stdio.h>
9 schorsch 2.3 #include <string.h>
10    
11 greg 2.1 #include "platform.h"
12     #include "color.h"
13 greg 2.4 #include "tonemap.h"
14 greg 2.1 #include "resolu.h"
15     #include "bmpfile.h"
16    
17     int bradj = 0; /* brightness adjustment */
18    
19     double gamcor = 2.2; /* gamma correction value */
20    
21     char *progname;
22    
23 greg 2.4 static void quiterr(const char *err);
24     static void tmap2bmp(char *fnin, char *fnout, char *expec,
25     RGBPRIMP monpri, double gamval);
26 schorsch 2.3 static void rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, int gry);
27     static void bmp2rad(BMPReader *brd, FILE *rfp, int inv);
28 greg 2.1
29    
30     int
31     main(int argc, char *argv[])
32     {
33 greg 2.4 char *inpfile=NULL, *outfile=NULL;
34     char *expec = NULL;
35     int reverse = 0;
36     RGBPRIMP rgbp = stdprims;
37     RGBPRIMS myprims;
38     RESOLU rs;
39     int i;
40 greg 2.1
41     progname = argv[0];
42    
43     for (i = 1; i < argc; i++)
44 greg 2.6 if (argv[i][0] == '-' && argv[i][1])
45 greg 2.1 switch (argv[i][1]) {
46     case 'b':
47 greg 2.4 rgbp = NULL;
48 greg 2.1 break;
49     case 'g':
50     gamcor = atof(argv[++i]);
51     break;
52     case 'e':
53     if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
54 greg 2.4 expec = argv[++i];
55     else
56     bradj = atoi(argv[++i]);
57     break;
58     case 'p':
59     if (argc-i < 9)
60 greg 2.1 goto userr;
61 greg 2.4 myprims[RED][CIEX] = atof(argv[++i]);
62     myprims[RED][CIEY] = atof(argv[++i]);
63     myprims[GRN][CIEX] = atof(argv[++i]);
64     myprims[GRN][CIEY] = atof(argv[++i]);
65     myprims[BLU][CIEX] = atof(argv[++i]);
66     myprims[BLU][CIEY] = atof(argv[++i]);
67     myprims[WHT][CIEX] = atof(argv[++i]);
68     myprims[WHT][CIEY] = atof(argv[++i]);
69     if (rgbp == stdprims)
70     rgbp = myprims;
71 greg 2.1 break;
72     case 'r':
73     reverse = !reverse;
74     break;
75     default:
76     goto userr;
77     }
78     else
79     break;
80    
81     if (i < argc-2)
82     goto userr;
83    
84     SET_FILE_BINARY(stdin);
85     SET_FILE_BINARY(stdout);
86     SET_DEFAULT_BINARY();
87    
88     if (i <= argc-1 && strcmp(argv[i], "-"))
89     inpfile = argv[i];
90    
91     if (i == argc-2 && strcmp(argv[i+1], "-"))
92     outfile = argv[i+1];
93 greg 2.4 /* check for tone-mapping */
94     if (expec != NULL) {
95     if (reverse)
96     goto userr;
97     tmap2bmp(inpfile, outfile, expec, rgbp, gamcor);
98     return(0);
99     }
100 greg 2.1
101     setcolrgam(gamcor); /* set up conversion */
102    
103     if (reverse) {
104     BMPReader *rdr;
105     /* open BMP file or stream */
106     if (inpfile != NULL)
107     rdr = BMPopenInputFile(inpfile);
108     else
109     rdr = BMPopenInputStream(stdin);
110    
111     if (rdr == NULL) {
112     fprintf(stderr, "%s: cannot open or recognize BMP\n",
113     inpfile != NULL ? inpfile : "<stdin>");
114     exit(1);
115     }
116     /* open Radiance output */
117     if (outfile != NULL && freopen(outfile, "w", stdout) == NULL) {
118     fprintf(stderr, "%s: cannot open for output\n",
119     outfile);
120     exit(1);
121     }
122     /* put Radiance header */
123     newheader("RADIANCE", stdout);
124     printargs(i, argv, stdout);
125     fputformat(COLRFMT, stdout);
126     putchar('\n');
127     rs.xr = rdr->hdr->width;
128     rs.yr = rdr->hdr->height;
129     rs.rt = YMAJOR;
130 greg 2.2 /* write scans downward if we can */
131 greg 2.1 if (rdr->hdr->yIsDown || inpfile != NULL)
132     rs.rt |= YDECR;
133     fputsresolu(&rs, stdout);
134     /* convert file */
135     bmp2rad(rdr, stdout, !rdr->hdr->yIsDown && inpfile!=NULL);
136     /* flush output */
137 greg 2.2 BMPcloseInput(rdr);
138 greg 2.1 if (fflush(stdout) < 0)
139     quiterr("error writing Radiance output");
140     } else {
141     BMPHeader *hdr;
142     BMPWriter *wtr;
143     /* open Radiance input */
144     if (inpfile != NULL && freopen(inpfile, "r", stdin) == NULL) {
145     fprintf(stderr, "%s: cannot open input file\n",
146     inpfile);
147     exit(1);
148     }
149     /* get header info. */
150     if (checkheader(stdin, COLRFMT, NULL) < 0 ||
151     !fgetsresolu(&rs, stdin))
152     quiterr("bad Radiance picture format");
153     /* initialize BMP header */
154 greg 2.4 if (rgbp == NULL) {
155     hdr = BMPmappedHeader(scanlen(&rs),
156     numscans(&rs), 0, 256);
157 greg 2.2 if (outfile != NULL)
158     hdr->compr = BI_RLE8;
159     } else
160 greg 2.4 hdr = BMPtruecolorHeader(scanlen(&rs),
161     numscans(&rs), 0);
162 greg 2.1 if (hdr == NULL)
163     quiterr("cannot initialize BMP header");
164 greg 2.2 /* set up output direction */
165 greg 2.7 hdr->yIsDown = ((outfile == NULL) | (hdr->compr == BI_RLE8));
166 greg 2.1 /* open BMP output */
167     if (outfile != NULL)
168     wtr = BMPopenOutputFile(outfile, hdr);
169     else
170     wtr = BMPopenOutputStream(stdout, hdr);
171 greg 2.2 if (wtr == NULL)
172     quiterr("cannot allocate writer structure");
173 greg 2.1 /* convert file */
174 greg 2.7 rad2bmp(stdin, wtr, !hdr->yIsDown, rgbp==NULL);
175 greg 2.1 /* flush output */
176     if (fflush((FILE *)wtr->c_data) < 0)
177     quiterr("error writing BMP output");
178 greg 2.2 BMPcloseOutput(wtr);
179 greg 2.1 }
180 greg 2.4 return(0); /* success */
181 greg 2.1 userr:
182     fprintf(stderr,
183 greg 2.4 "Usage: %s [-b][-g gamma][-e spec][-p xr yr xg yg xb yb xw yw] [input|- [output]]\n",
184 greg 2.1 progname);
185 greg 2.4 fprintf(stderr,
186     " or: %s -r [-g gamma][-e +/-stops] [input|- [output]]\n",
187     progname);
188     return(1);
189 greg 2.1 }
190    
191     /* print message and exit */
192 schorsch 2.3 static void
193 greg 2.1 quiterr(const char *err)
194     {
195     if (err != NULL) {
196     fprintf(stderr, "%s: %s\n", progname, err);
197     exit(1);
198     }
199     exit(0);
200     }
201    
202     /* convert Radiance picture to BMP */
203 schorsch 2.3 static void
204 greg 2.1 rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, int gry)
205     {
206     COLR *scanin;
207     int y, yend, ystp;
208     int x;
209     /* allocate scanline */
210     scanin = (COLR *)malloc(bwr->hdr->width*sizeof(COLR));
211     if (scanin == NULL)
212     quiterr("out of memory in rad2bmp");
213     /* convert image */
214     if (inv) {
215     y = bwr->hdr->height - 1;
216     ystp = -1; yend = -1;
217     } else {
218     y = 0;
219     ystp = 1; yend = bwr->hdr->height;
220     }
221     /* convert each scanline */
222     for ( ; y != yend; y += ystp) {
223     if (freadcolrs(scanin, bwr->hdr->width, rfp) < 0)
224     quiterr("error reading Radiance picture");
225     if (bradj)
226     shiftcolrs(scanin, bwr->hdr->width, bradj);
227     for (x = gry ? bwr->hdr->width : 0; x--; )
228     scanin[x][GRN] = normbright(scanin[x]);
229     colrs_gambs(scanin, bwr->hdr->width);
230     if (gry)
231     for (x = bwr->hdr->width; x--; )
232     bwr->scanline[x] = scanin[x][GRN];
233     else
234     for (x = bwr->hdr->width; x--; ) {
235     bwr->scanline[3*x] = scanin[x][BLU];
236     bwr->scanline[3*x+1] = scanin[x][GRN];
237     bwr->scanline[3*x+2] = scanin[x][RED];
238     }
239     bwr->yscan = y;
240     x = BMPwriteScanline(bwr);
241     if (x != BIR_OK)
242     quiterr(BMPerrorMessage(x));
243     }
244     /* free scanline */
245     free((void *)scanin);
246     }
247    
248     /* convert BMP file to Radiance */
249 schorsch 2.3 static void
250 greg 2.1 bmp2rad(BMPReader *brd, FILE *rfp, int inv)
251     {
252     COLR *scanout;
253     int y, yend, ystp;
254     int x;
255     /* allocate scanline */
256     scanout = (COLR *)malloc(brd->hdr->width*sizeof(COLR));
257     if (scanout == NULL)
258     quiterr("out of memory in bmp2rad");
259     /* convert image */
260     if (inv) {
261     y = brd->hdr->height - 1;
262     ystp = -1; yend = -1;
263     } else {
264     y = 0;
265     ystp = 1; yend = brd->hdr->height;
266     }
267     /* convert each scanline */
268     for ( ; y != yend; y += ystp) {
269     x = BMPseekScanline(y, brd);
270     if (x != BIR_OK)
271     quiterr(BMPerrorMessage(x));
272     for (x = brd->hdr->width; x--; ) {
273     RGBquad rgbq = BMPdecodePixel(x, brd);
274     scanout[x][RED] = rgbq.r;
275     scanout[x][GRN] = rgbq.g;
276     scanout[x][BLU] = rgbq.b;
277     }
278     gambs_colrs(scanout, brd->hdr->width);
279     if (bradj)
280     shiftcolrs(scanout, brd->hdr->width, bradj);
281     if (fwritecolrs(scanout, brd->hdr->width, rfp) < 0)
282     quiterr("error writing Radiance picture");
283     }
284     /* clean up */
285     free((void *)scanout);
286     }
287 greg 2.4
288     /* Tone-map and convert Radiance picture */
289     static void
290     tmap2bmp(char *fnin, char *fnout, char *expec, RGBPRIMP monpri, double gamval)
291     {
292     int tmflags;
293     BMPHeader *hdr;
294     BMPWriter *wtr;
295     FILE *fp;
296     int xr, yr;
297     BYTE *pa;
298     int i;
299     /* check tone-mapping spec */
300     i = strlen(expec);
301     if (i && !strncmp(expec, "auto", i))
302     tmflags = TM_F_CAMERA;
303     else if (i && !strncmp(expec, "human", i))
304     tmflags = TM_F_HUMAN & ~TM_F_UNIMPL;
305     else if (i && !strncmp(expec, "linear", i))
306     tmflags = TM_F_LINEAR;
307     else
308     quiterr("illegal exposure specification (auto|human|linear)");
309     if (monpri == NULL) {
310     tmflags |= TM_F_BW;
311     monpri = stdprims;
312     }
313     /* open Radiance input */
314     if (fnin == NULL)
315     fp = stdin;
316     else if ((fp = fopen(fnin, "r")) == NULL) {
317     fprintf(stderr, "%s: cannot open\n", fnin);
318     exit(1);
319     }
320     /* tone-map picture */
321     if (tmMapPicture(&pa, &xr, &yr, tmflags, monpri, gamval,
322     0., 0., fnin, fp) != TM_E_OK)
323     exit(1);
324     /* initialize BMP header */
325     if (tmflags & TM_F_BW) {
326     hdr = BMPmappedHeader(xr, yr, 0, 256);
327 greg 2.5 if (fnout != NULL)
328     hdr->compr = BI_RLE8;
329 greg 2.4 } else
330     hdr = BMPtruecolorHeader(xr, yr, 0);
331     if (hdr == NULL)
332     quiterr("cannot initialize BMP header");
333     /* open BMP output */
334     if (fnout != NULL)
335     wtr = BMPopenOutputFile(fnout, hdr);
336     else
337     wtr = BMPopenOutputStream(stdout, hdr);
338     if (wtr == NULL)
339     quiterr("cannot allocate writer structure");
340     /* write to BMP file */
341     while (wtr->yscan < yr) {
342     BYTE *scn = pa + xr*((tmflags & TM_F_BW) ? 1 : 3)*
343 greg 2.7 (yr-1 - wtr->yscan);
344 greg 2.4 if (tmflags & TM_F_BW)
345     memcpy((void *)wtr->scanline, (void *)scn, xr);
346     else
347     for (i = xr; i--; ) {
348     wtr->scanline[3*i] = scn[3*i+BLU];
349     wtr->scanline[3*i+1] = scn[3*i+GRN];
350     wtr->scanline[3*i+2] = scn[3*i+RED];
351     }
352     if ((i = BMPwriteScanline(wtr)) != BIR_OK)
353     quiterr(BMPerrorMessage(i));
354     }
355     /* flush output */
356     if (fflush((FILE *)wtr->c_data) < 0)
357     quiterr("error writing BMP output");
358     /* clean up */
359 greg 2.8 if (fnin != NULL)
360     fclose(fp);
361 greg 2.4 free((void *)pa);
362     BMPcloseOutput(wtr);
363     }