LAMPIRAN A : LISTING PROGRAM

Arithmetic coding dengan floating point : Modul acp.cpp : #include #include #include #include



#include "resource.h" #include "arithmetic_codec.h" const char * W_MSG = "file tidak dapat ditulis !"; const char * R_MSG = "file tidak dapat dibaca !"; const unsigned NumModels

= 16;

const unsigned FILE_ID

= 0xB8AA3B29U;

const unsigned BufferSize = 6555555; char FileSumber[MAX_PATH] = ""; char FileHasil[MAX_PATH] = ""; char pesan[256]; void Encode_File(char * data_file_name, char * code_file_name); void Decode_File(char * code_file_name, char * data_file_name); void Error(const char * s) { fprintf(stderr, "\n Error: %s.\n\n", s); exit(1); } unsigned Buffer_CRC(unsigned bytes, unsigned char * buffer) { static const unsigned CRC_Gen[8] = { 0xEC1A5A3EU, 0x5975F5D7U, 0xB2EBEBAEU, 0xE49696F7U, 0x486C6C45U, 0x90D8D88AU, 0xA0F0F0BFU, 0xC0A0A0D5U }; static unsigned CRC_Table[256]; if (CRC_Table[1] == 0)

Universitas Sumatera Utara

for (unsigned k = CRC_Table[0] = 0; k < 8; k++) { unsigned s = 1 > 8) ^ CRC_Table[(crc&0xFFU)^unsigned(*buffer++)]; } while (--bytes); return crc; } FILE * Open_Input_File(char * file_name) { FILE * new_file = fopen(file_name, "rb"); if (new_file == 0) Error("input file tidak dapat dibuka !"); return new_file; } FILE * Open_Output_File(char * file_name) { FILE * new_file = fopen(file_name, "rb"); if (new_file != 0) { fclose(new_file); } new_file = fopen(file_name, "wb"); if (new_file == 0) Error("output file tidak dapat dibuka"); return new_file; } void Save_Number(unsigned n, unsigned char * b) { (unsigned char)( n & 0xFFU); b[1] = (unsigned char)((n >> 8) & 0xFFU); b[2] = (unsigned char)((n >> 16) & 0xFFU); b[3] = (unsigned char)( n >> 24 ); }

b[0] =

unsigned Recover_Number(unsigned char * b) { return unsigned(b[0]) + (unsigned(b[1]) > 1) != s); base = x; length = y - x; if (base >= 1.0) { base -= 1.0; value -= 1.0; } if ((length -= AC__Leakage) = M.data_symbols) AC_Error("simbol data tidak berlaku"); #endif double y; if (data == M.data_symbols - 1) y = base + length; else y = base + length * M.distribution[data+1]; base += length * M.distribution[data]; length = y - base;

Universitas Sumatera Utara

if (base >= 1.0) propagate_carry(); if ((length -= AC__Leakage) > 1; double x = base, y = base + length; double shifted_value = value + AC__LeastSignifBit;

do { double z = base + length * M.distribution[m]; if (z > shifted_value) { y = z; n = m; } else { x = z; s = m; } } while ((m = (s + n) >> 1) != s);

base = x; length = y - x; if (base >= 1.0) { base -= 1.0; value -= 1.0; } if ((length -= AC__Leakage) 0x1000000U)) AC_Error("ukuran buffer cacat"); if (mode != 0) AC_Error("buffer tidak dapat dibuat selama encoding atau decoding"); if (user_buffer != 0) { buffer_size = max_code_bytes; code_buffer = user_buffer; delete [] new_buffer; new_buffer = 0; return; } if (max_code_bytes > 8) - (a >> 8) < 2) { base += AC__MinLength; last_bytes = 2;

Universitas Sumatera Utara

} else { base += 256.0 * AC__MinLength; last_bytes = 1; } if (base >= 1.0) propagate_carry(); do { base *= 256.0; unsigned a = unsigned(base); *ac_pointer++ = (unsigned char) a; base -= double(a); } while (--last_bytes); unsigned code_bytes = unsigned(ac_pointer - code_buffer); if (code_bytes > buffer_size) AC_Error("code buffer overflow"); return code_bytes; } unsigned Arithmetic_Codec::write_to_file(FILE * code_file) { unsigned header_bytes = 0, code_bytes = stop_encoder(), nb = code_bytes;

do { int file_byte = int(nb & 0x7FU); if ((nb >>= 7) > 0) file_byte |= 0x80; if (putc(file_byte, code_file) == EOF) AC_Error("data tidak bisa ditulis ke dalam file"); header_bytes++; } while (nb); if (fwrite(code_buffer, 1, code_bytes, code_file) != code_bytes) AC_Error("data tidak bisa ditulis ke dalam file"); return code_bytes + header_bytes; } void Arithmetic_Codec::stop_decoder(void) { if (mode != 2) AC_Error("decoder tidak bisa berhenti"); mode = 0; } Adaptive_Data_Model::Adaptive_Data_Model(void) { data_symbols = 0; distribution = 0; symbol_count = 0; }

