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