375 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			375 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/* Lzma2Dec.c -- LZMA2 Decoder
							 | 
						||
| 
								 | 
							
								2017-04-03 : Igor Pavlov : Public domain */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* #define SHOW_DEBUG_INFO */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "Precomp.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef SHOW_DEBUG_INFO
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "Lzma2Dec.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								00000000  -  EOS
							 | 
						||
| 
								 | 
							
								00000001 U U  -  Uncompressed Reset Dic
							 | 
						||
| 
								 | 
							
								00000010 U U  -  Uncompressed No Reset
							 | 
						||
| 
								 | 
							
								100uuuuu U U P P  -  LZMA no reset
							 | 
						||
| 
								 | 
							
								101uuuuu U U P P  -  LZMA reset state
							 | 
						||
| 
								 | 
							
								110uuuuu U U P P S  -  LZMA reset state + new prop
							 | 
						||
| 
								 | 
							
								111uuuuu U U P P S  -  LZMA reset state + new prop + reset dic
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  u, U - Unpack Size
							 | 
						||
| 
								 | 
							
								  P - Pack Size
							 | 
						||
| 
								 | 
							
								  S - Props
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define LZMA2_CONTROL_LZMA (1 << 7)
							 | 
						||
| 
								 | 
							
								#define LZMA2_CONTROL_COPY_NO_RESET 2
							 | 
						||
| 
								 | 
							
								#define LZMA2_CONTROL_COPY_RESET_DIC 1
							 | 
						||
| 
								 | 
							
								#define LZMA2_CONTROL_EOF 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
							 | 
						||
| 
								 | 
							
								#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define LZMA2_LCLP_MAX 4
							 | 
						||
| 
								 | 
							
								#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef SHOW_DEBUG_INFO
							 | 
						||
| 
								 | 
							
								#define PRF(x) x
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define PRF(x)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef enum
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_CONTROL,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_UNPACK0,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_UNPACK1,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_PACK0,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_PACK1,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_PROP,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_DATA,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_DATA_CONT,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_FINISHED,
							 | 
						||
| 
								 | 
							
								  LZMA2_STATE_ERROR
							 | 
						||
| 
								 | 
							
								} ELzma2State;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  UInt32 dicSize;
							 | 
						||
| 
								 | 
							
								  if (prop > 40)
							 | 
						||
| 
								 | 
							
								    return SZ_ERROR_UNSUPPORTED;
							 | 
						||
| 
								 | 
							
								  dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
							 | 
						||
| 
								 | 
							
								  props[0] = (Byte)LZMA2_LCLP_MAX;
							 | 
						||
| 
								 | 
							
								  props[1] = (Byte)(dicSize);
							 | 
						||
| 
								 | 
							
								  props[2] = (Byte)(dicSize >> 8);
							 | 
						||
| 
								 | 
							
								  props[3] = (Byte)(dicSize >> 16);
							 | 
						||
| 
								 | 
							
								  props[4] = (Byte)(dicSize >> 24);
							 | 
						||
| 
								 | 
							
								  return SZ_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  Byte props[LZMA_PROPS_SIZE];
							 | 
						||
| 
								 | 
							
								  RINOK(Lzma2Dec_GetOldProps(prop, props));
							 | 
						||
| 
								 | 
							
								  return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  Byte props[LZMA_PROPS_SIZE];
							 | 
						||
| 
								 | 
							
								  RINOK(Lzma2Dec_GetOldProps(prop, props));
							 | 
						||
| 
								 | 
							
								  return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Lzma2Dec_Init(CLzma2Dec *p)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  p->state = LZMA2_STATE_CONTROL;
							 | 
						||
| 
								 | 
							
								  p->needInitDic = True;
							 | 
						||
| 
								 | 
							
								  p->needInitState = True;
							 | 
						||
| 
								 | 
							
								  p->needInitProp = True;
							 | 
						||
