--- ray/src/px/ra_t8.c 1991/12/19 14:52:23 2.2 +++ ray/src/px/ra_t8.c 2003/05/13 17:58:33 2.11 @@ -1,9 +1,6 @@ -/* Copyright (c) 1991 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: ra_t8.c,v 2.11 2003/05/13 17:58:33 greg Exp $"; #endif - /* * ra_t8.c - program to convert between RADIANCE and * Targa 8-bit color-mapped images. @@ -13,59 +10,51 @@ static char SCCSid[] = "$SunId$ LBL"; #include +#include + #include "color.h" #include "resolu.h" -#include "pic.h" - #include "targa.h" -#ifndef BSD -#define bcopy(s,d,n) (void)memcpy(d,s,n) -extern char *memcpy(); +#ifdef MSDOS +#include #endif - /* 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; -#define goodpic(h) (my_imType(h) && my_mapType(h)) -#define my_imType(h) (((h)->dataType==IM_CMAP || (h)->dataType==IM_CCMAP) \ +#include + +#ifndef BSD +#define bcopy(s,d,n) (void)memcpy(d,s,n) +#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 && \ +#define my_mapType(h) ((h)->mapType==CM_HASMAP && \ ((h)->CMapBits==24 || (h)->CMapBits==32)) -#define taralloc(h) (pixel *)emalloc((h)->x*(h)->y*sizeof(pixel)) +#define taralloc(h) (BYTE *)emalloc((h)->x*(h)->y) -extern pic *openinput(); +BYTE clrtab[256][3]; +extern int samplefac; + extern char *ecalloc(), *emalloc(); extern long ftell(); -extern double pow(); +double gamv = 2.2; /* gamv correction */ -double gamma = 2.2; /* gamma correction */ - int bradj = 0; /* brightness adjustment */ -pic *inpic; - char *progname; char errmsg[128]; COLR *inl; -pixel *tarData; +BYTE *tarData; int xmax, ymax; @@ -74,15 +63,20 @@ main(argc, argv) int argc; char *argv[]; { - colormap rasmap; - struct hdStruct head; + 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]; + samplefac = 0; for (i = 1; i < argc; i++) if (argv[i][0] == '-') @@ -91,7 +85,7 @@ char *argv[]; dither = !dither; break; case 'g': - gamma = atof(argv[++i]); + gamv = atof(argv[++i]); break; case 'r': reverse = !reverse; @@ -107,19 +101,26 @@ char *argv[]; case 'c': ncolors = atoi(argv[++i]); break; + case 'n': + samplefac = 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) { - 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); - } /* get header */ if (getthead(&head, NULL, stdin) < 0) quiterr("bad targa file"); @@ -127,12 +128,8 @@ char *argv[]; quiterr("incompatible format"); xmax = head.x; ymax = head.y; - /* open output file */ - if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) { - sprintf(errmsg, "can't open output \"%s\"", argv[i+1]); - quiterr(errmsg); - } /* put header */ + newheader("RADIANCE", stdout); printargs(i, argv, stdout); fputformat(COLRFMT, stdout); putchar('\n'); @@ -140,32 +137,24 @@ char *argv[]; /* convert file */ tg2ra(&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 (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) { - sprintf(errmsg, "can't open output \"%s\"", argv[i+1]); - quiterr(errmsg); - } + if (getrhead(&head, stdin) < 0) + quiterr("bad Radiance input"); /* write header */ putthead(&head, NULL, stdout); /* convert file */ if (greyscale) - biq(dither,ncolors,1,rasmap); + getgrey(ncolors); else - ciq(dither,ncolors,1,rasmap); + getmapped(ncolors, dither); /* write data */ writetarga(&head, tarData, stdout); } quiterr(NULL); userr: fprintf(stderr, - "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n", + "Usage: %s [-d][-n samp][-c ncolors][-b][-g gamv][-e +/-stops] input [output]\n", progname); - fprintf(stderr, " Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n", + fprintf(stderr, " Or: %s -r [-g gamv][-e +/-stops] [input [output]]\n", progname); exit(1); } @@ -204,6 +193,7 @@ char *err; } +void eputs(s) char *s; { @@ -211,6 +201,7 @@ char *s; } +void quit(code) int code; { @@ -219,7 +210,7 @@ int code; getthead(hp, ip, fp) /* read header from input */ -struct hdStruct *hp; +struct hdStruct *hp; char *ip; register FILE *fp; { @@ -252,7 +243,7 @@ register FILE *fp; putthead(hp, ip, fp) /* write header to output */ -struct hdStruct *hp; +struct hdStruct *hp; char *ip; register FILE *fp; { @@ -279,27 +270,14 @@ register FILE *fp; } -pic * -openinput(fname, h) /* open RADIANCE input file */ -char *fname; +getrhead(h, fp) /* load RADIANCE input file header */ register struct hdStruct *h; +FILE *fp; { - 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); /* get header info. */ - 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); + if (checkheader(fp, COLRFMT, NULL) < 0 || + fgetresolu(&xmax, &ymax, fp) < 0) + return(-1); /* assign header */ h->textSize = 0; h->mapType = CM_HASMAP; @@ -318,12 +296,12 @@ register struct hdStruct *h; /* allocate targa data */ tarData = taralloc(h); - return(p); + return(0); } tg2ra(hp) /* targa file to RADIANCE file */ -struct hdStruct *hp; +struct hdStruct *hp; { union { BYTE c3[256][3]; @@ -343,14 +321,14 @@ struct hdStruct *hp; for (i = hp->mapOrig; i < hp->mapOrig+hp->mapLength; i++) if (hp->CMapBits == 24) setcolr(ctab[i], - pow((map.c3[i][2]+.5)/256.,gamma), - pow((map.c3[i][1]+.5)/256.,gamma), - pow((map.c3[i][0]+.5)/256.,gamma)); + 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.,gamma), - pow((map.c4[i][2]+.5)/256.,gamma), - pow((map.c4[i][1]+.5)/256.,gamma)); + 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 */ @@ -366,59 +344,103 @@ struct hdStruct *hp; if (fwritecolrs(scanline, xmax, stdout) < 0) quiterr("error writing RADIANCE file"); } - free((char *)scanline); - free((char *)tarData); + free((void *)scanline); + free((void *)tarData); } -picreadline3(y, l3) /* read in 3-byte scanline */ -int y; -register rgbpixel *l3; +getmapped(nc, dith) /* read in and quantize image */ +int nc; /* number of colors to use */ +int dith; /* use dithering? */ { - register int i; + long fpos; + register int y; - 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]; + setcolrgam(gamv); + fpos = ftell(stdin); + if ((samplefac ? neu_init(xmax*ymax) : new_histo(xmax*ymax)) == -1) + quiterr("cannot initialized 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); + if (samplefac) + neu_colrs(inl, xmax); + else + cnt_colrs(inl, xmax); } + if (fseek(stdin, fpos, 0) == EOF) + quiterr("Radiance input must be from a file"); + if (samplefac) /* map colors */ + neu_clrtab(nc); + else + new_clrtab(nc); + 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 (samplefac) + if (dith) + neu_dith_colrs(tarData+y*xmax, inl, xmax); + else + neu_map_colrs(tarData+y*xmax, inl, xmax); + else + if (dith) + dith_colrs(tarData+y*xmax, inl, xmax); + else + map_colrs(tarData+y*xmax, inl, xmax); + } } -picwriteline(y, l) /* save output scanline */ -int y; -pixel *l; +getgrey(nc) /* read in and convert to greyscale image */ +int nc; /* number of colors to use */ { - bcopy((char *)l, (char *)&tarData[(ymax-1-y)*xmax], xmax*sizeof(pixel)); + 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); + x = xmax; + while (x--) + inl[x][GRN] = normbright(inl[x]); + colrs_gambs(inl, xmax); + x = xmax; + if (nc < 256) + while (x--) + *--dp = ((long)inl[x][GRN]*nc+nc/2)>>8; + else + while (x--) + *--dp = inl[x][GRN]; + } + for (x = 0; x < nc; x++) + clrtab[x][RED] = clrtab[x][GRN] = + clrtab[x][BLU] = ((long)x*256+128)/nc; } writetarga(h, d, fp) /* write out targa data */ -struct hdStruct *h; -pixel *d; +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(pixel),h->y,fp) != h->y) + if (fwrite((char *)d,h->x*sizeof(BYTE),h->y,fp) != h->y) quiterr("error writing targa file"); return; } @@ -427,15 +449,15 @@ FILE *fp; readtarga(h, data, fp) /* read in targa data */ -struct hdStruct *h; -pixel *data; +struct hdStruct *h; +BYTE *data; FILE *fp; { register int cnt, c; - register pixel *dp; + register BYTE *dp; if (h->dataType == IM_CMAP) { /* uncompressed */ - if (fread((char *)data,h->x*sizeof(pixel),h->y,fp) != h->y) + if (fread((char *)data,h->x*sizeof(BYTE),h->y,fp) != h->y) goto readerr; return; } @@ -458,27 +480,4 @@ FILE *fp; return; readerr: quiterr("error reading targa file"); -} - - -picwritecm(cm) /* write out color map */ -colormap cm; -{ - register int i, j; - - for (j = 0; j < 256; j++) - for (i = 2; i >= 0; i--) - putc(cm[i][j], stdout); -} - - -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/gamma) * 256.0; - map[0][i] = map[1][i] = map[2][i] = val; - } }