home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / formats / uray / code / output.c < prev    next >
C/C++ Source or Header  |  1994-06-20  |  8KB  |  277 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *            Copyright (c) 1988, David B. Wecker            *
  4.  *                All Rights Reserved                *
  5.  *                                    *
  6.  * This file is part of DBW_uRAY                    *
  7.  *                                    *
  8.  * DBW_uRAY is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts        *
  10.  * responsibility to anyone for the consequences of using it or for    *
  11.  * whether it serves any particular purpose or works at all, unless    *
  12.  * he says so in writing. Refer to the DBW_uRAY General Public        *
  13.  * License for full details.                        *
  14.  *                                    *
  15.  * Everyone is granted permission to copy, modify and redistribute    *
  16.  * DBW_uRAY, but only under the conditions described in the        *
  17.  * DBW_uRAY General Public License. A copy of this license is        *
  18.  * supposed to have been given to you along with DBW_uRAY so you    *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named LICENSE. Among other things, the copyright notice and this    *
  21.  * notice must be preserved on all copies.                *
  22.  ************************************************************************
  23.  *                                    *
  24.  * Authors:                                *
  25.  *    DBW - David B. Wecker                        *
  26.  *                                    *
  27.  * Versions:                                *
  28.  *    V1.0 881023 DBW    - First released version            *
  29.  *    V1.1 881110 DBW - Fixed scan coherence code            *
  30.  *    V1.2 881125 DBW - Removed ALL scan coherence code (useless)    *
  31.  *              added "fat" extent boxes            *
  32.  *    V1.3 881203 DBW - Fixed single precision TOLerances        *
  33.  *                                    *
  34.  ************************************************************************/
  35.  
  36. #include "uray.h"
  37.  
  38.  
  39. /************************************************************************/
  40. /************ module to write output files ******************************/
  41. /************************************************************************/
  42.  
  43.  
  44. void wfil(fil,cnt,val)        /* write a number to a file (68000 order) */
  45. FILE    *fil;
  46. short    cnt;
  47. char    val[];
  48.     {
  49.  
  50. #ifndef VAXBYTES
  51.     fwrite(val,cnt,1,fil);
  52. #else
  53.     while (cnt--) fwrite(&val[cnt],1,1,fil);
  54. #endif
  55.  
  56.     }
  57.  
  58. short rfil(fil,cnt,val)        /* read a number from a file (68000 order) */
  59. FILE    *fil;
  60. short    cnt;
  61. char    val[];
  62.     {
  63.  
  64. #ifndef VAXBYTES
  65.     if (fread(val,cnt,1,fil) != 1)           return(-1);
  66. #else
  67.     while (cnt--) if (fread(&val[cnt],1,1,fil) != 1) return(-1);
  68. #endif
  69.  
  70.     return(0);
  71.     }
  72.  
  73.  
  74. /* create output files */
  75. void coutputs() {
  76.     int        i;
  77.  
  78.     /* first create the output .tmp file */
  79.     if (bpp) {
  80.     sprintf(str,"%s.tmp",basnam);
  81.     fp = fopen(str,"w");
  82.     if (!fp) leave("Bad output file");
  83.  
  84.     /* write out the header */
  85.     wfil(fp,sizeof(short),&startrow);
  86.     wfil(fp,sizeof(short),&endrow);
  87.     wfil(fp,sizeof(short),&cols);
  88.     wfil(fp,sizeof(short),&bpp);
  89.     }
  90.  
  91.     /* second, create the output .ilbm file */
  92.     sprintf(str,"%s.ilbm",basnam);
  93.     fp2 = fopen(str,"w");
  94.     if (!fp2) leave("Bad output file (ilbm)");
  95.  
  96.     /* write out the header */
  97.     sprintf(str,"FORM");    fwrite(str,1,4,fp2);
  98.     pos1 = ftell(fp2);
  99.     lng = FORMsize;        wfil(fp2,sizeof(long),&lng);
  100.     sprintf(str,"ILBM");    fwrite(str,1,4,fp2);
  101.  
  102.     sprintf(str,"BMHD");    fwrite(str,1,4,fp2);
  103.     lng = BMHDsize;        wfil(fp2,4,&lng);
  104.     wrd = cols;            wfil(fp2,2,&wrd);   /* width */
  105.     wrd = rows;            wfil(fp2,2,&wrd);   /* height */
  106.     wrd = startrow;        wfil(fp2,2,&wrd);   /* top */
  107.     wrd = 0;            wfil(fp2,2,&wrd);   /* left */
  108.     byt = DEPTH;        wfil(fp2,1,&byt);   /* Depth */
  109.     byt = 0;            wfil(fp2,1,&byt);   /* mask */
  110.     byt = 1;            wfil(fp2,1,&byt);   /* compress */
  111.     byt = 0;            wfil(fp2,1,&byt);   /* pad */
  112.     wrd = 0;            wfil(fp2,2,&wrd);   /* transparency */
  113.     byt = 10;            wfil(fp2,1,&byt);   /* aspect x */
  114.     byt = 11;            wfil(fp2,1,&byt);   /* aspect y */
  115.     wrd = cols;            wfil(fp2,2,&wrd);   /* page width */
  116.     wrd = rows;            wfil(fp2,2,&wrd);   /* page height */
  117.  
  118.     sprintf(str,"CAMG");    fwrite(str,1,4,fp2);
  119.     lng = CAMGsize;        wfil(fp2,4,&lng);
  120.     lng    = HAM | LACE;        wfil(fp2,4,&lng);
  121.  
  122.     sprintf(str,"CMAP");    fwrite(str,1,4,fp2);
  123.     lng = CMAPsize;        wfil(fp2,4,&lng);
  124.     pos3 = ftell(fp2);
  125.     colors[0][0] = colors[0][1] = colors[0][2] = 0;
  126.     lstcolor      = 1;
  127.     fwrite(colors,1,48,fp2);
  128.     fwrite(colors,1,48,fp2);
  129.  
  130.     sprintf(str,"BODY");    fwrite(str,1,4,fp2);
  131.     pos2 = ftell(fp2);
  132.     lng = BODYsize;        wfil(fp2,4,&lng);
  133.  
  134.     lsize = 0L;
  135.     }
  136.  
  137. /* write a scan line to the output files */
  138. void woutputs(sline)
  139. short    sline;
  140.     {
  141.     int            i,j,k,c,d,old[3],new[3],x,pxl,scr,addok,
  142.             index,bdist,ndist,maxdist,dcol,dval;
  143.     unsigned char   buf[512],planes[6][128],b1,b2;
  144.  
  145.     /* print out 'dots' so the user knows we're working */
  146.     if (sline % 50 == 0 || sline == startrow)    
  147.                 printf("Row %4d: ",sline);
  148.     printf(".");
  149.     if (sline % 50 == 49)   printf("\n");
  150.     else            fflush(stdout);
  151.  
  152.     /* write out a scan line to .tmp file */
  153.     if (bpp) {
  154.     wfil(fp,sizeof(short),&sline);
  155.  
  156.     /* now write out each color of the scan line */
  157.     for (i=0; i<3; i++) {
  158.  
  159.         /* write out 24 bits per pixel */
  160.         if (cols == obpsl) fwrite(outary[i],1,obpsl,fp);
  161.  
  162.         /* or 12 bits per pixel (need to pack it) */
  163.         else {
  164.         for (x=0; x<cols; x++) {
  165.             b1   = outary[i][x];
  166.             b2   = b1 >> 4;
  167.             if (x & 1)    buf[x>>1] |= b2 & 0x0F;
  168.             else    buf[x>>1]  = b1 & 0xF0;
  169.             }
  170.         fwrite(buf,1,obpsl,fp);
  171.         }
  172.         }
  173.     fflush(fp);
  174.     }
  175.  
  176.     /* initialize the HAM encoding */
  177.     for (i=0; i<3; i++) old[i] = 0;
  178.     for (d=0; d<6; d++)
  179.     for (i=0; i<MAXBYTE; i++)
  180.         planes[d][i] = 0;
  181.  
  182.     /* allow 1 new color to be added to colors[] per scan line (max) */
  183.     addok = 1;
  184.  
  185.     /* set the amount of error for adding new colors[] */
  186.     if (sline < (rows>>1))  maxdist = 127;
  187.     else            maxdist = 63;
  188.  
  189.     for (x=0; x<cols; x++,dcol++) {
  190.  
  191.     /* first get the desired old values (dither as necessary) */
  192.     for (i=0; i<3; i++) {
  193.         dval    = ((int)outary[i][x]) & 0xF;
  194.         new[i]  = ((int)outary[i][x]) & 0xF0;
  195.         if (dval && new[i] != 0xF0 && dval > (random() & 0xF))
  196.         new[i] += 0x10;
  197.         }
  198.  
  199.     /* get the best absolute color */
  200.     bdist = 9999;
  201.     for (i=0; i<lstcolor; i++) {
  202.         ndist = 0;
  203.         for (j=0; j<3; j++) 
  204.         ndist += ABS(new[j] - (int)colors[i][j]);
  205.         if (ndist < bdist) {
  206.         bdist = ndist;
  207.         index = i;
  208.         }
  209.         }
  210.  
  211.     /* now find worst color (to make relative change) */
  212.     ndist = 0;
  213.     j     = -1;
  214.     for (i = 0; i<3; i++) {
  215.         if ((k=ABS(new[i] - old[i])) > j) { 
  216.         c   = i; 
  217.         j   = k;
  218.         }
  219.         ndist += k;
  220.         }
  221.  
  222.     /* subtract off the gun we want to fix */
  223.     ndist -= j;
  224.  
  225.     /* if relative is best, flag it (index = -1) (unless first pixel) */
  226.     if (x > 0 && ndist < bdist) {
  227.         bdist = ndist;
  228.         index = -1;
  229.         }
  230.  
  231.     /* decide if we need a new color in the color table */
  232.     if (addok && lstcolor < 16 && bdist > maxdist) {
  233.         for (i=0; i<3; i++) colors[lstcolor][i] = (unsigned char)new[i];
  234.         addok = 0;
  235.         bdist = 0;
  236.         index = lstcolor++;
  237. #        if DEBUG_ilbm
  238.         printf("Adding color %2d: %02x%02x%02x\n",index,
  239.             new[0],new[1],new[2]);
  240. #        endif
  241.         }
  242.  
  243.     /* now change the gun (for relative) */
  244.     if (index == -1) {
  245.         pxl = (old[c] = new[c]) >> 4;
  246.         switch (c) {
  247.         case 0: pxl |= 0x20;  break;
  248.         case 1: pxl |= 0x30;  break;
  249.         case 2: pxl |= 0x10;  break;
  250.         }
  251.         }
  252.     else {
  253.         pxl = index;
  254.         for (i=0; i<3; i++) old[i] = (int)colors[index][i];
  255.         }
  256.  
  257. #    if DEBUG_ilbm
  258.         printf("%4d,%4d: %02x (%d)\n",sline,x,pxl,bdist);
  259. #        endif
  260.  
  261.     /* and store the pixel away */
  262.     j = x >> 3;
  263.     k = 7 - (x & 0x7);
  264.     for (i=0; i<DEPTH; i++) {
  265.         planes[i][j] |= (pxl & 1) << k;
  266.         pxl >>= 1;
  267.         }
  268.     }
  269.  
  270.     /* now pack the row away (RKM run length encoding) */
  271.     for (i=0; i < DEPTH; i++) {
  272.     wrd    = PackRow(planes[i],buf,MAXBYTE);
  273.     lsize += (long)wrd;
  274.     fwrite(buf,1,wrd,fp2);
  275.     }
  276.     }
  277.