home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fonts 1 / freshfonts1.bin / bbs / programs / amiga / pastex13.lha / DVIPS / dvips5519.lha / dvips / repack.c < prev    next >
C/C++ Source or Header  |  1993-01-31  |  14KB  |  459 lines

  1. /*
  2.  *   Compressed TeX fonts in PostScript.
  3.  *   By Radical Eye Software.
  4.  *   (Slight mods by Don Knuth in December 89.)
  5.  */
  6. #include "dvips.h" /* The copyright notice in that file is included too! */
  7. #ifdef DEBUG
  8. extern integer debug_flag;
  9. #endif /* DEBUG */
  10.  
  11. /*   Given a raster that has been unpacked from PK format,
  12.  *   we compress it by another scheme that is suitable for
  13.  *   a PostScript-oriented unpacking. We write instructions for
  14.  *   a little interpreter whose one-byte instructions have the form
  15.  *   18*opcode+parameter. The interpreter forms each row based
  16.  *   on simple transformations to the previous row. */
  17.  
  18. #define MAXOUT (18)
  19. #define CMD(n) (MAXOUT*(n))
  20. #define ADVXCHG1 CMD(0)
  21. #define ADVXCHG1END CMD(1)
  22. #define CHGX CMD(2)-1
  23. #define CHGXEND CMD(3)-1
  24. #define ADVXLSH CMD(4)
  25. #define ADVXLSHEND CMD(5)
  26. #define ADVXRSH CMD(6)
  27. #define ADVXRSHEND CMD(7)
  28. #define ADVX CMD(8)-1
  29. #define REPX CMD(9)-1
  30. #define SETX CMD(10)-1
  31. #define CLRX CMD(11)-1
  32. #define ADVXCHG2 CMD(12)
  33. #define ADVXCHG2END CMD(13)
  34. #define END CMD(14)
  35.  
  36. extern void error() ;
  37. extern long getlong() ;
  38. extern long unpack() ;
  39.  
  40. static int rowlength = 0 ;
  41. static unsigned char *specdata ;
  42. static long tslen = 0 ;
  43. static unsigned char *tempstore, *tsp, *tsend ;
  44.  
  45. void putlong(a, i)
  46. register char *a ;
  47. long i ;
  48. {
  49.    a[0] = i >> 24 ;
  50.    a[1] = i >> 16 ;
  51.    a[2] = i >> 8 ;
  52.    a[3] = i ;
  53. }
  54.  
  55. long getlong(a)
  56. register unsigned char *a ;
  57. {
  58.    return ((((((a[0] << 8L) + a[1]) << 8L) + a[2]) << 8L) + a[3]) ;
  59. }
  60.  
  61. /* First, a routine that appends one byte to the compressed output. */
  62.  
  63. #define addtse(n) {lcm=tsp-tempstore;addts(n);} /* mark END option position */
  64.  
  65. static void addts(what)
  66. register unsigned char what ;
  67. {
  68.    register unsigned char *p, *q ;
  69.  
  70.    if (tsp >= tsend) {
  71.       if (tempstore == NULL) {
  72.          tslen = 2020 ;
  73.          tempstore = (unsigned char *)mymalloc((integer)tslen) ;
  74.          tsp = tempstore ;
  75.       } else {
  76.          tslen = 2 * tslen ;
  77.          tsp = (unsigned char *)mymalloc((integer)tslen) ;
  78.          for (p=tempstore, q=tsp; p<tsend; p++, q++)
  79.             *q = *p ;
  80.          free((char *)tempstore) ;
  81.          tempstore = tsp ;
  82.          tsp = q ;
  83.       }
  84.       tsend = tempstore + tslen ;
  85.    }
  86.    *tsp++ = what ;
  87. }
  88.  
  89. /* Next, a routine that discovers how to do the compression. */
  90.  
  91. #define rsh(a,b) ( ((a)==0) ? ((b)==128) : ( ((a)==255) ? ((b)==127) :\
  92.                                     ((b)==(((a)>>1)|((a)&128))) ))
  93. #define lsh(a,b) ( ((a)==0) ? ((b)==1) : ( ((a)==255) ? ((b)==254) :\
  94.                                     ((b)==((((a)<<1)&255)|((a)&1))) ))
  95. #define DIFFERENT (1)
  96. #define LSHPOSSIB (2)
  97. #define RSHPOSSIB (4)
  98. #define BLKPOSSIB (8)
  99. #define WHTPOSSIB (16)
  100. #define ENDROW (32)
  101. #define NOPOSSIB(n) ((n&(LSHPOSSIB|RSHPOSSIB|BLKPOSSIB|WHTPOSSIB))==0)
  102. #define NOSHIFT(n) ((n&(LSHPOSSIB|RSHPOSSIB))==0)
  103. /*
  104.  *   Our input bytes are packed to the 16-bit word.  On output,
  105.  *   they're packed to bytes. Thus, we may have to skip a byte at
  106.  *   the end of each row.
  107.  */
  108. void dochar(from, width, height)
  109. unsigned char *from ;
  110. short width, height ; /* in bytes */
  111. {
  112.    register int i ;
  113.    register unsigned char *f, *t, *d ;
  114.    register unsigned char *e ;
  115.    register int accum ;
  116.    int j, k, kk ;
  117.    int diffrow ;
  118.    int repeatcount ;
  119.    int lit, pos, cmd = 0 ;
  120.    long lcm ;
  121.    int widthc ;
  122.  
  123.    widthc = width + (width & 1) ; /* halfword correction */
  124.    lcm = -1 ;
  125.    if (widthc > rowlength) {
  126.       if (rowlength)
  127.          free((char *)specdata) ;
  128.       rowlength = widthc + 30 ;
  129.       specdata = (unsigned char *)mymalloc((integer)(rowlength + 15)) ;
  130.    }
  131.    for (i= -15, t=specdata; i<=widthc; i++, t++)
  132.       *t = 0 ;
  133.    repeatcount = 0 ;
  134.    f = specdata + 2 ;
  135.    for (j=0; j<height; j++, f = from, from += widthc) {
  136.       diffrow = 0 ;
  137.       for (i=0, t=from, d=specdata; i<width; i++, f++, t++, d++) {
  138.          if (*f == *t) {
  139.             if (*t == 0)
  140.                *d = WHTPOSSIB ;
  141.             else if (*t == 255)
  142.                *d = BLKPOSSIB ;
  143.             else
  144.                *d = 0 ;
  145.          } else {
  146.             accum = DIFFERENT ;
  147.             if (rsh(*f, *t))
  148.                accum |= RSHPOSSIB ;
  149.             else if (lsh(*f, *t))
  150.                accum |= LSHPOSSIB ;
  151.             if (*t == 0)
  152.                accum |= WHTPOSSIB ;
  153.             else if (*t == 255)
  154.                accum |= BLKPOSSIB ;
  155.             *d = accum ;
  156.             diffrow++ ;
  157.          }
  158.       } /* end 'for i' */
  159.       *d = ENDROW ;
  160.       if (diffrow == 0) {
  161.          repeatcount++ ;
  162.       } else {
  163.          if (repeatcount) {
  164.             while (repeatcount > MAXOUT) {
  165.                addts((unsigned char)(REPX+MAXOUT)) ;
  166.                repeatcount -= MAXOUT ;
  167.             }
  168.             addts((unsigned char)(REPX+repeatcount)) ;
  169.             repeatcount = 0 ;
  170.          }
  171.          pos = 0 ;
  172.          for (i=0, d=specdata, f=t-width; i<width;) {
  173.             if ((*d & DIFFERENT) == 0) {
  174.                i++ ;
  175.                d++ ;
  176.                f++ ;
  177.             } else {
  178.                accum = 0 ;
  179.                if (pos != i)
  180.                   lit = NOSHIFT(*d) ;
  181.                else /* N.B.: 'lit' does not imply literate programming here */
  182.                   lit = NOPOSSIB(*d) ;
  183.                for (e=d; ;e++) {
  184.                   if (NOPOSSIB(*e))
  185.                      lit = 1 ;
  186.                   if ((*e & DIFFERENT) == 0)
  187.                      break ;
  188.                   if ((*e & WHTPOSSIB) &&
  189.                       (e[1] & WHTPOSSIB)) {
  190.                      while (*e & WHTPOSSIB) {
  191.                         e++ ;
  192.                         accum++ ;
  193.                      }
  194.                      cmd = CLRX ;
  195.                      e -= accum ;
  196.                      break ;
  197.                   } else if ((*e & BLKPOSSIB) &&
  198.                       (e[1] & BLKPOSSIB)) {
  199.                      while (*e & BLKPOSSIB) {
  200.                         e++ ;
  201.                         accum++ ;
  202.                      }
  203.                      cmd = SETX ;
  204.                      e -= accum ;
  205.                      break ;
  206.                   }
  207.                } /* end 'for e'; d pts to first bad byte, e to next good one */
  208.                while (i - pos > MAXOUT) {
  209.                   addts((unsigned char)(ADVX+MAXOUT)) ;
  210.                   pos += MAXOUT ;
  211.                }
  212.                if (0 != (k = (e - d))) {
  213.                   if (lit) {
  214.                      if (k > 2) {
  215.                         if (i > pos) {
  216.                            addts((unsigned char)(ADVX + i - pos)) ;
  217.                            pos = i ;
  218.                         }
  219.                         while (k > MAXOUT) {
  220.                            addts((unsigned char)(CHGX + MAXOUT)) ;
  221.                            for (kk=0; kk<MAXOUT; kk++)
  222.                               addts((unsigned char)(*f++)) ;
  223.                            d += MAXOUT ;
  224.                            pos += MAXOUT ;
  225.                            i += MAXOUT ;
  226.                            k -= MAXOUT ;
  227.                         }
  228.                         addtse((unsigned char)(CHGX + k)) ;
  229.                         pos += k ;
  230.                         for (; d<e; d++, i++, f++)
  231.                            addts((unsigned char)(*f)) ;
  232.                      } else {
  233.                         if (k == 1) {
  234.                            if (i == pos+MAXOUT) {
  235.                               addts((unsigned char)(ADVX + MAXOUT)) ;
  236.                               pos = i ;
  237.                            }
  238.                            addtse((unsigned char)(ADVXCHG1 + i - pos)) ;
  239.                            addts((unsigned char)(*f)) ;
  240.                            i++ ;
  241.                            pos = i ;
  242.                            d++ ;
  243.                            f++ ;
  244.                         } else {
  245.                            if (i == pos+MAXOUT) {
  246.                               addts((unsigned char)(ADVX + MAXOUT)) ;
  247.                               pos = i ;
  248.                            }
  249.                            addtse((unsigned char)(ADVXCHG2 + i - pos)) ;
  250.                            addts((unsigned char)(*f)) ;
  251.                            addts((unsigned char)(f[1])) ;
  252.                            i += 2 ;
  253.                            pos = i ;
  254.                            d += 2 ;
  255.