1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
/*
* 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) ;
}
|