home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / PVQUAN15.ZIP / FLILIB.ZIP / LCCOMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-30  |  3.7 KB  |  148 lines

  1. /* fii_lccomp.c - Some C code that mixes with the assembler code in
  2.    comp.asm and skip.asm to make up compressed pixel packets suitable
  3.    for incorporation into a FLI file.  See also writefli.c */
  4.  
  5. #ifdef __TURBOC__
  6. #include <mem.h>
  7. #endif
  8.  
  9. #include "aatypes.h"
  10. #include "aaerr.h"
  11. #include "aascreen.h"
  12. #include "str_low.h"
  13. #include "aafli.h"
  14. #include "aaflisav.h"
  15. #include "aafii.h"
  16.  
  17. #define INERTIA 4
  18.  
  19. static Pixel *sbrc_line(Pixel *s1, Pixel *s2, Pixel *cbuf, int count)
  20. {
  21.     register int wcount;
  22.     register Pixel *c;
  23.     int op_count;
  24.     int next_match;
  25.     int bcount;
  26.  
  27.     op_count = 0;
  28.     c = cbuf+1;
  29.     while(count > 0) {
  30.         /* first find out how many bytes to skip... */
  31.         wcount = bcompare(s1, s2, count);
  32.         if ((count -= wcount) <= 0) break;    /* same until the end... */
  33.         /* if skip is longer than 255 have to break it up into smaller ops */
  34.         while (wcount > 255) {
  35.             s1 += 255+1;
  36.             s2 += 255;
  37.             wcount -= 255+1;
  38.             /* make dummy copy 1 op */
  39.             *c++ = 255;
  40.             *c++ = 1;
  41.             *c++ = *s2++;
  42.             op_count++;
  43.         }
  44.         /* save initial skip and move screen pointer to 1st different byte */
  45.         *c++ = wcount;
  46.         s1 += wcount;
  47.         s2 += wcount;
  48.         op_count++;
  49.  
  50.         /* if have skipped to near the end do a literal copy... */
  51.         if (count <= INERTIA) {
  52.             *c++ = count;
  53.             memcpy(c, s2, count);
  54.             c += count;
  55.             break;
  56.         }
  57.  
  58.         /* now look for a run of same... */
  59.         bcount = count;
  60.         if (bcount > FLI_MAX_RUN)        bcount = FLI_MAX_RUN;
  61.  
  62.         wcount = bsame(s2, bcount);
  63.         if (wcount >= INERTIA) {    /* it's worth doing a same thing thing */
  64.             next_match = fii_tnskip(s1, s2, wcount,INERTIA);
  65.  
  66.             if (next_match < wcount) /* if it's in our space and a decent size */
  67.                                              /* we'll cut short same run for the skip */
  68.                 wcount = next_match;
  69.             *c++ = -wcount;
  70.             *c++ = *s2;
  71.             s1 += wcount;
  72.             s2 += wcount;
  73.             count -= wcount;
  74.         } else {    /* doing a literal copy.  What can we do to make it short? */
  75.             /* figure out how long until the next worthwhile "skip" */
  76.             /* Have wcount of stuff we can't skip through. */
  77.             wcount = fii_tnsame(s2, fii_tnskip(s1,s2,bcount,INERTIA-1),INERTIA);
  78.             /* Say copy positive count as lit copy op, and put bytes to copy
  79.                 into the compression buffer */
  80.             *c++ = wcount;
  81.             memcpy(c, s2, wcount);
  82.             s1 += wcount;
  83.             s2 += wcount;
  84.             c += wcount;
  85.             count -= wcount;
  86.         }
  87.     }
  88.     *cbuf = op_count;
  89.     return c;
  90. }
  91.  
  92. unsigned fii_lccomp(Pixel *s1, Pixel *s2, Cbuf *cbuf, int width, int height)
  93. {
  94.     USHORT skip_count, j;
  95.     Pixel *c;
  96.     Pixel *oc;
  97.     USHORT acc;
  98.     long total;
  99.     USHORT last_real;
  100.  
  101. /* find out how many lines of s1 and s2 are the same */
  102.     acc = width >> 1;    /* SHORTS in line */
  103.     j = height;
  104.     skip_count = 0;
  105.     total = 0;
  106.     while (--j >= 0)    {
  107.         if (wcompare(s1, s2, acc) != acc)        break;
  108.         s1 += width;
  109.         s2 += width;
  110.         skip_count++;
  111.     }
  112.  
  113. /* If all same do special case for empty frame*/
  114.     if (skip_count == height)        return 2;
  115.  
  116. /* store offset of 1st real line and set up for main line-at-a-time loop */
  117. #ifdef __TURBOC__
  118.     *((USHORT *)cbuf)++ = skip_count;
  119. #else
  120.     cbuf = wbuf(cbuf, skip_count);
  121. #endif
  122.     height -= skip_count;
  123.     c = cbuf + 2;
  124.     last_real = 0;    /* keep track of last moving line */
  125.     for (j=1; j<=height; j++) {
  126.         oc = c;
  127.         if (wcompare(s1,s2,acc) == acc)    /* whole line is the same */
  128.             *c++ = 0;                                /* set op count to 0 */
  129.         else    {                    /* compress line */
  130.             c = sbrc_line(s1, s2, c, width);
  131.             last_real = j;
  132.         }
  133.         total += (long)(c - oc);
  134.         if (total >= 60000L)        return 0;
  135.         s1 += width;
  136.         s2 += width;
  137.     }
  138. /* set # of lines in compression to last real, removing empty bottom lines
  139.    from buffer */
  140. #ifdef __TURBOC__
  141.     *(USHORT *)cbuf = last_real;
  142. #else
  143.     wbuf(cbuf, last_real);
  144. #endif
  145.     c -= height-last_real;
  146.     return (unsigned)(c - cbuf) + 2;
  147. }
  148.