4 #include "../../../Common/Types.h"
5 #include "../LZMA/LZMADecoder.h"
6 #include "../LZMA/LZMAEncoder.h"
11 #include "../../../../C/Compress/Branch/BranchX86.h"
15 public ISequentialInStream,
23 void Init(const Byte *data, size_t size)
29 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
32 STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
34 if (size > (Size - Pos))
35 size = (UInt32)(Size - Pos);
36 for (UInt32 i = 0; i < size; i++)
37 ((Byte *)data)[i] = Data[Pos + i];
39 if(processedSize != NULL)
40 *processedSize = size;
45 public ISequentialOutStream,
53 void Init(Byte *data, size_t size)
60 void SetPos(size_t pos)
66 HRESULT WriteByte(Byte b)
76 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
79 STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
82 for (i = 0; i < size && Pos < Size; i++)
83 Data[Pos++] = ((const Byte *)data)[i];
84 if(processedSize != NULL)
94 #define SZ_RAM_E_FAIL (1)
95 #define SZ_RAM_E_OUTOFMEMORY (2)
96 #define SZE_OUT_OVERFLOW (3)
99 const Byte *inBuffer, size_t inSize,
100 Byte *outBuffer, size_t outSize, size_t *outSizeProcessed,
101 UInt32 dictionarySize, ESzFilterMode filterMode)
103 #ifndef _NO_EXCEPTIONS
107 *outSizeProcessed = 0;
108 const size_t kIdSize = 1;
109 const size_t kLzmaPropsSize = 5;
110 const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8;
111 if (outSize < kMinDestSize)
112 return SZE_OUT_OVERFLOW;
113 NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
114 CMyComPtr<ICompressCoder> encoder = encoderSpec;
118 NCoderPropID::kAlgorithm,
119 NCoderPropID::kDictionarySize,
120 NCoderPropID::kNumFastBytes,
122 const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
123 PROPVARIANT properties[kNumProps];
124 properties[0].vt = VT_UI4;
125 properties[1].vt = VT_UI4;
126 properties[2].vt = VT_UI4;
127 properties[0].ulVal = (UInt32)2;
128 properties[1].ulVal = (UInt32)dictionarySize;
129 properties[2].ulVal = (UInt32)64;
131 if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
134 COutStreamRam *outStreamSpec = new COutStreamRam;
135 if (outStreamSpec == 0)
136 return SZ_RAM_E_OUTOFMEMORY;
137 CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
138 CInStreamRam *inStreamSpec = new CInStreamRam;
139 if (inStreamSpec == 0)
140 return SZ_RAM_E_OUTOFMEMORY;
141 CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
143 outStreamSpec->Init(outBuffer, outSize);
144 if (outStreamSpec->WriteByte(0) != S_OK)
145 return SZE_OUT_OVERFLOW;
147 if (encoderSpec->WriteCoderProperties(outStream) != S_OK)
148 return SZE_OUT_OVERFLOW;
149 if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize)
153 for (i = 0; i < 8; i++)
155 UInt64 t = (UInt64)(inSize);
156 if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK)
157 return SZE_OUT_OVERFLOW;
160 Byte *filteredStream = 0;
162 bool useFilter = (filterMode != SZ_FILTER_NO);
167 filteredStream = (Byte *)MyAlloc(inSize);
168 if (filteredStream == 0)
169 return SZ_RAM_E_OUTOFMEMORY;
170 memmove(filteredStream, inBuffer, inSize);
173 x86_Convert_Init(x86State);
174 x86_Convert(filteredStream, (SizeT)inSize, 0, &x86State, 1);
178 int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
179 bool bestIsFiltered = false;
181 size_t startPos = outStreamSpec->Pos;
182 for (i = 0; i < numPasses; i++)
184 if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered)
186 outStreamSpec->SetPos(startPos);
187 bool curModeIsFiltered = false;
188 if (useFilter && i == 0)
189 curModeIsFiltered = true;
190 if (numPasses > 1 && i == numPasses - 1)
191 curModeIsFiltered = true;
193 inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize);
195 HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0);
198 if (lzmaResult == E_OUTOFMEMORY)
200 mainResult = SZ_RAM_E_OUTOFMEMORY;
203 if (i == 0 || outStreamSpec->Pos <= minSize)
205 minSize = outStreamSpec->Pos;
206 bestIsFiltered = curModeIsFiltered;
208 if (outStreamSpec->Overflow)
209 mainResult = SZE_OUT_OVERFLOW;
210 else if (lzmaResult != S_OK)
212 mainResult = SZ_RAM_E_FAIL;
216 *outSizeProcessed = outStreamSpec->Pos;
220 MyFree(filteredStream);
223 #ifndef _NO_EXCEPTIONS
224 } catch(...) { return SZ_RAM_E_OUTOFMEMORY; }