home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)ra_t8.c 2.4 10/13/92 LBL";
- #endif
-
- /*
- * ra_t8.c - program to convert between RADIANCE and
- * Targa 8-bit color-mapped images.
- *
- * 8/22/88 Adapted from ra_pr.c
- */
-
- #include <stdio.h>
-
- #include "color.h"
-
- #include "resolu.h"
-
- #include "targa.h"
-
- #ifdef MSDOS
- #include <fcntl.h>
- #endif
-
- #include <math.h>
-
- #ifndef BSD
- #define bcopy(s,d,n) (void)memcpy(d,s,n)
- extern char *memcpy();
- #endif
-
- #define goodpic(h) (my_imType(h) && my_mapType(h))
- #define my_imType(h) (((h)->dataType==IM_CMAP || (h)->dataType==IM_CCMAP) \
- && (h)->dataBits==8 && (h)->imType==0)
- #define my_mapType(h) ((h)->mapType==CM_HASMAP && \
- ((h)->CMapBits==24 || (h)->CMapBits==32))
-
- #define taralloc(h) (BYTE *)emalloc((h)->x*(h)->y)
-
- extern BYTE clrtab[][3];
-
- extern char *ecalloc(), *emalloc();
-
- extern long ftell();
-
- double gamv = 2.2; /* gamv correction */
-
- int bradj = 0; /* brightness adjustment */
-
- char *progname;
-
- char errmsg[128];
-
- COLR *inl;
-
- BYTE *tarData;
-
- int xmax, ymax;
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- struct hdStruct head;
- int dither = 1;
- int reverse = 0;
- int ncolors = 256;
- int greyscale = 0;
- int i;
- #ifdef MSDOS
- extern int _fmode;
- _fmode = O_BINARY;
- setmode(fileno(stdin), O_BINARY);
- setmode(fileno(stdout), O_BINARY);
- #endif
- progname = argv[0];
-
- for (i = 1; i < argc; i++)
- if (argv[i][0] == '-')
- switch (argv[i][1]) {
- case 'd':
- dither = !dither;
- break;
- case 'g':
- gamv = atof(argv[++i]);
- break;
- case 'r':
- reverse = !reverse;
- break;
- case 'b':
- greyscale = 1;
- break;
- case 'e':
- if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
- goto userr;
- bradj = atoi(argv[++i]);
- break;
- case 'c':
- ncolors = atoi(argv[++i]);
- break;
- default:
- goto userr;
- }
- else
- break;
-
- if (i < argc-2)
- goto userr;
- if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
- sprintf(errmsg, "cannot open input \"%s\"", argv[i]);
- quiterr(errmsg);
- }
- if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
- sprintf(errmsg, "cannot open output \"%s\"", argv[i+1]);
- quiterr(errmsg);
- }
- if (reverse) {
- /* get header */
- if (getthead(&head, NULL, stdin) < 0)
- quiterr("bad targa file");
- if (!goodpic(&head))
- quiterr("incompatible format");
- xmax = head.x;
- ymax = head.y;
- /* put header */
- printargs(i, argv, stdout);
- fputformat(COLRFMT, stdout);
- putchar('\n');
- fprtresolu(xmax, ymax, stdout);
- /* convert file */
- tg2ra(&head);
- } else {
- if (getrhead(&head, stdin) < 0)
- quiterr("bad Radiance input");
- /* write header */
- putthead(&head, NULL, stdout);
- /* convert file */
- if (greyscale)
- getgrey(ncolors);
- else
- getmapped(ncolors, dither);
- /* write data */
- writetarga(&head, tarData, stdout);
- }
- quiterr(NULL);
- userr:
- fprintf(stderr,
- "Usage: %s [-d][-c ncolors][-b][-g gamv][-e +/-stops] input [output]\n",
- progname);
- fprintf(stderr, " Or: %s -r [-g gamv][-e +/-stops] [input [output]]\n",
- progname);
- exit(1);
- }
-
-
- int
- getint2(fp) /* get a 2-byte positive integer */
- register FILE *fp;
- {
- register int b1, b2;
-
- if ((b1 = getc(fp)) == EOF || (b2 = getc(fp)) == EOF)
- quiterr("read error");
-
- return(b1 | b2<<8);
- }
-
-
- putint2(i, fp) /* put a 2-byte positive integer */
- register int i;
- register FILE *fp;
- {
- putc(i&0xff, fp);
- putc(i>>8&0xff, fp);
- }
-
-
- 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);
- }
-
-
- getthead(hp, ip, fp) /* read header from input */
- struct hdStruct *hp;
- char *ip;
- register FILE *fp;
- {
- int nidbytes;
-
- if ((nidbytes = getc(fp)) == EOF)
- return(-1);
- hp->mapType = getc(fp);
- hp->dataType = getc(fp);
- hp->mapOrig = getint2(fp);
- hp->mapLength = getint2(fp);
- hp->CMapBits = getc(fp);
- hp->XOffset = getint2(fp);
- hp->YOffset = getint2(fp);
- hp->x = getint2(fp);
- hp->y = getint2(fp);
- hp->dataBits = getc(fp);
- hp->imType = getc(fp);
-
- if (ip != NULL)
- if (nidbytes)
- fread((char *)ip, nidbytes, 1, fp);
- else
- *ip = '\0';
- else if (nidbytes)
- fseek(fp, (long)nidbytes, 1);
-
- return(feof(fp) || ferror(fp) ? -1 : 0);
- }
-
-
- putthead(hp, ip, fp) /* write header to output */
- struct hdStruct *hp;
- char *ip;
- register FILE *fp;
- {
- if (ip != NULL)
- putc(strlen(ip), fp);
- else
- putc(0, fp);
- putc(hp->mapType, fp);
- putc(hp->dataType, fp);
- putint2(hp->mapOrig, fp);
- putint2(hp->mapLength, fp);
- putc(hp->CMapBits, fp);
- putint2(hp->XOffset, fp);
- putint2(hp->YOffset, fp);
- putint2(hp->x, fp);
- putint2(hp->y, fp);
- putc(hp->dataBits, fp);
- putc(hp->imType, fp);
-
- if (ip != NULL)
- fputs(ip, fp);
-
- return(ferror(fp) ? -1 : 0);
- }
-
-
- getrhead(h, fp) /* load RADIANCE input file header */
- register struct hdStruct *h;
- FILE *fp;
- {
- /* get header info. */
- if (checkheader(fp, COLRFMT, NULL) < 0 ||
- fgetresolu(&xmax, &ymax, fp) < 0)
- return(-1);
- /* assign header */
- h->textSize = 0;
- h->mapType = CM_HASMAP;
- h->dataType = IM_CMAP;
- h->mapOrig = 0;
- h->mapLength = 256;
- h->CMapBits = 24;
- h->XOffset = 0;
- h->YOffset = 0;
- h->x = xmax;
- h->y = ymax;
- h->dataBits = 8;
- h->imType = 0;
- /* allocate scanline */
- inl = (COLR *)emalloc(xmax*sizeof(COLR));
- /* allocate targa data */
- tarData = taralloc(h);
-
- return(0);
- }
-
-
- tg2ra(hp) /* targa file to RADIANCE file */
- struct hdStruct *hp;
- {
- union {
- BYTE c3[256][3];
- BYTE c4[256][4];
- } map;
- COLR ctab[256];
- COLR *scanline;
- register int i, j;
-
- /* get color table */
- if ((hp->CMapBits==24 ? fread((char *)(map.c3+hp->mapOrig),
- 3*hp->mapLength,1,stdin) :
- fread((char *)(map.c4+hp->mapOrig),
- 4*hp->mapLength,1,stdin)) != 1)
- quiterr("error reading color table");
- /* convert table */
- for (i = hp->mapOrig; i < hp->mapOrig+hp->mapLength; i++)
- if (hp->CMapBits == 24)
- setcolr(ctab[i],
- pow((map.c3[i][2]+.5)/256.,gamv),
- pow((map.c3[i][1]+.5)/256.,gamv),
- pow((map.c3[i][0]+.5)/256.,gamv));
- else
- setcolr(ctab[i],
- pow((map.c4[i][3]+.5)/256.,gamv),
- pow((map.c4[i][2]+.5)/256.,gamv),
- pow((map.c4[i][1]+.5)/256.,gamv));
- if (bradj)
- shiftcolrs(ctab, 256, bradj);
- /* allocate targa data */
- tarData = taralloc(hp);
- /* get data */
- readtarga(hp, tarData, stdin);
- /* allocate input scanline */
- scanline = (COLR *)emalloc(xmax*sizeof(COLR));
- /* convert file */
- for (i = ymax-1; i >= 0; i--) {
- for (j = 0; j < xmax; j++)
- copycolr(scanline[j], ctab[tarData[i*xmax+j]]);
- if (fwritecolrs(scanline, xmax, stdout) < 0)
- quiterr("error writing RADIANCE file");
- }
- free((char *)scanline);
- free((char *)tarData);
- }
-
-
- getmapped(nc, dith) /* read in and quantize image */
- int nc; /* number of colors to use */
- int dith; /* use dithering? */
- {
- long fpos;
- register int y;
-
- setcolrgam(gamv);
- fpos = ftell(stdin);
- new_histo(); /* build histogram */
- for (y = ymax-1; y >= 0; y--) {
- if (freadcolrs(inl, xmax, stdin) < 0)
- quiterr("error reading Radiance input");
- if (bradj)
- shiftcolrs(inl, xmax, bradj);
- colrs_gambs(inl, xmax);
- cnt_colrs(inl, xmax);
- }
- if (fseek(stdin, fpos, 0) == EOF)
- quiterr("Radiance input must be from a file");
- new_clrtab(nc); /* map colors */
- for (y = ymax-1; y >= 0; y--) {
- if (freadcolrs(inl, xmax, stdin) < 0)
- quiterr("error reading Radiance input");
- if (bradj)
- shiftcolrs(inl, xmax, bradj);
- colrs_gambs(inl, xmax);
- if (dith)
- dith_colrs(tarData+y*xmax, inl, xmax);
- else
- map_colrs(tarData+y*xmax, inl, xmax);
- }
- }
-
-
- getgrey(nc) /* read in and convert to greyscale image */
- int nc; /* number of colors to use */
- {
- int y;
- register BYTE *dp;
- register int x;
-
- setcolrgam(gamv);
- dp = tarData+xmax*ymax;;
- for (y = ymax-1; y >= 0; y--) {
- if (freadcolrs(inl, xmax, stdin) < 0)
- quiterr("error reading Radiance input");
- if (bradj)
- shiftcolrs(inl, xmax, bradj);
- colrs_gambs(inl, xmax);
- x = xmax;
- if (nc < 256)
- while (x--)
- *--dp = ((long)normbright(inl[x])*nc+128)>>8;
- else
- while (x--)
- *--dp = normbright(inl[x]);
- }
- for (x = 0; x < nc; x++)
- clrtab[x][RED] = clrtab[x][GRN] =
- clrtab[x][BLU] = ((long)x*256+nc/2)/nc;
- }
-
-
- writetarga(h, d, fp) /* write out targa data */
- struct hdStruct *h;
- BYTE *d;
- FILE *fp;
- {
- register int i, j;
-
- for (i = 0; i < h->mapLength; i++) /* write color map */
- for (j = 2; j >= 0; j--)
- putc(clrtab[i][j], fp);
- if (h->dataType == IM_CMAP) { /* uncompressed */
- if (fwrite((char *)d,h->x*sizeof(BYTE),h->y,fp) != h->y)
- quiterr("error writing targa file");
- return;
- }
- quiterr("unsupported output type");
- }
-
-
- readtarga(h, data, fp) /* read in targa data */
- struct hdStruct *h;
- BYTE *data;
- FILE *fp;
- {
- register int cnt, c;
- register BYTE *dp;
-
- if (h->dataType == IM_CMAP) { /* uncompressed */
- if (fread((char *)data,h->x*sizeof(BYTE),h->y,fp) != h->y)
- goto readerr;
- return;
- }
- for (dp = data; dp < data+h->x*h->y; ) {
- if ((c = getc(fp)) == EOF)
- goto readerr;
- cnt = (c & 0x7f) + 1;
- if (c & 0x80) { /* repeated pixel */
- if ((c = getc(fp)) == EOF)
- goto readerr;
- while (cnt--)
- *dp++ = c;
- } else /* non-repeating pixels */
- while (cnt--) {
- if ((c = getc(fp)) == EOF)
- goto readerr;
- *dp++ = c;
- }
- }
- return;
- readerr:
- quiterr("error reading targa file");
- }
-