ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_bmp.c
Revision: 2.2
Committed: Sat Mar 27 05:43:37 2004 UTC (20 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +14 -7 lines
Log Message:
Bug fixes in run-length encoding code

File Contents

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