home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3.4.17 [SPARC, PA-RISC] / nextstep33_risc.iso / NextLibrary / TeX / tex / src / texview / unpack.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-28  |  6.6 KB  |  246 lines

  1. /*
  2.  *   This is dvips, a freely redistributable PostScript driver
  3.  *   for dvi files.  It is (C) Copyright 1987 by Tomas Rokicki.
  4.  *   You may modify and use this program to your heart's content,
  5.  *   so long as you send modifications to Tomas Rokicki.  It can
  6.  *   be included in any distribution, commercial or otherwise, so
  7.  *   long as the banner string defined in structures.h is not
  8.  *   modified (except for the version number) and this banner is
  9.  *   printed on program invocation, or can be printed on program
  10.  *   invocation with the -? option.
  11.  */
  12. /*
  13.  *   unpack.c of dvisw software package.  This code is copyright (C) 1986
  14.  *   by Radical Eye Software.
  15.  *
  16.  *   unpacks the raster data from the packed buffer.  This code was 
  17.  *   translated from pktopx.web using an automatic translator, then
  18.  *   converted for this purpose.  This little routine can be very useful
  19.  *   in other drivers as well.
  20.  */
  21. #include "structures.h"
  22.  
  23. /*
  24.  * external procedures
  25.  */
  26. extern void error();
  27.  
  28. /*
  29.  *   Some statics for use here.
  30.  */
  31. static halfword bitweight ; 
  32. static halfword dynf ;
  33. static halfword gpower[17] = { 0 , 1 , 3 , 7 , 15 , 31 , 63 , 127 ,
  34.      255 , 511 , 1023 , 2047 , 4095 , 8191 , 16383 , 32767 , 65535 } ; 
  35. static halfword repeatcount ;
  36. static quarterword *p ;
  37.  
  38. /*
  39.  *   We need procedures to get a nybble, bit, and packed word from the
  40.  *   packed data structure.
  41.  */
  42.  
  43. shalfword
  44. getnyb ()
  45. {
  46.     if ( bitweight == 0 ) 
  47.     { bitweight = 16 ; 
  48.       return(*p++ & 15) ;
  49.     } else {
  50.       bitweight = 0 ;
  51.       return(*p >> 4) ;
  52.     }
  53.  
  54. Boolean
  55. getbit ()
  56. {
  57.     bitweight >>= 1 ; 
  58.     if ( bitweight == 0 ) 
  59.     { p++ ;
  60.       bitweight = 128 ;
  61.     } 
  62.     return(*p & bitweight) ;
  63. static halfword (*realfunc)() ;
  64. long remainder ;
  65. halfword handlehuge() ;
  66. halfword pkpackednum () {
  67. register halfword i, j ; 
  68.     i = getnyb () ; 
  69.     if ( i == 0 ) 
  70.     { do { j = getnyb () ; 
  71.         i++ ; 
  72.         } while ( ! ( j != 0 ) ) ; 
  73.       if ( i > 3 ) {
  74. /*
  75.  *   Damn, we got a huge count!  We *fake* it by giving an artificially
  76.  *   large repeat count.
  77.  */
  78.          return( handlehuge ( i , j ) ) ;
  79.       } else {
  80.          while ( i > 0 ) 
  81.            { j = j * 16 + getnyb () ; 
  82.              i-- ; 
  83.              } 
  84.            return ( j - 15 + ( 13 - dynf ) * 16 + dynf ) ; 
  85.          } 
  86.       }
  87.     else if ( i <= dynf ) return ( i ) ; 
  88.     else if ( i < 14 ) return ( ( i - dynf - 1 ) * 16 + getnyb () + dynf + 1 
  89.     ) ; 
  90.     else 
  91.     { if ( i == 14 ) repeatcount = pkpackednum () ; 
  92.       else repeatcount = 1 ; 
  93.       return ( (*realfunc)() ) ;
  94.       } 
  95.     } 
  96. halfword rest ()
  97. {
  98.    halfword i ;
  99.  
  100.    if (remainder < 0) {
  101.       remainder = - remainder ;
  102.       return ( 0 ) ;
  103.    } else if (remainder > 0) {
  104.       if (remainder > 4000) {
  105.          remainder = 4000 - remainder ;
  106.          return ( 4000 ) ;
  107.       } else {
  108.          i = remainder ;
  109.          remainder = 0 ;
  110.          realfunc = pkpackednum ;
  111.          return ( i ) ;
  112.       }
  113.    } else {
  114.       error("! shouldn't happen") ;
  115.    }
  116.    return 0 ;
  117. }
  118. halfword handlehuge ( i , k )
  119. halfword i , k ;
  120. {
  121.    register long j = k ;
  122.  
  123.    while (i) {
  124.       j = (j << 4L) + getnyb() ;
  125.       i-- ;
  126.    }
  127.    remainder = j - 15 + ( 13 - dynf ) * 16 + dynf ;
  128.    realfunc = rest ;
  129.    return ( rest() ) ;
  130. }
  131. void flip(p, howmany)
  132. register char *p ;
  133. register long howmany ;
  134. {
  135.    register char t ;
  136.  
  137.    while (howmany > 0) {
  138.       t = *p ;
  139.       *p = p[1] ;
  140.       p[1] = t ;
  141.       howmany-- ;
  142.       p += 2 ;
  143.    }
  144. }
  145. /*
  146.  *   And now we have our main routine.
  147.  */
  148. static halfword bftest = 1 ;
  149. long
  150. unpack(pack, raster, cwidth, cheight, cmd)
  151.     quarterword *pack ;
  152.     halfword *raster ;
  153.     halfword cwidth, cheight, cmd ;
  154.   register integer i, j ; 
  155.   shalfword wordwidth ; 
  156.   register halfword word, wordweight ;
  157.   shalfword rowsleft ; 
  158.   Boolean turnon ; 
  159.   shalfword hbit ; 
  160.   int count ; 
  161.   halfword *oraster ;
  162.  
  163.       oraster = raster ;
  164.       realfunc = pkpackednum ;
  165.       p = pack ;
  166.       dynf = cmd / 16 ; 
  167.       turnon = cmd & 8 ; 
  168.       wordwidth = (cwidth + 15)/16 ;
  169.       raster += (cheight - 1) * (long)wordwidth ;
  170.       if ( dynf == 14 ) 
  171.       { bitweight = 256 ; 
  172.         for ( i = 1 ; i <= cheight ; i ++ ) 
  173.           { word = 0 ; 
  174.             wordweight = 32768 ; 
  175.             for ( j = 1 ; j <= cwidth ; j ++ ) 
  176.               { if ( getbit () ) word += wordweight ; 
  177.                 wordweight >>= 1 ;
  178.                 if ( wordweight == 0 ) 
  179.                 { *raster++ = word ; 
  180.                   word = 0 ;
  181.                   wordweight = 32768 ; 
  182.                   } 
  183.                 } 
  184.               if ( wordweight != 32768 ) 
  185.                  *raster++ = word ; 
  186.               raster -= 2 * wordwidth ;
  187.             } 
  188.       } else {
  189.         rowsleft = cheight ; 
  190.         hbit = cwidth ; 
  191.         repeatcount = 0 ; 
  192.         wordweight = 16 ; 
  193.         word = 0 ; 
  194.         bitweight = 16 ;
  195.         while ( rowsleft > 0 ) 
  196.           { count = (*realfunc)() ; 
  197.             while ( count != 0 ) 
  198.               { if ( ( count < wordweight ) && ( count < hbit ) ) 
  199.                 { if ( turnon ) word += gpower [ wordweight ] - gpower 
  200.                   [ wordweight - count ] ; 
  201.                   hbit -= count ; 
  202.                   wordweight -= count ; 
  203.                   count = 0 ; 
  204.                   } 
  205.                 else if ( ( count >= hbit ) && ( hbit <= (int)wordweight ) ) 
  206.                 { if ( turnon )
  207.                      word += gpower [ wordweight ] - gpower 
  208.                   [ wordweight - hbit ] ; 
  209.                   *raster++ = word ; 
  210.                   raster -= 2 * wordwidth ;
  211.                   for ( i = 1 ; i <= repeatcount ; i ++ ) {
  212.                     for ( j = 1 ; j <= wordwidth ; j ++ ) {
  213.                       *raster = *(raster + wordwidth) ;
  214.                       raster++ ;
  215.                     }
  216.                     raster -= 2 * wordwidth ;
  217.                   }
  218.                   rowsleft -= repeatcount + 1 ; 
  219.                   repeatcount = 0 ; 
  220.                   word = 0 ; 
  221.                   wordweight = 16 ; 
  222.                   count -= hbit ; 
  223.                   hbit = cwidth ; 
  224.                   } 
  225.                 else 
  226.                 { if ( turnon ) word += gpower [ wordweight ] ; 
  227.                   *raster++ = word ;
  228.                   word = 0 ; 
  229.                   count -= wordweight ; 
  230.                   hbit -= wordweight ; 
  231.                   wordweight = 16 ; 
  232.                   } 
  233.                 } 
  234.               turnon = ! turnon ; 
  235.             } 
  236.           if ( ( rowsleft != 0 ) || ( hbit != (int)cwidth ) ) 
  237.           error ( "! error while unpacking; more bits than required" ) ; 
  238.         } 
  239.     if (*(char *)&bftest)
  240.        flip(oraster, ((cwidth + 15) >> 4) * (long)cheight) ;
  241.    return(p-pack) ;
  242. }
  243.