⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compress.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:

#define out_bits_9(w)              \
     if (bit > 9) {                \
       byte|=(w << (bit-9));       \
       *pbyte++=(UCHAR)(byte >> 8);\
       bit--;                      \
       byte <<= 8;                 \
     } else {                      \
       bit=16; byte |= w;          \
       *pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); byte=0; \
     }


#define out_bits_10(w)             \
     if (bit > 10) {               \
       bit-=10; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
     } else {                      \
       out_bits_2((w >> 8));       \
       out_bits_8((w & 0xFF));     \
     }

//
// Weird effect - if out_bits_9 used instead of out_bits_8,
// it's faster!  if (bit == 11) is faster than if (bit != 11).
//

#define out_bits_11(w)             \
     if (bit > 11) {               \
        bit-=11; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
     } else {                      \
        if (bit == 11) {           \
          bit=16; byte |= w;       \
          *pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); byte=0; \
        } else {                   \
          bit=11-bit;              \
          byte|=(w >> bit);        \
          *pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); \
          bit=16-bit;              \
          byte=(w << bit);         \
        }                          \
     }


#define out_bits_12(w)             \
     if (bit > 12) {               \
        bit-=12; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
     } else {                      \
        out_bits_4((w >> 8));      \
        out_bits_8((w & 0xFF));    \
     }
    
#define out_bits_13(w)             \
     if (bit > 13) {               \
        bit-=13; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
     } else {                      \
        out_bits_5((w >> 8));      \
        out_bits_8((w & 0xFF));    \
     }

#define out_bits_14(w)             \
     if (bit > 14) {               \
        bit-=14; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
     } else {                      \
        out_bits_6((w >> 8));      \
        out_bits_8((w & 0xFF));    \
     }


#define out_reserve_4()            \
     bit-=4; bitptr_advance();


/* Starts the given bit pointer */
#define inbit_start(s) pbyte = s; bit = 16; byte=(*pbyte << 8) + *(pbyte+1); pbyte++;
#define inbit_end()      if (bit != 16) pbyte++;    

#define in_bit_next()    if (bit < 9) {          \
                            bit=16;              \
                            byte <<=8;           \
                            byte |= *(++pbyte);  \
                         }


#define in_bit_advance() if (bit < 9) {          \
                            bit+=8;              \
                            byte <<=8;           \
                            byte |= *(++pbyte);  \
                         }

/* Returns non-zero in bitset if the next bit in the stream is a 1. */
#define in_bit()     bit--; bitset = (byte >> bit) & 1; in_bit_next()


#define in_bits_2(w) bit-=2; w = (byte >> bit) & 0x03;\
                     in_bit_advance();

#define in_bits_3(w) bit-=3; w = (byte >> bit) & 0x07;\
                     in_bit_advance();

#define in_bits_4(w) bit-=4; w = (byte >> bit) & 0x0F;\
                     in_bit_advance();

#define in_bits_5(w) bit-=5; w = (byte >> bit) & 0x1F;\
                     in_bit_advance();

#define in_bits_6(w) bit-=6; w = (byte >> bit) & 0x3F;\
                     in_bit_advance();

#define in_bits_7(w) bit-=7; w = (byte >> bit) & 0x7F;\
                     in_bit_advance();

#define in_bits_8(w) bit-=8; w = (byte >> bit) & 0xFF;\
                     bit+=8; byte <<=8; byte |= *(++pbyte);


#define in_bits_9(w) bit-=9; w = (byte >> bit) & 0x1FF;          \
                     bit+=8; byte <<=8; byte |= *(++pbyte);      \
                     in_bit_advance();

#define in_bits_10(w) if (bit > 10) {                            \
                        bit-=10; w = (byte >> bit) & 0x3FF;      \
                        bit+=8; byte <<=8; byte |= *(++pbyte);   \
                      } else {                                   \
                        in_bits_2(bitset);                       \
                        in_bits_8(w);                            \
                        w= w + (bitset << 8);                    \
                      }

#define in_bits_11(w) if (bit > 11) {                            \
                        bit-=11; w = (byte >> bit) & 0x7FF;      \
                        bit+=8; byte <<=8; byte |= *(++pbyte);   \
                      } else {                                   \
                        in_bits_3(bitset);                       \
                        in_bits_8(w);                            \
                        w= w + (bitset << 8);                    \
                      }


