/*
* 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 "dvips.h" /* The copyright notice in that file is included too! */
/*
* external procedures
*/
#include "protos.h"
/*
* 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 long repeatcount ;
static quarterword *p ;
/*
* We need procedures to get a nybble, bit, and packed word from the
* packed data structure.
*/
shalfword
getnyb P1H(void)
{
if ( bitweight == 0 )
{ bitweight = 16 ;
return(*p++ & 15) ;
} else {
bitweight = 0 ;
return(*p >> 4) ;
}
}
Boolean
getbit P1H(void)
{
bitweight >>= 1 ;
if ( bitweight == 0 )
{ p++ ;
bitweight = 128 ;
}
return(*p & bitweight) ;
}
long pkpackednum P1H(void) {
register halfword i;
register long j ;
i = getnyb () ;
if ( i == 0 ) {
do { j = getnyb () ;
i++ ;
} while ( j == 0 ) ;
while ( i != 0 ) {
j = j * 16 + ((long) 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 (repeatcount != 0)
error("! recursive repeat count in pk file") ;
repeatcount = 1 ;
if ( i == 14 ) repeatcount = pkpackednum () ;
return ( pkpackednum() ) ;
}
}
void flip P2C(register char *, s, register long, howmany)
{
register char t ;
while (howmany > 0) {
t = *s ;
*s = s[1] ;
s[1] = t ;
howmany-- ;
s += 2 ;
}
}
/*
* And now we have our main routine.
*/
static halfword bftest = 1 ;
long
unpack P5C(quarterword *, pack, halfword *, raster,
halfword, cwidth, halfword, cheight, halfword, cmd)
{
register integer i, j ;
shalfword wordwidth ;
register halfword word, wordweight ;
shalfword rowsleft ;
Boolean turnon ;
shalfword hbit, ww ;
long count ;
halfword *oraster ;
oraster = raster ;
p = pack ;
dynf = cmd / 16 ;
turnon = cmd & 8 ;
wordwidth = (cwidth + 15)/16 ;
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 ;
}
} else {
rowsleft = cheight ;
hbit = cwidth ;
repeatcount = 0 ;
ww = 16 ;
word = 0 ;
bitweight = 16 ;
while ( rowsleft > 0 )
{ count = pkpackednum() ;
while ( count != 0 )
{ if ( ( count <= ww ) && ( count < hbit ) )
{ if ( turnon ) word += gpower [ ww ] - gpower
[ ww - count ] ;
hbit -= count ;
ww -= count ;
count = 0 ;
}
else if ( ( count >= hbit ) && ( hbit <= ww ) )
{ if ( turnon )
word += gpower[ww] - gpower[ww-hbit] ;
*raster++ = word ;
for ( i = 1 ; i <= repeatcount ; i ++ ) {
for ( j = 1 ; j <= wordwidth ; j ++ ) {
*raster = *(raster - wordwidth) ;
raster++ ;
}
}
rowsleft -= repeatcount + 1 ;
repeatcount = 0 ;
word = 0 ;
ww = 16 ;
count -= hbit ;
hbit = cwidth ;
}
else
{ if ( turnon ) word += gpower [ ww ] ;
*raster++ = word ;
word = 0 ;
count -= ww ;
hbit -= ww ;
ww = 16 ;
}
}
turnon = ! turnon ;
}
if ( ( rowsleft != 0 ) || ( (unsigned)hbit != cwidth ) )
error ( "! error while unpacking; more bits than required" ) ;
}
if (*(char *)&bftest) /* is the hardware LittleEndian? */
flip((char *)oraster, ((cwidth + 15) >> 4) * (long)cheight) ;
return(p-pack) ;
}
|