home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fonts 1 / freshfonts1.bin / bbs / programs / amiga / pastex13.lha / DVIPS / dvips5519.lha / dvips / unpack.c < prev    next >
C/C++ Source or Header  |  1993-08-12  |  5KB  |  184 lines

  1. /*
  2.  *   Unpacks the raster data from the packed buffer.  This code was 
  3.  *   translated from pktopx.web using an automatic translator, then
  4.  *   converted for this purpose.  This little routine can be very useful
  5.  *   in other drivers as well.
  6.  */
  7. #include "dvips.h" /* The copyright notice in that file is included too! */
  8.  
  9. /*
  10.  * external procedures
  11.  */
  12. extern void error();
  13.  
  14. /*
  15.  *   Some statics for use here.
  16.  */
  17. static halfword bitweight ; 
  18. static halfword dynf ;
  19. static halfword gpower[17] = { 0 , 1 , 3 , 7 , 15 , 31 , 63 , 127 ,
  20.      255 , 511 , 1023 , 2047 , 4095 , 8191 , 16383 , 32767 , 65535 } ; 
  21. static long repeatcount ;
  22. static quarterword *p ;
  23.  
  24. /*
  25.  *   We need procedures to get a nybble, bit, and packed word from the
  26.  *   packed data structure.
  27.  */
  28.  
  29. shalfword
  30. getnyb ()
  31. {
  32.     if ( bitweight == 0 ) 
  33.     { bitweight = 16 ; 
  34.       return(*p++ & 15) ;
  35.     } else {
  36.       bitweight = 0 ;
  37.       return(*p >> 4) ;
  38.     }
  39.  
  40. Boolean
  41. getbit ()
  42. {
  43.     bitweight >>= 1 ; 
  44.     if ( bitweight == 0 ) 
  45.     { p++ ;
  46.       bitweight = 128 ;
  47.     } 
  48.     return(*p & bitweight) ;
  49.  
  50. long pkpackednum () {
  51.     register halfword i;
  52.     register long j ; 
  53.     i = getnyb () ; 
  54.     if ( i == 0 ) {
  55.        do { j = getnyb () ; 
  56.           i++ ; 
  57.           } while ( j == 0 ) ; 
  58.        while ( i != 0 ) {
  59.           j = j * 16 + ((long) getnyb ()) ; 
  60.           i-- ; 
  61.           } 
  62.        return ( j - 15 + ( 13 - dynf ) * 16 + dynf ) ; 
  63.     }
  64.     else if ( i <= dynf ) return ( i ) ; 
  65.     else if ( i < 14 ) return ( ( i - dynf - 1 )*16 + getnyb() + dynf + 1 ) ; 
  66.     else {
  67.        if (repeatcount != 0)
  68.           error("! recursive repeat count in pk file") ;
  69.        repeatcount = 1 ;
  70.        if ( i == 14 ) repeatcount = pkpackednum () ; 
  71.        return ( pkpackednum() ) ;
  72.     } 
  73.  
  74. void flip(s, howmany)
  75. register char *s ;
  76. register long howmany ;
  77. {
  78.    register char t ;
  79.  
  80.    while (howmany > 0) {
  81.       t = *s ;
  82.       *s = s[1] ;
  83.       s[1] = t ;
  84.       howmany-- ;
  85.       s += 2 ;
  86.    }
  87. }
  88. /*
  89.  *   And now we have our main routine.
  90.  */
  91. static halfword bftest = 1 ;
  92. long
  93. unpack(pack, raster, cwidth, cheight, cmd)
  94.         quarterword *pack ;
  95.         halfword *raster ;
  96.         halfword cwidth, cheight, cmd ;
  97.   register integer i, j ; 
  98.   shalfword wordwidth ; 
  99.   register halfword word, wordweight ;
  100.   shalfword rowsleft ; 
  101.   Boolean turnon ; 
  102.   shalfword hbit, ww ; 
  103.   long count ; 
  104.   halfword *oraster ;
  105.  
  106.       oraster = raster ;
  107.       p = pack ;
  108.       dynf = cmd / 16 ; 
  109.       turnon = cmd & 8 ; 
  110.       wordwidth = (cwidth + 15)/16 ;
  111.       if ( dynf == 14 ) 
  112.       { bitweight = 256 ; 
  113.         for ( i = 1 ; i <= cheight ; i ++ ) 
  114.           { word = 0 ; 
  115.             wordweight = 32768 ; 
  116.             for ( j = 1 ; j <= cwidth ; j ++ ) 
  117.               { if ( getbit () ) word += wordweight ; 
  118.                 wordweight >>= 1 ;
  119.                 if ( wordweight == 0 ) 
  120.                 { *raster++ = word ; 
  121.                   word = 0 ;
  122.                   wordweight = 32768 ; 
  123.                   } 
  124.                 } 
  125.               if ( wordweight != 32768 ) 
  126.                  *raster++ = word ; 
  127.             } 
  128.       } else {
  129.         rowsleft = cheight ; 
  130.         hbit = cwidth ; 
  131.         repeatcount = 0 ; 
  132.         ww = 16 ; 
  133.         word = 0 ; 
  134.         bitweight = 16 ;
  135.         while ( rowsleft > 0 ) 
  136.           { count = pkpackednum() ; 
  137.             while ( count != 0 ) 
  138.               { if ( ( count <= ww ) && ( count < hbit ) ) 
  139.                 { if ( turnon ) word += gpower [ ww ] - gpower 
  140.                   [ ww - count ] ; 
  141.                   hbit -= count ; 
  142.                   ww -= count ; 
  143.                   count = 0 ; 
  144.                   } 
  145.                 else if ( ( count >= hbit ) && ( hbit <= ww ) ) 
  146.                 { if ( turnon )
  147.                      word += gpower[ww] - gpower[ww-hbit] ; 
  148.                   *raster++ = word ; 
  149.                   for ( i = 1 ; i <= repeatcount ; i ++ ) {
  150.                     for ( j = 1 ; j <= wordwidth ; j ++ ) {
  151.                       *raster = *(raster - wordwidth) ;
  152.                       raster++ ;
  153.                     }
  154.                   }
  155.                   rowsleft -= repeatcount + 1 ; 
  156.                   repeatcount = 0 ; 
  157.                   word = 0 ; 
  158.                   ww = 16 ; 
  159.                   count -= hbit ; 
  160.                   hbit = cwidth ; 
  161.                   } 
  162.                 else 
  163.                 { if ( turnon ) word += gpower [ ww ] ; 
  164.                   *raster++ = word ;
  165.                   word = 0 ; 
  166.                   count -= ww ; 
  167.                   hbit -= ww ; 
  168.                   ww = 16 ; 
  169.                   } 
  170.                 } 
  171.               turnon = ! turnon ; 
  172.             } 
  173.           if ( ( rowsleft != 0 ) || ( (unsigned)hbit != cwidth ) ) 
  174.              error ( "! error while unpacking; more bits than required" ) ; 
  175.         } 
  176.     if (*(char *)&bftest) /* is the hardware LittleEndian? */
  177.        flip((char *)oraster, ((cwidth + 15) >> 4) * (long)cheight) ;
  178.    return(p-pack) ;
  179. }
  180.