1
0

7zDecode.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /* 7zDecode.c */
  2. #include "7zDecode.h"
  3. #ifdef _SZ_ONE_DIRECTORY
  4. #include "LzmaDecode.h"
  5. #else
  6. #include "../../Compress/LZMA_C/LzmaDecode.h"
  7. #endif
  8. CMethodID k_Copy = { { 0x0 }, 1 };
  9. CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
  10. #ifdef _LZMA_IN_CB
  11. typedef struct _CLzmaInCallbackImp
  12. {
  13. ILzmaInCallback InCallback;
  14. ISzInStream *InStream;
  15. size_t Size;
  16. } CLzmaInCallbackImp;
  17. int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
  18. {
  19. CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
  20. size_t processedSize;
  21. SZ_RESULT res;
  22. *size = 0;
  23. res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
  24. *size = (SizeT)processedSize;
  25. if (processedSize > cb->Size)
  26. return (int)SZE_FAIL;
  27. cb->Size -= processedSize;
  28. if (res == SZ_OK)
  29. return 0;
  30. return (int)res;
  31. }
  32. #endif
  33. SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
  34. #ifdef _LZMA_IN_CB
  35. ISzInStream *inStream,
  36. #else
  37. const Byte *inBuffer,
  38. #endif
  39. Byte *outBuffer, size_t outSize,
  40. size_t *outSizeProcessed, ISzAlloc *allocMain)
  41. {
  42. UInt32 si;
  43. size_t inSize = 0;
  44. CCoderInfo *coder;
  45. if (folder->NumPackStreams != 1)
  46. return SZE_NOTIMPL;
  47. if (folder->NumCoders != 1)
  48. return SZE_NOTIMPL;
  49. coder = folder->Coders;
  50. *outSizeProcessed = 0;
  51. for (si = 0; si < folder->NumPackStreams; si++)
  52. inSize += (size_t)packSizes[si];
  53. if (AreMethodsEqual(&coder->MethodID, &k_Copy))
  54. {
  55. size_t i;
  56. if (inSize != outSize)
  57. return SZE_DATA_ERROR;
  58. #ifdef _LZMA_IN_CB
  59. for (i = 0; i < inSize;)
  60. {
  61. size_t j;
  62. void *inBuffer;
  63. size_t bufferSize;
  64. RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
  65. if (bufferSize == 0)
  66. return SZE_DATA_ERROR;
  67. if (bufferSize > inSize - i)
  68. return SZE_FAIL;
  69. *outSizeProcessed += bufferSize;
  70. for (j = 0; j < bufferSize && i < inSize; j++, i++)
  71. outBuffer[i] = ((Byte*)inBuffer)[j];
  72. }
  73. #else
  74. for (i = 0; i < inSize; i++)
  75. outBuffer[i] = inBuffer[i];
  76. *outSizeProcessed = inSize;
  77. #endif
  78. return SZ_OK;
  79. }
  80. if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
  81. {
  82. #ifdef _LZMA_IN_CB
  83. CLzmaInCallbackImp lzmaCallback;
  84. #else
  85. SizeT inProcessed;
  86. #endif
  87. CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
  88. int result;
  89. SizeT outSizeProcessedLoc;
  90. #ifdef _LZMA_IN_CB
  91. lzmaCallback.Size = inSize;
  92. lzmaCallback.InStream = inStream;
  93. lzmaCallback.InCallback.Read = LzmaReadImp;
  94. #endif
  95. if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
  96. coder->Properties.Capacity) != LZMA_RESULT_OK)
  97. return SZE_FAIL;
  98. state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
  99. if (state.Probs == 0)
  100. return SZE_OUTOFMEMORY;
  101. #ifdef _LZMA_OUT_READ
  102. if (state.Properties.DictionarySize == 0)
  103. state.Dictionary = 0;
  104. else
  105. {
  106. state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
  107. if (state.Dictionary == 0)
  108. {
  109. allocMain->Free(state.Probs);
  110. return SZE_OUTOFMEMORY;
  111. }
  112. }
  113. LzmaDecoderInit(&state);
  114. #endif
  115. result = LzmaDecode(&state,
  116. #ifdef _LZMA_IN_CB
  117. &lzmaCallback.InCallback,
  118. #else
  119. inBuffer, (SizeT)inSize, &inProcessed,
  120. #endif
  121. outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
  122. *outSizeProcessed = (size_t)outSizeProcessedLoc;
  123. allocMain->Free(state.Probs);
  124. #ifdef _LZMA_OUT_READ
  125. allocMain->Free(state.Dictionary);
  126. #endif
  127. if (result == LZMA_RESULT_DATA_ERROR)
  128. return SZE_DATA_ERROR;
  129. if (result != LZMA_RESULT_OK)
  130. return SZE_FAIL;
  131. return SZ_OK;
  132. }
  133. return SZE_NOTIMPL;
  134. }