Universitas Sumatera Utara

Adaptive_Data_Model::Adaptive_Data_Model(unsigned number_of_symbols) { data_symbols = 0; distribution = 0; symbol_count = 0; set_alphabet(number_of_symbols); } Adaptive_Data_Model::~Adaptive_Data_Model(void) { delete [] distribution; delete [] symbol_count; } void Adaptive_Data_Model::set_alphabet(unsigned number_of_symbols) { if ((number_of_symbols < 2) || (number_of_symbols > (1 DM__MaxCount) { total_count = 0; for (unsigned n = 0; n < data_symbols; n++) total_count += (symbol_count[n] = (symbol_count[n] + 1) >> 1); } unsigned sum = 0; double scale = 1.0 / double(total_count); for (unsigned k = 0; k < data_symbols; k++) { distribution[k] = scale * sum; sum += symbol_count[k]; } update_cycle = (5 * update_cycle) >> 2;

Universitas Sumatera Utara

unsigned max_cycle = (data_symbols + 6) max_cycle) update_cycle = max_cycle; symbols_until_update = update_cycle; } void Adaptive_Data_Model::reset(void) { if (data_symbols == 0) return;

total_count = 0; update_cycle = data_symbols; for (unsigned k = 0; k < data_symbols; k++) symbol_count[k] = 1; update(); symbols_until_update = update_cycle = (data_symbols + 6) >> 1; }

Modul arithmetic_codec.h : #ifndef ARITHMETIC_CODEC #define ARITHMETIC_CODEC #include class Adaptive_Data_Model { public: Adaptive_Data_Model(void); Adaptive_Data_Model(unsigned number_of_symbols); ~Adaptive_Data_Model(void); unsigned model_symbols(void) { return data_symbols; } void reset(void); void set_alphabet(unsigned number_of_symbols); private: void update(void); double * distribution; unsigned * symbol_count; unsigned data_symbols, total_count, update_cycle, symbols_until_update; friend class Arithmetic_Codec; }; class Arithmetic_Codec { public: Arithmetic_Codec(void); ~Arithmetic_Codec(void); Arithmetic_Codec(unsigned max_code_bytes,

Universitas Sumatera Utara

unsigned char * user_buffer = 0); unsigned char * buffer(void) { return code_buffer; } void set_buffer(unsigned max_code_bytes, unsigned char * user_buffer = 0); void void void

start_encoder(void); start_decoder(void); read_from_file(FILE * code_file);

unsigned stop_encoder(void); unsigned write_to_file(FILE * code_file); void stop_decoder(void); void put_bit(unsigned bit); unsigned get_bit(void); void put_bits(unsigned data, unsigned number_of_bits); unsigned get_bits(unsigned number_of_bits); void

encode(unsigned data, Adaptive_Data_Model &); unsigned decode(Adaptive_Data_Model &); private: void void void unsigned double unsigned };

propagate_carry(void); renorm_enc_interval(void); renorm_dec_interval(void); buffer_size, mode; base, value, length; char * code_buffer, * new_buffer, * ac_pointer;

#endif

Arithmetic coding dengan integer : Modul aci.cpp : #include #include #include #include



#include "resource.h" #include "arithmetic_codec.h" const char * W_MSG = "file tidak dapat ditulis !"; const char * R_MSG = "file tidak dapat dibaca !"; const unsigned NumModels

= 16;

Universitas Sumatera Utara

const unsigned FILE_ID

= 0xB8AA3B29U;

