Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/Branch/x86_2.cpp, revision 1.1

1.1     ! misho       1: // x86_2.cpp
        !             2: 
        !             3: #include "StdAfx.h"
        !             4: #include "x86_2.h"
        !             5: 
        !             6: #include "../../../Common/Alloc.h"
        !             7: 
        !             8: static const int kBufferSize = 1 << 17;
        !             9: 
        !            10: inline bool IsJcc(Byte b0, Byte b1)
        !            11: {
        !            12:   return (b0 == 0x0F && (b1 & 0xF0) == 0x80);
        !            13: }
        !            14: 
        !            15: #ifndef EXTRACT_ONLY
        !            16: 
        !            17: static bool inline Test86MSByte(Byte b)
        !            18: {
        !            19:   return (b == 0 || b == 0xFF);
        !            20: }
        !            21: 
        !            22: bool CBCJ2_x86_Encoder::Create()
        !            23: {
        !            24:   if (!_mainStream.Create(1 << 16))
        !            25:     return false;
        !            26:   if (!_callStream.Create(1 << 20))
        !            27:     return false;
        !            28:   if (!_jumpStream.Create(1 << 20))
        !            29:     return false;
        !            30:   if (!_rangeEncoder.Create(1 << 20))
        !            31:     return false;
        !            32:   if (_buffer == 0)
        !            33:   {
        !            34:     _buffer = (Byte *)BigAlloc(kBufferSize);
        !            35:     if (_buffer == 0)
        !            36:       return false;
        !            37:   }
        !            38:   return true;
        !            39: }
        !            40: 
        !            41: CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder()
        !            42: {
        !            43:   BigFree(_buffer);
        !            44: }
        !            45: 
        !            46: HRESULT CBCJ2_x86_Encoder::Flush()
        !            47: {
        !            48:   RINOK(_mainStream.Flush());
        !            49:   RINOK(_callStream.Flush());
        !            50:   RINOK(_jumpStream.Flush());
        !            51:   _rangeEncoder.FlushData();
        !            52:   return _rangeEncoder.FlushStream();
        !            53: }
        !            54: 
        !            55: const UInt32 kDefaultLimit = (1 << 24);
        !            56: 
        !            57: HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
        !            58:       const UInt64 **inSizes,
        !            59:       UInt32 numInStreams,
        !            60:       ISequentialOutStream **outStreams,
        !            61:       const UInt64 **outSizes,
        !            62:       UInt32 numOutStreams,
        !            63:       ICompressProgressInfo *progress)
        !            64: {
        !            65:   if (numInStreams != 1 || numOutStreams != 4)
        !            66:     return E_INVALIDARG;
        !            67: 
        !            68:   if (!Create())
        !            69:     return E_OUTOFMEMORY;
        !            70: 
        !            71:   bool sizeIsDefined = false;
        !            72:   UInt64 inSize;
        !            73:   if (inSizes != NULL)
        !            74:     if (inSizes[0] != NULL)
        !            75:     {
        !            76:       inSize = *inSizes[0];
        !            77:       if (inSize <= kDefaultLimit)
        !            78:         sizeIsDefined = true;
        !            79:     }
        !            80: 
        !            81:   ISequentialInStream *inStream = inStreams[0];
        !            82: 
        !            83:   _mainStream.SetStream(outStreams[0]);
        !            84:   _mainStream.Init();
        !            85:   _callStream.SetStream(outStreams[1]);
        !            86:   _callStream.Init();
        !            87:   _jumpStream.SetStream(outStreams[2]);
        !            88:   _jumpStream.Init();
        !            89:   _rangeEncoder.SetStream(outStreams[3]);
        !            90:   _rangeEncoder.Init();
        !            91:   for (int i = 0; i < 256; i++)
        !            92:     _statusE8Encoder[i].Init();
        !            93:   _statusE9Encoder.Init();
        !            94:   _statusJccEncoder.Init();
        !            95:   CCoderReleaser releaser(this);
        !            96: 
        !            97:   CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
        !            98:   {
        !            99:     inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
        !           100:   }
        !           101: 
        !           102:   UInt32 nowPos = 0;
        !           103:   UInt64 nowPos64 = 0;
        !           104:   UInt32 bufferPos = 0;
        !           105:   UInt32 processedSize;
        !           106: 
        !           107:   Byte prevByte = 0;
        !           108: 
        !           109:   UInt64 subStreamIndex = 0;
        !           110:   UInt64 subStreamStartPos  = 0;
        !           111:   UInt64 subStreamEndPos = 0;
        !           112: 
        !           113:   while(true)
        !           114:   {
        !           115:     UInt32 size = kBufferSize - bufferPos;
        !           116:     RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
        !           117:     UInt32 endPos = bufferPos + processedSize;
        !           118:     
        !           119:     if (endPos < 5)
        !           120:     {
        !           121:       // change it 
        !           122:       for (bufferPos = 0; bufferPos < endPos; bufferPos++)
        !           123:       {
        !           124:         Byte b = _buffer[bufferPos];
        !           125:         _mainStream.WriteByte(b);
        !           126:         if (b == 0xE8)
        !           127:           _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
        !           128:         else if (b == 0xE9)
        !           129:           _statusE9Encoder.Encode(&_rangeEncoder, 0);
        !           130:         else if (IsJcc(prevByte, b))
        !           131:           _statusJccEncoder.Encode(&_rangeEncoder, 0);
        !           132:         prevByte = b;
        !           133:       }
        !           134:       return Flush();
        !           135:     }
        !           136: 
        !           137:     bufferPos = 0;
        !           138: 
        !           139:     UInt32 limit = endPos - 5;
        !           140:     while(bufferPos <= limit)
        !           141:     {
        !           142:       Byte b = _buffer[bufferPos];
        !           143:       _mainStream.WriteByte(b);
        !           144:       if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
        !           145:       {
        !           146:         bufferPos++;
        !           147:         prevByte = b;
        !           148:         continue;
        !           149:       }
        !           150:       Byte nextByte = _buffer[bufferPos + 4];
        !           151:       UInt32 src = 
        !           152:         (UInt32(nextByte) << 24) |
        !           153:         (UInt32(_buffer[bufferPos + 3]) << 16) |
        !           154:         (UInt32(_buffer[bufferPos + 2]) << 8) |
        !           155:         (_buffer[bufferPos + 1]);
        !           156:       UInt32 dest = (nowPos + bufferPos + 5) + src;
        !           157:       // if (Test86MSByte(nextByte))
        !           158:       bool convert;
        !           159:       if (getSubStreamSize != NULL)
        !           160:       {
        !           161:         UInt64 currentPos = (nowPos64 + bufferPos);
        !           162:         while (subStreamEndPos < currentPos)
        !           163:         {
        !           164:           UInt64 subStreamSize;
        !           165:           HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
        !           166:           if (result == S_OK)
        !           167:           {
        !           168:             subStreamStartPos = subStreamEndPos;
        !           169:             subStreamEndPos += subStreamSize;          
        !           170:             subStreamIndex++;
        !           171:           }
        !           172:           else if (result == S_FALSE || result == E_NOTIMPL)
        !           173:           {
        !           174:             getSubStreamSize.Release();
        !           175:             subStreamStartPos = 0;
        !           176:             subStreamEndPos = subStreamStartPos - 1;          
        !           177:           }
        !           178:           else
        !           179:             return result;
        !           180:         }
        !           181:         if (getSubStreamSize == NULL)
        !           182:         {
        !           183:           if (sizeIsDefined)
        !           184:             convert = (dest < inSize);
        !           185:           else
        !           186:             convert = Test86MSByte(nextByte);
        !           187:         }
        !           188:         else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)
        !           189:           convert = Test86MSByte(nextByte);
        !           190:         else
        !           191:         {
        !           192:           UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
        !           193:           convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
        !           194:         }
        !           195:       }
        !           196:       else if (sizeIsDefined)
        !           197:         convert = (dest < inSize);
        !           198:       else
        !           199:         convert = Test86MSByte(nextByte);
        !           200:       if (convert)
        !           201:       {
        !           202:         if (b == 0xE8)
        !           203:           _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1);
        !           204:         else if (b == 0xE9)
        !           205:           _statusE9Encoder.Encode(&_rangeEncoder, 1);
        !           206:         else 
        !           207:           _statusJccEncoder.Encode(&_rangeEncoder, 1);
        !           208: 
        !           209:         bufferPos += 5;
        !           210:         if (b == 0xE8)
        !           211:         {
        !           212:           _callStream.WriteByte((Byte)(dest >> 24));
        !           213:           _callStream.WriteByte((Byte)(dest >> 16));
        !           214:           _callStream.WriteByte((Byte)(dest >> 8));
        !           215:           _callStream.WriteByte((Byte)(dest));
        !           216:         }
        !           217:         else 
        !           218:         {
        !           219:           _jumpStream.WriteByte((Byte)(dest >> 24));
        !           220:           _jumpStream.WriteByte((Byte)(dest >> 16));
        !           221:           _jumpStream.WriteByte((Byte)(dest >> 8));
        !           222:           _jumpStream.WriteByte((Byte)(dest));
        !           223:         }
        !           224:         prevByte = nextByte;
        !           225:       }
        !           226:       else
        !           227:       {
        !           228:         if (b == 0xE8)
        !           229:           _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
        !           230:         else if (b == 0xE9)
        !           231:           _statusE9Encoder.Encode(&_rangeEncoder, 0);
        !           232:         else
        !           233:           _statusJccEncoder.Encode(&_rangeEncoder, 0);
        !           234:         bufferPos++;
        !           235:         prevByte = b;
        !           236:       }
        !           237:     }
        !           238:     nowPos += bufferPos;
        !           239:     nowPos64 += bufferPos;
        !           240: 
        !           241:     if (progress != NULL)
        !           242:     {
        !           243:       RINOK(progress->SetRatioInfo(&nowPos64, NULL));
        !           244:     }
        !           245:  
        !           246:     UInt32 i = 0;
        !           247:     while(bufferPos < endPos)
        !           248:       _buffer[i++] = _buffer[bufferPos++];
        !           249:     bufferPos = i;
        !           250:   }
        !           251: }
        !           252: 
        !           253: STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
        !           254:       const UInt64 **inSizes,
        !           255:       UInt32 numInStreams,
        !           256:       ISequentialOutStream **outStreams,
        !           257:       const UInt64 **outSizes,
        !           258:       UInt32 numOutStreams,
        !           259:       ICompressProgressInfo *progress)
        !           260: {
        !           261:   try
        !           262:   {
        !           263:     return CodeReal(inStreams, inSizes, numInStreams,
        !           264:       outStreams, outSizes,numOutStreams, progress);
        !           265:   }
        !           266:   catch(const COutBufferException &e) { return e.ErrorCode; }
        !           267:   catch(...) { return S_FALSE; }
        !           268: }
        !           269: 
        !           270: #endif
        !           271: 
        !           272: HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
        !           273:       const UInt64 **inSizes,
        !           274:       UInt32 numInStreams,
        !           275:       ISequentialOutStream **outStreams,
        !           276:       const UInt64 **outSizes,
        !           277:       UInt32 numOutStreams,
        !           278:       ICompressProgressInfo *progress)
        !           279: {
        !           280:   if (numInStreams != 4 || numOutStreams != 1)
        !           281:     return E_INVALIDARG;
        !           282: 
        !           283:   if (!_mainInStream.Create(1 << 16))
        !           284:     return E_OUTOFMEMORY;
        !           285:   if (!_callStream.Create(1 << 20))
        !           286:     return E_OUTOFMEMORY;
        !           287:   if (!_jumpStream.Create(1 << 16))
        !           288:     return E_OUTOFMEMORY;
        !           289:   if (!_rangeDecoder.Create(1 << 20))
        !           290:     return E_OUTOFMEMORY;
        !           291:   if (!_outStream.Create(1 << 16))
        !           292:     return E_OUTOFMEMORY;
        !           293: 
        !           294:   _mainInStream.SetStream(inStreams[0]);
        !           295:   _callStream.SetStream(inStreams[1]);
        !           296:   _jumpStream.SetStream(inStreams[2]);
        !           297:   _rangeDecoder.SetStream(inStreams[3]);
        !           298:   _outStream.SetStream(outStreams[0]);
        !           299: 
        !           300:   _mainInStream.Init();
        !           301:   _callStream.Init();
        !           302:   _jumpStream.Init();
        !           303:   _rangeDecoder.Init();
        !           304:   _outStream.Init();
        !           305: 
        !           306:   for (int i = 0; i < 256; i++)
        !           307:     _statusE8Decoder[i].Init();
        !           308:   _statusE9Decoder.Init();
        !           309:   _statusJccDecoder.Init();
        !           310: 
        !           311:   CCoderReleaser releaser(this);
        !           312: 
        !           313:   Byte prevByte = 0;
        !           314:   UInt32 processedBytes = 0;
        !           315:   while(true)
        !           316:   {
        !           317:     if (processedBytes > (1 << 20) && progress != NULL)
        !           318:     {
        !           319:       UInt64 nowPos64 = _outStream.GetProcessedSize();
        !           320:       RINOK(progress->SetRatioInfo(NULL, &nowPos64));
        !           321:       processedBytes = 0;
        !           322:     }
        !           323:     processedBytes++;
        !           324:     Byte b;
        !           325:     if (!_mainInStream.ReadByte(b))
        !           326:       return Flush();
        !           327:     _outStream.WriteByte(b);
        !           328:     if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
        !           329:     {
        !           330:       prevByte = b;
        !           331:       continue;
        !           332:     }
        !           333:     bool status;
        !           334:     if (b == 0xE8)
        !           335:       status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1);
        !           336:     else if (b == 0xE9)
        !           337:       status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1);
        !           338:     else
        !           339:       status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
        !           340:     if (status)
        !           341:     {
        !           342:       UInt32 src;
        !           343:       if (b == 0xE8)
        !           344:       {
        !           345:         Byte b0;
        !           346:         if(!_callStream.ReadByte(b0))
        !           347:           return S_FALSE;
        !           348:         src = ((UInt32)b0) << 24;
        !           349:         if(!_callStream.ReadByte(b0))
        !           350:           return S_FALSE;
        !           351:         src |= ((UInt32)b0) << 16;
        !           352:         if(!_callStream.ReadByte(b0))
        !           353:           return S_FALSE;
        !           354:         src |= ((UInt32)b0) << 8;
        !           355:         if(!_callStream.ReadByte(b0))
        !           356:           return S_FALSE;
        !           357:         src |= ((UInt32)b0);
        !           358:       }
        !           359:       else
        !           360:       {
        !           361:         Byte b0;
        !           362:         if(!_jumpStream.ReadByte(b0))
        !           363:           return S_FALSE;
        !           364:         src = ((UInt32)b0) << 24;
        !           365:         if(!_jumpStream.ReadByte(b0))
        !           366:           return S_FALSE;
        !           367:         src |= ((UInt32)b0) << 16;
        !           368:         if(!_jumpStream.ReadByte(b0))
        !           369:           return S_FALSE;
        !           370:         src |= ((UInt32)b0) << 8;
        !           371:         if(!_jumpStream.ReadByte(b0))
        !           372:           return S_FALSE;
        !           373:         src |= ((UInt32)b0);
        !           374:       }
        !           375:       UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
        !           376:       _outStream.WriteByte((Byte)(dest));
        !           377:       _outStream.WriteByte((Byte)(dest >> 8));
        !           378:       _outStream.WriteByte((Byte)(dest >> 16));
        !           379:       _outStream.WriteByte((Byte)(dest >> 24));
        !           380:       prevByte = (dest >> 24);
        !           381:       processedBytes += 4;
        !           382:     }
        !           383:     else
        !           384:       prevByte = b;
        !           385:   }
        !           386: }
        !           387: 
        !           388: STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
        !           389:       const UInt64 **inSizes,
        !           390:       UInt32 numInStreams,
        !           391:       ISequentialOutStream **outStreams,
        !           392:       const UInt64 **outSizes,
        !           393:       UInt32 numOutStreams,
        !           394:       ICompressProgressInfo *progress)
        !           395: {
        !           396:   try
        !           397:   {
        !           398:     return CodeReal(inStreams, inSizes, numInStreams,
        !           399:         outStreams, outSizes,numOutStreams, progress);
        !           400:   }
        !           401:   catch(const COutBufferException &e) { return e.ErrorCode; }
        !           402:   catch(...) { return S_FALSE; }
        !           403: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>