#define in_bits_12(w) if (bit > 12) {                            \
                        bit-=12; w = (byte >> bit) & 0xFFF;      \
                        bit+=8; byte <<=8; byte |= *(++pbyte);   \
                      } else {                                   \
                        in_bits_4(bitset);                       \
                        in_bits_8(w);                            \
                        w= w + (bitset << 8);                    \
                      }



#define in_bits_13(w)\
                      if (bit > 13) {                            \
                        bit-=13; w = (byte >> bit) & 0x1FFF;     \
                        bit+=8; byte <<=8; byte |= *(++pbyte);   \
                      } else {                                   \
                        in_bits_5(bitset);                       \
                        in_bits_8(w);                            \
                        w=w + (bitset << 8);                     \
                      }


#define in_bits_14(w)\
                      if (bit > 14) {                            \
                        bit-=14; w = (byte >> bit) & 0x3FFF;     \
                        bit+=8; byte <<=8; byte |= *(++pbyte);   \
                      } else {                                   \
                        in_bits_6(bitset);                       \
                        in_bits_8(w);                            \
                        w=w + (bitset << 8);                     \
                      }



#if 0
#ifdef DEBUG
char
ChPrint(UCHAR b)
{
    if (isprint(b))
        return (char)b;
    else
        return '.';
}
#endif
#endif