const unsigned BufferSize = 6555555; char FileSumber[MAX_PATH] = ""; char FileHasil[MAX_PATH] = ""; char pesan[256]; void Encode_File(char * data_file_name, char * code_file_name); void Decode_File(char * code_file_name, char * data_file_name); void Error(const char * s) { fprintf(stderr, "\n Error: %s.\n\n", s); exit(1); } unsigned Buffer_CRC(unsigned bytes, unsigned char * buffer) { static const unsigned CRC_Gen[8] = { 0xEC1A5A3EU, 0x5975F5D7U, 0xB2EBEBAEU, 0xE49696F7U, 0x486C6C45U, 0x90D8D88AU, 0xA0F0F0BFU, 0xC0A0A0D5U }; static unsigned CRC_Table[256]; if (CRC_Table[1] == 0) for (unsigned k = CRC_Table[0] = 0; k < 8; k++) { unsigned s = 1 > 8) ^ CRC_Table[(crc&0xFFU)^unsigned(*buffer++)]; } while (--bytes); return crc; } FILE * Open_Input_File(char * file_name) { FILE * new_file = fopen(file_name, "rb"); if (new_file == 0) Error("input file tidak dapat dibuka !");

Universitas Sumatera Utara

return new_file; } FILE * Open_Output_File(char * file_name) { FILE * new_file = fopen(file_name, "rb"); if (new_file != 0) { fclose(new_file); } new_file = fopen(file_name, "wb"); if (new_file == 0) Error("output file tidak dapat dibuka"); return new_file; } void Save_Number(unsigned n, unsigned char * b) { (unsigned char)( n & 0xFFU); b[1] = (unsigned char)((n >> 8) & 0xFFU); b[2] = (unsigned char)((n >> 16) & 0xFFU); b[3] = (unsigned char)( n >> 24 ); }

b[0] =

unsigned Recover_Number(unsigned char * b) { return unsigned(b[0]) + (unsigned(b[1]) base) propagate_carry(); if (length < AC__MinLength) renorm_enc_interval(); } unsigned Arithmetic_Codec::get_bits(unsigned bits) { #ifdef _DEBUG if (mode != 2) AC_Error("decoder tidak diinisialisasi");

Universitas Sumatera Utara

if ((bits < 1) || (bits > 20)) AC_Error("jumlah bit tidak berlaku"); #endif unsigned s = value / (length >>= bits); value -= length * s; if (length < AC__MinLength) renorm_dec_interval(); return s; } void Arithmetic_Codec::encode(unsigned data, Adaptive_Data_Model & M) { #ifdef _DEBUG if (mode != 1) AC_Error("encoder tidak diinisialisasi"); if (data >= M.data_symbols) AC_Error("simbol data tidak berlaku"); #endif unsigned x, init_base = base; if (data == M.last_symbol) { x = M.distribution[data] * (length >> DM__LengthShift); base += x; length -= x; } else { x = M.distribution[data] * (length >>= DM__LengthShift); base += x; length = M.distribution[data+1] * length - x; } if (init_base > base) propagate_carry(); if (length < AC__MinLength) renorm_enc_interval(); ++M.symbol_count[data]; if (--M.symbols_until_update == 0) M.update(true); } unsigned Arithmetic_Codec::decode(Adaptive_Data_Model & M) { #ifdef _DEBUG if (mode != 2) AC_Error("decoder tidak diinisialisasi"); #endif unsigned n, s, x, y = length; if (M.decoder_table) { unsigned dv = value / (length >>= DM__LengthShift); unsigned t = dv >> M.table_shift; s = M.decoder_table[t]; n = M.decoder_table[t+1] + 1;

Universitas Sumatera Utara

while (n > s + 1) { unsigned m = (s + n) >> 1; if (M.distribution[m] > dv) n = m; else s = m; } x = M.distribution[s] * length; if (s != M.last_symbol) y = M.distribution[s+1] * length; } else { x = s = 0; length >>= DM__LengthShift; unsigned m = (n = M.data_symbols) >> 1; do { unsigned z = length * M.distribution[m]; if (z > value) { n = m; y = z; } else { s = m; x = z; } while ((m = (s + n) >> 1) != s);

}

} value -= x; length = y - x; if (length < AC__MinLength) renorm_dec_interval(); ++M.symbol_count[s]; if (--M.symbols_until_update == 0) M.update(false); return s; } Arithmetic_Codec::Arithmetic_Codec(void) { mode = buffer_size = 0; new_buffer = code_buffer = 0; } Arithmetic_Codec::Arithmetic_Codec(unsigned max_code_bytes, unsigned char * user_buffer) { mode = buffer_size = 0; new_buffer = code_buffer = 0; set_buffer(max_code_bytes, user_buffer); } Arithmetic_Codec::~Arithmetic_Codec(void) { delete [] new_buffer; }

Universitas Sumatera Utara

