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

📄 compress.c

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


    // get any remaining chars as literals
    while (currentptr <= endptr) {

#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=*currentptr ;


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

        *historyptr++ = *currentptr++ ;
    }


    bitptr_end() ;


    // Check if we expanded the buffer
    //
    if ((ULONG)(pbyte - CompOutBuffer) > *CurrentLength) { // expanded.

        //
        // We don't need to do this copy since we can just signal the outside world
        // that compression did not take place and the valid data is still in the
        // current buffer
        //
        // RtlMoveMemory(CompOutBuffer, CurrentBuffer, *CurrentLength) ;

        memset (context->History, 0, sizeof(context->History)) ;
        memset (context->HashTable, 0, sizeof(context->HashTable)) ;
#ifdef COMP_12K
        status = 0 ;
#else
        status = PACKET_FLUSHED << 8;
#endif
        context->CurrentIndex = HISTORY_SIZE+1 ; // this forces a start over next time

    } else {     // compression successful

        *CurrentLength = pbyte - CompOutBuffer;

        //
        // the compressed data is now in CompOutBuffer - tonybe 01-12-95
        //
        //  *CurrentLength = pbyte - CurrentBuffer ;

        status |= PACKET_COMPRESSED << 8;
        context->CurrentIndex = historyptr - context->History ;
    }

    return status;
}



//* getcontextsizes()
//
//  Function:   Returns size of send and receive context blocks
//
//  Parameters: OUT send -> sizeof(SendContext)
//      OUT recv -> sizeof(RecvContext)
//
//  Returns:    Nothing
//
//*
void
getcontextsizes (long *send, long *recv)
{
    *send = sizeof(SendContext) ;
    *recv = sizeof(RecvContext) ;
}


//* initsendcontext()
//
//  Function:   Initialize SendContext block
//
//  Parameters: IN  context -> connection compress context
//
//  Returns:    Nothing
//
//*
void
initsendcontext (SendContext *context)
{
    context->CurrentIndex = 0;   // Index into the history
    context->ValidHistory = 0 ;  // reset valid history
    memset (context->HashTable, 0, sizeof(context->HashTable)) ;
    memset (context->History, 0, sizeof(context->History)) ;
}



//* initrecvcontext()
//
//  Function:   Initialize RecvContext block
//
//  Parameters: IN  context -> connection decompress context
//
//  Returns:    Nothing
//
//*
void
initrecvcontext (RecvContext *context)
{
    context->CurrentPtr = context->History ;

#if DBG
    context->DebugFence = DEBUG_FENCE_VALUE;
#endif

    memset (context->History, 0, sizeof(context->History)) ;
}



