Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/LZMA_Alone/LzmaRam.cpp, revision 1.1
1.1 ! misho 1: // LzmaRam.cpp
! 2:
! 3: #include "StdAfx.h"
! 4: #include "../../../Common/Types.h"
! 5: #include "../LZMA/LZMADecoder.h"
! 6: #include "../LZMA/LZMAEncoder.h"
! 7: #include "LzmaRam.h"
! 8:
! 9: extern "C"
! 10: {
! 11: #include "../Branch/BranchX86.h"
! 12: }
! 13:
! 14: class CInStreamRam:
! 15: public ISequentialInStream,
! 16: public CMyUnknownImp
! 17: {
! 18: const Byte *Data;
! 19: size_t Size;
! 20: size_t Pos;
! 21: public:
! 22: MY_UNKNOWN_IMP
! 23: void Init(const Byte *data, size_t size)
! 24: {
! 25: Data = data;
! 26: Size = size;
! 27: Pos = 0;
! 28: }
! 29: STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
! 30: STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
! 31: };
! 32:
! 33: STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
! 34: {
! 35: UInt32 remain = Size - Pos;
! 36: if (size > remain)
! 37: size = remain;
! 38: for (UInt32 i = 0; i < size; i++)
! 39: {
! 40: ((Byte *)data)[i] = Data[Pos + i];
! 41: }
! 42: Pos += size;
! 43: if(processedSize != NULL)
! 44: *processedSize = size;
! 45: return S_OK;
! 46: }
! 47:
! 48: STDMETHODIMP CInStreamRam::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
! 49: {
! 50: return Read(data, size, processedSize);
! 51: }
! 52:
! 53: class COutStreamRam:
! 54: public ISequentialOutStream,
! 55: public CMyUnknownImp
! 56: {
! 57: size_t Size;
! 58: public:
! 59: Byte *Data;
! 60: size_t Pos;
! 61: bool Overflow;
! 62: void Init(Byte *data, size_t size)
! 63: {
! 64: Data = data;
! 65: Size = size;
! 66: Pos = 0;
! 67: Overflow = false;
! 68: }
! 69: void SetPos(size_t pos)
! 70: {
! 71: Overflow = false;
! 72: Pos = pos;
! 73: }
! 74: MY_UNKNOWN_IMP
! 75: HRESULT WriteByte(Byte b)
! 76: {
! 77: if (Pos >= Size)
! 78: {
! 79: Overflow = true;
! 80: return E_FAIL;
! 81: }
! 82: Data[Pos++] = b;
! 83: return S_OK;
! 84: }
! 85: STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
! 86: STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
! 87: };
! 88:
! 89: STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
! 90: {
! 91: UInt32 i;
! 92: for (i = 0; i < size && Pos < Size; i++)
! 93: Data[Pos++] = ((const Byte *)data)[i];
! 94: if(processedSize != NULL)
! 95: *processedSize = i;
! 96: if (i != size)
! 97: {
! 98: Overflow = true;
! 99: return E_FAIL;
! 100: }
! 101: return S_OK;
! 102: }
! 103:
! 104: STDMETHODIMP COutStreamRam::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
! 105: {
! 106: return Write(data, size, processedSize);
! 107: }
! 108:
! 109: #define SZE_FAIL (1)
! 110: #define SZE_OUTOFMEMORY (2)
! 111: #define SZE_OUT_OVERFLOW (3)
! 112:
! 113: int LzmaRamEncode(
! 114: const Byte *inBuffer, size_t inSize,
! 115: Byte *outBuffer, size_t outSize, size_t *outSizeProcessed,
! 116: UInt32 dictionarySize, ESzFilterMode filterMode)
! 117: {
! 118: #ifndef _NO_EXCEPTIONS
! 119: try {
! 120: #endif
! 121:
! 122: *outSizeProcessed = 0;
! 123: const size_t kIdSize = 1;
! 124: const size_t kLzmaPropsSize = 5;
! 125: const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8;
! 126: if (outSize < kMinDestSize)
! 127: return SZE_OUT_OVERFLOW;
! 128: NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
! 129: CMyComPtr<ICompressCoder> encoder = encoderSpec;
! 130:
! 131: PROPID propIDs[] =
! 132: {
! 133: NCoderPropID::kAlgorithm,
! 134: NCoderPropID::kDictionarySize,
! 135: NCoderPropID::kNumFastBytes,
! 136: };
! 137: const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
! 138: PROPVARIANT properties[kNumProps];
! 139: properties[0].vt = VT_UI4;
! 140: properties[1].vt = VT_UI4;
! 141: properties[2].vt = VT_UI4;
! 142: properties[0].ulVal = (UInt32)2;
! 143: properties[1].ulVal = (UInt32)dictionarySize;
! 144: properties[2].ulVal = (UInt32)64;
! 145:
! 146: if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
! 147: return 1;
! 148:
! 149: COutStreamRam *outStreamSpec = new COutStreamRam;
! 150: if (outStreamSpec == 0)
! 151: return SZE_OUTOFMEMORY;
! 152: CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
! 153: CInStreamRam *inStreamSpec = new CInStreamRam;
! 154: if (inStreamSpec == 0)
! 155: return SZE_OUTOFMEMORY;
! 156: CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
! 157:
! 158: outStreamSpec->Init(outBuffer, outSize);
! 159: if (outStreamSpec->WriteByte(0) != S_OK)
! 160: return SZE_OUT_OVERFLOW;
! 161:
! 162: if (encoderSpec->WriteCoderProperties(outStream) != S_OK)
! 163: return SZE_OUT_OVERFLOW;
! 164: if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize)
! 165: return 1;
! 166:
! 167: int i;
! 168: for (i = 0; i < 8; i++)
! 169: {
! 170: UInt64 t = (UInt64)(inSize);
! 171: if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK)
! 172: return SZE_OUT_OVERFLOW;
! 173: }
! 174:
! 175: Byte *filteredStream = 0;
! 176:
! 177: bool useFilter = (filterMode != SZ_FILTER_NO);
! 178: if (useFilter)
! 179: {
! 180: filteredStream = (Byte *)MyAlloc(inSize);
! 181: if (filteredStream == 0)
! 182: return SZE_OUTOFMEMORY;
! 183: memmove(filteredStream, inBuffer, inSize);
! 184: UInt32 _prevMask;
! 185: UInt32 _prevPos;
! 186: x86_Convert_Init(_prevMask, _prevPos);
! 187: x86_Convert(filteredStream, (UInt32)inSize, 0, &_prevMask, &_prevPos, 1);
! 188: }
! 189:
! 190: UInt32 minSize = 0;
! 191: int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
! 192: bool bestIsFiltered = false;
! 193: int mainResult = 0;
! 194: size_t startPos = outStreamSpec->Pos;
! 195: for (i = 0; i < numPasses; i++)
! 196: {
! 197: if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered)
! 198: break;
! 199: outStreamSpec->SetPos(startPos);
! 200: bool curModeIsFiltered = false;
! 201: if (useFilter && i == 0)
! 202: curModeIsFiltered = true;
! 203: if (numPasses > 1 && i == numPasses - 1)
! 204: curModeIsFiltered = true;
! 205:
! 206: inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize);
! 207:
! 208: HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0);
! 209:
! 210: mainResult = 0;
! 211: if (lzmaResult == E_OUTOFMEMORY)
! 212: {
! 213: mainResult = SZE_OUTOFMEMORY;
! 214: break;
! 215: }
! 216: if (i == 0 || outStreamSpec->Pos <= minSize)
! 217: {
! 218: minSize = outStreamSpec->Pos;
! 219: bestIsFiltered = curModeIsFiltered;
! 220: }
! 221: if (outStreamSpec->Overflow)
! 222: mainResult = SZE_OUT_OVERFLOW;
! 223: else if (lzmaResult != S_OK)
! 224: {
! 225: mainResult = SZE_FAIL;
! 226: break;
! 227: }
! 228: }
! 229: *outSizeProcessed = outStreamSpec->Pos;
! 230: if (bestIsFiltered)
! 231: outBuffer[0] = 1;
! 232: if (useFilter)
! 233: MyFree(filteredStream);
! 234: return mainResult;
! 235:
! 236: #ifndef _NO_EXCEPTIONS
! 237: } catch(...) { return SZE_OUTOFMEMORY; }
! 238: #endif
! 239: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>