1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Bcj2Coder.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../C/Alloc.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Bcj2Coder.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 9baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NCompress { 10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NBcj2 { 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncinline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); } 13baa3858d3f5d128a5c8466b700098109edcad5f2repo syncinline bool IsJ(Byte b0, Byte b1) { return ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)); } 14baa3858d3f5d128a5c8466b700098109edcad5f2repo syncinline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == 0xE9) ? 256 : 257)); } 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef EXTRACT_ONLY 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 18baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const int kBufferSize = 1 << 17; 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 20baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic bool inline Test86MSByte(Byte b) 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (b == 0 || b == 0xFF); 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 25baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CEncoder::Create() 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_mainStream.Create(1 << 18)) 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_callStream.Create(1 << 18)) 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_jumpStream.Create(1 << 18)) 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_rangeEncoder.Create(1 << 20)) 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_buffer == 0) 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buffer = (Byte *)MidAlloc(kBufferSize); 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_buffer == 0) 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 44baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCEncoder::~CEncoder() 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ::MidFree(_buffer); 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 49baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CEncoder::Flush() 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_mainStream.Flush()); 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_callStream.Flush()); 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_jumpStream.Flush()); 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.FlushData(); 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _rangeEncoder.FlushStream(); 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 58baa3858d3f5d128a5c8466b700098109edcad5f2repo syncconst UInt32 kDefaultLimit = (1 << 24); 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 60baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CEncoder::CodeReal(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams, 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ICompressProgressInfo *progress) 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numInStreams != 1 || numOutStreams != 4) 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!Create()) 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_OUTOFMEMORY; 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool sizeIsDefined = false; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 inSize = 0; 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (inSizes != NULL) 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (inSizes[0] != NULL) 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync inSize = *inSizes[0]; 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (inSize <= kDefaultLimit) 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sizeIsDefined = true; 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCoderReleaser releaser(this); 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISequentialInStream *inStream = inStreams[0]; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mainStream.SetStream(outStreams[0]); 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mainStream.Init(); 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _callStream.SetStream(outStreams[1]); 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _callStream.Init(); 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _jumpStream.SetStream(outStreams[2]); 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _jumpStream.Init(); 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.SetStream(outStreams[3]); 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.Init(); 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < 256 + 2; i++) 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _statusEncoder[i].Init(); 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize; 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 nowPos = 0; 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 nowPos64 = 0; 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 bufferPos = 0; 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte prevByte = 0; 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 subStreamIndex = 0; 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 subStreamStartPos = 0; 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 subStreamEndPos = 0; 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 processedSize = 0; 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 size = kBufferSize - (bufferPos + processedSize); 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 processedSizeLoc; 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size == 0) 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc)); 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processedSizeLoc == 0) 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync processedSize += processedSizeLoc; 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 endPos = bufferPos + processedSize; 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (endPos < 5) 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // change it 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (bufferPos = 0; bufferPos < endPos; bufferPos++) 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b = _buffer[bufferPos]; 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mainStream.WriteByte(b); 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 index; 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (b == 0xE8) 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync index = prevByte; 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (b == 0xE9) 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync index = 256; 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (IsJcc(prevByte, b)) 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync index = 257; 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prevByte = b; 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _statusEncoder[index].Encode(&_rangeEncoder, 0); 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prevByte = b; 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return Flush(); 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bufferPos = 0; 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 limit = endPos - 5; 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while(bufferPos <= limit) 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b = _buffer[bufferPos]; 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mainStream.WriteByte(b); 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!IsJ(prevByte, b)) 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bufferPos++; 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prevByte = b; 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte nextByte = _buffer[bufferPos + 4]; 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 src = 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (UInt32(nextByte) << 24) | 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (UInt32(_buffer[bufferPos + 3]) << 16) | 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (UInt32(_buffer[bufferPos + 2]) << 8) | 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (_buffer[bufferPos + 1]); 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 dest = (nowPos + bufferPos + 5) + src; 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // if (Test86MSByte(nextByte)) 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool convert; 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (getSubStreamSize != NULL) 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 currentPos = (nowPos64 + bufferPos); 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (subStreamEndPos < currentPos) 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 subStreamSize; 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result == S_OK) 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStreamStartPos = subStreamEndPos; 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStreamEndPos += subStreamSize; 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStreamIndex++; 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (result == S_FALSE || result == E_NOTIMPL) 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync getSubStreamSize.Release(); 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStreamStartPos = 0; 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStreamEndPos = subStreamStartPos - 1; 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result; 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (getSubStreamSize == NULL) 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (sizeIsDefined) 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync convert = (dest < inSize); 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync convert = Test86MSByte(nextByte); 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (subStreamEndPos - subStreamStartPos > kDefaultLimit) 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync convert = Test86MSByte(nextByte); 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 dest64 = (currentPos + 5) + Int64(Int32(src)); 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos); 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (sizeIsDefined) 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync convert = (dest < inSize); 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync convert = Test86MSByte(nextByte); 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned index = GetIndex(prevByte, b); 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (convert) 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _statusEncoder[index].Encode(&_rangeEncoder, 1); 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bufferPos += 5; 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream; 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 24; i >= 0; i -= 8) 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync s.WriteByte((Byte)(dest >> i)); 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prevByte = nextByte; 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _statusEncoder[index].Encode(&_rangeEncoder, 0); 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bufferPos++; 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prevByte = b; 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nowPos += bufferPos; 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nowPos64 += bufferPos; 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (progress != NULL) 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt64 compressedSize = 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mainStream.GetProcessedSize() + 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _callStream.GetProcessedSize() + 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _jumpStream.GetProcessedSize() + 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeEncoder.GetProcessedSize(); 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(progress->SetRatioInfo(&nowPos64, NULL)); 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i = 0; 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while(bufferPos < endPos) 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buffer[i++] = _buffer[bufferPos++]; 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bufferPos = i; 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 253baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ICompressProgressInfo *progress) 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync try 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress); 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync catch(const COutBufferException &e) { return e.ErrorCode; } 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync catch(...) { return S_FALSE; } 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 268baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _inBufSizes[streamIndex] = size; return S_OK; } 269baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; } 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 271baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCDecoder::CDecoder(): 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outBufSize(1 << 16) 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _inBufSizes[0] = 1 << 20; 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _inBufSizes[1] = 1 << 20; 276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _inBufSizes[2] = 1 << 20; 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _inBufSizes[3] = 1 << 20; 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 280baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CDecoder::CodeReal(ISequentialInStream **inStreams, const UInt64 ** /* inSizes */, UInt32 numInStreams, 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISequentialOutStream **outStreams, const UInt64 ** /* outSizes */, UInt32 numOutStreams, 282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ICompressProgressInfo *progress) 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numInStreams != 4 || numOutStreams != 1) 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_mainInStream.Create(_inBufSizes[0])) 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_OUTOFMEMORY; 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_callStream.Create(_inBufSizes[1])) 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_OUTOFMEMORY; 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_jumpStream.Create(_inBufSizes[2])) 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_OUTOFMEMORY; 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_rangeDecoder.Create(_inBufSizes[3])) 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_OUTOFMEMORY; 295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_outStream.Create(_outBufSize)) 296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_OUTOFMEMORY; 297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCoderReleaser releaser(this); 299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mainInStream.SetStream(inStreams[0]); 301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _callStream.SetStream(inStreams[1]); 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _jumpStream.SetStream(inStreams[2]); 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeDecoder.SetStream(inStreams[3]); 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outStream.SetStream(outStreams[0]); 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mainInStream.Init(); 307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _callStream.Init(); 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _jumpStream.Init(); 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeDecoder.Init(); 310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outStream.Init(); 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < 256 + 2; i++) 313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _statusDecoder[i].Init(); 314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte prevByte = 0; 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 processedBytes = 0; 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processedBytes >= (1 << 20) && progress != NULL) 320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt64 compressedSize = 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _mainInStream.GetProcessedSize() + 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _callStream.GetProcessedSize() + 325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _jumpStream.GetProcessedSize() + 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _rangeDecoder.GetProcessedSize(); 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt64 nowPos64 = _outStream.GetProcessedSize(); 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(progress->SetRatioInfo(NULL, &nowPos64)); 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync processedBytes = 0; 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b = 0; 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt32 kBurstSize = (1 << 18); 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < kBurstSize; i++) 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_mainInStream.ReadByte(b)) 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return Flush(); 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outStream.WriteByte(b); 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (IsJ(prevByte, b)) 341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prevByte = b; 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync processedBytes += i; 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i == kBurstSize) 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned index = GetIndex(prevByte, b); 348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_statusDecoder[index].Decode(&_rangeDecoder) == 1) 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 src = 0; 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream; 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < 4; i++) 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b0; 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if(!s.ReadByte(b0)) 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync src <<= 8; 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync src |= ((UInt32)b0); 359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ; 361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outStream.WriteByte((Byte)(dest)); 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outStream.WriteByte((Byte)(dest >> 8)); 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outStream.WriteByte((Byte)(dest >> 16)); 364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _outStream.WriteByte((Byte)(dest >> 24)); 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prevByte = (Byte)(dest >> 24); 366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync processedBytes += 4; 367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prevByte = b; 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 373baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, 374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, 375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ICompressProgressInfo *progress) 376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync try 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress); 380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync catch(const CInBufferException &e) { return e.ErrorCode; } 382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync catch(const COutBufferException &e) { return e.ErrorCode; } 383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync catch(...) { return S_FALSE; } 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 387