lzma/7zDecode.c
changeset 774 916c2e81e77f
child 775 a8cc6b8a8e9c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lzma/7zDecode.c	Tue Apr 11 14:33:48 2006 +0000
@@ -0,0 +1,147 @@
+/* 7zDecode.c */
+
+#include "7zDecode.h"
+#include "LzmaStateDecode.h" // NOTE : Modified to use LzmaStateDecode(.c,.h) instead of LzmaDecode(.c,.h) and hardcoded _SZ_ONE_DIRECTORY behaviour
+
+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, const unsigned char **buffer, size_t *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 = (size_t)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(const CFileSize *packSizes, const CFolder *folder,
+    #ifdef _LZMA_IN_CB
+    ISzInStream *inStream,
+    #else
+    const 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;
+    #else
+    size_t inProcessed;
+    #endif
+
+    CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
+    int result;
+    size_t outSizeProcessedLoc;
+
+    #ifdef _LZMA_IN_CB
+    lzmaCallback.Size = inSize;
+    lzmaCallback.InStream = inStream;
+    lzmaCallback.InCallback.Read = LzmaReadImp;
+    #endif
+
+    if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
+        coder->Properties.Capacity) != LZMA_RESULT_OK)
+      return SZE_FAIL;
+
+    state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+    if (state.Probs == 0)
+      return SZE_OUTOFMEMORY;
+
+    #ifdef _LZMA_OUT_READ
+    if (state.Properties.DictionarySize == 0)
+      state.Dictionary = 0;
+    else
+    {
+      state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
+      if (state.Dictionary == 0)
+      {
+        allocMain->Free(state.Probs);
+        return SZE_OUTOFMEMORY;
+      }
+    }
+    LzmaDecoderInit(&state);
+    #endif
+
+    result = LzmaDecode(&state,
+        #ifdef _LZMA_IN_CB
+        &lzmaCallback.InCallback,
+        #else
+        inBuffer, (size_t)inSize, &inProcessed,
+        #endif
+        outBuffer, (size_t)outSize, &outSizeProcessedLoc,
+	1); // NOTE : Added by Dennis Schridde to make SzDecode be compatible with LzmaStateDecode(.c,.h)
+    *outSizeProcessed = (size_t)outSizeProcessedLoc;
+    allocMain->Free(state.Probs);
+    #ifdef _LZMA_OUT_READ
+    allocMain->Free(state.Dictionary);
+    #endif
+    if (result == LZMA_RESULT_DATA_ERROR)
+      return SZE_DATA_ERROR;
+    if (result != LZMA_RESULT_OK)
+      return SZE_FAIL;
+    return SZ_OK;
+  }
+  return SZE_NOTIMPL;
+}