home *** CD-ROM | disk | FTP | other *** search
- /*
- * This is dvips, a freely redistributable PostScript driver
- * for dvi files. It is (C) Copyright 1987 by Tomas Rokicki.
- * You may modify and use this program to your heart's content,
- * so long as you send modifications to Tomas Rokicki. It can
- * be included in any distribution, commercial or otherwise, so
- * long as the banner string defined in structures.h is not
- * modified (except for the version number) and this banner is
- * printed on program invocation, or can be printed on program
- * invocation with the -? option.
- */
- /*
- * unpack.c of dvisw software package. This code is copyright (C) 1986
- * by Radical Eye Software.
- *
- * unpacks the raster data from the packed buffer. This code was
- * translated from pktopx.web using an automatic translator, then
- * converted for this purpose. This little routine can be very useful
- * in other drivers as well.
- */
- #include "structures.h"
-
- /*
- * external procedures
- */
- extern void error();
-
- /*
- * Some statics for use here.
- */
- static halfword bitweight ;
- static halfword dynf ;
- static halfword gpower[17] = { 0 , 1 , 3 , 7 , 15 , 31 , 63 , 127 ,
- 255 , 511 , 1023 , 2047 , 4095 , 8191 , 16383 , 32767 , 65535 } ;
- static halfword repeatcount ;
- static quarterword *p ;
-
- /*
- * We need procedures to get a nybble, bit, and packed word from the
- * packed data structure.
- */
-
- shalfword
- getnyb ()
- {
- if ( bitweight == 0 )
- { bitweight = 16 ;
- return(*p++ & 15) ;
- } else {
- bitweight = 0 ;
- return(*p >> 4) ;
- }
- }
-
- Boolean
- getbit ()
- {
- bitweight >>= 1 ;
- if ( bitweight == 0 )
- { p++ ;
- bitweight = 128 ;
- }
- return(*p & bitweight) ;
- }
- static halfword (*realfunc)() ;
- long remainder ;
- halfword handlehuge() ;
- halfword pkpackednum () {
- register halfword i, j ;
- i = getnyb () ;
- if ( i == 0 )
- { do { j = getnyb () ;
- i++ ;
- } while ( ! ( j != 0 ) ) ;
- if ( i > 3 ) {
- /*
- * Damn, we got a huge count! We *fake* it by giving an artificially
- * large repeat count.
- */
- return( handlehuge ( i , j ) ) ;
- } else {
- while ( i > 0 )
- { j = j * 16 + getnyb () ;
- i-- ;
- }
- return ( j - 15 + ( 13 - dynf ) * 16 + dynf ) ;
- }
- }
- else if ( i <= dynf ) return ( i ) ;
- else if ( i < 14 ) return ( ( i - dynf - 1 ) * 16 + getnyb () + dynf + 1
- ) ;
- else
- { if ( i == 14 ) repeatcount = pkpackednum () ;
- else repeatcount = 1 ;
- return ( (*realfunc)() ) ;
- }
- }
- halfword rest ()
- {
- halfword i ;
-
- if (remainder < 0) {
- remainder = - remainder ;
- return ( 0 ) ;
- } else if (remainder > 0) {
- if (remainder > 4000) {
- remainder = 4000 - remainder ;
- return ( 4000 ) ;
- } else {
- i = remainder ;
- remainder = 0 ;
- realfunc = pkpackednum ;
- return ( i ) ;
- }
- } else {
- error("! shouldn't happen") ;
- }
- return 0 ;
- }
- halfword handlehuge ( i , k )
- halfword i , k ;
- {
- register long j = k ;
-
- while (i) {
- j = (j << 4L) + getnyb() ;
- i-- ;
- }
- remainder = j - 15 + ( 13 - dynf ) * 16 + dynf ;
- realfunc = rest ;
- return ( rest() ) ;
- }
- void flip(p, howmany)
- register char *p ;
- register long howmany ;
- {
- register char t ;
-
- while (howmany > 0) {
- t = *p ;
- *p = p[1] ;
- p[1] = t ;
- howmany-- ;
- p += 2 ;
- }
- }
- /*
- * And now we have our main routine.
- */
- static halfword bftest = 1 ;
- long
- unpack(pack, raster, cwidth, cheight, cmd)
- quarterword *pack ;
- halfword *raster ;
- halfword cwidth, cheight, cmd ;
- {
- register integer i, j ;
- shalfword wordwidth ;
- register halfword word, wordweight ;
- shalfword rowsleft ;
- Boolean turnon ;
- shalfword hbit ;
- int count ;
- halfword *oraster ;
-
- oraster = raster ;
- realfunc = pkpackednum ;
- p = pack ;
- dynf = cmd / 16 ;
- turnon = cmd & 8 ;
- wordwidth = (cwidth + 15)/16 ;
- raster += (cheight - 1) * (long)wordwidth ;
- if ( dynf == 14 )
- { bitweight = 256 ;
- for ( i = 1 ; i <= cheight ; i ++ )
- { word = 0 ;
- wordweight = 32768 ;
- for ( j = 1 ; j <= cwidth ; j ++ )
- { if ( getbit () ) word += wordweight ;
- wordweight >>= 1 ;
- if ( wordweight == 0 )
- { *raster++ = word ;
- word = 0 ;
- wordweight = 32768 ;
- }
- }
- if ( wordweight != 32768 )
- *raster++ = word ;
- raster -= 2 * wordwidth ;
- }
- } else {
- rowsleft = cheight ;
- hbit = cwidth ;
- repeatcount = 0 ;
- wordweight = 16 ;
- word = 0 ;
- bitweight = 16 ;
- while ( rowsleft > 0 )
- { count = (*realfunc)() ;
- while ( count != 0 )
- { if ( ( count < wordweight ) && ( count < hbit ) )
- { if ( turnon ) word += gpower [ wordweight ] - gpower
- [ wordweight - count ] ;
- hbit -= count ;
- wordweight -= count ;
- count = 0 ;
- }
- else if ( ( count >= hbit ) && ( hbit <= (int)wordweight ) )
- { if ( turnon )
- word += gpower [ wordweight ] - gpower
- [ wordweight - hbit ] ;
- *raster++ = word ;
- raster -= 2 * wordwidth ;
- for ( i = 1 ; i <= repeatcount ; i ++ ) {
- for ( j = 1 ; j <= wordwidth ; j ++ ) {
- *raster = *(raster + wordwidth) ;
- raster++ ;
- }
- raster -= 2 * wordwidth ;
- }
- rowsleft -= repeatcount + 1 ;
- repeatcount = 0 ;
- word = 0 ;
- wordweight = 16 ;
- count -= hbit ;
- hbit = cwidth ;
- }
- else
- { if ( turnon ) word += gpower [ wordweight ] ;
- *raster++ = word ;
- word = 0 ;
- count -= wordweight ;
- hbit -= wordweight ;
- wordweight = 16 ;
- }
- }
- turnon = ! turnon ;
- }
- if ( ( rowsleft != 0 ) || ( hbit != (int)cwidth ) )
- error ( "! error while unpacking; more bits than required" ) ;
- }
- if (*(char *)&bftest)
- flip(oraster, ((cwidth + 15) >> 4) * (long)cheight) ;
- return(p-pack) ;
- }
-