| 
								 | 
							
								  LzmaDec_Init(&p->decoder);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  switch (p->state)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    case LZMA2_STATE_CONTROL:
							 | 
						||
| 
								 | 
							
								      p->control = b;
							 | 
						||
| 
								 | 
							
								      PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
							 | 
						||
| 
								 | 
							
								      PRF(printf(" %2X", (unsigned)b));
							 | 
						||
| 
								 | 
							
								      if (b == 0)
							 | 
						||
| 
								 | 
							
								        return LZMA2_STATE_FINISHED;
							 | 
						||
| 
								 | 
							
								      if (LZMA2_IS_UNCOMPRESSED_STATE(p))
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        if (b > 2)
							 | 
						||
| 
								 | 
							
								          return LZMA2_STATE_ERROR;
							 | 
						||
| 
								 | 
							
								        p->unpackSize = 0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								        p->unpackSize = (UInt32)(b & 0x1F) << 16;
							 | 
						||
| 
								 | 
							
								      return LZMA2_STATE_UNPACK0;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    case LZMA2_STATE_UNPACK0:
							 | 
						||
| 
								 | 
							
								      p->unpackSize |= (UInt32)b << 8;
							 | 
						||
| 
								 | 
							
								      return LZMA2_STATE_UNPACK1;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    case LZMA2_STATE_UNPACK1:
							 | 
						||
| 
								 | 
							
								      p->unpackSize |= (UInt32)b;
							 | 
						||
| 
								 | 
							
								      p->unpackSize++;
							 | 
						||
| 
								 | 
							
								      PRF(printf(" %8u", (unsigned)p->unpackSize));
							 | 
						||
| 
								 | 
							
								      return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    case LZMA2_STATE_PACK0:
							 | 
						||
| 
								 | 
							
								      p->packSize = (UInt32)b << 8;
							 | 
						||
| 
								 | 
							
								      return LZMA2_STATE_PACK1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case LZMA2_STATE_PACK1:
							 | 
						||
| 
								 | 
							
								      p->packSize |= (UInt32)b;
							 | 
						||
| 
								 | 
							
								      p->packSize++;
							 | 
						||
| 
								 | 
							
								      PRF(printf(" %8u", (unsigned)p->packSize));
							 | 
						||
| 
								 | 
							
								      return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
							 | 
						||
| 
								 | 
							
								        (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case LZMA2_STATE_PROP:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      unsigned lc, lp;
							 | 
						||
| 
								 | 
							
								      if (b >= (9 * 5 * 5))
							 | 
						||
| 
								 | 
							
								        return LZMA2_STATE_ERROR;
							 | 
						||
| 
								 | 
							
								      lc = b % 9;
							 | 
						||
| 
								 | 
							
								      b /= 9;
							 | 
						||
| 
								 | 
							
								      p->decoder.prop.pb = b / 5;
							 | 
						||
| 
								 | 
							
								      lp = b % 5;
							 | 
						||
| 
								 | 
							
								      if (lc + lp > LZMA2_LCLP_MAX)
							 | 
						||
| 
								 | 
							
								        return LZMA2_STATE_ERROR;
							 | 
						||
| 
								 | 
							
								      p->decoder.prop.lc = lc;
							 | 
						||
| 
								 | 
							
								      p->decoder.prop.lp = lp;
							 | 
						||
| 
								 | 
							
								      p->needInitProp = False;
							 | 
						||
| 
								 | 
							
								      return LZMA2_STATE_DATA;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return LZMA2_STATE_ERROR;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  memcpy(p->dic + p->dicPos, src, size);
							 | 
						||
| 
								 | 
							
								  p->dicPos += size;
							 | 
						||
| 
								 | 
							
								  if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
							 | 
						||
| 
								 | 
							
								    p->checkDicSize = p->prop.dicSize;
							 | 
						||
| 
								 | 
							
								  p->processedPos += (UInt32)size;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
							 | 
						||
| 
								 | 
							
								    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  SizeT inSize = *srcLen;
							 | 
						||
| 
								 | 
							
								  *srcLen = 0;
							 | 
						||
| 
								 | 
							
								  *status = LZMA_STATUS_NOT_SPECIFIED;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while (p->state != LZMA2_STATE_ERROR)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    SizeT dicPos;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p->state == LZMA2_STATE_FINISHED)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      *status = LZMA_STATUS_FINISHED_WITH_MARK;
							 | 
						||
