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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: ra_bmp.c,v 2.1 2004/03/26 03:11:50 greg Exp $";
3 #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 /* write scans downward if we can */
104 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 BMPcloseInput(rdr);
111 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 if (gryflag) {
128 hdr = BMPmappedHeader(numscans(&rs),
129 scanlen(&rs), 0, 256);
130 if (outfile != NULL)
131 hdr->compr = BI_RLE8;
132 } else
133 hdr = BMPtruecolorHeader(numscans(&rs),
134 scanlen(&rs), 0);
135 if (hdr == NULL)
136 quiterr("cannot initialize BMP header");
137 /* set up output direction */
138 hdr->yIsDown = (rs.rt & YDECR) &&
139 (outfile == NULL | hdr->compr == BI_RLE8);
140 /* open BMP output */
141 if (outfile != NULL)
142 wtr = BMPopenOutputFile(outfile, hdr);
143 else
144 wtr = BMPopenOutputStream(stdout, hdr);
145 if (wtr == NULL)
146 quiterr("cannot allocate writer structure");
147 /* 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 BMPcloseOutput(wtr);
153 }
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 return(1); /* gratis return */
161 }
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 }