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 ;
halfword 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 <= 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 != 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.