/* * 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! */ /* * The external declarations: */ #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. */ static shalfword getnyb(void) { if ( bitweight == 0 ) { bitweight = 16; return(*p++ & 15); } else { bitweight = 0; return(*p >> 4); } } static Boolean getbit(void) { bitweight >>= 1; if ( bitweight == 0 ) { p++; bitweight = 128; } return(*p & bitweight); } static long pkpackednum(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() ); } } static void flip(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(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); }