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