//* compress()
//
//  Function:   Main compression function.
//
//  Parameters:
//      IN  CurrentBuffer -> points to NDIS_WAN_PACKET with data to compress
//      OUT CompOutBuffer -> points to NDIS_WAN_PACKET to compress data to
//      IN  CurrentLength -> points to Length of data to compress
//      IN  context -> connection compress context
//
//  Returns:    Nothing
//
//  WARNING:    CODE IS HIGHLY OPTIMIZED FOR TIME ON 386
//
//
USHORT
compress (UCHAR *CurrentBuffer, UCHAR *CompOutBuffer, ULONG *CurrentLength, SendContext *context)
{
    int     bit;
    int     byte;
    int     backptr ;
    int     cbMatch;
    int     hashvalue ;
    UCHAR   *matchptr ;
    UCHAR   *pbyte;
    UCHAR   *historyptr ;
    UCHAR   *currentptr ;
    UCHAR   *endptr ;
    UCHAR   hashchar1;
    UCHAR   hashchar2;
    UCHAR   hashchar3;
    int     literal ;
    USHORT   status=0;   // return flags

#ifdef DEBUG
	// Worst case data expansion that can occur is 12.5%, which would happen
	// when every byte was encoded as a literal, and each byte was >= 0x80,
	// requiring 9 bits per byte.
	//
	// Write over all the output buffer memory to which we should be entitled,
	// to catch cases where the caller does not provide sufficient space to
	// handle the worst case (which would occur only very rarely).

	memset(CompOutBuffer, 0xDD, (*CurrentLength * 9 + 7) / 8);
#endif

    // Will this packet fit at the end of the history buffer?
    //
    if (((context->CurrentIndex + *CurrentLength) >= (HISTORY_MAX - 1 )) ||
        (context->CurrentIndex == 0)) {
        context->CurrentIndex = 0;   // Index into the history
        status |= PACKET_AT_FRONT << 8;
    }

	//
    // Start out the bit pointing output - CompOutBuffer is where the
	// compressed data is written.
    //
    bitptr_init(CompOutBuffer);

    historyptr = context->History + context->CurrentIndex ;

	//
	// Setup the compress data source pointer.
	//
    currentptr = CurrentBuffer;

    endptr = currentptr + *CurrentLength - 1;

    while (currentptr < (endptr-2)) {

        *historyptr++ = hashchar1 = *currentptr++ ;
        hashchar2 = *currentptr ;
        hashchar3 = *(currentptr+1) ;

        // "fast" hash function
        // hashvalue = (int)hashchar1 ^ xorlookup1[hashchar2] ^ xorlookup2[hashchar3];
        // hashvalue = MULTHASH1(hashchar1, hashchar2, hashchar3) ;

        hashvalue = MULTHASH2(hashchar1, hashchar2, hashchar3) ;

        matchptr = context->History  + context->HashTable[hashvalue] ;

        if (matchptr != (historyptr - 1))
            context->HashTable[hashvalue] = historyptr - context->History ;

        if (context->ValidHistory < historyptr)
            context->ValidHistory = historyptr ;

        if (matchptr != context->History &&
            *(matchptr-1) == hashchar1 && *matchptr  == hashchar2 &&
            *(matchptr+1) == hashchar3 && matchptr    != (historyptr - 1) &&
            matchptr      != historyptr  && (matchptr+1)  <= context->ValidHistory) {

            backptr = (historyptr - matchptr) & (HISTORY_SIZE - 1) ;

            *historyptr++ = hashchar2 ;     // copy the other 2 chars
            *historyptr++ = hashchar3 ;     // copy the other 2 chars
            currentptr  +=2 ;
            cbMatch = 3 ;           // length of match
            matchptr    +=2 ; // we have already matched 3

            while ((*matchptr == *currentptr) && (currentptr < endptr) && (matchptr <= context->ValidHistory)) {
                matchptr++ ;
                *historyptr++ = *currentptr++ ;
                cbMatch++ ;
            }

#if 0
#ifdef DEBUG
            DbgPrint("\tCOMP: Location:%d  Char %c, matched length %d, backindex %d\n", (currentptr - context->CompressBuffer), ChPrint(*currentptr), cbMatch, backptr) ;
#endif
#endif

            // First output the backpointer
            //
            if (backptr >= 320) {
                backptr -= 320 ;
                out_bits_8((0xc000 + backptr) >> 8) ;   // 110 + 13 bits
                out_bits_8((backptr)) ;
            } else if (backptr < 64) {          // 1111 + 6 bits
                backptr += 0x3c0 ;
                out_bits_10(backptr);
            } else  {
                backptr += (0xE00 - 64);        // 1110 + 8 bits
                out_bits_12(backptr);
            }

            // output the length of the match encoding
            //
            switch (cbMatch) {
    
                case 3:
                    out_bit_0();    // length of 3 - most common
                    break;
    
                case 4:
                case 5:
                case 6:
                case 7:
                    out_bits_4((cbMatch+4));
                    break;
    
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                case 14:
                case 15:
                    out_bits_6((cbMatch+40));
                    break;
    
                case 16:
                case 17:
                case 18:
                case 19:
                case 20:
                case 21:
                case 22:
                case 23:
                case 24:
                case 25:
                case 26:
                case 27:
                case 28:
                case 29:
                case 30:
                case 31:
                    out_bits_8((cbMatch+208));
                    break;
    
                default:
                    if (cbMatch < 64) {
                        out_bits_4(0xF) ;
                        cbMatch -= 32 ;
                        out_bits_6(cbMatch) ;
                    }
                    else if (cbMatch < 128) {
                        out_bits_5(0x1F) ;
                        cbMatch -= 64 ;
                        out_bits_7(cbMatch) ;
                    }
                    else if (cbMatch < 256) {
                        out_bits_6(0x3F) ;
                        cbMatch -= 128 ;
                        out_bits_8(cbMatch) ;
                    }
                    else if (cbMatch < 512) {
                        out_bits_7(0x7F) ;
                        cbMatch -= 256 ;
                        out_bits_9(cbMatch) ;
                    }
                    else if (cbMatch < 1024) {
                        out_bits_8(0xFF) ;
                        cbMatch -= 512 ;
                        out_bits_10(cbMatch) ;
                    }
                    else if (cbMatch < 2048) {
                        out_bits_9(0x1FF) ;
                        cbMatch -= 1024 ;
                        out_bits_11(cbMatch) ;
                    }
                    else if (cbMatch < 4096) {
                        out_bits_10(0x3FF) ;
                        cbMatch -= 2048 ;
                        out_bits_12(cbMatch) ;
                    }
                    else if (cbMatch < 8192) {
                        out_bits_11(0x7FF) ;
                        cbMatch -= 4096 ;
                        out_bits_13(cbMatch) ;
                    }
                    else  {             // 8192 and greater
                        out_bits_12(0xFFF) ;
                        cbMatch -= 8192 ;
                        out_bits_14(cbMatch) ;
                    }
                    break ;
            }

        } else {    // encode a literal

#if 0
#ifdef DEBUG
            DbgPrint("\t COMP:Location %d, <No Match>: '%c'\n", (currentptr - context->CompressBuffer),*currentptr) ;
#endif
#endif
            // temp=literallookup[context->History[i-1]] ;
            literal= hashchar1 ;

            if (literal & 0x80) {
                literal += 0x80;
                out_bits_9(literal) ;
            } else {
                out_bits_8(literal) ;
            }

        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -