#ifdef _WINDOWS #include #endif #include #include #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; iusLen; i++) { pOutBloc->pData[i] = Memory[i]; } GMEM_Free (Memory); return (RV_SUCCESS); }