home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1991 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)ra_pr.c 2.4 10/30/92 LBL";
- #endif
-
- /*
- * ra_pr.c - program to convert between RADIANCE and pixrect picture format.
- *
- * 11/10/87
- * 3/1/88 Added Paul Heckbert's color map allocation
- */
-
- #include <stdio.h>
-
- #include <math.h>
-
- #include "rasterfile.h"
-
- #include "color.h"
-
- #include "resolu.h"
-
- #include "pic.h"
-
- /* descriptor for a picture file or frame buffer */
- typedef struct {
- char *name; /* file name */
- FILE *fp; /* file pointer */
- int nexty; /* file positioning */
- int bytes_line; /* 0 == variable length lines */
- union {
- long b; /* initial scanline */
- long *y; /* individual scanline */
- } pos; /* position(s) */
- } pic;
-
- extern pic *openinput(), *openoutput();
-
- extern char *ecalloc(), *emalloc();
-
- extern long ftell();
-
- double gamcor = 2.2; /* gamma correction */
-
- int bradj = 0; /* brightness adjustment */
-
- pic *inpic, *outpic;
-
- char *progname;
-
- char errmsg[128];
-
- COLR *inl;
-
- int xmax, ymax;
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- colormap rasmap;
- struct rasterfile head;
- int dither = 1;
- int reverse = 0;
- int ncolors = 256;
- int greyscale = 0;
- int i;
-
- progname = argv[0];
-
- for (i = 1; i < argc; i++)
- if (argv[i][0] == '-')
- switch (argv[i][1]) {
- case 'd':
- dither = !dither;
- break;
- case 'g':
- gamcor = atof(argv[++i]);
- break;
- case 'b':
- greyscale = !greyscale;
- break;
- case 'e':
- if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
- goto userr;
- bradj = atoi(argv[++i]);
- break;
- case 'r':
- reverse = !reverse;
- break;
- case 'c':
- ncolors = atoi(argv[++i]);
- break;
- default:
- goto userr;
- }
- else
- break;
-
- if (reverse) {
- if (i < argc-2)
- goto userr;
- if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
- sprintf(errmsg, "can't open input \"%s\"", argv[i]);
- quiterr(errmsg);
- }
- if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
- sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
- quiterr(errmsg);
- }
- /* get header */
- if (fread((char *)&head, sizeof(head), 1, stdin) != 1)
- quiterr("missing header");
- if (head.ras_magic != RAS_MAGIC)
- quiterr("bad raster format");
- xmax = head.ras_width;
- ymax = head.ras_height;
- if (head.ras_type != RT_STANDARD ||
- head.ras_maptype != RMT_EQUAL_RGB ||
- head.ras_depth != 8)
- quiterr("incompatible format");
- /* put header */
- printargs(i, argv, stdout);
- fputformat(COLRFMT, stdout);
- putchar('\n');
- fprtresolu(xmax, ymax, stdout);
- /* convert file */
- pr2ra(&head);
- } else {
- if (i < argc-2 || (!greyscale && i > argc-1))
- goto userr;
- if ((inpic = openinput(argv[i], &head)) == NULL) {
- sprintf(errmsg, "can't open input \"%s\"", argv[i]);
- quiterr(errmsg);
- }
- if ((outpic = openoutput(i==argc-2 ? argv[i+1] : (char *)NULL,
- &head)) == NULL) {
- sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
- quiterr(errmsg);
- }
- /* convert file */
- if (greyscale)
- biq(dither,ncolors,1,rasmap);
- else
- ciq(dither,ncolors,1,rasmap);
- }
- quiterr(NULL);
- userr:
- fprintf(stderr,
- "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n",
- progname);
- fprintf(stderr, " Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n",
- progname);
- exit(1);
- }
-
-
- quiterr(err) /* print message and exit */
- char *err;
- {
- if (err != NULL) {
- fprintf(stderr, "%s: %s\n", progname, err);
- exit(1);
- }
- exit(0);
- }
-
-
- eputs(s)
- char *s;
- {
- fputs(s, stderr);
- }
-
-
- quit(code)
- int code;
- {
- exit(code);
- }
-
-
- pic *
- openinput(fname, h) /* open RADIANCE input file */
- char *fname;
- register struct rasterfile *h;
- {
- register pic *p;
-
- p = (pic *)emalloc(sizeof(pic));
- p->name = fname;
- if (fname == NULL)
- p->fp = stdin;
- else if ((p->fp = fopen(fname, "r")) == NULL)
- return(NULL);
- /* check header */
- if (checkheader(p->fp, COLRFMT, NULL) < 0 ||
- fgetresolu(&xmax, &ymax, p->fp) < 0)
- quiterr("bad picture format");
- p->nexty = 0;
- p->bytes_line = 0; /* variable length lines */
- p->pos.y = (long *)ecalloc(ymax, sizeof(long));
- p->pos.y[0] = ftell(p->fp);
- /* assign header */
- h->ras_magic = RAS_MAGIC;
- h->ras_width = xmax + (xmax&1); /* round to 16 bits */
- h->ras_height = ymax;
- h->ras_depth = 8;
- h->ras_type = RT_STANDARD;
- h->ras_length = h->ras_width*h->ras_height;
- h->ras_maptype = RMT_EQUAL_RGB;
- h->ras_maplength = 256*3;
- /* allocate scanline */
- inl = (COLR *)emalloc(xmax*sizeof(COLR));
-
- return(p);
- }
-
-
- pic *
- openoutput(fname, h) /* open output rasterfile */
- char *fname;
- register struct rasterfile *h;
- {
- register pic *p;
-
- p = (pic *)emalloc(sizeof(pic));
- p->name = fname;
- if (fname == NULL)
- p->fp = stdout;
- else if ((p->fp = fopen(fname, "w")) == NULL)
- return(NULL);
- /* write header */
- fwrite((char *)h, sizeof(*h), 1, p->fp);
- p->nexty = -1; /* needs color map */
- p->bytes_line = h->ras_width;
- p->pos.b = 0;
-
- return(p);
- }
-
-
- pr2ra(h) /* pixrect file to RADIANCE file */
- struct rasterfile *h;
- {
- BYTE cmap[3][256];
- COLR ctab[256];
- COLR *scanline;
- register int i, j, c;
-
- scanline = (COLR *)emalloc(xmax*sizeof(COLR));
- /* get color table */
- for (i = 0; i < 3; i ++)
- if (fread((char *)cmap[i], h->ras_maplength/3, 1, stdin) != 1)
- quiterr("error reading color table");
- /* convert table */
- for (i = 0; i < h->ras_maplength/3; i++)
- setcolr(ctab[i],
- pow((cmap[0][i]+.5)/256.,gamcor),
- pow((cmap[1][i]+.5)/256.,gamcor),
- pow((cmap[2][i]+.5)/256.,gamcor));
- if (bradj)
- shiftcolrs(ctab, 256, bradj);
- /* convert file */
- for (i = 0; i < ymax; i++) {
- for (j = 0; j < xmax; j++) {
- if ((c = getc(stdin)) == EOF)
- quiterr("error reading rasterfile");
- copycolr(scanline[j], ctab[c]);
- }
- if (xmax & 1) /* extra byte */
- getc(stdin);
- if (fwritecolrs(scanline, xmax, stdout) < 0)
- quiterr("error writing RADIANCE file");
- }
- free((char *)scanline);
- }
-
-
- picreadline3(y, l3) /* read in 3-byte scanline */
- int y;
- register rgbpixel *l3;
- {
- register int i;
-
- if (inpic->nexty != y) { /* find scanline */
- if (inpic->bytes_line == 0) {
- if (inpic->pos.y[y] == 0) {
- while (inpic->nexty < y) {
- if (freadcolrs(inl, xmax, inpic->fp) < 0)
- quiterr("read error in picreadline3");
- inpic->pos.y[++inpic->nexty] = ftell(inpic->fp);
- }
- } else if (fseek(inpic->fp, inpic->pos.y[y], 0) == EOF)
- quiterr("seek error in picreadline3");
- } else if (fseek(inpic->fp, y*inpic->bytes_line+inpic->pos.b, 0) == EOF)
- quiterr("seek error in picreadline3");
- } else if (inpic->bytes_line == 0 && inpic->pos.y[inpic->nexty] == 0)
- inpic->pos.y[inpic->nexty] = ftell(inpic->fp);
- if (freadcolrs(inl, xmax, inpic->fp) < 0) /* read scanline */
- quiterr("read error in picreadline3");
- inpic->nexty = y+1;
- /* convert scanline */
- normcolrs(inl, xmax, bradj);
- for (i = 0; i < xmax; i++) {
- l3[i].r = inl[i][RED];
- l3[i].g = inl[i][GRN];
- l3[i].b = inl[i][BLU];
- }
- }
-
-
- picwriteline(y, l) /* write out scanline */
- int y;
- register pixel *l;
- {
- if (outpic->nexty != y) { /* seek to scanline */
- if (outpic->bytes_line == 0) {
- if (outpic->pos.y[y] == 0)
- quiterr("cannot seek in picwriteline");
- else if (fseek(outpic->fp, outpic->pos.y[y], 0) == EOF)
- quiterr("seek error in picwriteline");
- } else if (fseek(outpic->fp, y*outpic->bytes_line+outpic->pos.b, 0) == EOF)
- quiterr("seek error in picwriteline");
- }
- /* write scanline */
- if (fwrite((char *)l, sizeof(pixel), xmax, outpic->fp) != xmax)
- quiterr("write error in picwriteline");
- if (xmax&1) /* on 16-bit boundary */
- putc(l[xmax-1], outpic->fp);
- outpic->nexty = y+1;
- if (outpic->bytes_line == 0 && outpic->pos.y[outpic->nexty] == 0)
- outpic->pos.y[outpic->nexty] = ftell(outpic->fp);
- }
-
-
- picwritecm(cm) /* write out color map */
- colormap cm;
- {
- register int i, j;
-
- if (outpic->nexty != -1 &&
- fseek(outpic->fp, (long)sizeof(struct rasterfile), 0) == EOF)
- quiterr("seek error in picwritecm");
- for (i = 0; i < 3; i++)
- for (j = 0; j < 256; j++)
- putc(cm[i][j], outpic->fp);
- outpic->nexty = 0;
- if (outpic->bytes_line == 0)
- outpic->pos.y[0] = ftell(outpic->fp);
- else
- outpic->pos.b = ftell(outpic->fp);
- }
-
-
- picreadcm(map) /* do gamma correction if requested */
- colormap map;
- {
- register int i, val;
-
- for (i = 0; i < 256; i++) {
- val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
- map[0][i] = map[1][i] = map[2][i] = val;
- }
- }
-