xref: /OK3568_Linux_fs/u-boot/lib/lzma/LzmaDec.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* LzmaDec.h -- LZMA Decoder
2*4882a593Smuzhiyun 2009-02-07 : Igor Pavlov : Public domain */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #ifndef __LZMA_DEC_H
5*4882a593Smuzhiyun #define __LZMA_DEC_H
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include "Types.h"
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun /* #define _LZMA_PROB32 */
10*4882a593Smuzhiyun /* _LZMA_PROB32 can increase the speed on some CPUs,
11*4882a593Smuzhiyun    but memory usage for CLzmaDec::probs will be doubled in that case */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #ifdef _LZMA_PROB32
14*4882a593Smuzhiyun #define CLzmaProb UInt32
15*4882a593Smuzhiyun #else
16*4882a593Smuzhiyun #define CLzmaProb UInt16
17*4882a593Smuzhiyun #endif
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /* ---------- LZMA Properties ---------- */
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define LZMA_PROPS_SIZE 5
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun typedef struct _CLzmaProps
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun   unsigned lc, lp, pb;
27*4882a593Smuzhiyun   UInt32 dicSize;
28*4882a593Smuzhiyun } CLzmaProps;
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* LzmaProps_Decode - decodes properties
31*4882a593Smuzhiyun Returns:
32*4882a593Smuzhiyun   SZ_OK
33*4882a593Smuzhiyun   SZ_ERROR_UNSUPPORTED - Unsupported properties
34*4882a593Smuzhiyun */
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /* ---------- LZMA Decoder state ---------- */
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
42*4882a593Smuzhiyun    Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define LZMA_REQUIRED_INPUT_MAX 20
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun typedef struct
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun   CLzmaProps prop;
49*4882a593Smuzhiyun   CLzmaProb *probs;
50*4882a593Smuzhiyun   Byte *dic;
51*4882a593Smuzhiyun   const Byte *buf;
52*4882a593Smuzhiyun   UInt32 range, code;
53*4882a593Smuzhiyun   SizeT dicPos;
54*4882a593Smuzhiyun   SizeT dicBufSize;
55*4882a593Smuzhiyun   UInt32 processedPos;
56*4882a593Smuzhiyun   UInt32 checkDicSize;
57*4882a593Smuzhiyun   unsigned state;
58*4882a593Smuzhiyun   UInt32 reps[4];
59*4882a593Smuzhiyun   unsigned remainLen;
60*4882a593Smuzhiyun   int needFlush;
61*4882a593Smuzhiyun   int needInitState;
62*4882a593Smuzhiyun   UInt32 numProbs;
63*4882a593Smuzhiyun   unsigned tempBufSize;
64*4882a593Smuzhiyun   Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
65*4882a593Smuzhiyun } CLzmaDec;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun void LzmaDec_Init(CLzmaDec *p);
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /* There are two types of LZMA streams:
72*4882a593Smuzhiyun      0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
73*4882a593Smuzhiyun      1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun typedef enum
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun   LZMA_FINISH_ANY,   /* finish at any point */
78*4882a593Smuzhiyun   LZMA_FINISH_END    /* block must be finished at the end */
79*4882a593Smuzhiyun } ELzmaFinishMode;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun /* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun    You must use LZMA_FINISH_END, when you know that current output buffer
84*4882a593Smuzhiyun    covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun    If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
87*4882a593Smuzhiyun    and output value of destLen will be less than output buffer size limit.
88*4882a593Smuzhiyun    You can check status result also.
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun    You can use multiple checks to test data integrity after full decompression:
91*4882a593Smuzhiyun      1) Check Result and "status" variable.
92*4882a593Smuzhiyun      2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
93*4882a593Smuzhiyun      3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
94*4882a593Smuzhiyun         You must use correct finish mode in that case. */
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun typedef enum
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun   LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
99*4882a593Smuzhiyun   LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
100*4882a593Smuzhiyun   LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
101*4882a593Smuzhiyun   LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
102*4882a593Smuzhiyun   LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
103*4882a593Smuzhiyun } ELzmaStatus;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /* ELzmaStatus is used only as output value for function call */
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun /* ---------- Interfaces ---------- */
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /* There are 3 levels of interfaces:
111*4882a593Smuzhiyun      1) Dictionary Interface
112*4882a593Smuzhiyun      2) Buffer Interface
113*4882a593Smuzhiyun      3) One Call Interface
114*4882a593Smuzhiyun    You can select any of these interfaces, but don't mix functions from different
115*4882a593Smuzhiyun    groups for same object. */
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun /* There are two variants to allocate state for Dictionary Interface:
119*4882a593Smuzhiyun      1) LzmaDec_Allocate / LzmaDec_Free
120*4882a593Smuzhiyun      2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
121*4882a593Smuzhiyun    You can use variant 2, if you set dictionary buffer manually.
122*4882a593Smuzhiyun    For Buffer Interface you must always use variant 1.
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun LzmaDec_Allocate* can return:
125*4882a593Smuzhiyun   SZ_OK
126*4882a593Smuzhiyun   SZ_ERROR_MEM         - Memory allocation error
127*4882a593Smuzhiyun   SZ_ERROR_UNSUPPORTED - Unsupported properties
128*4882a593Smuzhiyun */
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
131*4882a593Smuzhiyun void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
134*4882a593Smuzhiyun void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun /* ---------- Dictionary Interface ---------- */
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /* You can use it, if you want to eliminate the overhead for data copying from
139*4882a593Smuzhiyun    dictionary to some other external buffer.
140*4882a593Smuzhiyun    You must work with CLzmaDec variables directly in this interface.
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun    STEPS:
143*4882a593Smuzhiyun      LzmaDec_Constr()
144*4882a593Smuzhiyun      LzmaDec_Allocate()
145*4882a593Smuzhiyun      for (each new stream)
146*4882a593Smuzhiyun      {
147*4882a593Smuzhiyun        LzmaDec_Init()
148*4882a593Smuzhiyun        while (it needs more decompression)
149*4882a593Smuzhiyun        {
150*4882a593Smuzhiyun          LzmaDec_DecodeToDic()
151*4882a593Smuzhiyun          use data from CLzmaDec::dic and update CLzmaDec::dicPos
152*4882a593Smuzhiyun        }
153*4882a593Smuzhiyun      }
154*4882a593Smuzhiyun      LzmaDec_Free()
155*4882a593Smuzhiyun */
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /* LzmaDec_DecodeToDic
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun    The decoding to internal dictionary buffer (CLzmaDec::dic).
160*4882a593Smuzhiyun    You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun finishMode:
163*4882a593Smuzhiyun   It has meaning only if the decoding reaches output limit (dicLimit).
164*4882a593Smuzhiyun   LZMA_FINISH_ANY - Decode just dicLimit bytes.
165*4882a593Smuzhiyun   LZMA_FINISH_END - Stream must be finished after dicLimit.
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun Returns:
168*4882a593Smuzhiyun   SZ_OK
169*4882a593Smuzhiyun     status:
170*4882a593Smuzhiyun       LZMA_STATUS_FINISHED_WITH_MARK
171*4882a593Smuzhiyun       LZMA_STATUS_NOT_FINISHED
172*4882a593Smuzhiyun       LZMA_STATUS_NEEDS_MORE_INPUT
173*4882a593Smuzhiyun       LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
174*4882a593Smuzhiyun   SZ_ERROR_DATA - Data error
175*4882a593Smuzhiyun */
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
178*4882a593Smuzhiyun     const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun /* ---------- Buffer Interface ---------- */
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun /* It's zlib-like interface.
184*4882a593Smuzhiyun    See LzmaDec_DecodeToDic description for information about STEPS and return results,
185*4882a593Smuzhiyun    but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
186*4882a593Smuzhiyun    to work with CLzmaDec variables manually.
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun finishMode:
189*4882a593Smuzhiyun   It has meaning only if the decoding reaches output limit (*destLen).
190*4882a593Smuzhiyun   LZMA_FINISH_ANY - Decode just destLen bytes.
191*4882a593Smuzhiyun   LZMA_FINISH_END - Stream must be finished after (*destLen).
192*4882a593Smuzhiyun */
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
195*4882a593Smuzhiyun     const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun /* ---------- One Call Interface ---------- */
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun /* LzmaDecode
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun finishMode:
203*4882a593Smuzhiyun   It has meaning only if the decoding reaches output limit (*destLen).
204*4882a593Smuzhiyun   LZMA_FINISH_ANY - Decode just destLen bytes.
205*4882a593Smuzhiyun   LZMA_FINISH_END - Stream must be finished after (*destLen).
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun Returns:
208*4882a593Smuzhiyun   SZ_OK
209*4882a593Smuzhiyun     status:
210*4882a593Smuzhiyun       LZMA_STATUS_FINISHED_WITH_MARK
211*4882a593Smuzhiyun       LZMA_STATUS_NOT_FINISHED
212*4882a593Smuzhiyun       LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
213*4882a593Smuzhiyun   SZ_ERROR_DATA - Data error
214*4882a593Smuzhiyun   SZ_ERROR_MEM  - Memory allocation error
215*4882a593Smuzhiyun   SZ_ERROR_UNSUPPORTED - Unsupported properties
216*4882a593Smuzhiyun   SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
217*4882a593Smuzhiyun */
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
220*4882a593Smuzhiyun     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
221*4882a593Smuzhiyun     ELzmaStatus *status, ISzAlloc *alloc);
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun #endif
224