| 
								 | 
							
								      return SZ_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    dicPos = p->decoder.dicPos;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      *status = LZMA_STATUS_NOT_FINISHED;
							 | 
						||
| 
								 | 
							
								      return SZ_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (*srcLen == inSize)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        *status = LZMA_STATUS_NEEDS_MORE_INPUT;
							 | 
						||
| 
								 | 
							
								        return SZ_OK;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      (*srcLen)++;
							 | 
						||
| 
								 | 
							
								      p->state = Lzma2Dec_UpdateState(p, *src++);
							 | 
						||
| 
								 | 
							
								      if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      SizeT inCur = inSize - *srcLen;
							 | 
						||
| 
								 | 
							
								      SizeT outCur = dicLimit - dicPos;
							 | 
						||
| 
								 | 
							
								      ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      if (outCur >= p->unpackSize)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        outCur = (SizeT)p->unpackSize;
							 | 
						||
| 
								 | 
							
								        curFinishMode = LZMA_FINISH_END;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (LZMA2_IS_UNCOMPRESSED_STATE(p))
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        if (inCur == 0)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
							 | 
						||
| 
								 | 
							
								          return SZ_OK;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (p->state == LZMA2_STATE_DATA)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
							 | 
						||
| 
								 | 
							
								          if (initDic)
							 | 
						||
| 
								 | 
							
								            p->needInitProp = p->needInitState = True;
							 | 
						||
| 
								 | 
							
								          else if (p->needInitDic)
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								          p->needInitDic = False;
							 | 
						||
| 
								 | 
							
								          LzmaDec_InitDicAndState(&p->decoder, initDic, False);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (inCur > outCur)
							 | 
						||
| 
								 | 
							
								          inCur = outCur;
							 | 
						||
| 
								 | 
							
								        if (inCur == 0)
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        src += inCur;
							 | 
						||
| 
								 | 
							
								        *srcLen += inCur;
							 | 
						||
| 
								 | 
							
								        p->unpackSize -= (UInt32)inCur;
							 | 
						||
| 
								 | 
							
								        p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        SRes res;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (p->state == LZMA2_STATE_DATA)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          unsigned mode = LZMA2_GET_LZMA_MODE(p);
							 | 
						||
| 
								 | 
							
								          Bool initDic = (mode == 3);
							 | 
						||
| 
								 | 
							
								          Bool initState = (mode != 0);
							 | 
						||
| 
								 | 
							
								          if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
							 | 
						||
| 
								 | 
							
								          p->needInitDic = False;
							 | 
						||
| 
								 | 
							
								          p->needInitState = False;
							 | 
						||
| 
								 | 
							
								          p->state = LZMA2_STATE_DATA_CONT;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								        if (inCur > p->packSize)
							 | 
						||
| 
								 | 
							
								          inCur = (SizeT)p->packSize;
							 | 
						||
| 
								 | 
							
								          
							 | 
						||
| 
								 | 
							
								        res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        src += inCur;
							 | 
						||
| 
								 | 
							
								        *srcLen += inCur;
							 | 
						||
| 
								 | 
							
								        p->packSize -= (UInt32)inCur;
							 | 
						||
| 
								 | 
							
								        outCur = p->decoder.dicPos - dicPos;
							 | 
						||
| 
								 | 
							
								        p->unpackSize -= (UInt32)outCur;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (res != 0)
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          if (p->packSize == 0)
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								          return SZ_OK;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (inCur == 0 && outCur == 0)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
							 | 
						||
