home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / flilib.arj / LCCOMP.C < prev    next >
C/C++ Source or Header  |  1989-11-17  |  4KB  |  162 lines

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