From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- .../squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp | 412 +++++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp (limited to 'release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp') diff --git a/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp new file mode 100644 index 00000000..fc87bd93 --- /dev/null +++ b/release/src/linux/linux/scripts/squashfs/lzma/C/7zip/Compress/Branch/x86_2.cpp @@ -0,0 +1,412 @@ +// x86_2.cpp + +#include "StdAfx.h" +#include "x86_2.h" + +#include "../../../Common/Alloc.h" + +static const int kBufferSize = 1 << 17; + +inline bool IsJcc(Byte b0, Byte b1) +{ + return (b0 == 0x0F && (b1 & 0xF0) == 0x80); +} + +#ifndef EXTRACT_ONLY + +static bool inline Test86MSByte(Byte b) +{ + return (b == 0 || b == 0xFF); +} + +bool CBCJ2_x86_Encoder::Create() +{ + if (!_mainStream.Create(1 << 16)) + return false; + if (!_callStream.Create(1 << 20)) + return false; + if (!_jumpStream.Create(1 << 20)) + return false; + if (!_rangeEncoder.Create(1 << 20)) + return false; + if (_buffer == 0) + { + _buffer = (Byte *)MidAlloc(kBufferSize); + if (_buffer == 0) + return false; + } + return true; +} + +CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder() +{ + ::MidFree(_buffer); +} + +HRESULT CBCJ2_x86_Encoder::Flush() +{ + RINOK(_mainStream.Flush()); + RINOK(_callStream.Flush()); + RINOK(_jumpStream.Flush()); + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); +} + +const UInt32 kDefaultLimit = (1 << 24); + +HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 1 || numOutStreams != 4) + return E_INVALIDARG; + + if (!Create()) + return E_OUTOFMEMORY; + + bool sizeIsDefined = false; + UInt64 inSize; + if (inSizes != NULL) + if (inSizes[0] != NULL) + { + inSize = *inSizes[0]; + if (inSize <= kDefaultLimit) + sizeIsDefined = true; + } + + ISequentialInStream *inStream = inStreams[0]; + + _mainStream.SetStream(outStreams[0]); + _mainStream.Init(); + _callStream.SetStream(outStreams[1]); + _callStream.Init(); + _jumpStream.SetStream(outStreams[2]); + _jumpStream.Init(); + _rangeEncoder.SetStream(outStreams[3]); + _rangeEncoder.Init(); + for (int i = 0; i < 256; i++) + _statusE8Encoder[i].Init(); + _statusE9Encoder.Init(); + _statusJccEncoder.Init(); + CCoderReleaser releaser(this); + + CMyComPtr getSubStreamSize; + { + inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); + } + + UInt32 nowPos = 0; + UInt64 nowPos64 = 0; + UInt32 bufferPos = 0; + + Byte prevByte = 0; + + UInt64 subStreamIndex = 0; + UInt64 subStreamStartPos = 0; + UInt64 subStreamEndPos = 0; + + while(true) + { + UInt32 processedSize = 0; + while(true) + { + UInt32 size = kBufferSize - (bufferPos + processedSize); + UInt32 processedSizeLoc; + if (size == 0) + break; + RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc)); + if (processedSizeLoc == 0) + break; + processedSize += processedSizeLoc; + } + UInt32 endPos = bufferPos + processedSize; + + if (endPos < 5) + { + // change it + for (bufferPos = 0; bufferPos < endPos; bufferPos++) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 0); + else if (IsJcc(prevByte, b)) + _statusJccEncoder.Encode(&_rangeEncoder, 0); + prevByte = b; + } + return Flush(); + } + + bufferPos = 0; + + UInt32 limit = endPos - 5; + while(bufferPos <= limit) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b)) + { + bufferPos++; + prevByte = b; + continue; + } + Byte nextByte = _buffer[bufferPos + 4]; + UInt32 src = + (UInt32(nextByte) << 24) | + (UInt32(_buffer[bufferPos + 3]) << 16) | + (UInt32(_buffer[bufferPos + 2]) << 8) | + (_buffer[bufferPos + 1]); + UInt32 dest = (nowPos + bufferPos + 5) + src; + // if (Test86MSByte(nextByte)) + bool convert; + if (getSubStreamSize != NULL) + { + UInt64 currentPos = (nowPos64 + bufferPos); + while (subStreamEndPos < currentPos) + { + UInt64 subStreamSize; + HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); + if (result == S_OK) + { + subStreamStartPos = subStreamEndPos; + subStreamEndPos += subStreamSize; + subStreamIndex++; + } + else if (result == S_FALSE || result == E_NOTIMPL) + { + getSubStreamSize.Release(); + subStreamStartPos = 0; + subStreamEndPos = subStreamStartPos - 1; + } + else + return result; + } + if (getSubStreamSize == NULL) + { + if (sizeIsDefined) + convert = (dest < inSize); + else + convert = Test86MSByte(nextByte); + } + else if (subStreamEndPos - subStreamStartPos > kDefaultLimit) + convert = Test86MSByte(nextByte); + else + { + UInt64 dest64 = (currentPos + 5) + Int64(Int32(src)); + convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos); + } + } + else if (sizeIsDefined) + convert = (dest < inSize); + else + convert = Test86MSByte(nextByte); + if (convert) + { + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 1); + else + _statusJccEncoder.Encode(&_rangeEncoder, 1); + + bufferPos += 5; + if (b == 0xE8) + { + _callStream.WriteByte((Byte)(dest >> 24)); + _callStream.WriteByte((Byte)(dest >> 16)); + _callStream.WriteByte((Byte)(dest >> 8)); + _callStream.WriteByte((Byte)(dest)); + } + else + { + _jumpStream.WriteByte((Byte)(dest >> 24)); + _jumpStream.WriteByte((Byte)(dest >> 16)); + _jumpStream.WriteByte((Byte)(dest >> 8)); + _jumpStream.WriteByte((Byte)(dest)); + } + prevByte = nextByte; + } + else + { + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 0); + else + _statusJccEncoder.Encode(&_rangeEncoder, 0); + bufferPos++; + prevByte = b; + } + } + nowPos += bufferPos; + nowPos64 += bufferPos; + + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&nowPos64, NULL)); + } + + UInt32 i = 0; + while(bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } +} + +STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, + outStreams, outSizes,numOutStreams, progress); + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +#endif + +HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 4 || numOutStreams != 1) + return E_INVALIDARG; + + if (!_mainInStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_callStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_jumpStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_outStream.Create(1 << 16)) + return E_OUTOFMEMORY; + + _mainInStream.SetStream(inStreams[0]); + _callStream.SetStream(inStreams[1]); + _jumpStream.SetStream(inStreams[2]); + _rangeDecoder.SetStream(inStreams[3]); + _outStream.SetStream(outStreams[0]); + + _mainInStream.Init(); + _callStream.Init(); + _jumpStream.Init(); + _rangeDecoder.Init(); + _outStream.Init(); + + for (int i = 0; i < 256; i++) + _statusE8Decoder[i].Init(); + _statusE9Decoder.Init(); + _statusJccDecoder.Init(); + + CCoderReleaser releaser(this); + + Byte prevByte = 0; + UInt32 processedBytes = 0; + while(true) + { + if (processedBytes > (1 << 20) && progress != NULL) + { + UInt64 nowPos64 = _outStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(NULL, &nowPos64)); + processedBytes = 0; + } + processedBytes++; + Byte b; + if (!_mainInStream.ReadByte(b)) + return Flush(); + _outStream.WriteByte(b); + if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b)) + { + prevByte = b; + continue; + } + bool status; + if (b == 0xE8) + status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1); + else if (b == 0xE9) + status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1); + else + status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1); + if (status) + { + UInt32 src; + if (b == 0xE8) + { + Byte b0; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0); + } + else + { + Byte b0; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0); + } + UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ; + _outStream.WriteByte((Byte)(dest)); + _outStream.WriteByte((Byte)(dest >> 8)); + _outStream.WriteByte((Byte)(dest >> 16)); + _outStream.WriteByte((Byte)(dest >> 24)); + prevByte = (dest >> 24); + processedBytes += 4; + } + else + prevByte = b; + } +} + +STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, + outStreams, outSizes,numOutStreams, progress); + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} -- cgit v1.2.3-54-g00ecf