ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_bmp.c
(Generate patch)

Comparing ray/src/px/ra_bmp.c (file contents):
Revision 2.3 by schorsch, Sun Mar 28 20:33:14 2004 UTC vs.
Revision 2.14 by greg, Sun Apr 5 19:10:51 2020 UTC

# Line 5 | Line 5 | static const char RCSid[] = "$Id$";
5   *  program to convert between RADIANCE and Windows BMP file
6   */
7  
8 < #include  <stdio.h>
9 < #include  <string.h>
8 > #include  <math.h>
9  
10 + #include  "rtio.h"
11   #include  "platform.h"
12   #include  "color.h"
13 + #include  "tonemap.h"
14   #include  "resolu.h"
15   #include  "bmpfile.h"
16  
17 < int  bradj = 0;                         /* brightness adjustment */
17 > int             bradj = 0;              /* brightness adjustment */
18  
19 < double  gamcor = 2.2;                   /* gamma correction value */
19 > double          gamcor = 2.2;           /* gamma correction value */
20  
21 < char  *progname;
21 > char            *progname;
22  
23 < static void quiterr(const char *);
24 < static void rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, int gry);
23 > static void quiterr(const char *err);
24 > static void tmap2bmp(char *fnin, char *fnout, char *expec,
25 >                                RGBPRIMP monpri, double gamval);
26 > static void rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, RGBPRIMP monpri);
27   static void bmp2rad(BMPReader *brd, FILE *rfp, int inv);
28  
29 + static RGBPRIMP rgbinp = stdprims;      /* RGB input primitives */
30 + static RGBPRIMS myinprims;              /* custom primitives holder */
31  
32 + static gethfunc headline;
33 +
34 +
35   int
36   main(int argc, char *argv[])
37   {
38 <        char    *inpfile=NULL, *outfile=NULL;
39 <        int     gryflag = 0;
40 <        int     reverse = 0;
41 <        RESOLU  rs;
42 <        int     i;
38 >        char            *inpfile=NULL, *outfile=NULL;
39 >        char            *expec = NULL;
40 >        int             reverse = 0;
41 >        RGBPRIMP        rgbp = stdprims;
42 >        RGBPRIMS        myprims;
43 >        RESOLU          rs;
44 >        int             i;
45          
46          progname = argv[0];
47  
48          for (i = 1; i < argc; i++)
49 <                if (argv[i][0] == '-')
49 >                if (argv[i][0] == '-' && argv[i][1])
50                          switch (argv[i][1]) {
51                          case 'b':
52 <                                gryflag = 1;
52 >                                rgbp = NULL;
53                                  break;
54                          case 'g':
55                                  gamcor = atof(argv[++i]);
56                                  break;
57                          case 'e':
58                                  if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
59 +                                        expec = argv[++i];
60 +                                else
61 +                                        bradj = atoi(argv[++i]);
62 +                                break;
63 +                        case 'p':
64 +                                if (argc-i < 9)
65                                          goto userr;
66 <                                bradj = atoi(argv[++i]);
66 >                                myprims[RED][CIEX] = atof(argv[++i]);
67 >                                myprims[RED][CIEY] = atof(argv[++i]);
68 >                                myprims[GRN][CIEX] = atof(argv[++i]);
69 >                                myprims[GRN][CIEY] = atof(argv[++i]);
70 >                                myprims[BLU][CIEX] = atof(argv[++i]);
71 >                                myprims[BLU][CIEY] = atof(argv[++i]);
72 >                                myprims[WHT][CIEX] = atof(argv[++i]);
73 >                                myprims[WHT][CIEY] = atof(argv[++i]);
74 >                                if (rgbp == stdprims)
75 >                                        rgbp = myprims;
76                                  break;
77                          case 'r':
78                                  reverse = !reverse;
79                                  break;
55                        case '\0':
56                                break;
80                          default:
81                                  goto userr;
82                          }
# Line 72 | Line 95 | main(int argc, char *argv[])
95  
96          if (i == argc-2 && strcmp(argv[i+1], "-"))
97                  outfile = argv[i+1];
98 +                                        /* check for tone-mapping */
99 +        if (expec != NULL) {
100 +                if (reverse)
101 +                        goto userr;
102 +                tmap2bmp(inpfile, outfile, expec, rgbp, gamcor);
103 +                return(0);
104 +        }
105  
106          setcolrgam(gamcor);             /* set up conversion */
107  
# Line 122 | Line 152 | main(int argc, char *argv[])
152                          exit(1);
153                  }
154                                          /* get header info. */
155 <                if (checkheader(stdin, COLRFMT, NULL) < 0 ||
155 >                if (getheader(stdin, headline, NULL) < 0 ||
156                                  !fgetsresolu(&rs, stdin))
157                          quiterr("bad Radiance picture format");
158                                          /* initialize BMP header */
159 <                if (gryflag) {
160 <                        hdr = BMPmappedHeader(numscans(&rs),
161 <                                                scanlen(&rs), 0, 256);
159 >                if (rgbp == NULL) {
160 >                        hdr = BMPmappedHeader(scanlen(&rs),
161 >                                                numscans(&rs), 0, 256);
162 >                        /*
163                          if (outfile != NULL)
164                                  hdr->compr = BI_RLE8;
165 +                        */
166                  } else
167 <                        hdr = BMPtruecolorHeader(numscans(&rs),
168 <                                                scanlen(&rs), 0);
167 >                        hdr = BMPtruecolorHeader(scanlen(&rs),
168 >                                                numscans(&rs), 0);
169                  if (hdr == NULL)
170                          quiterr("cannot initialize BMP header");
171                                          /* set up output direction */
172 <                hdr->yIsDown = (rs.rt & YDECR) &&
141 <                                ((outfile == NULL) | (hdr->compr == BI_RLE8));
172 >                hdr->yIsDown = ((outfile == NULL) | (hdr->compr == BI_RLE8));
173                                          /* open BMP output */
174                  if (outfile != NULL)
175                          wtr = BMPopenOutputFile(outfile, hdr);
# Line 147 | Line 178 | main(int argc, char *argv[])
178                  if (wtr == NULL)
179                          quiterr("cannot allocate writer structure");
180                                          /* convert file */
181 <                rad2bmp(stdin, wtr, !hdr->yIsDown && (rs.rt&YDECR), gryflag);
181 >                rad2bmp(stdin, wtr, !hdr->yIsDown, rgbp);
182                                          /* flush output */
183                  if (fflush((FILE *)wtr->c_data) < 0)
184                          quiterr("error writing BMP output");
185                  BMPcloseOutput(wtr);
186          }
187 <        exit(0);                        /* success */
187 >        return(0);                      /* success */
188   userr:
189          fprintf(stderr,
190 <                "Usage: %s [-r][-g gamma][-e +/-stops] [input [output]]\n",
190 > "Usage: %s [-b][-g gamma][-e spec][-p xr yr xg yg xb yb xw yw] [input|- [output]]\n",
191                          progname);
192 <        exit(1);
193 <        return(1);      /* gratis return */
192 >        fprintf(stderr,
193 >                "   or: %s -r [-g gamma][-e +/-stops] [input|- [output]]\n",
194 >                        progname);
195 >        return(1);
196   }
197  
198   /* print message and exit */
# Line 173 | Line 206 | quiterr(const char *err)
206          exit(0);
207   }
208  
209 + /* process header line (don't echo) */
210 + static int
211 + headline(char *s, void *p)
212 + {
213 +        char    fmt[MAXFMTLEN];
214 +
215 +        if (formatval(fmt, s)) {        /* check if format string */
216 +                if (!strcmp(fmt,COLRFMT))
217 +                        return(0);
218 +                if (!strcmp(fmt,CIEFMT)) {
219 +                        rgbinp = TM_XYZPRIM;
220 +                        return(0);
221 +                }
222 +                return(-1);
223 +        }
224 +        if (isprims(s)) {               /* get input primaries */
225 +                primsval(myinprims, s);
226 +                rgbinp = myinprims;
227 +                return(0);
228 +        }
229 +                                        /* should I grok colcorr also? */
230 +        return(0);
231 + }
232 +
233 +
234   /* convert Radiance picture to BMP */
235   static void
236 < rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, int gry)
236 > rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, RGBPRIMP monpri)
237   {
238 +        int     usexfm = 0;
239 +        COLORMAT        xfm;
240          COLR    *scanin;
241 +        COLOR   cval;
242          int     y, yend, ystp;
243          int     x;
244                                                  /* allocate scanline */
245          scanin = (COLR *)malloc(bwr->hdr->width*sizeof(COLR));
246          if (scanin == NULL)
247                  quiterr("out of memory in rad2bmp");
248 +                                                /* set up color conversion */
249 +        usexfm = (monpri != NULL ? rgbinp != monpri :
250 +                        rgbinp != TM_XYZPRIM && rgbinp != stdprims);
251 +        if (usexfm) {
252 +                RGBPRIMP        destpri = monpri != NULL ? monpri : stdprims;
253 +                double          expcomp = pow(2.0, (double)bradj);
254 +                if (rgbinp == TM_XYZPRIM)
255 +                        compxyz2rgbWBmat(xfm, destpri);
256 +                else
257 +                        comprgb2rgbWBmat(xfm, rgbinp, destpri);
258 +                for (y = 0; y < 3; y++)
259 +                        for (x = 0; x < 3; x++)
260 +                                xfm[y][x] *= expcomp;
261 +        }
262                                                  /* convert image */
263          if (inv) {
264                  y = bwr->hdr->height - 1;
# Line 196 | Line 271 | rad2bmp(FILE *rfp, BMPWriter *bwr, int inv, int gry)
271          for ( ; y != yend; y += ystp) {
272                  if (freadcolrs(scanin, bwr->hdr->width, rfp) < 0)
273                          quiterr("error reading Radiance picture");
274 <                if (bradj)
274 >                if (usexfm)
275 >                        for (x = bwr->hdr->width; x--; ) {
276 >                                colr_color(cval, scanin[x]);
277 >                                colortrans(cval, xfm, cval);
278 >                                setcolr(scanin[x], colval(cval,RED),
279 >                                                colval(cval,GRN),
280 >                                                colval(cval,BLU));
281 >                        }
282 >                else if (bradj)
283                          shiftcolrs(scanin, bwr->hdr->width, bradj);
284 <                for (x = gry ? bwr->hdr->width : 0; x--; )
285 <                        scanin[x][GRN] = normbright(scanin[x]);
284 >                if (monpri == NULL && rgbinp != TM_XYZPRIM)
285 >                        for (x = bwr->hdr->width; x--; )
286 >                                scanin[x][GRN] = normbright(scanin[x]);
287                  colrs_gambs(scanin, bwr->hdr->width);
288 <                if (gry)
288 >                if (monpri == NULL)
289                          for (x = bwr->hdr->width; x--; )
290                                  bwr->scanline[x] = scanin[x][GRN];
291                  else
# Line 257 | Line 341 | bmp2rad(BMPReader *brd, FILE *rfp, int inv)
341          }
342                                                  /* clean up */
343          free((void *)scanout);
344 + }
345 +
346 + /* Tone-map and convert Radiance picture */
347 + static void
348 + tmap2bmp(char *fnin, char *fnout, char *expec, RGBPRIMP monpri, double gamval)
349 + {
350 +        int             tmflags;
351 +        BMPHeader       *hdr;
352 +        BMPWriter       *wtr;
353 +        FILE            *fp;
354 +        int             xr, yr;
355 +        uby8            *pa;
356 +        int             i;
357 +                                        /* check tone-mapping spec */
358 +        i = strlen(expec);
359 +        if (i && !strncmp(expec, "auto", i))
360 +                tmflags = TM_F_CAMERA;
361 +        else if (i && !strncmp(expec, "human", i))
362 +                tmflags = TM_F_HUMAN & ~TM_F_UNIMPL;
363 +        else if (i && !strncmp(expec, "linear", i))
364 +                tmflags = TM_F_LINEAR;
365 +        else
366 +                quiterr("illegal exposure specification (auto|human|linear)");
367 +        if (monpri == NULL) {
368 +                tmflags |= TM_F_BW;
369 +                monpri = stdprims;
370 +        }
371 +                                        /* open Radiance input */
372 +        if (fnin == NULL)
373 +                fp = stdin;
374 +        else if ((fp = fopen(fnin, "r")) == NULL) {
375 +                fprintf(stderr, "%s: cannot open\n", fnin);
376 +                exit(1);
377 +        }
378 +                                        /* tone-map picture */
379 +        if (tmMapPicture(&pa, &xr, &yr, tmflags, monpri, gamval,
380 +                        0., 0., fnin, fp) != TM_E_OK)
381 +                exit(1);
382 +                                        /* initialize BMP header */
383 +        if (tmflags & TM_F_BW) {
384 +                hdr = BMPmappedHeader(xr, yr, 0, 256);
385 +                if (fnout != NULL)
386 +                        hdr->compr = BI_RLE8;
387 +        } else
388 +                hdr = BMPtruecolorHeader(xr, yr, 0);
389 +        if (hdr == NULL)
390 +                quiterr("cannot initialize BMP header");
391 +                                        /* open BMP output */
392 +        if (fnout != NULL)
393 +                wtr = BMPopenOutputFile(fnout, hdr);
394 +        else
395 +                wtr = BMPopenOutputStream(stdout, hdr);
396 +        if (wtr == NULL)
397 +                quiterr("cannot allocate writer structure");
398 +                                        /* write to BMP file */
399 +        while (wtr->yscan < yr) {
400 +                uby8    *scn = pa + xr*((tmflags & TM_F_BW) ? 1 : 3)*
401 +                                                (yr-1 - wtr->yscan);
402 +                if (tmflags & TM_F_BW)
403 +                        memcpy((void *)wtr->scanline, (void *)scn, xr);
404 +                else
405 +                        for (i = xr; i--; ) {
406 +                                wtr->scanline[3*i] = scn[3*i+BLU];
407 +                                wtr->scanline[3*i+1] = scn[3*i+GRN];
408 +                                wtr->scanline[3*i+2] = scn[3*i+RED];
409 +                        }
410 +                if ((i = BMPwriteScanline(wtr)) != BIR_OK)
411 +                        quiterr(BMPerrorMessage(i));
412 +        }
413 +                                        /* flush output */
414 +        if (fflush((FILE *)wtr->c_data) < 0)
415 +                quiterr("error writing BMP output");
416 +                                        /* clean up */
417 +        if (fnin != NULL)
418 +                fclose(fp);
419 +        free((void *)pa);
420 +        BMPcloseOutput(wtr);
421   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines