Back to index

tetex-bin  3.0
unpack.c
Go to the documentation of this file.
00001 /*
00002  *   Unpacks the raster data from the packed buffer.  This code was 
00003  *   translated from pktopx.web using an automatic translator, then
00004  *   converted for this purpose.  This little routine can be very useful
00005  *   in other drivers as well.
00006  */
00007 #include "dvips.h" /* The copyright notice in that file is included too! */
00008 
00009 /*
00010  * external procedures
00011  */
00012 #include "protos.h"
00013 
00014 /*
00015  *   Some statics for use here.
00016  */
00017 static halfword bitweight ; 
00018 static halfword dynf ;
00019 static halfword gpower[17] = { 0 , 1 , 3 , 7 , 15 , 31 , 63 , 127 ,
00020      255 , 511 , 1023 , 2047 , 4095 , 8191 , 16383 , 32767 , 65535 } ; 
00021 static long repeatcount ;
00022 static quarterword *p ;
00023 
00024 /*
00025  *   We need procedures to get a nybble, bit, and packed word from the
00026  *   packed data structure.
00027  */
00028 
00029 shalfword
00030 getnyb P1H(void)
00031 {
00032     if ( bitweight == 0 ) 
00033     { bitweight = 16 ; 
00034       return(*p++ & 15) ;
00035     } else {
00036       bitweight = 0 ;
00037       return(*p >> 4) ;
00038     }
00039 } 
00040 
00041 Boolean
00042 getbit P1H(void)
00043 {
00044     bitweight >>= 1 ; 
00045     if ( bitweight == 0 ) 
00046     { p++ ;
00047       bitweight = 128 ;
00048     } 
00049     return(*p & bitweight) ;
00050 } 
00051 
00052 long pkpackednum P1H(void) {
00053     register halfword i;
00054     register long j ; 
00055     i = getnyb () ; 
00056     if ( i == 0 ) {
00057        do { j = getnyb () ; 
00058           i++ ; 
00059           } while ( j == 0 ) ; 
00060        while ( i != 0 ) {
00061           j = j * 16 + ((long) getnyb ()) ; 
00062           i-- ; 
00063           } 
00064        return ( j - 15 + ( 13 - dynf ) * 16 + dynf ) ; 
00065     }
00066     else if ( i <= dynf ) return ( i ) ; 
00067     else if ( i < 14 ) return ( ( i - dynf - 1 )*16 + getnyb() + dynf + 1 ) ; 
00068     else {
00069        if (repeatcount != 0)
00070           error("! recursive repeat count in pk file") ;
00071        repeatcount = 1 ;
00072        if ( i == 14 ) repeatcount = pkpackednum () ; 
00073        return ( pkpackednum() ) ;
00074     } 
00075 } 
00076 
00077 void flip P2C(register char *, s, register long, howmany)
00078 {
00079    register char t ;
00080 
00081    while (howmany > 0) {
00082       t = *s ;
00083       *s = s[1] ;
00084       s[1] = t ;
00085       howmany-- ;
00086       s += 2 ;
00087    }
00088 }
00089 /*
00090  *   And now we have our main routine.
00091  */
00092 static halfword bftest = 1 ;
00093 long
00094 unpack P5C(quarterword *, pack, halfword *, raster,
00095           halfword, cwidth, halfword, cheight, halfword, cmd)
00096 { 
00097   register integer i, j ; 
00098   shalfword wordwidth ; 
00099   register halfword word, wordweight ;
00100   shalfword rowsleft ; 
00101   Boolean turnon ; 
00102   shalfword hbit, ww ; 
00103   long count ; 
00104   halfword *oraster ;
00105 
00106       oraster = raster ;
00107       p = pack ;
00108       dynf = cmd / 16 ; 
00109       turnon = cmd & 8 ; 
00110       wordwidth = (cwidth + 15)/16 ;
00111       if ( dynf == 14 ) 
00112       { bitweight = 256 ; 
00113         for ( i = 1 ; i <= cheight ; i ++ ) 
00114           { word = 0 ; 
00115             wordweight = 32768 ; 
00116             for ( j = 1 ; j <= cwidth ; j ++ ) 
00117               { if ( getbit () ) word += wordweight ; 
00118                 wordweight >>= 1 ;
00119                 if ( wordweight == 0 ) 
00120                 { *raster++ = word ; 
00121                   word = 0 ;
00122                   wordweight = 32768 ; 
00123                   } 
00124                 } 
00125               if ( wordweight != 32768 ) 
00126                  *raster++ = word ; 
00127             } 
00128       } else {
00129         rowsleft = cheight ; 
00130         hbit = cwidth ; 
00131         repeatcount = 0 ; 
00132         ww = 16 ; 
00133         word = 0 ; 
00134         bitweight = 16 ;
00135         while ( rowsleft > 0 ) 
00136           { count = pkpackednum() ; 
00137             while ( count != 0 ) 
00138               { if ( ( count <= ww ) && ( count < hbit ) ) 
00139                 { if ( turnon ) word += gpower [ ww ] - gpower 
00140                   [ ww - count ] ; 
00141                   hbit -= count ; 
00142                   ww -= count ; 
00143                   count = 0 ; 
00144                   } 
00145                 else if ( ( count >= hbit ) && ( hbit <= ww ) ) 
00146                 { if ( turnon )
00147                      word += gpower[ww] - gpower[ww-hbit] ; 
00148                   *raster++ = word ; 
00149                   for ( i = 1 ; i <= repeatcount ; i ++ ) {
00150                     for ( j = 1 ; j <= wordwidth ; j ++ ) {
00151                       *raster = *(raster - wordwidth) ;
00152                       raster++ ;
00153                     }
00154                   }
00155                   rowsleft -= repeatcount + 1 ; 
00156                   repeatcount = 0 ; 
00157                   word = 0 ; 
00158                   ww = 16 ; 
00159                   count -= hbit ; 
00160                   hbit = cwidth ; 
00161                   } 
00162                 else 
00163                 { if ( turnon ) word += gpower [ ww ] ; 
00164                   *raster++ = word ;
00165                   word = 0 ; 
00166                   count -= ww ; 
00167                   hbit -= ww ; 
00168                   ww = 16 ; 
00169                   } 
00170                 } 
00171               turnon = ! turnon ; 
00172             } 
00173           if ( ( rowsleft != 0 ) || ( (unsigned)hbit != cwidth ) ) 
00174              error ( "! error while unpacking; more bits than required" ) ; 
00175         } 
00176     if (*(char *)&bftest) /* is the hardware LittleEndian? */
00177        flip((char *)oraster, ((cwidth + 15) >> 4) * (long)cheight) ;
00178    return(p-pack) ;
00179 }