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>