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