home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)ra_pict.c 2.5 10/30/92 LBL";
- #endif
-
- /* Convert an Radiance image to APPLE pict format.
- *
- * Orginally Iris to PICT by Paul Haeberli - 1990
- * Hacked into Rad to PICT by Russell Street 1990
- *
- * History:
- * V 1 -- Does basic conversion
- * V 1.1 (2/11/91) -- Added options for Gamma
- * -- verbose option
- * -- man page
- * -- better about allocating buffers
- * V 1.2 (19/11/91) -- Revised to handle opening "The Radiance Way"
- * -- Added exposure level adjustment
- */
-
- #include <stdio.h>
- #ifdef MSDOS
- #include <fcntl.h>
- #endif
-
- #include "pict.h"
- #include "color.h"
- #include "resolu.h"
-
- extern char *malloc();
-
- int outbytes; /* This had better be 32 bits! */
- char *progname;
- int verbose = 0;
- float gamma = 2.0;
- int bradj = 0;
-
- /* First some utility routines */
-
- putrect(xorg,yorg,xsize,ysize)
- int xorg, yorg, xsize, ysize;
- {
- putashort(yorg);
- putashort(xorg);
- putashort(ysize);
- putashort(xsize);
- }
-
- putfprect(xorg,yorg,xsize,ysize)
- int xorg, yorg, xsize, ysize;
- {
- putalong(yorg<<16);
- putalong(xorg<<16);
- putalong(ysize<<16);
- putalong(xsize<<16);
- }
-
- putalong(l)
- long l;
- {
- putbyte((l>>24)&0xff);
- putbyte((l>>16)&0xff);
- putbyte((l>>8)&0xff);
- putbyte((l>>0)&0xff);
- }
-
- putashort(s)
- short s;
- {
- putbyte((s>>8)&0xff);
- putbyte((s>>0)&0xff);
- }
-
- putbyte(b)
- int b;
- {
- if (putc(b,stdout) == EOF && ferror(stdout)) {
- fprintf(stderr,"%s: error on write\n", progname);
- exit(1);
- }
- outbytes++;
- }
-
- putbytes(buf,n)
- unsigned char *buf;
- int n;
- {
- if(!fwrite(buf,n,1,stdout)) {
- fprintf(stderr,"%s: error on write\n", progname);
- exit(1);
- }
- outbytes+=n;
- }
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- int xsize, ysize;
- int i, picsize;
- int ssizepos, lsizepos;
- #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 'g': gamma = atof(argv[++i]);
- break;
-
- case 'e': if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
- usage();
- else
- bradj = atoi(argv[++i]);
- break;
-
- case 'v': ;
- verbose = 1;
- break;
-
- case 'r': fprintf(stderr, "Sorry. Get a Macintosh :-)\n");
- exit(1);
-
- case '-': i++;
- goto outofparse;
- break; /* NOTREACHED */
-
- otherwise: usage();
- break;
- }
- else
- break;
-
- outofparse:
-
- if (i < argc - 2)
- usage();
-
- if (i <= argc - 1 && freopen(argv[i], "r", stdin) == NULL) {
- fprintf(stderr, "%s: can not open input \"%s\"\n",
- progname, argv[i]);
- exit(1);
- }
-
- if (i <= argc - 2 && freopen(argv[i+1], "w", stdout) == NULL) {
- fprintf(stderr, "%s: can not open input \"%s\"\n",
- progname, argv[i+1]);
- exit(1);
- }
-
- #ifdef DEBUG
- fprintf(stderr, "Input file: %s\n", i <= argc - 1 ? argv[i] : "stdin");
- fprintf(stderr, "Outut file: %s\n", i <= argc - 2 ? argv[i+1] : "stdout" );
- fprintf(stderr, "Gamma: %f\n", gamma);
- fprintf(stderr, "Brightness adjust: %d\n", bradj);
- fprintf(stderr, "Verbose: %s\n", verbose ? "on" : "off");
- #endif
-
-
- /* OK. Now we read the size of the Radiance picture */
- if (checkheader(stdin, COLRFMT, NULL) < 0 ||
- fgetresolu(&xsize, &ysize, stdin) < 0 /* != (YMAJOR|YDECR) */ ) {
- fprintf(stderr, "%s: not a radiance picture\n", progname);
- exit(1);
- }
-
- /* Set the gamma correction */
-
- setcolrgam(gamma);
-
- for(i=0; i<HEADER_SIZE; i++)
- putbyte(0);
-
- ssizepos = outbytes;
- putashort(0); /* low 16 bits of file size less HEADER_SIZE */
- putrect(0,0,xsize,ysize); /* bounding box of picture */
- putashort(PICT_picVersion);
- putashort(0x02ff); /* version 2 pict */
- putashort(PICT_reservedHeader); /* reserved header opcode */
-
- lsizepos = outbytes;
- putalong(0); /* full size of the file */
- putfprect(0,0,xsize,ysize); /* fixed point bounding box of picture */
- putalong(0); /* reserved */
-
- putashort(PICT_clipRgn); /* the clip region */
- putashort(10);
- putrect(0,0,xsize,ysize);
-
- if (verbose)
- fprintf(stderr, "%s: The picture is %d by %d, with a gamma of %f\n",
- progname, xsize, ysize, gamma);
-
-
- putpict(xsize, ysize); /* Here is where all the work is done */
-
- putashort(PICT_EndOfPicture); /* end of pict */
-
- picsize = outbytes-HEADER_SIZE;
- fseek(stdout,ssizepos,0);
- putashort(picsize&0xffff);
- fseek(stdout,lsizepos,0);
- putalong(picsize);
-
- fclose(stdout);
- fclose(stdin);
-
- exit(0);
- return 0; /* lint fodder */
- }
-
- putpict(xsize, ysize)
- int xsize;
- int ysize;
- {
- int y;
- int nbytes, rowbytes;
- char *cbuf, *pbuf;
-
- cbuf = malloc(4 * xsize);
-
- if (cbuf == NULL) {
- fprintf(stderr, "%s: not enough memory\n", progname);
- exit(1);
- }
-
- pbuf = malloc(4 * xsize);
-
- if (pbuf == NULL) {
- fprintf(stderr, "%s: not enough memory\n", progname);
- exit(1);
- }
-
- putashort(PICT_Pack32BitsRect); /* 32 bit rgb */
- rowbytes = 4*xsize;
- putalong(0x000000ff); /* base address */
-
-
- if(rowbytes&1)
- rowbytes++;
- putashort(rowbytes|0x8000); /* rowbytes */
- putrect(0,0,xsize,ysize); /* bounds */
- putashort(0); /* version */
-
- putashort(4); /* packtype */
- putalong(0); /* packsize */
- putalong(72<<16); /* hres */
- putalong(72<<16); /* vres */
-
- putashort(16); /* pixeltype */
- putashort(32); /* pixelsize */
- putashort(3); /* cmpcount */
-
-
- putashort(8); /* cmpsize */
- putalong(0); /* planebytes */
- putalong(0); /* pmtable */
- putalong(0); /* pmreserved */
-
-
- putrect(0,0,xsize,ysize); /* scr rect */
- putrect(0,0,xsize,ysize); /* dest rect */
-
-
- putashort(0x40); /* transfer mode */
-
- for(y=0; y<ysize; y++) {
- getrow(stdin, cbuf, xsize);
-
- nbytes = packbits(cbuf,pbuf,24*xsize);
- if(rowbytes>250)
- putashort(nbytes);
- else
- putbyte(nbytes);
- putbytes(pbuf,nbytes);
- }
-
- if(outbytes&1)
- putbyte(0);
-
- free(cbuf);
- free(pbuf);
- }
-
- int getrow(in, cbuf, xsize)
- FILE *in;
- char *cbuf;
- int xsize;
- {
- extern char *tempbuffer(); /* defined in color.c */
- COLR *scanin = NULL;
- int x;
-
- if ((scanin = (COLR *)tempbuffer(xsize*sizeof(COLR))) == NULL) {
- fprintf(stderr, "%s: not enough memory\n", progname);
- exit(1);
- }
-
- if (freadcolrs(scanin, xsize, in) < 0) {
- fprintf(stderr, "%s: read error\n", progname);
- exit(1);
- }
-
- if (bradj) /* Adjust exposure level */
- shiftcolrs(scanin, xsize, bradj);
-
-
- colrs_gambs(scanin, xsize); /* Gamma correct it */
-
- for (x = 0; x < xsize; x++) {
- cbuf[x] = scanin[x][RED];
- cbuf[xsize + x] = scanin[x][GRN];
- cbuf[2*xsize + x] = scanin[x][BLU];
- }
-
- }
-
-
- packbits(ibits,pbits,nbits)
- unsigned char *ibits, *pbits;
- int nbits;
- {
- int bytes; /* UNUSED */
- unsigned char *sptr;
- unsigned char *ibitsend;
- unsigned char *optr = pbits;
- int nbytes, todo, cc, count;
-
- nbytes = ((nbits-1)/8)+1;
- ibitsend = ibits+nbytes;
- while(ibits<ibitsend) {
- sptr = ibits;
- ibits += 2;
- while((ibits<ibitsend)&&((ibits[-2]!=ibits[-1])||(ibits[-1]!=ibits[0])))
- ibits++;
- if(ibits != ibitsend) {
- ibits -= 2;
- }
- count = ibits-sptr;
- while(count) {
- todo = count>127 ? 127:count;
- count -= todo;
- *optr++ = todo-1;
- while(todo--)
- *optr++ = *sptr++;
- }
- if(ibits == ibitsend)
- break;
- sptr = ibits;
- cc = *ibits++;
- while( (ibits<ibitsend) && (*ibits == cc) )
- ibits++;
- count = ibits-sptr;
- while(count) {
- todo = count>128 ? 128:count;
- count -= todo;
- *optr++ = 257-todo;
- *optr++ = cc;
- }
- }
- return optr-pbits;
- }
-
- usage()
- {
- fprintf(stderr, "Usage: %s [-v] [-g gamma] [infile [outfile]]\n",
- progname);
- exit(2);
- }
-