home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / radsrc22 / src / px / ra_t16.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-30  |  9.6 KB  |  450 lines

  1. /* Copyright (c) 1991 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)ra_t16.c 2.4 10/30/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  ra_t16.c - program to convert between RADIANCE and
  9.  *        Targa 16, 24 and 32-bit images.
  10.  *
  11.  *    11/2/88        Adapted from ra_t8.c
  12.  */
  13.  
  14. #include  <stdio.h>
  15.  
  16. #ifdef MSDOS
  17. #include  <fcntl.h>
  18. #endif
  19.  
  20. #include  <math.h>
  21.  
  22. #include  "color.h"
  23.  
  24. #include  "resolu.h"
  25.  
  26. #include  "random.h"
  27.  
  28. #include  "targa.h"
  29.  
  30. #define  goodpic(h)    (((h)->dataType==IM_RGB || (h)->dataType==IM_CRGB) \
  31.                 && ((h)->dataBits==16 || (h)->dataBits==24))
  32.  
  33. #define  taralloc(h)    (unsigned char *)emalloc((h)->x*(h)->y*(h)->dataBits/8)
  34.  
  35. #define  readtarga(h,d,f)    ((h)->dataBits==16 ? readt16(h,d,f) : \
  36.                     readt24(h,d,f))
  37.  
  38. #define  writetarga(h,d,f)    ((h)->dataBits==16 ? writet16(h,d,f) : \
  39.                     writet24(h,d,f))
  40.  
  41. extern char    *ecalloc(), *emalloc();
  42.  
  43. double    gamcor = 2.2;            /* gamma correction */
  44.  
  45. int  bradj = 0;                /* brightness adjustment */
  46.  
  47. char  *progname;
  48.  
  49. char  msg[128];
  50.  
  51.  
  52. main(argc, argv)
  53. int  argc;
  54. char  *argv[];
  55. {
  56.     struct hdStruct  head;
  57.     int  reverse = 0;
  58.     int  i;
  59. #ifdef MSDOS
  60.     extern int  _fmode;
  61.     _fmode = O_BINARY;
  62.     setmode(fileno(stdin), O_BINARY);
  63.     setmode(fileno(stdout), O_BINARY);
  64. #endif
  65.     progname = argv[0];
  66.  
  67.     head.dataBits = 16;
  68.     for (i = 1; i < argc; i++)
  69.         if (argv[i][0] == '-')
  70.             switch (argv[i][1]) {
  71.             case 'g':
  72.                 gamcor = atof(argv[++i]);
  73.                 break;
  74.             case 'r':
  75.                 reverse = !reverse;
  76.                 break;
  77.             case '2':
  78.                 head.dataBits = 16;
  79.                 break;
  80.             case '3':
  81.                 head.dataBits = 24;
  82.                 break;
  83.             case 'e':
  84.                 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
  85.                     goto userr;
  86.                 bradj = atoi(argv[++i]);
  87.                 break;
  88.             default:
  89.                 goto userr;
  90.             }
  91.         else
  92.             break;
  93.  
  94.     if (i < argc-2)
  95.         goto userr;
  96.                     /* open input file */
  97.     if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
  98.         sprintf(msg, "can't open input \"%s\"", argv[i]);
  99.         quiterr(msg);
  100.     }
  101.                     /* open output file */
  102.     if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
  103.         sprintf(msg, "can't open output \"%s\"", argv[i+1]);
  104.         quiterr(msg);
  105.     }
  106.                     /* set gamma */
  107.     setcolrgam(gamcor);
  108.                     /* convert */
  109.     if (reverse) {
  110.                     /* get header */
  111.         if (getthead(&head, NULL, stdin) < 0)
  112.             quiterr("bad targa file");
  113.         if (!goodpic(&head))
  114.             quiterr("incompatible format");
  115.                     /* put header */
  116.         printargs(i, argv, stdout);
  117.         fputformat(COLRFMT, stdout);
  118.         putchar('\n');
  119.         fprtresolu(head.x, head.y, stdout);
  120.                     /* convert file */
  121.         tg2ra(&head);
  122.     } else {
  123.         if (checkheader(stdin, COLRFMT, NULL) < 0 ||
  124.                 fgetresolu(&head.x, &head.y, stdin) < 0)
  125.             quiterr("bad picture file");
  126.                     /* assign header */
  127.         head.textSize = 0;
  128.         head.mapType = CM_NOMAP;
  129.         head.dataType = IM_RGB;
  130.         head.XOffset = 0;
  131.         head.YOffset = 0;
  132.         head.imType = 0;
  133.                     /* write header */
  134.         putthead(&head, NULL, stdout);
  135.                     /* convert file */
  136.         ra2tg(&head);
  137.     }
  138.     exit(0);
  139. userr:
  140.     fprintf(stderr, "Usage: %s [-2|-3|-r][-g gamma][-e +/-stops] [input [output]]\n",
  141.             progname);
  142.     exit(1);
  143. }
  144.  
  145.  
  146. int
  147. getint2(fp)            /* get a 2-byte positive integer */
  148. register FILE    *fp;
  149. {
  150.     register int  b1, b2;
  151.  
  152.     if ((b1 = getc(fp)) == EOF || (b2 = getc(fp)) == EOF)
  153.         quiterr("read error");
  154.  
  155.     return(b1 | b2<<8);
  156. }
  157.  
  158.  
  159. putint2(i, fp)            /* put a 2-byte positive integer */
  160. register int  i;
  161. register FILE    *fp;
  162. {
  163.     putc(i&0xff, fp);
  164.     putc(i>>8&0xff, fp);
  165. }
  166.  
  167.  
  168. quiterr(err)        /* print message and exit */
  169. char  *err;
  170. {
  171.     fprintf(stderr, "%s: %s\n", progname, err);
  172.     exit(1);
  173. }
  174.  
  175.  
  176. eputs(s)
  177. char *s;
  178. {
  179.     fputs(s, stderr);
  180. }
  181.  
  182.  
  183. quit(code)
  184. int code;
  185. {
  186.     exit(code);
  187. }
  188.  
  189.  
  190. getthead(hp, ip, fp)        /* read header from input */
  191. struct hdStruct  *hp;
  192. char  *ip;
  193. register FILE  *fp;
  194. {
  195.     int    nidbytes;
  196.  
  197.     if ((nidbytes = getc(fp)) == EOF)
  198.         return(-1);
  199.     hp->mapType = getc(fp);
  200.     hp->dataType = getc(fp);
  201.     hp->mapOrig = getint2(fp);
  202.     hp->mapLength = getint2(fp);
  203.     hp->CMapBits = getc(fp);
  204.     hp->XOffset = getint2(fp);
  205.     hp->YOffset = getint2(fp);
  206.     hp->x = getint2(fp);
  207.     hp->y = getint2(fp);
  208.     hp->dataBits = getc(fp);
  209.     hp->imType = getc(fp);
  210.  
  211.     if (ip != NULL)
  212.         if (nidbytes)
  213.             fread((char *)ip, nidbytes, 1, fp);
  214.         else
  215.             *ip = '\0';
  216.     else if (nidbytes)
  217.         fseek(fp, (long)nidbytes, 1);
  218.  
  219.     return(feof(fp) || ferror(fp) ? -1 : 0);
  220. }
  221.  
  222.  
  223. putthead(hp, ip, fp)        /* write header to output */
  224. struct hdStruct  *hp;
  225. char  *ip;
  226. register FILE  *fp;
  227. {
  228.     if (ip != NULL)
  229.         putc(strlen(ip), fp);
  230.     else
  231.         putc(0, fp);
  232.     putc(hp->mapType, fp);
  233.     putc(hp->dataType, fp);
  234.     putint2(hp->mapOrig, fp);
  235.     putint2(hp->mapLength, fp);
  236.     putc(hp->CMapBits, fp);
  237.     putint2(hp->XOffset, fp);
  238.     putint2(hp->YOffset, fp);
  239.     putint2(hp->x, fp);
  240.     putint2(hp->y, fp);
  241.     putc(hp->dataBits, fp);
  242.     putc(hp->imType, fp);
  243.  
  244.     if (ip != NULL)
  245.         fputs(ip, fp);
  246.  
  247.     return(ferror(fp) ? -1 : 0);
  248. }
  249.  
  250.  
  251. tg2ra(hp)            /* targa file to RADIANCE file */
  252. struct hdStruct  *hp;
  253. {
  254.     COLR  *scanline;
  255.     unsigned char  *tarData;
  256.     register int  i, j;
  257.                     /* skip color table */
  258.     if (hp->mapType == CM_HASMAP)
  259.         fseek(stdin, (long)hp->mapLength*hp->CMapBits/8, 1);
  260.                     /* allocate targa data */
  261.     tarData = taralloc(hp);
  262.                     /* get data */
  263.     readtarga(hp, tarData, stdin);
  264.                     /* allocate input scanline */
  265.     scanline = (COLR *)emalloc(hp->x*sizeof(COLR));
  266.                     /* convert file */
  267.     for (i = hp->y-1; i >= 0; i--) {
  268.         if (hp->dataBits == 16) {
  269.             register unsigned short  *dp;
  270.             dp = (unsigned short *)tarData + i*hp->x;
  271.             for (j = 0; j < hp->x; j++) {
  272.                 scanline[j][RED] = *dp>>7 & 0xf8;
  273.                 scanline[j][GRN] = *dp>>2 & 0xf8;
  274.                 scanline[j][BLU] = *dp<<3 & 0xf8;
  275.                 dp++;
  276.             }
  277.         } else {    /* hp->dataBits == 24 */
  278.             register unsigned char  *dp;
  279.             dp = (unsigned char *)tarData + i*3*hp->x;
  280.             for (j = 0; j < hp->x; j++) {
  281.                 scanline[j][RED] = dp[2];
  282.                 scanline[j][GRN] = dp[1];
  283.                 scanline[j][BLU] = dp[0];
  284.                 dp += 3;
  285.             }
  286.         }
  287.         gambs_colrs(scanline, hp->x);
  288.         if (bradj)
  289.             shiftcolrs(scanline, hp->x, bradj);
  290.         if (fwritecolrs(scanline, hp->x, stdout) < 0)
  291.             quiterr("error writing RADIANCE file");
  292.     }
  293.     free((char *)scanline);
  294.     free((char *)tarData);
  295. }
  296.  
  297.  
  298. ra2tg(hp)            /* convert radiance to targa file */
  299. struct hdStruct  *hp;
  300. {
  301.     register int    i, j;
  302.     unsigned char  *tarData;
  303.     COLR    *inl;
  304.                     /* allocate space for data */
  305.     inl = (COLR *)emalloc(hp->x*sizeof(COLR));
  306.     tarData = taralloc(hp);
  307.                     /* convert file */
  308.     for (j = hp->y-1; j >= 0; j--) {
  309.         if (freadcolrs(inl, hp->x, stdin) < 0)
  310.             quiterr("error reading RADIANCE file");
  311.         if (bradj)
  312.             shiftcolrs(inl, hp->x, bradj);
  313.         colrs_gambs(inl, hp->x);
  314.         if (hp->dataBits == 16) {
  315.             register unsigned short  *dp;
  316.             register int  v;
  317.             dp = (unsigned short *)tarData + j*hp->x;
  318.             for (i = 0; i < hp->x; i++) {
  319.                 v = inl[i][RED] + (random()&7);
  320.                 if (v > 255) v = 255;
  321.                 *dp = (v&0xf8)<<7;
  322.                 v = inl[i][GRN] + (random()&7);
  323.                 if (v > 255) v = 255;
  324.                 *dp |= (v&0xf8)<<2;
  325.                 v = inl[i][BLU] + (random()&7);
  326.                 if (v > 255) v = 255;
  327.                 *dp++ |= v>>3;
  328.             }
  329.         } else {    /* hp->dataBits == 24 */
  330.             register unsigned char  *dp;
  331.             dp = (unsigned char *)tarData + j*3*hp->x;
  332.             for (i = 0; i < hp->x; i++) {
  333.                 *dp++ = inl[i][BLU];
  334.                 *dp++ = inl[i][GRN];
  335.                 *dp++ = inl[i][RED];
  336.             }
  337.         }
  338.     }
  339.                         /* write out targa data */
  340.     writetarga(hp, tarData, stdout);
  341.  
  342.     free((char *)inl);
  343.     free((char *)tarData);
  344. }
  345.  
  346.  
  347. writet24(h, d, fp)        /* write out 24-bit targa data */
  348. struct hdStruct  *h;
  349. unsigned char  *d;
  350. FILE  *fp;
  351. {
  352.     if (h->dataType == IM_RGB) {        /* uncompressed */
  353.         if (fwrite((char *)d, 3*h->x, h->y, fp) != h->y)
  354.             quiterr("error writing targa file");
  355.         return;
  356.     }
  357.     quiterr("unsupported output type");
  358. }
  359.  
  360.  
  361. writet16(h, d, fp)        /* write out 16-bit targa data */
  362. struct hdStruct  *h;
  363. register unsigned short  *d;
  364. FILE  *fp;
  365. {
  366.     register int  cnt;
  367.  
  368.     if (h->dataType == IM_RGB) {        /* uncompressed */
  369.         for (cnt = h->x*h->y; cnt-- > 0; )
  370.             putint2(*d++, fp);
  371.         if (ferror(fp))
  372.             quiterr("error writing targa file");
  373.         return;
  374.     }
  375.     quiterr("unsupported output type");
  376. }
  377.  
  378.  
  379. readt24(h, data, fp)        /* read in 24-bit targa data */
  380. register struct hdStruct  *h;
  381. unsigned char  *data;
  382. FILE  *fp;
  383. {
  384.     register int  cnt, c;
  385.     register unsigned char  *dp;
  386.     int  r, g, b;
  387.  
  388.     if (h->dataType == IM_RGB) {        /* uncompressed */
  389.         if (fread((char *)data, 3*h->x, h->y, fp) != h->y)
  390.             goto readerr;
  391.         return;
  392.     }
  393.     for (dp = data; dp < data+3*h->x*h->y; ) {
  394.         if ((c = getc(fp)) == EOF)
  395.             goto readerr;
  396.         cnt = (c & 0x7f) + 1;
  397.         if (c & 0x80) {            /* repeated pixel */
  398.             b = getc(fp); g = getc(fp);
  399.             if ((r = getc(fp)) == EOF)
  400.                 goto readerr;
  401.             while (cnt--) {
  402.                 *dp++ = b;
  403.                 *dp++ = g;
  404.                 *dp++ = r;
  405.             }
  406.         } else                /* non-repeating pixels */
  407.             while (cnt--) {
  408.                 *dp++ = getc(fp); *dp++ = getc(fp);
  409.                 if ((r = getc(fp)) == EOF)
  410.                     goto readerr;
  411.                 *dp++ = r;
  412.             }
  413.     }
  414.     return;
  415. readerr:
  416.     quiterr("error reading targa file");
  417. }
  418.  
  419.  
  420. readt16(h, data, fp)        /* read in 16-bit targa data */
  421. register struct hdStruct  *h;
  422. unsigned short  *data;
  423. FILE  *fp;
  424. {
  425.     register int  cnt, c;
  426.     register unsigned short  *dp;
  427.  
  428.     if (h->dataType == IM_RGB) {        /* uncompressed */
  429.         dp = data;
  430.         for (cnt = h->x*h->y; cnt-- > 0; )
  431.             *dp++ = getint2(fp);
  432.         return;
  433.     }
  434.     for (dp = data; dp < data+h->x*h->y; ) {
  435.         if ((c = getc(fp)) == EOF)
  436.             goto readerr;
  437.         cnt = (c & 0x7f) + 1;
  438.         if (c & 0x80) {            /* repeated pixel */
  439.             c = getint2(fp);
  440.             while (cnt--)
  441.                 *dp++ = c;
  442.         } else                /* non-repeating pixels */
  443.             while (cnt--)
  444.                 *dp++ = getint2(fp);
  445.     }
  446.     return;
  447. readerr:
  448.     quiterr("error reading targa file");
  449. }
  450.