File:  [ELWIX - Embedded LightWeight unIX -] / elwix / tools / oldlzma / SRC / 7zip / Archive / 7z_C / 7zDecode.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 14 09:04:51 2013 UTC (11 years, 2 months ago) by misho
Branches: misho, elwix1_9_mips, MAIN
CVS tags: start, elwix2_8, elwix2_7, elwix2_6, elwix2_3, elwix2_2, HEAD, ELWIX2_7, ELWIX2_6, ELWIX2_5, ELWIX2_2p0
oldlzma needs for uboot

/* 7zDecode.c */

#include "7zDecode.h"
#ifdef _SZ_ONE_DIRECTORY
#include "LzmaDecode.h"
#else

#include "../../Compress/LZMA_C/LzmaDecode.h"
#endif


CMethodID k_Copy = { { 0x0 }, 1 };
CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };

#ifdef _LZMA_IN_CB

typedef struct _CLzmaInCallbackImp
{
  ILzmaInCallback InCallback;
  ISzInStream *InStream;
  size_t Size;
} CLzmaInCallbackImp;

int LzmaReadImp(void *object, unsigned char **buffer, UInt32 *size)
{
  CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
  size_t processedSize;
  SZ_RESULT res;
  *size = 0;
  res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
  *size = (UInt32)processedSize;
  if (processedSize > cb->Size)
    return (int)SZE_FAIL;
  cb->Size -= processedSize;
  if (res == SZ_OK)
    return 0;
  return (int)res;
}

#endif


SZ_RESULT SzDecode(CFileSize *packSizes, CFolder *folder,
    #ifdef _LZMA_IN_CB
    ISzInStream *inStream,
    #else
    Byte *inBuffer,
    #endif
    Byte *outBuffer, size_t outSize, 
    size_t *outSizeProcessed, ISzAlloc *allocMain)
{
  UInt32 si;
  size_t inSize = 0;
  CCoderInfo *coder;
  if (folder->NumPackStreams != 1)
    return SZE_NOTIMPL;
  if (folder->NumCoders != 1)
    return SZE_NOTIMPL;
  coder = folder->Coders;
  *outSizeProcessed = 0;

  for (si = 0; si < folder->NumPackStreams; si++)
    inSize += (size_t)packSizes[si];

  if (AreMethodsEqual(&coder->MethodID, &k_Copy))
  {
    size_t i;
    if (inSize != outSize)
      return SZE_DATA_ERROR;
    #ifdef _LZMA_IN_CB
    for (i = 0; i < inSize;)
    {
      size_t j;
      Byte *inBuffer;
      size_t bufferSize;
      RINOK(inStream->Read((void *)inStream,  (void **)&inBuffer, inSize - i, &bufferSize));
      if (bufferSize == 0)
        return SZE_DATA_ERROR;
      if (bufferSize > inSize - i)
        return SZE_FAIL;
      *outSizeProcessed += bufferSize;
      for (j = 0; j < bufferSize && i < inSize; j++, i++)
        outBuffer[i] = inBuffer[j];
    }
    #else
    for (i = 0; i < inSize; i++)
      outBuffer[i] = inBuffer[i];
    *outSizeProcessed = inSize;
    #endif
    return SZ_OK;
  }

  if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
  {
    #ifdef _LZMA_IN_CB
    CLzmaInCallbackImp lzmaCallback;
    #endif

    int lc, lp, pb;
    size_t lzmaInternalSize;
    void *lzmaInternalData;
    int result;
    UInt32 outSizeProcessedLoc;

    #ifdef _LZMA_IN_CB
    lzmaCallback.Size = inSize;
    lzmaCallback.InStream = inStream;
    lzmaCallback.InCallback.Read = LzmaReadImp;
    #endif

    if (coder->Properties.Capacity < 5)
      return SZE_FAIL;
    lc = (unsigned char)coder->Properties.Items[0];
    if (lc >= (9 * 5 * 5))
      return SZE_FAIL;
    for (pb = 0; lc >= (9 * 5); pb++, lc -= (9 * 5));
    for (lp = 0; lc >= 9; lp++, lc -= 9);

    lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb);
    lzmaInternalData = allocMain->Alloc(lzmaInternalSize);
    if (lzmaInternalData == 0)
      return SZE_OUTOFMEMORY;

    result = LzmaDecode((Byte *)lzmaInternalData, (UInt32)lzmaInternalSize,
        lc, lp, pb,
        #ifdef _LZMA_IN_CB
        &lzmaCallback.InCallback,
        #else
        inBuffer, (UInt32)inSize,
        #endif
        outBuffer, (UInt32)outSize, 
        &outSizeProcessedLoc);
    *outSizeProcessed = (size_t)outSizeProcessedLoc;
    allocMain->Free(lzmaInternalData);
    /*
    NOT_ENOUGH_MEM error is impossible for this code
    if (result = LZMA_RESULT_NOT_ENOUGH_MEM)
      return SZE_OUTOFMEMORY;
    */
    if (result == LZMA_RESULT_DATA_ERROR)
      return SZE_DATA_ERROR;
    if (result != LZMA_RESULT_OK)
      return SZE_FAIL;
    return SZ_OK;
  }
  return SZE_NOTIMPL;
}

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