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 + -
显示快捷键?