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>