Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/LZMA_Alone/LzmaRam.cpp, revision 1.1.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>