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

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)ra_pict.c 2.5 10/30/92 LBL";
  5. #endif
  6.  
  7. /*        Convert an Radiance image to APPLE pict format.
  8.  *
  9.  *            Orginally Iris to PICT by    Paul Haeberli - 1990
  10.  *            Hacked into Rad to PICT by Russell Street 1990
  11.  *
  12.  *    History:
  13.  *        V 1            -- Does basic conversion
  14.  *        V 1.1 (2/11/91)    -- Added options for Gamma
  15.  *                -- verbose option
  16.  *                -- man page
  17.  *                -- better about allocating buffers
  18.  *        V 1.2 (19/11/91)    -- Revised to handle opening "The Radiance Way"
  19.  *                -- Added exposure level adjustment
  20.  */
  21.  
  22. #include <stdio.h>
  23. #ifdef MSDOS
  24. #include <fcntl.h>
  25. #endif
  26.  
  27. #include "pict.h"
  28. #include "color.h"
  29. #include "resolu.h"
  30.  
  31. extern char    *malloc();
  32.  
  33. int    outbytes;            /* This had better be 32 bits! */
  34. char    *progname;
  35. int    verbose = 0;
  36. float    gamma = 2.0;
  37. int    bradj = 0;
  38.  
  39.     /* First some utility routines */
  40.  
  41. putrect(xorg,yorg,xsize,ysize)
  42. int xorg, yorg, xsize, ysize;
  43. {
  44.     putashort(yorg);
  45.     putashort(xorg);
  46.     putashort(ysize);
  47.     putashort(xsize);
  48. }
  49.  
  50. putfprect(xorg,yorg,xsize,ysize)
  51. int xorg, yorg, xsize, ysize;
  52. {
  53.     putalong(yorg<<16);
  54.     putalong(xorg<<16);
  55.     putalong(ysize<<16);
  56.     putalong(xsize<<16);
  57. }
  58.  
  59. putalong(l)
  60. long l;
  61. {
  62.     putbyte((l>>24)&0xff);
  63.     putbyte((l>>16)&0xff);
  64.     putbyte((l>>8)&0xff);
  65.     putbyte((l>>0)&0xff);
  66. }
  67.  
  68. putashort(s)
  69. short s;
  70. {
  71.     putbyte((s>>8)&0xff);
  72.     putbyte((s>>0)&0xff);
  73. }
  74.  
  75. putbyte(b)
  76. int b;
  77. {
  78.     if (putc(b,stdout) == EOF && ferror(stdout)) {
  79.     fprintf(stderr,"%s: error on write\n", progname);
  80.     exit(1);
  81.     }
  82.     outbytes++;
  83. }
  84.  
  85. putbytes(buf,n)
  86. unsigned char *buf;
  87. int n;
  88. {
  89.     if(!fwrite(buf,n,1,stdout)) {
  90.     fprintf(stderr,"%s: error on write\n", progname);
  91.     exit(1);
  92.     }
  93.     outbytes+=n;
  94. }
  95.  
  96. main(argc,argv)
  97. int argc;
  98. char **argv;
  99. {
  100.     int xsize, ysize;
  101.     int i, picsize;
  102.     int ssizepos, lsizepos;
  103. #ifdef MSDOS
  104.     extern int    _fmode;
  105.     _fmode = O_BINARY;
  106.     setmode(fileno(stdin), O_BINARY);
  107.     setmode(fileno(stdout), O_BINARY);
  108. #endif
  109.     progname = argv[0];
  110.  
  111.     for (i = 1; i < argc ; i++)
  112.     if (argv[i][0] ==  '-')
  113.         switch (argv[i][1]) {
  114.         case 'g':    gamma = atof(argv[++i]);
  115.                 break;
  116.  
  117.         case 'e':    if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
  118.                    usage();
  119.                 else
  120.                     bradj = atoi(argv[++i]);
  121.                 break;
  122.  
  123.         case 'v':    ;
  124.                 verbose = 1;
  125.                 break;
  126.  
  127.         case 'r':    fprintf(stderr, "Sorry. Get a Macintosh :-)\n");
  128.                 exit(1);
  129.  
  130.         case '-':    i++;
  131.                 goto outofparse;
  132.                 break;            /* NOTREACHED */
  133.  
  134.         otherwise:    usage();
  135.                 break;
  136.          }
  137.     else
  138.         break;
  139.  
  140. outofparse:
  141.  
  142.     if (i < argc - 2)
  143.     usage();
  144.  
  145.     if (i <= argc - 1 && freopen(argv[i], "r", stdin) == NULL) {
  146.     fprintf(stderr, "%s: can not open input \"%s\"\n",
  147.         progname, argv[i]);
  148.     exit(1);
  149.     }
  150.  
  151.     if (i <= argc - 2 && freopen(argv[i+1], "w", stdout) == NULL) {
  152.     fprintf(stderr, "%s: can not open input \"%s\"\n",
  153.         progname, argv[i+1]);
  154.     exit(1);
  155.     }
  156.     
  157. #ifdef DEBUG
  158.     fprintf(stderr, "Input file: %s\n", i <= argc - 1 ? argv[i] : "stdin");
  159.     fprintf(stderr, "Outut file: %s\n", i <= argc - 2 ? argv[i+1] : "stdout" );
  160.     fprintf(stderr, "Gamma: %f\n", gamma);
  161.     fprintf(stderr, "Brightness adjust: %d\n", bradj);
  162.     fprintf(stderr, "Verbose: %s\n", verbose ? "on" : "off");
  163. #endif
  164.  
  165.  
  166.          /* OK. Now we read the size of the Radiance picture */
  167.     if (checkheader(stdin, COLRFMT, NULL) < 0 ||
  168.         fgetresolu(&xsize, &ysize, stdin) < 0 /* != (YMAJOR|YDECR) */ ) {
  169.     fprintf(stderr, "%s: not a radiance picture\n", progname);
  170.     exit(1);
  171.     }
  172.  
  173.         /* Set the gamma correction */
  174.  
  175.     setcolrgam(gamma);
  176.  
  177.     for(i=0; i<HEADER_SIZE; i++) 
  178.     putbyte(0);
  179.  
  180.     ssizepos = outbytes;
  181.     putashort(0);        /* low 16 bits of file size less HEADER_SIZE */
  182.     putrect(0,0,xsize,ysize);    /* bounding box of picture */
  183.     putashort(PICT_picVersion);
  184.     putashort(0x02ff);        /* version 2 pict */
  185.     putashort(PICT_reservedHeader);    /* reserved header opcode */
  186.  
  187.     lsizepos = outbytes;
  188.     putalong(0);        /* full size of the file */
  189.     putfprect(0,0,xsize,ysize); /* fixed point bounding box of picture */
  190.     putalong(0);        /* reserved */
  191.  
  192.     putashort(PICT_clipRgn);    /* the clip region */
  193.     putashort(10);
  194.     putrect(0,0,xsize,ysize);
  195.  
  196.     if (verbose)
  197.     fprintf(stderr, "%s: The picture is %d by %d, with a gamma of %f\n",
  198.         progname, xsize, ysize, gamma);
  199.  
  200.  
  201.     putpict(xsize, ysize);    /* Here is where all the work is done */
  202.  
  203.     putashort(PICT_EndOfPicture); /* end of pict */
  204.  
  205.     picsize = outbytes-HEADER_SIZE;
  206.     fseek(stdout,ssizepos,0);
  207.     putashort(picsize&0xffff);
  208.     fseek(stdout,lsizepos,0);
  209.     putalong(picsize);
  210.  
  211.     fclose(stdout);
  212.     fclose(stdin);
  213.     
  214.     exit(0);
  215.     return 0;        /* lint fodder */
  216. }
  217.  
  218. putpict(xsize, ysize)
  219. int xsize;
  220. int ysize;
  221. {
  222.     int        y;
  223.     int        nbytes, rowbytes;
  224.     char    *cbuf, *pbuf;
  225.  
  226.     cbuf = malloc(4 * xsize);
  227.  
  228.     if (cbuf == NULL) {
  229.     fprintf(stderr, "%s: not enough memory\n", progname);
  230.     exit(1);
  231.     }
  232.  
  233.     pbuf = malloc(4 * xsize);
  234.  
  235.     if (pbuf == NULL) {
  236.     fprintf(stderr, "%s: not enough memory\n", progname);
  237.     exit(1);
  238.     }
  239.  
  240.     putashort(PICT_Pack32BitsRect); /* 32 bit rgb */
  241.     rowbytes = 4*xsize;
  242.     putalong(0x000000ff);        /* base address */
  243.  
  244.  
  245.     if(rowbytes&1)
  246.     rowbytes++;
  247.     putashort(rowbytes|0x8000); /* rowbytes */
  248.     putrect(0,0,xsize,ysize);    /* bounds */
  249.     putashort(0);        /* version */
  250.  
  251.     putashort(4);    /* packtype */
  252.     putalong(0);    /* packsize */
  253.     putalong(72<<16);    /* hres */
  254.     putalong(72<<16);    /* vres */
  255.  
  256.     putashort(16);    /* pixeltype */
  257.     putashort(32);    /* pixelsize */
  258.     putashort(3);    /* cmpcount */
  259.  
  260.  
  261.     putashort(8);    /* cmpsize */
  262.     putalong(0);    /* planebytes */
  263.     putalong(0);    /* pmtable */
  264.     putalong(0);    /* pmreserved */
  265.  
  266.  
  267.     putrect(0,0,xsize,ysize);    /* scr rect */
  268.     putrect(0,0,xsize,ysize);    /* dest rect */
  269.  
  270.  
  271.     putashort(0x40);    /* transfer mode */
  272.  
  273.     for(y=0; y<ysize; y++) {
  274.     getrow(stdin, cbuf, xsize);
  275.  
  276.     nbytes = packbits(cbuf,pbuf,24*xsize);
  277.     if(rowbytes>250) 
  278.         putashort(nbytes);
  279.     else
  280.         putbyte(nbytes);
  281.     putbytes(pbuf,nbytes);
  282.     }
  283.  
  284.     if(outbytes&1) 
  285.     putbyte(0);
  286.  
  287.     free(cbuf);
  288.     free(pbuf);
  289. }
  290.  
  291. int getrow(in, cbuf, xsize)
  292. FILE *in;
  293. char *cbuf;
  294. int xsize;
  295. {
  296.     extern char *tempbuffer();        /* defined in color.c */
  297.     COLR    *scanin = NULL;
  298.     int        x;
  299.  
  300.     if ((scanin = (COLR *)tempbuffer(xsize*sizeof(COLR))) == NULL) {
  301.     fprintf(stderr, "%s: not enough memory\n", progname);
  302.     exit(1);
  303.     }
  304.  
  305.     if (freadcolrs(scanin, xsize, in) < 0) {
  306.     fprintf(stderr, "%s: read error\n", progname);
  307.     exit(1);
  308.     }
  309.  
  310.     if (bradj)        /* Adjust exposure level */
  311.     shiftcolrs(scanin, xsize, bradj);
  312.  
  313.  
  314.     colrs_gambs(scanin, xsize);        /* Gamma correct it */
  315.     
  316.     for (x = 0; x < xsize; x++) {
  317.     cbuf[x] = scanin[x][RED];
  318.     cbuf[xsize + x] = scanin[x][GRN];
  319.     cbuf[2*xsize + x] = scanin[x][BLU];
  320.     }
  321.  
  322. }
  323.  
  324.  
  325. packbits(ibits,pbits,nbits)
  326. unsigned char *ibits, *pbits;
  327. int nbits;
  328. {
  329.     int bytes;                /* UNUSED */
  330.     unsigned char *sptr;
  331.     unsigned char *ibitsend;
  332.     unsigned char *optr = pbits;
  333.     int nbytes, todo, cc, count;
  334.  
  335.     nbytes = ((nbits-1)/8)+1;
  336.     ibitsend = ibits+nbytes;
  337.     while(ibits<ibitsend) {
  338.     sptr = ibits;
  339.     ibits += 2;
  340.     while((ibits<ibitsend)&&((ibits[-2]!=ibits[-1])||(ibits[-1]!=ibits[0])))
  341.         ibits++;
  342.     if(ibits != ibitsend) {
  343.         ibits -= 2;
  344.     }
  345.     count = ibits-sptr;
  346.     while(count) {
  347.         todo = count>127 ? 127:count;
  348.         count -= todo;
  349.         *optr++ = todo-1;
  350.         while(todo--)
  351.         *optr++ = *sptr++;
  352.     }
  353.     if(ibits == ibitsend)
  354.         break;
  355.     sptr = ibits;
  356.     cc = *ibits++;
  357.     while( (ibits<ibitsend) && (*ibits == cc) )
  358.         ibits++;
  359.     count = ibits-sptr;
  360.     while(count) {
  361.         todo = count>128 ? 128:count;
  362.         count -= todo;
  363.         *optr++ = 257-todo;
  364.         *optr++ = cc;
  365.     }
  366.     }
  367.     return optr-pbits;
  368. }
  369.  
  370. usage()
  371. {
  372.     fprintf(stderr, "Usage: %s [-v] [-g gamma] [infile [outfile]]\n",
  373.     progname);
  374.     exit(2);
  375. }
  376.