| 
								 | 
							
								              || p->unpackSize != 0
							 | 
						||
| 
								 | 
							
								              || p->packSize != 0)
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								          p->state = LZMA2_STATE_CONTROL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        *status = LZMA_STATUS_NOT_SPECIFIED;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  *status = LZMA_STATUS_NOT_SPECIFIED;
							 | 
						||
| 
								 | 
							
								  p->state = LZMA2_STATE_ERROR;
							 | 
						||
| 
								 | 
							
								  return SZ_ERROR_DATA;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  SizeT outSize = *destLen, inSize = *srcLen;
							 | 
						||
| 
								 | 
							
								  *srcLen = *destLen = 0;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    SizeT inCur = inSize, outCur, dicPos;
							 | 
						||
| 
								 | 
							
								    ELzmaFinishMode curFinishMode;
							 | 
						||
| 
								 | 
							
								    SRes res;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    if (p->decoder.dicPos == p->decoder.dicBufSize)
							 | 
						||
| 
								 | 
							
								      p->decoder.dicPos = 0;
							 | 
						||
| 
								 | 
							
								    dicPos = p->decoder.dicPos;
							 | 
						||
| 
								 | 
							
								    curFinishMode = LZMA_FINISH_ANY;
							 | 
						||
| 
								 | 
							
								    outCur = p->decoder.dicBufSize - dicPos;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    if (outCur >= outSize)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      outCur = outSize;
							 | 
						||
| 
								 | 
							
								      curFinishMode = finishMode;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    src += inCur;
							 | 
						||
| 
								 | 
							
								    inSize -= inCur;
							 | 
						||
| 
								 | 
							
								    *srcLen += inCur;
							 | 
						||
| 
								 | 
							
								    outCur = p->decoder.dicPos - dicPos;
							 | 
						||
| 
								 | 
							
								    memcpy(dest, p->decoder.dic + dicPos, outCur);
							 | 
						||
| 
								 | 
							
								    dest += outCur;
							 | 
						||
| 
								 | 
							
								    outSize -= outCur;
							 | 
						||
| 
								 | 
							
								    *destLen += outCur;
							 | 
						||
| 
								 | 
							
								    if (res != 0)
							 | 
						||
| 
								 | 
							
								      return res;
							 | 
						||
| 
								 | 
							
								    if (outCur == 0 || outSize == 0)
							 | 
						||
| 
								 | 
							
								      return SZ_OK;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
							 | 
						||
| 
								 | 
							
								    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  CLzma2Dec p;
							 | 
						||
| 
								 | 
							
								  SRes res;
							 | 
						||
| 
								 | 
							
								  SizeT outSize = *destLen, inSize = *srcLen;
							 | 
						||
| 
								 | 
							
								  *destLen = *srcLen = 0;
							 | 
						||
| 
								 | 
							
								  *status = LZMA_STATUS_NOT_SPECIFIED;
							 | 
						||
| 
								 | 
							
								  Lzma2Dec_Construct(&p);
							 | 
						||
| 
								 | 
							
								  RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
							 | 
						||
| 
								 | 
							
								  p.decoder.dic = dest;
							 | 
						||
| 
								 | 
							
								  p.decoder.dicBufSize = outSize;
							 | 
						||
| 
								 | 
							
								  Lzma2Dec_Init(&p);
							 | 
						||
| 
								 | 
							
								  *srcLen = inSize;
							 | 
						||
| 
								 | 
							
								  res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
							 | 
						||
| 
								 | 
							
								  *destLen = p.decoder.dicPos;
							 | 
						||
| 
								 | 
							
								  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
							 | 
						||
| 
								 | 
							
								    res = SZ_ERROR_INPUT_EOF;
							 | 
						||
| 
								 | 
							
								  Lzma2Dec_FreeProbs(&p, alloc);
							 | 
						||
| 
								 | 
							
								  return res;
							 | 
						||
| 
								 | 
							
								}
							 |