home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma01.dms / ma01.adf / wasp / src / wriffout.c < prev   
C/C++ Source or Header  |  1991-12-26  |  8KB  |  401 lines

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