static void write_backref(byte[] outb, int out_pos, backref_t backref) { int size = backref.length - 1; switch (backref.distance) { case 1: outb[out_pos] = (byte)(0x40 | size); break; case 2: outb[out_pos] = (byte)(0x60 | size); break; case 4: outb[out_pos] = (byte)(0x80 | size); break; case 16: outb[out_pos] = (byte)(0xA0 | size); break; case 32: outb[out_pos] = (byte)(0xC0 | size); break; case 64: outb[out_pos] = (byte)(0xE0 | size); break; } }
static backref_t new_backref_t() { backref_t t = new backref_t(); t.distance = 0; t.length = 0; return(t); }
static backref_t search_backref(int pos, byte[] buffer, int inputsize) { backref_t variant = new_backref_t(); int match = 0; int backref_len = 0; int backref_dist = 0; int searchPosition = 0; for (int idx = 0; idx < D; idx++) { searchPosition = pos - _distanceData[idx]; if (searchPosition > -1) {//added to try and fix the missing data bug... if ((buffer[searchPosition] == buffer[pos])) { match = 1; while ((buffer[searchPosition + match] == buffer[pos + match]) && (pos + match < inputsize) && ((searchPosition + MAX_MATCH_LENGTH) < (pos + MAX_MATCH_LENGTH))) { if (match >= MAX_MATCH_LENGTH) { break; } match++; } if (match > backref_len) { backref_len = match; backref_dist = _distanceData[idx]; } } } } variant.length = (ushort)backref_len; variant.distance = (ushort)backref_dist; //cout << hex << " len=[" << setw(4) << (int)variant.length << "]"; //cout << hex << " dist=[" << setw(4) << (int)variant.distance << "]"; return(variant); }
static backref_t search_incr(int pos, byte[] buffer, int inputsize) { backref_t variant = new_backref_t(); int match = 0; int backref_len = 0; int searchPosition = 0; //int i = 1; searchPosition = pos - 1; if (searchPosition > -1) {//added to try and fix the missing data bug... int c = buffer[searchPosition]; int n = buffer[searchPosition] + 1; //cout << hex << " c=[" << setw(4) << (int)c << "]"; //cout << hex << " n=[" << setw(4) << (int)n << "]"; if (buffer[pos] == n) { match = 1; //cout << hex << " match1=[" << setw(4) << (int)match << "]"; while (buffer[pos + match] == (n + match)) { if (match >= MAX_MATCH_LENGTH) { break; } match++; } if (match > backref_len) { backref_len = match; } } } variant.length = (ushort)backref_len; return(variant); }
public static byte[] Compress(byte[] indata) { //cout << "--===Super Bomberman 5===---" << endl; byte[] _inputData = new byte[buffersize]; byte[] _outputData = new byte[buffersize]; //byte[] _tempData = new byte[buffersize]; byte[] _rawData = new byte[MAX_RAW_LENGTH]; int _rawLength = 0; int _inputPosition = 0; int _outputPosition = 0; int _inputSize = 0; _inputSize = indata.Length; int _newSize = _inputSize; Array.Copy(indata, 0, _inputData, 0, _newSize); backref_t backref = new_backref_t(); backref_t incrref = new_backref_t(); //cout << hex << "Starting compression..."; //Console.Write("Starting Compression..."); while (_inputPosition < _newSize) { //Console.Write("\r\nIn Position: " + (_inputPosition).ToString("X") + " | Out Position: " + _outputPosition.ToString("X")); //cout << hex << "\nIn_pos=[" << setw(4) // << (int) _inputPosition - 0x40 << "]"; //cout << hex << " Out_pos=[" << setw(4) << (int) _outputPosition // << "]"; if (_inputPosition == 31) { //Console.Write("meh"); } backref = search_backref(_inputPosition, _inputData, _newSize); incrref = search_incr(_inputPosition, _inputData, _newSize); if (incrref.length > backref.length || (incrref.length >= _rawLength && incrref.length >= MIN_MATCH_LENGTH)) { //cout << " WRITE_INCRREF"; if (_rawLength > 0) { //cout << ", WRITE_RAW_FIRST"; write_raw(_outputData, _outputPosition, _rawData, _rawLength); _outputPosition += (_rawLength + 1); _rawLength = 0; } write_incrref(_outputData, _outputPosition, incrref); _inputPosition += incrref.length; _outputPosition++; } else { if (backref.length > _rawLength || backref.length > MIN_MATCH_LENGTH || (backref.length < _rawLength && backref.length > MIN_MATCH_LENGTH) ) { //cout << " WRITE_BACKREF"; if (_rawLength > 0) { //cout << ", WRITE_RAW_FIRST"; write_raw(_outputData, _outputPosition, _rawData, _rawLength); _outputPosition += (_rawLength + 1); _rawLength = 0; } write_backref(_outputData, _outputPosition, backref); _inputPosition += backref.length; _outputPosition++; } else { _rawData[_rawLength++] = _inputData[_inputPosition++]; //cout << hex << " RAW_LENGTH=[" << (int) _rawLength << "]"; if (_rawLength == MAX_RAW_LENGTH) { //cout << " WRITE_RAW"; write_raw(_outputData, _outputPosition, _rawData, _rawLength); //_inputPosition += _rawLength; int plus = _rawLength + 1; _outputPosition += plus; _rawLength = 0; } } } } if (_rawLength > 0) { //cout << " WRITE_RAW"; write_raw(_outputData, _outputPosition, _rawData, _rawLength); _inputPosition += _rawLength; int plus = _rawLength + 1; _outputPosition += plus; _rawLength = 0; } //Console.WriteLine("Compression Complete."); //write file here byte[] final = new byte[_outputPosition]; Array.Copy(_outputData, 0, final, 0, _outputPosition); //File.WriteAllBytes(outfile, final); return(final); }
static void write_incrref(byte[] outb, int out_pos, backref_t backref) { int size = backref.length - 1; outb[out_pos] = (byte)(0x20 | size); }
static backref_t new_backref_t() { backref_t t = new backref_t(); t.distance = 0; t.length = 0; return t; }