//* decompress()
//
//  Function:   de-compression function.
//
//  Parameters: IN     inbuf -> points to data to be uncompressed
//      IN     inlen -> length of data
//      IN     start -> flag indicating whether to start with a clean history buffer
//      OUT    output-> decompressed data
//      OUT    outlen-> lenght of decompressed data
//      IN     context -> connection decompress context
//
//  Returns:    TRUE  if decompress was successful
//              FALSE if it wasnt
//
//  WARNING:    CODE IS HIGHLY OPTIMIZED FOR TIME.
//
//*
int
decompress(
    UCHAR *inbuf,
    int inlen,
    int start,
    UCHAR **output,
    int *outlen,
    RecvContext *context)
{
    UCHAR   *inend;             // When we know we're done decompressing
    UCHAR   *outstart;          // Remember where in dbuf we started

    UCHAR   *current;

    int     backptr = 0x00;     // Back pointer for copy items
    int     length;             // Where to copy from in dbuf

    UCHAR   *s1, *s2;

    int     bitset;
    int     bit;
    int     byte;
    UCHAR   *pbyte;
    UCHAR   *historyend = context->History + HISTORY_SIZE ;

    inend = inbuf + inlen ;

    //
    // Start out looking at the first bit
    //
    inbit_start(inbuf);

    if (start)      // start over clean?
    context->CurrentPtr = current = context->History ;
    else
    current = context->CurrentPtr ;

    //
    // Save our starting position
    //
    outstart = current;

    //
    // Decompress until we run out of input
    //
    while (pbyte < inend) {

    //
    // Jump on what to do with these three bits.
    //
    in_bits_3(length);

    switch (length) {

    case 0:
        in_bits_5(length) ;
        goto LITERAL ;

    case 1:
        in_bits_5(length) ;
        length += 32 ;
        goto LITERAL ;

    case 2:
        in_bits_5(length) ;
        length += 64 ;
        goto LITERAL ;

    case 3:
        in_bits_5(length) ;
        length += 96 ;
        goto LITERAL ;

    case 4:
        in_bits_6(length) ;
        length +=128 ;
        goto LITERAL ;

    case 5:
        in_bits_6(length) ;
        length +=192 ;
        goto LITERAL ;

    case 6:
        in_bits_13 (backptr) ;      // 110 - 14 bit offset
        backptr+=320 ;
        break ;

    case 7:
        in_bit() ;
        if (bitset) {
        in_bits_6(backptr) ;
        } else {
        in_bits_8(backptr) ;
        backptr+=64 ;
        }
        break ;
    }

    //
    // If we reach here, it's a copy item
    //

    //
    // Now get the length
    //

    in_bit() ;  // 1st length bit
    if (!bitset) {
        length = 3 ;
        goto DONE ;
    }

    in_bit() ;  // 2nd length bit
    if (!bitset) {
        in_bits_2 (length) ;
        length += 4 ;
        goto DONE ;
    }

    in_bit() ; // 3rd length bit
    if (!bitset) {
        in_bits_3 (length) ;
        length += 8 ;
        goto DONE ;
    }

    in_bit() ; // 4th length bit
    if (!bitset) {
        in_bits_4 (length) ;
        length += 16 ;
        goto DONE ;
    }

    in_bit() ; // 5th length bit
    if (!bitset) {
        in_bits_5 (length) ;
        length += 32 ;
        goto DONE ;
    }

    in_bit() ; // 6th length bit
    if (!bitset) {
        in_bits_6 (length) ;
        length += 64 ;
        goto DONE ;
    }

    in_bit() ; // 7th length bit
    if (!bitset) {
        in_bits_7 (length) ;
        length += 128 ;
        goto DONE ;
    }

    in_bit() ; // 8th length bit
    if (!bitset) {
        in_bits_8 (length) ;
        length += 256 ;
        goto DONE ;
    }

    in_bit() ; // 9th length bit
    if (!bitset) {
        in_bits_9 (length) ;
        length += 512 ;
        goto DONE ;
    }

    in_bit() ; // 10th length bit
    if (!bitset) {
        in_bits_10 (length) ;
        length += 1024 ;
        goto DONE ;
    }

    //
    // length cannot be greater than max packets size which is 1500
    //
#if 0
    DbgPrint("NDISWAN: RAS Decompressor problem: Possible data corruption\n");
#endif

    return FALSE ;


    DONE:
    //
    // Turn the backptr into an index location
    //
#ifdef COMP_12K
    s2 = current - backptr ;
#else
    s2 = context->History + (((current - context->History) - backptr) & (HISTORY_SIZE -1)) ;
#endif

    s1 = current;

#if 0
#ifdef DEBUG
    DbgPrint("\tdecomp: location: %d,  bp %.4d  length %.4d\n", (current-context->CurrentPtr), backptr, length);
#endif
#endif
    current += length;

    // if we are past the end of the history this is a bad sign: abort decompression
    //
    if (current >= historyend) {
#if 0
        DbgPrint("NDISWAN: RAS Decompressor problem: Possible data corruption\n");
#endif
        return FALSE ;
    }

    // loop unrolled to handle lenght>backptr case
    //
    *s1=*s2;
    *(s1+1)=*(s2+1);
    s1+=2;
    s2+=2;
    length-=2;

    //
    // copy all the bytes
    //
    while (length) {
        *s1++=*s2++;
        length--;
    }

    //
    // We have another copy item, and no literals
    //
    continue;


    LITERAL:

#if 0
#ifdef DEBUG
    DbgPrint("\tdecomp: Location %d, literal '%c'\n",(current-context->CurrentPtr), length);
#endif
#endif

    //
    // We have a literal
    //
    //*current++ = literallookup[length];
    *current++ = length;

    } // while loop


    // End case:
    //
    if ((bit == 16) && (pbyte == inend)) {
    *current++ = *(pbyte -1) ;
    }

#if 0
#if DBG
    if (context->DebugFence != DEBUG_FENCE_VALUE) {
        DbgPrint("Decompression Error!\n");
        DbgPrint("context 0x%8.8x, current 0x%8.8x, outstart 0x%8.8x\n", context, current, outstart);
        DbgPrint("inbuf 0x%8.8x, inlength %d, start 0x%8.8x\n", inbuf, inlen, start);
        DbgBreakPoint();
    }
#endif
#endif

    *outlen = current - outstart ; // the length of decompressed data

    *output = context->CurrentPtr ;

    context->CurrentPtr = current ;

    return TRUE ;
}

⌨️ 快捷键说明

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