decode.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 609 行 · 第 1/2 页

C
609
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  wpack routines used to decode files.
*
****************************************************************************/


#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined( UNIX )
#include <clibext.h>
#elif defined( __UNIX__ )
#else
#include <dos.h>
#endif
#include "wpack.h"
#include "txttable.h"

// external function declarations
extern unsigned char    DecReadByte( void );
extern void             DecWriteByte( unsigned char );
extern void             FlushRead( void );
extern void             FlushWrite( void );
extern int              BufSeek( unsigned long );
extern void             QSetDate( char *, unsigned long );
extern int              QWrite( int, void *, int );
extern bool             CheckCRC( unsigned_32 );
extern void             QClose( int );
extern int              QOpenW( char * );
extern file_info **     ReadHeader( arccmd *, arc_header * );
extern void             FreeHeader( file_info ** );
extern void             AssignCodes( int );
extern void             ModifyCRC( unsigned long *, byte );
extern void             UnReadByte( byte );
extern void             DecWriteBuf( void *, int );
extern int              OK_ToReplace( char * );
extern int              OK_ReplaceRDOnly( char * );
extern void             LogUnPacking( char * );
extern int              UnPackHook( char * );

#ifdef __X86__
#pragma aux DecReadByte parm nomemory modify nomemory;
#pragma aux DecWriteByte parm nomemory modify nomemory;
#endif

extern int          infile, outfile;
extern uchar        text_buf[];
extern int          indicies[];
extern byte         len[];

unsigned short   MinCodeLen;
unsigned short   MinVal[ MAX_CODE_BITS + 1];
unsigned short   MapOffset[ MAX_CODE_BITS + 1];
unsigned short   CharMap[ NUM_CHARS ];

/* decoder table */
static uchar d_code[256] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
    0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
    0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
    0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
    0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
    0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
    0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
    0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
    0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
    0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
    0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
    0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
    0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
    0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
    0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
    0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
};

static uchar d_len[256] = {
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
};

static unsigned short getbuf;
static uchar          getlen;
static uchar          secondbuf;

// this not needed anymore
#if 0
GLOBAL int GetBit( void )
/***********************/
/* get one bit */
{
    int i;

    if( getlen == 0 ) {
        getbuf = secondbuf << 8;
        getlen = 8;
        secondbuf = DecReadByte();
    }
    i = (int) getbuf;
    getbuf <<= 1;
    getlen--;
    return ( i < 0 );
}
#endif

GLOBAL unsigned short GetByte(void)
/*********************************/
/* get a byte */
{
    unsigned short i;

    i = getbuf >> 8;
    if( getlen >= 8 ) {
        getbuf <<= 8;
        getlen -= 8;
    } else {
        getbuf = secondbuf;
        i |= getbuf >> getlen;
        getbuf <<= (16 - getlen);
        secondbuf = DecReadByte();
    }
    return( i );
}

static byte Mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF };

GLOBAL int DecodePosition( void )
/*******************************/
{
    unsigned short i, j, c;

    /* decode upper 6 bits from given table */
    i = GetByte();
    c = (unsigned short)d_code[i] << 6;
    j = d_len[i];

    /* input lower 6 bits directly */
    j -= 2;
    if( j > getlen ) {
        getbuf |= (unsigned short)secondbuf << (8 - getlen);
        getlen += 8;
        secondbuf = DecReadByte();
    }
    i = (i << j) | (getbuf >> (16 - j));
    getbuf <<= j;
    getlen -= j;
    return c | i & 0x3f;
}

static int  Location;

static void MakeShannonTrie( void )
/*********************************/
{
    unsigned short   numcoded;
    unsigned short   num;
    unsigned short   entry;
    unsigned short   curr;
    byte        entrylen;
    byte        entrynum;

/*
 * first read in and unpack table
*/
    curr = 0;
    num = 0;
    Location = 0;
    numcoded = DecReadByte() + 1;
    while( numcoded > 0 ) {
        entry = DecReadByte();
        if( entry & 0x80 ) {        // no codes assigned, so skip some
            curr += (entry & 0x7F) + 1;
        } else {
            entrynum = (entry >> 4) + 1;
            entrylen = (entry & 0xF) + 1;
            while( entrynum > 0 ) {
                indicies[ num ] = curr;
                len[ curr ] = entrylen;
                num++;
                curr++;
                entrynum--;
            }
        }
        numcoded--;
    }
    AssignCodes( num );         // assign codes to the lengths
}                               // & build decompression structures

static int CompLen( const int *left, const int *right )
/*****************************************************/
{
    return( (int)len[ *left ] - (int)len[ *right ] );
}


static void SortLengths( int num )
/********************************/
{
    extern int wpack_qsort( void *, int, int,
                            int (*)(const void *, const void *) );

    wpack_qsort( indicies, num, sizeof( int ),
                 (int (*)(const void *, const void *))CompLen );
}

extern void AssignCodes( int num )
/********************************/
// this builds the decompression structures.
{
    unsigned short   codeinc;
    unsigned short   lastlen;
    unsigned short   codeval;
    int         index;
    unsigned short   curroffset;

    SortLengths( num );
    for( index = 0; index <= MAX_CODE_BITS; index++ ) { // so lengths with no
        MinVal[ index ] = 0xFFFF;                   // codes are never decoded
    }
    codeval = 0;
    codeinc = 0;
    lastlen = 0;
    curroffset = 0;
    MinCodeLen = len[ indicies[ 0 ] ];
    for( index = num - 1; index >= 0; index-- ) {
        codeval += codeinc;
        if( len[ indicies[ index ] ] != lastlen ) {
            lastlen = len[ indicies[ index ] ];
            codeinc = 1 << (16 - lastlen);
            MinVal[ lastlen ] = codeval;
            MapOffset[ lastlen ] = curroffset;
        }
        CharMap[ curroffset ] = indicies[ index ];

⌨️ 快捷键说明

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