home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 564a.lha / wasp_v1.21 / Src.LZH / Src / wriffout.c < prev   
C/C++ Source or Header  |  1991-10-19  |  8KB  |  430 lines

  1. /* wasp - copyright Steven Reiz 1990, 1991
  2.  * see wasp.c for further info
  3.  * wriffout.c, 4/12/90 - 29/12/90,
  4.  * 4/5/91 - 2/6/91, 23/6/91 - 30/6/91, 3/7/91 - 8/7/91
  5.  */
  6.  
  7. #include "wasp.h"
  8. #include "wriff.h"
  9. #ifndef NOSH
  10. #include "wriffout.sh"
  11. #endif
  12.  
  13. static u_char *prtab[16], *pgtab[16], *pbtab[16], *pxtab[16];
  14. static long squares[]={
  15.     0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225
  16. };
  17.  
  18.  
  19. #ifdef __STDC__
  20. row_out(int row)
  21. #else
  22. row_out(row)
  23. int row;
  24. #endif
  25. {
  26.     long currow; /* u_char *currow; */
  27.     short *ps, i, x, bperrow;
  28.     char regind;
  29.     u_char *p, *q;
  30.  
  31.     counter();
  32.     currow=(long)next_row(0);
  33.     bperrow=bytesperrow;
  34.     ps=(short *)currow;
  35.     i=bperrow*nplanes/2-1;
  36.     do {
  37.         *ps++ =0;
  38.     } while (--i>=0);
  39.     ps=(short *)rgb[row];
  40.     for (x=0; x<xsz; ++x) {
  41.         i= *ps++;
  42.         regind=newcol[i];
  43.         err+=error[i];
  44.         err2+=error2[i];
  45.         p=conv+((regind<<3)|(x&7))*MAXNPLANES;
  46.         q=(u_char *)currow+(x>>3);
  47.         switch (nplanes) {
  48.         case 8: *q|= *p++; q+=bperrow;
  49.         case 7: *q|= *p++; q+=bperrow;
  50.         case 6: *q|= *p++; q+=bperrow;
  51.         case 5: *q|= *p++; q+=bperrow;
  52.         case 4: *q|= *p++; q+=bperrow;
  53.         case 3: *q|= *p++; q+=bperrow;
  54.         case 2: *q|= *p++; q+=bperrow;
  55.         case 1: *q|= *p;
  56.         }
  57.     }
  58. }
  59.  
  60.  
  61. #ifdef __STDC__
  62. rgb_row_out(int row)
  63. #else
  64. rgb_row_out(row)
  65. int row;
  66. #endif
  67. {
  68.     u_char *currow;
  69.     short *ps, i, bitlast;
  70.  
  71.     counter();
  72.     currow=next_row(0);
  73.     ps=(short *)currow;
  74.     i=bytesperrow*nplanes/2-1;
  75.     do {
  76.         *ps++ =0;
  77.     } while (--i>=0);
  78.     for (bitlast=12; bitlast>0; bitlast-=4) { /* walk over r, g, and b */
  79.         for (i=0; i<nzero; ++i)
  80.             currow+=bytesperrow;
  81.         for (i=bitlast-ncolor; i<bitlast; ++i) {
  82.             rgb_line(row, currow, (int)i);
  83.             currow+=bytesperrow;
  84.         }
  85.     }
  86. }
  87.  
  88.  
  89. #ifdef __STDC__
  90. PRIVATE rgb_line(int y, u_char *inq, int bitnum)
  91. #else
  92. PRIVATE rgb_line(y, inq, bitnum)
  93. int y;
  94. u_char *inq;
  95. int bitnum;
  96. #endif
  97. {
  98.     u_short *p, mask;
  99.     u_char *q, byte;
  100.     short i;
  101.     
  102.     i=bytesperrow-1;
  103.     p=rgb[y];
  104.     mask=1<<bitnum;
  105.     q=inq;
  106.     do {
  107.         byte=0;
  108.         if (*p++ & mask) byte|=0x80;
  109.         if (*p++ & mask) byte|=0x40;
  110.         if (*p++ & mask) byte|=0x20;
  111.         if (*p++ & mask) byte|=0x10;
  112.         if (*p++ & mask) byte|=0x08;
  113.         if (*p++ & mask) byte|=0x04;
  114.         if (*p++ & mask) byte|=0x02;
  115.         if (*p++ & mask) byte|=0x01;
  116.         *q++ =byte;
  117.     } while (--i>=0);
  118. }
  119.  
  120.  
  121. #ifdef __STDC__
  122. ham_row_out(int row)
  123. #else
  124. ham_row_out(row)
  125. int row;
  126. #endif
  127. {
  128.     NON_REG int alternate_rgb;
  129.     long currow; /* actually u_char *currow; */
  130.     short *ps;
  131.     long x, curcolor; /* curcolor doubles as bperrow */
  132.     long r, g, b, pr, pg, pb, d1, d2, d3;
  133.     u_char *p, *q;
  134.  
  135.     counter();
  136.     currow=(long)next_row(0);
  137.     p=(u_char *)currow;
  138.     r=bytesperrow*3-1;
  139. #ifdef LATTICE
  140.     do {
  141.         *(short *)p=0;
  142.         p+=2;
  143.     } while (--r>=0);
  144. #else
  145.     do {
  146.         *((short *)p)++ =0;
  147.     } while (--r>=0);
  148. #endif
  149.     ps=(short *)rgb[row];
  150.     pb=curcm[0];
  151.     pr=pb>>8;
  152.     pg=(pb>>4)&0xf;
  153.     pb&=0xf;
  154.     alternate_rgb=0;
  155.     for (x=0; x<xsz; ++x) {
  156.         curcolor= *ps++;
  157.         b=curcolor;
  158.         r=b>>8;
  159.         g=(b>>4)&0xf;
  160.         b&=0xf;
  161.         if (r==pr) {
  162.             if (g==pg) {
  163.                 if (b==pb) {    /* r ok, g ok, b ok */
  164.                     if (++alternate_rgb==1) {
  165.                         p=pgtab[g];
  166.                     } else if (alternate_rgb==2) {
  167.                         p=prtab[r];
  168.                     } else {
  169.                         p=pbtab[b];
  170.                         alternate_rgb=0;
  171.                     }
  172.                 } else {    /* r ok, g ok, b wrong */
  173.                     p=pbtab[b];
  174.                     pb=b;
  175.                 }
  176.             } else {
  177.                 if (b==pb) {    /* r ok, g wrong, b ok */
  178.                     p=pgtab[g];
  179.                     pg=g;
  180.                 } else {    /* r ok, g wrong, b wrong */
  181.                     if ((d1=g-pg)<0) d1= -d1;
  182.                     if ((d2=b-pb)<0) d2= -d2;
  183.                     if (error[curcolor]<(d1<d2 ? d1 : d2)) {
  184.                         err+=error[curcolor];
  185.                         err2+=error2[curcolor];
  186.                         curcolor=newcol[curcolor];
  187.                         p=pxtab[curcolor];
  188.                         pb=curcm[curcolor];
  189.                         pr=pb>>8;
  190.                         pg=(pb>>4)&0xf;
  191.                         pb&=0xf;
  192.                     } else if (d1>=d2) {
  193.                         err+=d2;
  194.                         err2+=squares[d2];
  195.                         p=pgtab[g];
  196.                         pg=g;
  197.                     } else {
  198.                         err+=d1;
  199.                         err2+=squares[d1];
  200.                         p=pbtab[b];
  201.                         pb=b;
  202.                     }
  203.                 }
  204.             }
  205.         } else {
  206.             if (g==pg) {
  207.                 if (b==pb) {    /* r wrong, g ok, b ok */
  208.                     p=prtab[r];
  209.                     pr=r;
  210.                 } else {    /* r wrong, g ok, b wrong */
  211.                     if ((d1=r-pr)<0) d1= -d1;
  212.                     if ((d2=b-pb)<0) d2= -d2;
  213.                     if (error[curcolor]<(d1<d2 ? d1 : d2)) {
  214.                         err+=error[curcolor];
  215.                         err2+=error2[curcolor];
  216.                         curcolor=newcol[curcolor];
  217.                         p=pxtab[curcolor];
  218.                         pb=curcm[curcolor];
  219.                         pr=pb>>8;
  220.                         pg=(pb>>4)&0xf;
  221.                         pb&=0xf;
  222.                     } else if (d1>=d2) {
  223.                         err+=d2;
  224.                         err2+=squares[d2];
  225.                         p=prtab[r];
  226.                         pr=r;
  227.                     } else {
  228.                         err+=d1;
  229.                         err2+=squares[d1];
  230.                         p=pbtab[b];
  231.                         pb=b;
  232.                     }
  233.                 }
  234.             } else {
  235.                 if (b==pb) {    /* r wrong, g wrong, b ok */
  236.                     if ((d1=r-pr)<0) d1= -d1;
  237.                     if ((d2=g-pg)<0) d2= -d2;
  238.                     if (error[curcolor]<(d1<d2 ? d1 : d2)) {
  239.                         err+=error[curcolor];
  240.                         err2+=error2[curcolor];
  241.                         curcolor=newcol[curcolor];
  242.                         p=pxtab[curcolor];
  243.                         pb=curcm[curcolor];
  244.                         pr=pb>>8;
  245.                         pg=(pb>>4)&0xf;
  246.                         pb&=0xf;
  247.                     } else if (d1>d2) {
  248.                         err+=d2;
  249.                         err2+=squares[d2];
  250.                         p=prtab[r];
  251.                         pr=r;
  252.                     } else {
  253.                         err+=d1;
  254.                         err2+=squares[d1];
  255.                         p=pgtab[g];
  256.                         pg=g;
  257.                     }
  258.                 } else {    /* r wrong, g wrong, b wrong */
  259.                     if ((d1=r-pr)<0) d1= -d1;
  260.                     if ((d2=g-pg)<0) d2= -d2;
  261.                     if ((d3=b-pb)<0) d3= -d3;
  262.                     if (error[curcolor]<(d1>d2 ? (d1>d3 ? d2+d3 : d1+d2) : (d2>d3 ? d1+d3 : d1+d2))) {
  263.                         err+=error[curcolor];
  264.                         err2+=error2[curcolor];
  265.                         curcolor=newcol[curcolor];
  266.                         p=pxtab[curcolor];
  267.                         pb=curcm[curcolor];
  268.                         pr=pb>>8;
  269.                         pg=(pb>>4)&0xf;
  270.                         pb&=0xf;
  271.                     } else if (d1>d2 && d1>=d3) {
  272.                         err+=d2+d3;
  273.                         err2+=squares[d2]+squares[d3];
  274.                         p=prtab[r];
  275.                         pr=r;
  276.                     } else if (d2>=d3) {
  277.                         err+=d1+d3;
  278.                         err2+=squares[d1]+squares[d3];
  279.                         p=pgtab[g];
  280.                         pg=g;
  281.                     } else {
  282.                         err+=d1+d2;
  283.                         err2+=squares[d1]+squares[d2];
  284.                         p=pbtab[b];
  285.                         pb=b;
  286.                     }
  287.                 }
  288.             }
  289.         }
  290.         p+=(x&7)<<MAXPLANESHIFT;
  291.         q=(u_char *)currow+(x>>3);
  292.         curcolor=bytesperrow;
  293.         *q|= *p++; q+=curcolor;
  294.         *q|= *p++; q+=curcolor;
  295.         *q|= *p++; q+=curcolor;
  296.         *q|= *p++; q+=curcolor;
  297.         *q|= *p++; q+=curcolor;
  298.         *q|= *p;
  299.     }
  300. }
  301.  
  302.  
  303. #ifdef __STDC__
  304. fill_prgbtab(void)
  305. #else
  306. fill_prgbtab()
  307. #endif
  308. {
  309.     int i;
  310.  
  311.     for (i=0; i<16; ++i) {
  312.         prtab[i]=conv+((0x20+i)<<(3+MAXPLANESHIFT));
  313.         pgtab[i]=conv+((0x30+i)<<(3+MAXPLANESHIFT));
  314.         pbtab[i]=conv+((0x10+i)<<(3+MAXPLANESHIFT));
  315.         pxtab[i]=conv+(i<<(3+MAXPLANESHIFT));
  316.     }
  317. }
  318.  
  319.  
  320. #ifdef __STDC__
  321. u_char *next_row(int flush)
  322. #else
  323. u_char *next_row(flush)
  324. int flush;
  325. #endif
  326. {
  327.     static int freerows= -1;
  328.     static u_char *currow;
  329.  
  330.     if (flush) {
  331.     char c;
  332.  
  333.         cwritec((int)((noutrows-freerows)*bytesperrow*nplanes));
  334.     if (body_size&1) {
  335.         c=0;
  336.         cwrite(&c, 1);
  337.         ++body_size;
  338.     }
  339.     if (compression)
  340.         erase_counter("IFF output; body compression: %ld%%",
  341.          body_size*100L/(xsz*ysz*(long)nplanes/8L));
  342.         return NULL; /* return value not used */
  343.     }
  344.     if (--freerows<0) {
  345.         if (freerows== -1)
  346.             cwritec(outbufsz);
  347.         freerows=noutrows-1;
  348.         currow=outrows;
  349.     } else 
  350.         currow+=bytesperrow*nplanes;
  351.     return currow;
  352. }
  353.  
  354.  
  355. #ifdef __STDC__
  356. PRIVATE cwritec(int inlen)
  357. #else
  358. PRIVATE cwritec(inlen)
  359. int inlen;
  360. #endif
  361. {
  362.     REG char *p, *r;
  363.     char *q, *countp, *curoutrows;
  364.     short n, todo;
  365.     char c;
  366.  
  367.     if (!compression) {
  368.         cwrite(outrows, inlen);
  369.         body_size+=inlen;
  370.         return;
  371.     }
  372.     assert(!(inlen%bytesperrow));
  373.     inlen/=bytesperrow;
  374.     curoutrows=(char *)outrows;
  375.     r=(char *)outcrows;
  376.     while (--inlen>=0) {
  377.         todo=bytesperrow;
  378.         p=(char *)curoutrows;
  379.         q=p+todo-2;
  380.         while (p<q) {
  381.             c= *p;
  382.             if (*(p+1)==c) {
  383.                 countp=p;
  384.                 p+=2;
  385.                 n=todo-(p-curoutrows);
  386.                 if (n>126)
  387.                     n=126;
  388.                 while (*p==c && --n>=0)
  389.                     ++p;
  390.                 *r++ =countp-p+1;
  391.                 *r++ =c;
  392.             } else {
  393.                 countp=r++;
  394.                 n=todo-(p-curoutrows);
  395.                 if (n>128)
  396.                     n=128;
  397.                 do {
  398.                     ++p;
  399.                     if (*p==c && *(p+1)==c) {
  400.                         --p;
  401.                         break;
  402.                     }
  403.                     *r++ =c;
  404.                     c= *p;
  405.                 } while (--n>0);
  406.                 *countp=r-countp-2;
  407.             }
  408.         }
  409.         todo=curoutrows+todo-p;
  410.         assert(todo<=2);
  411.         if (todo==1) {
  412.             *r++ =0;
  413.             *r++ = *p;
  414.         } else if (todo==2) {
  415.             c= *p++;
  416.             if (c== *p) {
  417.                 *r++ = -1;
  418.                 *r++=c;
  419.             } else {
  420.                 *r++ =1;
  421.                 *r++ =c;
  422.                 *r++ = *p;
  423.             }
  424.         }
  425.         curoutrows+=bytesperrow;
  426.     }
  427.     cwrite(outcrows, (int)(r-outcrows));
  428.     body_size+=r-outcrows;
  429. }
  430.