This is unpack.c in view mode; [Download] [Up]
/* * 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) ; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.