windows-nt/Source/XPSP1/NT/ds/security/csps/gemsafe/gemcomp/compalg.c
2020-09-26 16:20:57 +08:00

826 lines
23 KiB
C

#ifdef _WINDOWS
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include "ccdef.h"
#include "compcert.h"
#include "gmem.h"
#define FIXED_MODEL 1
#define ADAPTATIVE_MODEL 2
#define Code_value_bits 16
#define No_of_chars 256
#define Max_frequency 16383
#define EOF_symbol (No_of_chars+1)
#define No_of_symbols (No_of_chars+1)
#define Top_value (( (long) 1 << Code_value_bits) - 1)
#define First_qtr (Top_value / 4 + 1)
#define Half (2 * First_qtr)
#define Third_qtr (3 * First_qtr)
typedef long code_value;
static code_value value_dc;
static code_value low_dc, high_dc;
static code_value low_enc, high_enc;
static long bits_to_follow;
static unsigned int buffer_in;
static unsigned int bits_to_go_in;
static unsigned int garbage_bits_in;
static unsigned int buffer_out;
static unsigned int bits_to_go_out;
static int Error;
unsigned int char_to_index[No_of_chars];
unsigned char index_to_char[No_of_symbols+1];
unsigned int cum_freq[No_of_symbols+1];
unsigned char *Memory;
static unsigned MemoSize;
unsigned int FixedFreqA[No_of_symbols+1] =
{
0,
63, 260, 180, 216, 254, 63, 268, 95, 43, 62, 33, 28, 14, 6, 45, 38,
33, 35, 13, 303, 41, 37, 41, 8, 15, 81, 25, 2, 15, 88, 20, 6,
/* ! = # $ % & ' ( ) * + , - . / */
662, 3, 35, 18, 12, 3, 11, 3, 16, 12, 2, 34, 42, 32, 56, 31,
/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
300, 118, 42, 40, 21, 37, 63, 46, 10, 90, 33, 3, 1, 9, 15, 3,
/* @ A B C D E F G H I J K L M N O */
27, 158, 73, 122, 82, 31, 20, 14, 26, 56, 1, 2, 27, 20, 12, 31,
/* P Q R S T U V W X Y Z [ \ ] ^ _ */
64, 4, 65, 114, 106, 195, 10, 27, 3, 18, 25, 2, 3, 1, 2, 12,
/* ` a b c d e f g h i j k l m n o */
24, 271, 44, 171, 158, 439, 44, 50, 71, 308, 2, 5, 60, 73, 234, 280,
/* p q r s t u v w x y z { | } ~ */
76, 44, 274, 273, 358, 100, 36, 43, 12, 79, 2, 1, 1, 1, 1, 1,
48, 48, 30, 1, 1, 5, 100, 5, 1, 3, 1, 1, 1, 50, 1, 1,
1, 4, 2, 14, 1, 5, 12, 1, 4, 1, 1, 1, 1, 1, 1, 1,
6, 14, 1, 1, 24, 1, 1, 4, 1, 11, 1, 2, 23, 1, 1, 4,
1, 1, 1, 1, 5, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1,
1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 4, 1,
1, 1, 1, 13, 12, 1, 1, 1, 1, 1, 1, 2, 1, 13, 1, 1,
5, 1, 2, 1, 12, 1, 1, 1, 24, 2, 1, 1, 1, 4, 1, 308,
250
};
unsigned int AdaptativeFreqA[No_of_symbols+1] =
{
0,
12, 24, 19, 18, 19, 6, 20, 7, 4, 5, 3, 3, 2, 2, 4, 4,
3, 4, 2, 23, 4, 4, 4, 2, 2, 7, 3, 1, 2, 7, 3, 1,
/* ! = # $ % & ' ( ) * + , - . / */
49, 1, 3, 2, 2, 2, 2, 1, 2, 2, 1, 3, 4, 3, 5, 3,
/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
25, 9, 3, 3, 2, 3, 5, 4, 2, 7, 3, 1, 1, 1, 2, 1,
/* @ A B C D E F G H I J K L M N O */
3, 14, 6, 10, 7, 3, 3, 2, 3, 5, 1, 1, 3, 2, 1, 3,
/* P Q R S T U V W X Y Z [ \ ] ^ _ */
5, 2, 6, 9, 9, 15, 2, 3, 1, 2, 3, 2, 1, 1, 1, 2,
/* ` a b c d e f g h i j k l m n o */
2, 20, 4, 13, 12, 32, 4, 5, 6, 24, 1, 1, 5, 7, 18, 21,
/* p q r s t u v w x y z { | } ~ */
6, 4, 20, 21, 27, 8, 3, 4, 2, 7, 1, 1, 1, 1, 1, 1,
4, 9, 3, 1, 1, 1, 8, 1, 1, 3, 1, 1, 1, 5, 1, 1,
1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 1, 3, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2,
1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 24,
25
};
unsigned int freq[No_of_symbols+1];
/******************************************************************************/
void start_model(int ModelType)
{
int i;
for (i = 0; i < No_of_chars; i++)
{
char_to_index[i] = i+1;
index_to_char[i+1] = (BYTE)i;
}
if (ModelType == FIXED_MODEL)
{
for (i = 0; i <= No_of_symbols; i++)
{
freq[i] = FixedFreqA[i];
}
cum_freq[No_of_symbols] = 0;
for(i = No_of_symbols; i > 0; i--)
{
cum_freq[i-1] = cum_freq[i] + freq[i];
}
}
if (ModelType == ADAPTATIVE_MODEL)
{
for (i = 0; i <= No_of_symbols; i++)
{
freq[i] = AdaptativeFreqA[i];
}
cum_freq[No_of_symbols] = 0;
for(i = No_of_symbols; i > 0; i--)
{
cum_freq[i-1] = cum_freq[i] + freq[i];
}
}
}
/******************************************************************************/
void update_model(int ModelType, unsigned int symbol)
{
unsigned int i;
unsigned int cum;
unsigned int ch_i;
unsigned int ch_symbol;
if (ModelType == ADAPTATIVE_MODEL)
{
if (cum_freq[0] == Max_frequency)
{
cum = 0;
for (i = No_of_symbols + 1; i != 0; /**/)
{
--i;
freq[i] = (freq[i] + 1) / 2;
cum_freq[i] = cum;
cum += freq[i];
}
}
for (i = symbol; freq[i] == freq[i-1]; i--)
{
}
if (i < symbol)
{
ch_i = index_to_char[i];
ch_symbol = index_to_char[symbol];
index_to_char[i] = (BYTE)ch_symbol;
index_to_char[symbol] = (BYTE)ch_i;
char_to_index[ch_i] = symbol;
char_to_index[ch_symbol] = i;
}
freq[i] += 1;
while (i > 0)
{
i -= 1;
cum_freq[i] += 1;
}
}
}
/******************************************************************************/
void start_outputing_bits(void)
{
buffer_out = 0;
bits_to_go_out = 8;
}
/******************************************************************************/
int output_bit(unsigned short int *pOutCount, unsigned int bit)
{
buffer_out >>= 1;
if (bit)
{
buffer_out |= 0x80;
}
bits_to_go_out -= 1;
if (bits_to_go_out == 0)
{
if (*pOutCount == MemoSize)
{
return RV_COMPRESSION_FAILED;
}
Memory[(*pOutCount)++] = (BYTE)buffer_out;
bits_to_go_out = 8;
}
return RV_SUCCESS;
}
/******************************************************************************/
int done_outputing_bits(unsigned short int *pOutCount)
{
if (*pOutCount == MemoSize)
{
return RV_COMPRESSION_FAILED;
}
Memory[(*pOutCount)++] = buffer_out>>bits_to_go_out;
return RV_SUCCESS;
}
/******************************************************************************/
void start_inputing_bits(void)
{
bits_to_go_in = 0;
garbage_bits_in = 0;
Error = RV_SUCCESS;
}
/******************************************************************************/
unsigned int input_bit(BLOC InBloc, unsigned short int *pusInCount)
{
unsigned int t;
if (bits_to_go_in == 0)
{
if (*pusInCount < InBloc.usLen)
{
buffer_in = InBloc.pData[(*pusInCount)++];
}
else
{
buffer_in = 0x00;
}
if (*pusInCount == InBloc.usLen)
{
garbage_bits_in += 1;
if (garbage_bits_in > Code_value_bits - 2)
{
Error = RV_INVALID_DATA;
}
}
bits_to_go_in = 8;
}
t = buffer_in & 1;
buffer_in >>= 1;
bits_to_go_in -= 1;
return (t);
}
/******************************************************************************/
int bit_plus_follow(unsigned short int *pOutCount, unsigned int bit)
{
if (output_bit(pOutCount, bit) != RV_SUCCESS)
{
return RV_COMPRESSION_FAILED;
}
while (bits_to_follow > 0)
{
if (output_bit(pOutCount, !bit) != RV_SUCCESS)
{
return RV_COMPRESSION_FAILED;
}
bits_to_follow -= 1;
}
return RV_SUCCESS;
}
/******************************************************************************/
void start_encoding(void)
{
low_enc = 0;
high_enc = Top_value;
bits_to_follow = 0;
}
/******************************************************************************/
int encode_symbol(unsigned short int *pOutCount,
unsigned int symbol,
unsigned int cum_freq[]
)
{
long range;
range = (long) (high_enc-low_enc) + 1;
high_enc = low_enc + (range * cum_freq[symbol-1]) / cum_freq[0] - 1;
low_enc = low_enc + (range * cum_freq[symbol]) / cum_freq[0];
for ( ; ; )
{
if (high_enc < Half)
{
if (bit_plus_follow(pOutCount, 0) != RV_SUCCESS)
{
return RV_COMPRESSION_FAILED;
}
}
else if (low_enc >= Half)
{
if (bit_plus_follow(pOutCount, 1) != RV_SUCCESS)
{
return RV_COMPRESSION_FAILED;
}
low_enc -= Half;
high_enc -= Half;
}
else if ((low_enc >= First_qtr) && (high_enc < Third_qtr))
{
bits_to_follow += 1;
low_enc -= First_qtr;
high_enc -= First_qtr;
}
else
{
break;
}
low_enc = 2 * low_enc;
high_enc = 2 * high_enc + 1;
}
return RV_SUCCESS;
}
/******************************************************************************/
int done_encoding(unsigned short int *pOutCount)
{
bits_to_follow += 1;
if (low_enc < First_qtr)
{
if (bit_plus_follow(pOutCount, 0) != RV_SUCCESS)
{
return RV_COMPRESSION_FAILED;
}
}
else
{
if (bit_plus_follow(pOutCount, 1) != RV_SUCCESS)
{
return RV_COMPRESSION_FAILED;
}
}
return RV_SUCCESS;
}
/******************************************************************************/
void start_decoding(BLOC InBloc, unsigned short int *pusInCount)
{
unsigned int i;
value_dc = 0;
for (i = 1; i <= Code_value_bits; i++)
{
value_dc = 2 * value_dc + input_bit(InBloc, pusInCount);
if (Error != RV_SUCCESS)
{
break;
}
}
low_dc = 0;
high_dc = Top_value;
}
/******************************************************************************/
unsigned int decode_symbol(BLOC InBloc,
unsigned short int *pusInCount,
unsigned int cum_freq[]
)
{
long range;
unsigned int cum;
unsigned int symbol;
range = (long) (high_dc-low_dc) + 1;
cum = (((long) (value_dc-low_dc) + 1) * cum_freq[0] - 1) / range;
for (symbol = 1; cum_freq[symbol] > cum; symbol++)
{
}
high_dc = low_dc + (range * cum_freq[symbol-1]) / cum_freq[0] - 1;
low_dc = low_dc + (range * cum_freq[symbol]) / cum_freq[0];
for ( ; ; )
{
if (high_dc < Half)
{
}
else if (low_dc >= Half)
{
value_dc -= Half;
low_dc -= Half;
high_dc -= Half;
}
else if ((low_dc >= First_qtr) && (high_dc < Third_qtr))
{
value_dc -= First_qtr;
low_dc -= First_qtr;
high_dc -= First_qtr;
}
else
{
break;
}
low_dc = 2 * low_dc;
high_dc = 2 * high_dc + 1;
value_dc = 2 * value_dc + input_bit(InBloc, pusInCount);
if (Error != RV_SUCCESS)
{
break;
}
}
return (symbol);
}
/******************************************************************************/
int AcAd8_Encode(BLOC *pInBloc, BLOC *pOutBloc)
{
int i, ch;
unsigned int symbol;
unsigned short int usInCount = 0;
unsigned short int usOutCount = 0;
MemoSize = pInBloc->usLen;
Memory = GMEM_Alloc (MemoSize);
if (Memory == NULL)
{
return (RV_MALLOC_FAILED);
}
start_model(ADAPTATIVE_MODEL);
start_outputing_bits();
start_encoding();
for (usInCount = 0; usInCount < pInBloc->usLen; usInCount++)
{
ch = pInBloc->pData[usInCount];
symbol = char_to_index[ch];
if (encode_symbol(&usOutCount, symbol, cum_freq) != RV_SUCCESS)
{
goto err;
}
update_model(ADAPTATIVE_MODEL, symbol);
}
if (encode_symbol(&usOutCount, EOF_symbol, cum_freq) != RV_SUCCESS)
{
goto err;
}
if (done_encoding(&usOutCount) != RV_SUCCESS)
{
goto err;
}
if (done_outputing_bits(&usOutCount) != RV_SUCCESS)
{
goto err;
}
pOutBloc->usLen = usOutCount;
pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen);
if (pOutBloc->pData != NULL)
{
for (i=0; i < pOutBloc->usLen; i++)
{
pOutBloc->pData[i] = Memory[i];
}
GMEM_Free(Memory);
return (RV_SUCCESS);
}
else
{
pOutBloc->usLen = 0;
pOutBloc->pData = NULL;
GMEM_Free(Memory);
return (RV_MALLOC_FAILED);
}
err:
GMEM_Free(Memory);
pOutBloc->usLen = pInBloc->usLen;
pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen);
if (pOutBloc->pData != NULL)
{
for (i=0; i < pOutBloc->usLen; i++)
{
pOutBloc->pData[i] = pInBloc->pData[i];
}
return (RV_COMPRESSION_FAILED);
}
else
{
pOutBloc->usLen = 0;
pOutBloc->pData = NULL;
return (RV_MALLOC_FAILED);
}
}
/******************************************************************************/
int AcFx8_Encode(BLOC *pInBloc, BLOC *pOutBloc)
{
int i, ch;
unsigned int symbol;
unsigned short int usInCount = 0;
unsigned short int usOutCount = 0;
MemoSize = pInBloc->usLen;
Memory = GMEM_Alloc (MemoSize);
if (Memory == NULL)
{
return (RV_MALLOC_FAILED);
}
start_model(FIXED_MODEL);
start_outputing_bits();
start_encoding();
for (usInCount = 0; usInCount < pInBloc->usLen; usInCount++)
{
ch = pInBloc->pData[usInCount];
symbol = char_to_index[ch];
if (encode_symbol(&usOutCount, symbol, cum_freq) != RV_SUCCESS)
{
goto err;
}
update_model(FIXED_MODEL, symbol);
}
if (encode_symbol(&usOutCount, EOF_symbol, cum_freq))
{
goto err;
}
if (done_encoding(&usOutCount) != RV_SUCCESS)
{
goto err;
}
if (done_outputing_bits(&usOutCount) != RV_SUCCESS)
{
goto err;
}
pOutBloc->usLen = usOutCount;
pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen);
if (pOutBloc->pData != NULL)
{
for (i=0; i < pOutBloc->usLen; i++)
{
pOutBloc->pData[i] = Memory[i];
}
GMEM_Free(Memory);
return (RV_SUCCESS);
}
else
{
pOutBloc->usLen = 0;
pOutBloc->pData = NULL;
GMEM_Free(Memory);
return (RV_MALLOC_FAILED);
}
err:
GMEM_Free(Memory);
pOutBloc->usLen = pInBloc->usLen;
pOutBloc->pData = GMEM_Alloc(pOutBloc->usLen);
if (pOutBloc->pData != NULL)
{
for (i=0; i < pOutBloc->usLen; i++)
{
pOutBloc->pData[i] = pInBloc->pData[i];
}
return (RV_COMPRESSION_FAILED);
}
else
{
pOutBloc->usLen = 0;
pOutBloc->pData = NULL;
return (RV_MALLOC_FAILED);
}
}
/******************************************************************************/
int AcAd8_Decode(BLOC *pInBloc, BLOC *pOutBloc)
{
unsigned int ch;
unsigned int symbol;
unsigned short int usInCount = 0;
unsigned short int usOutCount = 0;
MemoSize = 2*pInBloc->usLen;
Memory = GMEM_Alloc(MemoSize);
if (Memory == NULL)
{
pOutBloc->pData = NULL;
pOutBloc->usLen = 0;
return (RV_MALLOC_FAILED);
}
start_model(ADAPTATIVE_MODEL);
start_inputing_bits();
start_decoding(*pInBloc, &usInCount);
while(1)
{
symbol = decode_symbol(*pInBloc, &usInCount, cum_freq);
if ((symbol == EOF_symbol) || (Error != RV_SUCCESS))
{
break;
}
ch = index_to_char[symbol];
if (usOutCount >= MemoSize)
{
Memory = GMEM_ReAlloc (Memory, 2*MemoSize);
if (Memory == NULL)
{
pOutBloc->pData = NULL;
pOutBloc->usLen = 0;
return (RV_MALLOC_FAILED);
}
MemoSize = MemoSize*2;
}
Memory[usOutCount++] = (BYTE)ch;
update_model(ADAPTATIVE_MODEL, symbol);
}
if (Error != RV_SUCCESS)
{
GMEM_Free (Memory);
pOutBloc->pData = NULL;
pOutBloc->usLen = 0;
return (Error);
}
pOutBloc->pData = GMEM_Alloc(usOutCount);
if (pOutBloc->pData == NULL)
{
GMEM_Free (Memory);
pOutBloc->usLen = 0;
return (RV_MALLOC_FAILED);
}
pOutBloc->usLen = usOutCount;
memcpy(pOutBloc->pData, Memory, usOutCount);
GMEM_Free (Memory);
return (RV_SUCCESS);
}
/******************************************************************************/
int AcFx8_Decode(BLOC *pInBloc, BLOC *pOutBloc)
{
unsigned int i, ch;
unsigned int symbol;
unsigned short int usInCount = 0;
unsigned short int usOutCount = 0;
MemoSize = 2*pInBloc->usLen;
Memory = GMEM_Alloc(MemoSize);
if (Memory == NULL)
{
pOutBloc->pData = NULL;
pOutBloc->usLen = 0;
return (RV_MALLOC_FAILED);
}
start_model(FIXED_MODEL);
start_inputing_bits();
start_decoding(*pInBloc, &usInCount);
while(1)
{
symbol = decode_symbol(*pInBloc, &usInCount, cum_freq);
if ((symbol == EOF_symbol) || (Error != RV_SUCCESS))
{
break;
}
ch = index_to_char[symbol];
if (usOutCount >= MemoSize)
{
Memory = GMEM_ReAlloc (Memory, 2*MemoSize);
if (Memory == NULL)
{
pOutBloc->pData = NULL;
pOutBloc->usLen = 0;
return (RV_MALLOC_FAILED);
}
MemoSize = MemoSize*2;
}
Memory[usOutCount++] = (BYTE)ch;
update_model(FIXED_MODEL, symbol);
}
if (Error != RV_SUCCESS)
{
GMEM_Free (Memory);
pOutBloc->pData = NULL;
pOutBloc->usLen = 0;
return (Error);
}
pOutBloc->pData = GMEM_Alloc(usOutCount);
if (pOutBloc->pData == NULL)
{
GMEM_Free (Memory);
pOutBloc->usLen = 0;
return (RV_MALLOC_FAILED);
}
pOutBloc->usLen = usOutCount;
for (i=0; i<pOutBloc->usLen; i++)
{
pOutBloc->pData[i] = Memory[i];
}
GMEM_Free (Memory);
return (RV_SUCCESS);
}