ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_bmp.c
Revision: 2.3
Committed: Sun Mar 28 20:33:14 2004 UTC (20 years, 1 month ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.2: +10 -8 lines
Log Message:
Continued ANSIfication, and other fixes and clarifications.

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 schorsch 2.3 static const char RCSid[] = "$Id: ra_bmp.c,v 2.2 2004/03/27 05:43:37 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     #include "resolu.h"
14     #include "bmpfile.h"
15    
16     int bradj = 0; /* brightness adjustment */
17    
18     double gamcor = 2.2; /* gamma correction value */
19    
20     char *progname;
21    
22 schorsch 2.3 static void quiterr(const char *);
23     static void rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, int gry);
24     static void bmp2rad(BMPReader *brd, FILE *rfp, int inv);
25 greg 2.1
26    
27     int
28     main(int argc, char *argv[])
29     {
30     char *inpfile=NULL, *outfile=NULL;
31     int gryflag = 0;
32     int reverse = 0;
33     RESOLU rs;
34     int i;
35    
36     progname = argv[0];
37    
38     for (i = 1; i < argc; i++)
39     if (argv[i][0] == '-')
40     switch (argv[i][1]) {
41     case 'b':
42     gryflag = 1;
43     break;
44     case 'g':
45     gamcor = atof(argv[++i]);
46     break;
47     case 'e':
48     if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
49     goto userr;
50     bradj = atoi(argv[++i]);
51     break;
52     case 'r':
53     reverse = !reverse;
54     break;
55     case '\0':
56     break;
57     default:
58     goto userr;
59     }
60     else
61     break;
62    
63     if (i < argc-2)
64     goto userr;
65    
66     SET_FILE_BINARY(stdin);
67     SET_FILE_BINARY(stdout);
68     SET_DEFAULT_BINARY();
69    
70     if (i <= argc-1 && strcmp(argv[i], "-"))
71     inpfile = argv[i];
72    
73     if (i == argc-2 && strcmp(argv[i+1], "-"))
74     outfile = argv[i+1];
75    
76     setcolrgam(gamcor); /* set up conversion */
77    
78     if (reverse) {
79     BMPReader *rdr;
80     /* open BMP file or stream */
81     if (inpfile != NULL)
82     rdr = BMPopenInputFile(inpfile);
83     else
84     rdr = BMPopenInputStream(stdin);
85    
86     if (rdr == NULL) {
87     fprintf(stderr, "%s: cannot open or recognize BMP\n",
88     inpfile != NULL ? inpfile : "<stdin>");
89     exit(1);
90     }
91     /* open Radiance output */
92     if (outfile != NULL && freopen(outfile, "w", stdout) == NULL) {
93     fprintf(stderr, "%s: cannot open for output\n",
94     outfile);
95     exit(1);
96     }
97     /* put Radiance header */
98     newheader("RADIANCE", stdout);
99     printargs(i, argv, stdout);
100     fputformat(COLRFMT, stdout);
101     putchar('\n');
102     rs.xr = rdr->hdr->width;
103     rs.yr = rdr->hdr->height;
104     rs.rt = YMAJOR;
105 greg 2.2 /* write scans downward if we can */
106 greg 2.1 if (rdr->hdr->yIsDown || inpfile != NULL)
107     rs.rt |= YDECR;
108     fputsresolu(&rs, stdout);
109     /* convert file */
110     bmp2rad(rdr, stdout, !rdr->hdr->yIsDown && inpfile!=NULL);
111     /* flush output */
112 greg 2.2 BMPcloseInput(rdr);
113 greg 2.1 if (fflush(stdout) < 0)
114     quiterr("error writing Radiance output");
115     } else {
116     BMPHeader *hdr;
117     BMPWriter *wtr;
118     /* open Radiance input */
119     if (inpfile != NULL && freopen(inpfile, "r", stdin) == NULL) {
120     fprintf(stderr, "%s: cannot open input file\n",
121     inpfile);
122     exit(1);
123     }
124     /* get header info. */
125     if (checkheader(stdin, COLRFMT, NULL) < 0 ||
126     !fgetsresolu(&rs, stdin))
127     quiterr("bad Radiance picture format");
128     /* initialize BMP header */
129 greg 2.2 if (gryflag) {
130 greg 2.1 hdr = BMPmappedHeader(numscans(&rs),
131     scanlen(&rs), 0, 256);
132 greg 2.2 if (outfile != NULL)
133     hdr->compr = BI_RLE8;
134     } else
135 greg 2.1 hdr = BMPtruecolorHeader(numscans(&rs),
136     scanlen(&rs), 0);
137     if (hdr == NULL)
138     quiterr("cannot initialize BMP header");
139 greg 2.2 /* set up output direction */
140     hdr->yIsDown = (rs.rt & YDECR) &&
141 schorsch 2.3 ((outfile == NULL) | (hdr->compr == BI_RLE8));
142 greg 2.1 /* open BMP output */
143     if (outfile != NULL)
144     wtr = BMPopenOutputFile(outfile, hdr);
145     else
146     wtr = BMPopenOutputStream(stdout, hdr);
147 greg 2.2 if (wtr == NULL)
148     quiterr("cannot allocate writer structure");
149 greg 2.1 /* convert file */
150     rad2bmp(stdin, wtr, !hdr->yIsDown && (rs.rt&YDECR), gryflag);
151     /* flush output */
152     if (fflush((FILE *)wtr->c_data) < 0)
153     quiterr("error writing BMP output");
154 greg 2.2 BMPcloseOutput(wtr);
155 greg 2.1 }
156     exit(0); /* success */
157     userr:
158     fprintf(stderr,
159     "Usage: %s [-r][-g gamma][-e +/-stops] [input [output]]\n",
160     progname);
161     exit(1);
162 greg 2.2 return(1); /* gratis return */
163 greg 2.1 }
164    
165     /* print message and exit */
166 schorsch 2.3 static void
167 greg 2.1 quiterr(const char *err)
168     {
169     if (err != NULL) {
170     fprintf(stderr, "%s: %s\n", progname, err);
171     exit(1);
172     }
173     exit(0);
174     }
175    
176     /* convert Radiance picture to BMP */
177 schorsch 2.3 static void
178 greg 2.1 rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, int gry)
179     {
180     COLR *scanin;
181     int y, yend, ystp;
182     int x;
183     /* allocate scanline */
184     scanin = (COLR *)malloc(bwr->hdr->width*sizeof(COLR));
185     if (scanin == NULL)
186     quiterr("out of memory in rad2bmp");
187     /* convert image */
188     if (inv) {
189     y = bwr->hdr->height - 1;
190     ystp = -1; yend = -1;
191     } else {
192     y = 0;
193     ystp = 1; yend = bwr->hdr->height;
194     }
195     /* convert each scanline */
196     for ( ; y != yend; y += ystp) {
197     if (freadcolrs(scanin, bwr->hdr->width, rfp) < 0)
198     quiterr("error reading Radiance picture");
199     if (bradj)
200     shiftcolrs(scanin, bwr->hdr->width, bradj);
201     for (x = gry ? bwr->hdr->width : 0; x--; )
202     scanin[x][GRN] = normbright(scanin[x]);
203     colrs_gambs(scanin, bwr->hdr->width);
204     if (gry)
205     for (x = bwr->hdr->width; x--; )
206     bwr->scanline[x] = scanin[x][GRN];
207     else
208     for (x = bwr->hdr->width; x--; ) {
209     bwr->scanline[3*x] = scanin[x][BLU];
210     bwr->scanline[3*x+1] = scanin[x][GRN];
211     bwr->scanline[3*x+2] = scanin[x][RED];
212     }
213     bwr->yscan = y;
214     x = BMPwriteScanline(bwr);
215     if (x != BIR_OK)
216     quiterr(BMPerrorMessage(x));
217     }
218     /* free scanline */
219     free((void *)scanin);
220     }
221    
222     /* convert BMP file to Radiance */
223 schorsch 2.3 static void
224 greg 2.1 bmp2rad(BMPReader *brd, FILE *rfp, int inv)
225     {
226     COLR *scanout;
227     int y, yend, ystp;
228     int x;
229     /* allocate scanline */
230     scanout = (COLR *)malloc(brd->hdr->width*sizeof(COLR));
231     if (scanout == NULL)
232     quiterr("out of memory in bmp2rad");
233     /* convert image */
234     if (inv) {
235     y = brd->hdr->height - 1;
236     ystp = -1; yend = -1;
237     } else {
238     y = 0;
239     ystp = 1; yend = brd->hdr->height;
240     }
241     /* convert each scanline */
242     for ( ; y != yend; y += ystp) {
243     x = BMPseekScanline(y, brd);
244     if (x != BIR_OK)
245     quiterr(BMPerrorMessage(x));
246     for (x = brd->hdr->width; x--; ) {
247     RGBquad rgbq = BMPdecodePixel(x, brd);
248     scanout[x][RED] = rgbq.r;
249     scanout[x][GRN] = rgbq.g;
250     scanout[x][BLU] = rgbq.b;
251     }
252     gambs_colrs(scanout, brd->hdr->width);
253     if (bradj)
254     shiftcolrs(scanout, brd->hdr->width, bradj);
255     if (fwritecolrs(scanout, brd->hdr->width, rfp) < 0)
256     quiterr("error writing Radiance picture");
257     }
258     /* clean up */
259     free((void *)scanout);
260     }