void Arithmetic_Codec::set_buffer(unsigned max_code_bytes, unsigned char * user_buffer) { if ((max_code_bytes < 16) || (max_code_bytes > 0x1000000U)) AC_Error("ukuran buffer cacat"); if (mode != 0) AC_Error("buffer tidak dapat dibuat selama encoding atau decoding"); if (user_buffer != 0) { buffer_size = max_code_bytes; code_buffer = user_buffer; delete [] new_buffer; new_buffer = 0; return; } if (max_code_bytes > 1; length = AC__MinLength >> 9; } if (init_base > base) propagate_carry(); renorm_enc_interval(); unsigned code_bytes = unsigned(ac_pointer - code_buffer); if (code_bytes > buffer_size) AC_Error("code buffer overflow"); return code_bytes; } unsigned Arithmetic_Codec::write_to_file(FILE * code_file) { unsigned header_bytes = 0, code_bytes = stop_encoder(), nb = code_bytes; do { int file_byte = int(nb & 0x7FU); if ((nb >>= 7) > 0) file_byte |= 0x80; if (putc(file_byte, code_file) == EOF) AC_Error("data tidak bisa ditulis ke dalam file");

Universitas Sumatera Utara

header_bytes++; } while (nb); if (fwrite(code_buffer, 1, code_bytes, code_file) != code_bytes) AC_Error("data tidak bisa ditulis ke dalam file"); return code_bytes + header_bytes; } void Arithmetic_Codec::stop_decoder(void) { if (mode != 2) AC_Error("decoder tidak bisa berhenti"); mode = 0; } Adaptive_Data_Model::Adaptive_Data_Model(void) { data_symbols = 0; distribution = 0; } Adaptive_Data_Model::Adaptive_Data_Model(unsigned number_of_symbols) { data_symbols = 0; distribution = 0; set_alphabet(number_of_symbols); } Adaptive_Data_Model::~Adaptive_Data_Model(void) { delete [] distribution; } void Adaptive_Data_Model::set_alphabet(unsigned number_of_symbols) { if ((number_of_symbols < 2) || (number_of_symbols > (1 16) { unsigned table_bits = 3; while (data_symbols > (1U > 1); } unsigned k, sum = 0, s = 0; unsigned scale = 0x80000000U / total_count; if (from_encoder || (table_size == 0)) for (k = 0; k < data_symbols; k++) { distribution[k] = (scale * sum) >> (31 DM__LengthShift); sum += symbol_count[k]; } else { for (k = 0; k < data_symbols; k++) { distribution[k] = (scale * sum) >> (31 DM__LengthShift); sum += symbol_count[k]; unsigned w = distribution[k] >> table_shift; while (s < w) decoder_table[++s] = k - 1; } decoder_table[0] = 0; while (s > 2; unsigned max_cycle = (data_symbols + 6) max_cycle) update_cycle = max_cycle; symbols_until_update = update_cycle; } void Adaptive_Data_Model::reset(void) { if (data_symbols == 0) return;

Universitas Sumatera Utara

total_count = 0; update_cycle = data_symbols; for (unsigned k = 0; k < data_symbols; k++) symbol_count[k] = 1; update(false); symbols_until_update = update_cycle = (data_symbols + 6) >> 1; }

Modul arithmetic_codec.h : #ifndef ARITHMETIC_CODEC #define ARITHMETIC_CODEC #include class Adaptive_Data_Model { public: Adaptive_Data_Model(void); Adaptive_Data_Model(unsigned number_of_symbols); ~Adaptive_Data_Model(void); unsigned model_symbols(void) { return data_symbols; } void reset(void); void set_alphabet(unsigned number_of_symbols); private: void update(bool); unsigned * distribution, * symbol_count, * decoder_table; unsigned total_count, update_cycle, symbols_until_update; unsigned data_symbols, last_symbol, table_size, table_shift; friend class Arithmetic_Codec; }; class Arithmetic_Codec { public: Arithmetic_Codec(void); ~Arithmetic_Codec(void); Arithmetic_Codec(unsigned max_code_bytes, unsigned char * user_buffer = 0); unsigned char * buffer(void) { return code_buffer; } void set_buffer(unsigned max_code_bytes, unsigned char * user_buffer = 0); void void void unsigned

start_encoder(void); start_decoder(void); read_from_file(FILE * code_file); stop_encoder(void);

Universitas Sumatera Utara

unsigned write_to_file(FILE * code_file); void stop_decoder(void); void put_bit(unsigned bit); unsigned get_bit(void); void put_bits(unsigned data, unsigned number_of_bits); unsigned get_bits(unsigned number_of_bits); void

encode(unsigned data, Adaptive_Data_Model &); unsigned decode(Adaptive_Data_Model &); private: void propagate_carry(void); void renorm_enc_interval(void); void renorm_dec_interval(void); unsigned char * code_buffer, * new_buffer, * ac_pointer; unsigned base, value, length; unsigned buffer_size, mode; }; #endif

Universitas Sumatera Utara