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