--- ray/src/px/ra_t8.c 1991/11/12 16:05:11 2.1 +++ ray/src/px/ra_t8.c 2004/03/28 20:33:14 2.13 @@ -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.13 2004/03/28 20:33:14 schorsch Exp $"; #endif - /* * ra_t8.c - program to convert between RADIANCE and * Targa 8-bit color-mapped images. @@ -12,77 +9,66 @@ static char SCCSid[] = "$SunId$ LBL"; */ #include +#include +#include +#include +#include "platform.h" +#include "rtmisc.h" #include "color.h" - #include "resolu.h" - -#include "pic.h" - +#include "clrtab.h" #include "targa.h" -#ifndef BSD -#define bcopy(s,d,n) (void)memcpy(d,s,n) -extern char *memcpy(); -#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) \ +#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(); - -extern char *ecalloc(), *emalloc(); - -extern long ftell(); - -extern double atof(), pow(); - -double gamma = 2.2; /* gamma correction */ - +BYTE clrtab[256][3]; +extern int samplefac; +double gamv = 2.2; /* gamv correction */ int bradj = 0; /* brightness adjustment */ - -pic *inpic; - char *progname; - char errmsg[128]; - COLR *inl; - -pixel *tarData; - +BYTE *tarData; int xmax, ymax; +static int getint2(FILE *fp); +static void putint2(int i, FILE *fp); +static void quiterr(char *err); +static int getthead(struct hdStruct *hp, char *ip, FILE *fp); +static int putthead(struct hdStruct *hp, char *ip, FILE *fp); +static int getrhead(struct hdStruct *h, FILE *fp); +static void tg2ra(struct hdStruct *hp); +static void getmapped(int nc, int dith); +static void getgrey(int nc); +static void writetarga(struct hdStruct *h, BYTE *d, FILE *fp); +static void readtarga(struct hdStruct *h, BYTE *data, FILE *fp); -main(argc, argv) -int argc; -char *argv[]; + +int +main( + 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; - + SET_DEFAULT_BINARY(); + SET_FILE_BINARY(stdin); + SET_FILE_BINARY(stdout); progname = argv[0]; + samplefac = 0; for (i = 1; i < argc; i++) if (argv[i][0] == '-') @@ -91,7 +77,7 @@ char *argv[]; dither = !dither; break; case 'g': - gamma = atof(argv[++i]); + gamv = atof(argv[++i]); break; case 'r': reverse = !reverse; @@ -107,19 +93,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 +120,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,40 +129,33 @@ 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); } -int -getint2(fp) /* get a 2-byte positive integer */ -register FILE *fp; +static int +getint2( /* get a 2-byte positive integer */ + register FILE *fp +) { register int b1, b2; @@ -184,17 +166,21 @@ register FILE *fp; } -putint2(i, fp) /* put a 2-byte positive integer */ -register int i; -register FILE *fp; +static void +putint2( /* 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; +static void +quiterr( /* print message and exit */ + char *err +) { if (err != NULL) { fprintf(stderr, "%s: %s\n", progname, err); @@ -204,6 +190,7 @@ char *err; } +void eputs(s) char *s; { @@ -211,6 +198,7 @@ char *s; } +void quit(code) int code; { @@ -218,10 +206,12 @@ int code; } -getthead(hp, ip, fp) /* read header from input */ -struct hdStruct *hp; -char *ip; -register FILE *fp; +static int +getthead( /* read header from input */ + struct hdStruct *hp, + char *ip, + register FILE *fp +) { int nidbytes; @@ -251,10 +241,12 @@ register FILE *fp; } -putthead(hp, ip, fp) /* write header to output */ -struct hdStruct *hp; -char *ip; -register FILE *fp; +static int +putthead( /* write header to output */ + struct hdStruct *hp, + char *ip, + register FILE *fp +) { if (ip != NULL) putc(strlen(ip), fp); @@ -279,27 +271,16 @@ register FILE *fp; } -pic * -openinput(fname, h) /* open RADIANCE input file */ -char *fname; -register struct hdStruct *h; +static int +getrhead( /* 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 +299,14 @@ register struct hdStruct *h; /* allocate targa data */ tarData = taralloc(h); - return(p); + return(0); } -tg2ra(hp) /* targa file to RADIANCE file */ -struct hdStruct *hp; +static void +tg2ra( /* targa file to RADIANCE file */ + struct hdStruct *hp +) { union { BYTE c3[256][3]; @@ -343,14 +326,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 +349,109 @@ 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; +static void +getmapped( /* 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; +static void +getgrey( /* 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; -FILE *fp; +static void +writetarga( /* 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(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; } @@ -426,16 +459,18 @@ FILE *fp; } -readtarga(h, data, fp) /* read in targa data */ -struct hdStruct *h; -pixel *data; -FILE *fp; +static void +readtarga( /* read in targa 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 +493,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; - } }