1*f6dc9357SAndroid Build Coastguard Worker /* Xz.h - Xz interface 2*f6dc9357SAndroid Build Coastguard Worker 2024-01-26 : Igor Pavlov : Public domain */ 3*f6dc9357SAndroid Build Coastguard Worker 4*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_XZ_H 5*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_XZ_H 6*f6dc9357SAndroid Build Coastguard Worker 7*f6dc9357SAndroid Build Coastguard Worker #include "Sha256.h" 8*f6dc9357SAndroid Build Coastguard Worker #include "Delta.h" 9*f6dc9357SAndroid Build Coastguard Worker 10*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN 11*f6dc9357SAndroid Build Coastguard Worker 12*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_Subblock 1 13*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_Delta 3 14*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_X86 4 15*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_PPC 5 16*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_IA64 6 17*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_ARM 7 18*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_ARMT 8 19*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_SPARC 9 20*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_ARM64 0xa 21*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_RISCV 0xb 22*f6dc9357SAndroid Build Coastguard Worker #define XZ_ID_LZMA2 0x21 23*f6dc9357SAndroid Build Coastguard Worker 24*f6dc9357SAndroid Build Coastguard Worker unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); 25*f6dc9357SAndroid Build Coastguard Worker unsigned Xz_WriteVarInt(Byte *buf, UInt64 v); 26*f6dc9357SAndroid Build Coastguard Worker 27*f6dc9357SAndroid Build Coastguard Worker /* ---------- xz block ---------- */ 28*f6dc9357SAndroid Build Coastguard Worker 29*f6dc9357SAndroid Build Coastguard Worker #define XZ_BLOCK_HEADER_SIZE_MAX 1024 30*f6dc9357SAndroid Build Coastguard Worker 31*f6dc9357SAndroid Build Coastguard Worker #define XZ_NUM_FILTERS_MAX 4 32*f6dc9357SAndroid Build Coastguard Worker #define XZ_BF_NUM_FILTERS_MASK 3 33*f6dc9357SAndroid Build Coastguard Worker #define XZ_BF_PACK_SIZE (1 << 6) 34*f6dc9357SAndroid Build Coastguard Worker #define XZ_BF_UNPACK_SIZE (1 << 7) 35*f6dc9357SAndroid Build Coastguard Worker 36*f6dc9357SAndroid Build Coastguard Worker #define XZ_FILTER_PROPS_SIZE_MAX 20 37*f6dc9357SAndroid Build Coastguard Worker 38*f6dc9357SAndroid Build Coastguard Worker typedef struct 39*f6dc9357SAndroid Build Coastguard Worker { 40*f6dc9357SAndroid Build Coastguard Worker UInt64 id; 41*f6dc9357SAndroid Build Coastguard Worker UInt32 propsSize; 42*f6dc9357SAndroid Build Coastguard Worker Byte props[XZ_FILTER_PROPS_SIZE_MAX]; 43*f6dc9357SAndroid Build Coastguard Worker } CXzFilter; 44*f6dc9357SAndroid Build Coastguard Worker 45*f6dc9357SAndroid Build Coastguard Worker typedef struct 46*f6dc9357SAndroid Build Coastguard Worker { 47*f6dc9357SAndroid Build Coastguard Worker UInt64 packSize; 48*f6dc9357SAndroid Build Coastguard Worker UInt64 unpackSize; 49*f6dc9357SAndroid Build Coastguard Worker Byte flags; 50*f6dc9357SAndroid Build Coastguard Worker CXzFilter filters[XZ_NUM_FILTERS_MAX]; 51*f6dc9357SAndroid Build Coastguard Worker } CXzBlock; 52*f6dc9357SAndroid Build Coastguard Worker 53*f6dc9357SAndroid Build Coastguard Worker #define XzBlock_GetNumFilters(p) (((unsigned)(p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1) 54*f6dc9357SAndroid Build Coastguard Worker #define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0) 55*f6dc9357SAndroid Build Coastguard Worker #define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0) 56*f6dc9357SAndroid Build Coastguard Worker #define XzBlock_HasUnsupportedFlags(p) (((p)->flags & ~(XZ_BF_NUM_FILTERS_MASK | XZ_BF_PACK_SIZE | XZ_BF_UNPACK_SIZE)) != 0) 57*f6dc9357SAndroid Build Coastguard Worker 58*f6dc9357SAndroid Build Coastguard Worker SRes XzBlock_Parse(CXzBlock *p, const Byte *header); 59*f6dc9357SAndroid Build Coastguard Worker SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStreamPtr inStream, BoolInt *isIndex, UInt32 *headerSizeRes); 60*f6dc9357SAndroid Build Coastguard Worker 61*f6dc9357SAndroid Build Coastguard Worker /* ---------- xz stream ---------- */ 62*f6dc9357SAndroid Build Coastguard Worker 63*f6dc9357SAndroid Build Coastguard Worker #define XZ_SIG_SIZE 6 64*f6dc9357SAndroid Build Coastguard Worker #define XZ_FOOTER_SIG_SIZE 2 65*f6dc9357SAndroid Build Coastguard Worker 66*f6dc9357SAndroid Build Coastguard Worker extern const Byte XZ_SIG[XZ_SIG_SIZE]; 67*f6dc9357SAndroid Build Coastguard Worker 68*f6dc9357SAndroid Build Coastguard Worker /* 69*f6dc9357SAndroid Build Coastguard Worker extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE]; 70*f6dc9357SAndroid Build Coastguard Worker */ 71*f6dc9357SAndroid Build Coastguard Worker 72*f6dc9357SAndroid Build Coastguard Worker #define XZ_FOOTER_SIG_0 'Y' 73*f6dc9357SAndroid Build Coastguard Worker #define XZ_FOOTER_SIG_1 'Z' 74*f6dc9357SAndroid Build Coastguard Worker 75*f6dc9357SAndroid Build Coastguard Worker #define XZ_STREAM_FLAGS_SIZE 2 76*f6dc9357SAndroid Build Coastguard Worker #define XZ_STREAM_CRC_SIZE 4 77*f6dc9357SAndroid Build Coastguard Worker 78*f6dc9357SAndroid Build Coastguard Worker #define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE) 79*f6dc9357SAndroid Build Coastguard Worker #define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4) 80*f6dc9357SAndroid Build Coastguard Worker 81*f6dc9357SAndroid Build Coastguard Worker #define XZ_CHECK_MASK 0xF 82*f6dc9357SAndroid Build Coastguard Worker #define XZ_CHECK_NO 0 83*f6dc9357SAndroid Build Coastguard Worker #define XZ_CHECK_CRC32 1 84*f6dc9357SAndroid Build Coastguard Worker #define XZ_CHECK_CRC64 4 85*f6dc9357SAndroid Build Coastguard Worker #define XZ_CHECK_SHA256 10 86*f6dc9357SAndroid Build Coastguard Worker 87*f6dc9357SAndroid Build Coastguard Worker typedef struct 88*f6dc9357SAndroid Build Coastguard Worker { 89*f6dc9357SAndroid Build Coastguard Worker unsigned mode; 90*f6dc9357SAndroid Build Coastguard Worker UInt32 crc; 91*f6dc9357SAndroid Build Coastguard Worker UInt64 crc64; 92*f6dc9357SAndroid Build Coastguard Worker CSha256 sha; 93*f6dc9357SAndroid Build Coastguard Worker } CXzCheck; 94*f6dc9357SAndroid Build Coastguard Worker 95*f6dc9357SAndroid Build Coastguard Worker void XzCheck_Init(CXzCheck *p, unsigned mode); 96*f6dc9357SAndroid Build Coastguard Worker void XzCheck_Update(CXzCheck *p, const void *data, size_t size); 97*f6dc9357SAndroid Build Coastguard Worker int XzCheck_Final(CXzCheck *p, Byte *digest); 98*f6dc9357SAndroid Build Coastguard Worker 99*f6dc9357SAndroid Build Coastguard Worker typedef UInt16 CXzStreamFlags; 100*f6dc9357SAndroid Build Coastguard Worker 101*f6dc9357SAndroid Build Coastguard Worker #define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK) 102*f6dc9357SAndroid Build Coastguard Worker #define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK) 103*f6dc9357SAndroid Build Coastguard Worker #define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32) 104*f6dc9357SAndroid Build Coastguard Worker unsigned XzFlags_GetCheckSize(CXzStreamFlags f); 105*f6dc9357SAndroid Build Coastguard Worker 106*f6dc9357SAndroid Build Coastguard Worker SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); 107*f6dc9357SAndroid Build Coastguard Worker SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStreamPtr inStream); 108*f6dc9357SAndroid Build Coastguard Worker 109*f6dc9357SAndroid Build Coastguard Worker typedef struct 110*f6dc9357SAndroid Build Coastguard Worker { 111*f6dc9357SAndroid Build Coastguard Worker UInt64 unpackSize; 112*f6dc9357SAndroid Build Coastguard Worker UInt64 totalSize; 113*f6dc9357SAndroid Build Coastguard Worker } CXzBlockSizes; 114*f6dc9357SAndroid Build Coastguard Worker 115*f6dc9357SAndroid Build Coastguard Worker typedef struct 116*f6dc9357SAndroid Build Coastguard Worker { 117*f6dc9357SAndroid Build Coastguard Worker CXzStreamFlags flags; 118*f6dc9357SAndroid Build Coastguard Worker // Byte _pad[6]; 119*f6dc9357SAndroid Build Coastguard Worker size_t numBlocks; 120*f6dc9357SAndroid Build Coastguard Worker CXzBlockSizes *blocks; 121*f6dc9357SAndroid Build Coastguard Worker UInt64 startOffset; 122*f6dc9357SAndroid Build Coastguard Worker } CXzStream; 123*f6dc9357SAndroid Build Coastguard Worker 124*f6dc9357SAndroid Build Coastguard Worker void Xz_Construct(CXzStream *p); 125*f6dc9357SAndroid Build Coastguard Worker void Xz_Free(CXzStream *p, ISzAllocPtr alloc); 126*f6dc9357SAndroid Build Coastguard Worker 127*f6dc9357SAndroid Build Coastguard Worker #define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1) 128*f6dc9357SAndroid Build Coastguard Worker 129*f6dc9357SAndroid Build Coastguard Worker UInt64 Xz_GetUnpackSize(const CXzStream *p); 130*f6dc9357SAndroid Build Coastguard Worker UInt64 Xz_GetPackSize(const CXzStream *p); 131*f6dc9357SAndroid Build Coastguard Worker 132*f6dc9357SAndroid Build Coastguard Worker typedef struct 133*f6dc9357SAndroid Build Coastguard Worker { 134*f6dc9357SAndroid Build Coastguard Worker size_t num; 135*f6dc9357SAndroid Build Coastguard Worker size_t numAllocated; 136*f6dc9357SAndroid Build Coastguard Worker CXzStream *streams; 137*f6dc9357SAndroid Build Coastguard Worker } CXzs; 138*f6dc9357SAndroid Build Coastguard Worker 139*f6dc9357SAndroid Build Coastguard Worker void Xzs_Construct(CXzs *p); 140*f6dc9357SAndroid Build Coastguard Worker void Xzs_Free(CXzs *p, ISzAllocPtr alloc); 141*f6dc9357SAndroid Build Coastguard Worker SRes Xzs_ReadBackward(CXzs *p, ILookInStreamPtr inStream, Int64 *startOffset, ICompressProgressPtr progress, ISzAllocPtr alloc); 142*f6dc9357SAndroid Build Coastguard Worker 143*f6dc9357SAndroid Build Coastguard Worker UInt64 Xzs_GetNumBlocks(const CXzs *p); 144*f6dc9357SAndroid Build Coastguard Worker UInt64 Xzs_GetUnpackSize(const CXzs *p); 145*f6dc9357SAndroid Build Coastguard Worker 146*f6dc9357SAndroid Build Coastguard Worker 147*f6dc9357SAndroid Build Coastguard Worker // ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder 148*f6dc9357SAndroid Build Coastguard Worker 149*f6dc9357SAndroid Build Coastguard Worker typedef enum 150*f6dc9357SAndroid Build Coastguard Worker { 151*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */ 152*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ 153*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_NOT_FINISHED, /* stream was not finished */ 154*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */ 155*f6dc9357SAndroid Build Coastguard Worker } ECoderStatus; 156*f6dc9357SAndroid Build Coastguard Worker 157*f6dc9357SAndroid Build Coastguard Worker 158*f6dc9357SAndroid Build Coastguard Worker // ECoderFinishMode values are identical to ELzmaFinishMode 159*f6dc9357SAndroid Build Coastguard Worker 160*f6dc9357SAndroid Build Coastguard Worker typedef enum 161*f6dc9357SAndroid Build Coastguard Worker { 162*f6dc9357SAndroid Build Coastguard Worker CODER_FINISH_ANY, /* finish at any point */ 163*f6dc9357SAndroid Build Coastguard Worker CODER_FINISH_END /* block must be finished at the end */ 164*f6dc9357SAndroid Build Coastguard Worker } ECoderFinishMode; 165*f6dc9357SAndroid Build Coastguard Worker 166*f6dc9357SAndroid Build Coastguard Worker 167*f6dc9357SAndroid Build Coastguard Worker typedef struct 168*f6dc9357SAndroid Build Coastguard Worker { 169*f6dc9357SAndroid Build Coastguard Worker void *p; // state object; 170*f6dc9357SAndroid Build Coastguard Worker void (*Free)(void *p, ISzAllocPtr alloc); 171*f6dc9357SAndroid Build Coastguard Worker SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc); 172*f6dc9357SAndroid Build Coastguard Worker void (*Init)(void *p); 173*f6dc9357SAndroid Build Coastguard Worker SRes (*Code2)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 174*f6dc9357SAndroid Build Coastguard Worker int srcWasFinished, ECoderFinishMode finishMode, 175*f6dc9357SAndroid Build Coastguard Worker // int *wasFinished, 176*f6dc9357SAndroid Build Coastguard Worker ECoderStatus *status); 177*f6dc9357SAndroid Build Coastguard Worker SizeT (*Filter)(void *p, Byte *data, SizeT size); 178*f6dc9357SAndroid Build Coastguard Worker } IStateCoder; 179*f6dc9357SAndroid Build Coastguard Worker 180*f6dc9357SAndroid Build Coastguard Worker 181*f6dc9357SAndroid Build Coastguard Worker typedef struct 182*f6dc9357SAndroid Build Coastguard Worker { 183*f6dc9357SAndroid Build Coastguard Worker UInt32 methodId; 184*f6dc9357SAndroid Build Coastguard Worker UInt32 delta; 185*f6dc9357SAndroid Build Coastguard Worker UInt32 ip; 186*f6dc9357SAndroid Build Coastguard Worker UInt32 X86_State; 187*f6dc9357SAndroid Build Coastguard Worker Byte delta_State[DELTA_STATE_SIZE]; 188*f6dc9357SAndroid Build Coastguard Worker } CXzBcFilterStateBase; 189*f6dc9357SAndroid Build Coastguard Worker 190*f6dc9357SAndroid Build Coastguard Worker typedef SizeT (*Xz_Func_BcFilterStateBase_Filter)(CXzBcFilterStateBase *p, Byte *data, SizeT size); 191*f6dc9357SAndroid Build Coastguard Worker 192*f6dc9357SAndroid Build Coastguard Worker SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id, 193*f6dc9357SAndroid Build Coastguard Worker Xz_Func_BcFilterStateBase_Filter func, ISzAllocPtr alloc); 194*f6dc9357SAndroid Build Coastguard Worker 195*f6dc9357SAndroid Build Coastguard Worker 196*f6dc9357SAndroid Build Coastguard Worker #define MIXCODER_NUM_FILTERS_MAX 4 197*f6dc9357SAndroid Build Coastguard Worker 198*f6dc9357SAndroid Build Coastguard Worker typedef struct 199*f6dc9357SAndroid Build Coastguard Worker { 200*f6dc9357SAndroid Build Coastguard Worker ISzAllocPtr alloc; 201*f6dc9357SAndroid Build Coastguard Worker Byte *buf; 202*f6dc9357SAndroid Build Coastguard Worker unsigned numCoders; 203*f6dc9357SAndroid Build Coastguard Worker 204*f6dc9357SAndroid Build Coastguard Worker Byte *outBuf; 205*f6dc9357SAndroid Build Coastguard Worker size_t outBufSize; 206*f6dc9357SAndroid Build Coastguard Worker size_t outWritten; // is equal to lzmaDecoder.dicPos (in outBuf mode) 207*f6dc9357SAndroid Build Coastguard Worker BoolInt wasFinished; 208*f6dc9357SAndroid Build Coastguard Worker SRes res; 209*f6dc9357SAndroid Build Coastguard Worker ECoderStatus status; 210*f6dc9357SAndroid Build Coastguard Worker // BoolInt SingleBufMode; 211*f6dc9357SAndroid Build Coastguard Worker 212*f6dc9357SAndroid Build Coastguard Worker int finished[MIXCODER_NUM_FILTERS_MAX - 1]; 213*f6dc9357SAndroid Build Coastguard Worker size_t pos[MIXCODER_NUM_FILTERS_MAX - 1]; 214*f6dc9357SAndroid Build Coastguard Worker size_t size[MIXCODER_NUM_FILTERS_MAX - 1]; 215*f6dc9357SAndroid Build Coastguard Worker UInt64 ids[MIXCODER_NUM_FILTERS_MAX]; 216*f6dc9357SAndroid Build Coastguard Worker SRes results[MIXCODER_NUM_FILTERS_MAX]; 217*f6dc9357SAndroid Build Coastguard Worker IStateCoder coders[MIXCODER_NUM_FILTERS_MAX]; 218*f6dc9357SAndroid Build Coastguard Worker } CMixCoder; 219*f6dc9357SAndroid Build Coastguard Worker 220*f6dc9357SAndroid Build Coastguard Worker 221*f6dc9357SAndroid Build Coastguard Worker typedef enum 222*f6dc9357SAndroid Build Coastguard Worker { 223*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_STREAM_HEADER, 224*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_STREAM_INDEX, 225*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_STREAM_INDEX_CRC, 226*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_STREAM_FOOTER, 227*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_STREAM_PADDING, 228*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_BLOCK_HEADER, 229*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_BLOCK, 230*f6dc9357SAndroid Build Coastguard Worker XZ_STATE_BLOCK_FOOTER 231*f6dc9357SAndroid Build Coastguard Worker } EXzState; 232*f6dc9357SAndroid Build Coastguard Worker 233*f6dc9357SAndroid Build Coastguard Worker 234*f6dc9357SAndroid Build Coastguard Worker typedef struct 235*f6dc9357SAndroid Build Coastguard Worker { 236*f6dc9357SAndroid Build Coastguard Worker EXzState state; 237*f6dc9357SAndroid Build Coastguard Worker unsigned pos; 238*f6dc9357SAndroid Build Coastguard Worker unsigned alignPos; 239*f6dc9357SAndroid Build Coastguard Worker unsigned indexPreSize; 240*f6dc9357SAndroid Build Coastguard Worker 241*f6dc9357SAndroid Build Coastguard Worker CXzStreamFlags streamFlags; 242*f6dc9357SAndroid Build Coastguard Worker 243*f6dc9357SAndroid Build Coastguard Worker unsigned blockHeaderSize; 244*f6dc9357SAndroid Build Coastguard Worker UInt64 packSize; 245*f6dc9357SAndroid Build Coastguard Worker UInt64 unpackSize; 246*f6dc9357SAndroid Build Coastguard Worker 247*f6dc9357SAndroid Build Coastguard Worker UInt64 numBlocks; // number of finished blocks in current stream 248*f6dc9357SAndroid Build Coastguard Worker UInt64 indexSize; 249*f6dc9357SAndroid Build Coastguard Worker UInt64 indexPos; 250*f6dc9357SAndroid Build Coastguard Worker UInt64 padSize; 251*f6dc9357SAndroid Build Coastguard Worker 252*f6dc9357SAndroid Build Coastguard Worker UInt64 numStartedStreams; 253*f6dc9357SAndroid Build Coastguard Worker UInt64 numFinishedStreams; 254*f6dc9357SAndroid Build Coastguard Worker UInt64 numTotalBlocks; 255*f6dc9357SAndroid Build Coastguard Worker 256*f6dc9357SAndroid Build Coastguard Worker UInt32 crc; 257*f6dc9357SAndroid Build Coastguard Worker CMixCoder decoder; 258*f6dc9357SAndroid Build Coastguard Worker CXzBlock block; 259*f6dc9357SAndroid Build Coastguard Worker CXzCheck check; 260*f6dc9357SAndroid Build Coastguard Worker CSha256 sha; 261*f6dc9357SAndroid Build Coastguard Worker 262*f6dc9357SAndroid Build Coastguard Worker BoolInt parseMode; 263*f6dc9357SAndroid Build Coastguard Worker BoolInt headerParsedOk; 264*f6dc9357SAndroid Build Coastguard Worker BoolInt decodeToStreamSignature; 265*f6dc9357SAndroid Build Coastguard Worker unsigned decodeOnlyOneBlock; 266*f6dc9357SAndroid Build Coastguard Worker 267*f6dc9357SAndroid Build Coastguard Worker Byte *outBuf; 268*f6dc9357SAndroid Build Coastguard Worker size_t outBufSize; 269*f6dc9357SAndroid Build Coastguard Worker size_t outDataWritten; // the size of data in (outBuf) that were fully unpacked 270*f6dc9357SAndroid Build Coastguard Worker 271*f6dc9357SAndroid Build Coastguard Worker Byte shaDigest[SHA256_DIGEST_SIZE]; 272*f6dc9357SAndroid Build Coastguard Worker Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; 273*f6dc9357SAndroid Build Coastguard Worker } CXzUnpacker; 274*f6dc9357SAndroid Build Coastguard Worker 275*f6dc9357SAndroid Build Coastguard Worker /* alloc : aligned for cache line allocation is better */ 276*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc); 277*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_Init(CXzUnpacker *p); 278*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize); 279*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_Free(CXzUnpacker *p); 280*f6dc9357SAndroid Build Coastguard Worker 281*f6dc9357SAndroid Build Coastguard Worker /* 282*f6dc9357SAndroid Build Coastguard Worker XzUnpacker 283*f6dc9357SAndroid Build Coastguard Worker The sequence for decoding functions: 284*f6dc9357SAndroid Build Coastguard Worker { 285*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Construct() 286*f6dc9357SAndroid Build Coastguard Worker [Decoding_Calls] 287*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Free() 288*f6dc9357SAndroid Build Coastguard Worker } 289*f6dc9357SAndroid Build Coastguard Worker 290*f6dc9357SAndroid Build Coastguard Worker [Decoding_Calls] 291*f6dc9357SAndroid Build Coastguard Worker 292*f6dc9357SAndroid Build Coastguard Worker There are 3 types of interfaces for [Decoding_Calls] calls: 293*f6dc9357SAndroid Build Coastguard Worker 294*f6dc9357SAndroid Build Coastguard Worker Interface-1 : Partial output buffers: 295*f6dc9357SAndroid Build Coastguard Worker { 296*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Init() 297*f6dc9357SAndroid Build Coastguard Worker for() 298*f6dc9357SAndroid Build Coastguard Worker { 299*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Code(); 300*f6dc9357SAndroid Build Coastguard Worker } 301*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_IsStreamWasFinished() 302*f6dc9357SAndroid Build Coastguard Worker } 303*f6dc9357SAndroid Build Coastguard Worker 304*f6dc9357SAndroid Build Coastguard Worker Interface-2 : Direct output buffer: 305*f6dc9357SAndroid Build Coastguard Worker Use it, if you know exact size of decoded data, and you need 306*f6dc9357SAndroid Build Coastguard Worker whole xz unpacked data in one output buffer. 307*f6dc9357SAndroid Build Coastguard Worker xz unpacker doesn't allocate additional buffer for lzma2 dictionary in that mode. 308*f6dc9357SAndroid Build Coastguard Worker { 309*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Init() 310*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_SetOutBufMode(); // to set output buffer and size 311*f6dc9357SAndroid Build Coastguard Worker for() 312*f6dc9357SAndroid Build Coastguard Worker { 313*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Code(); // (dest = NULL) in XzUnpacker_Code() 314*f6dc9357SAndroid Build Coastguard Worker } 315*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_IsStreamWasFinished() 316*f6dc9357SAndroid Build Coastguard Worker } 317*f6dc9357SAndroid Build Coastguard Worker 318*f6dc9357SAndroid Build Coastguard Worker Interface-3 : Direct output buffer : One call full decoding 319*f6dc9357SAndroid Build Coastguard Worker It unpacks whole input buffer to output buffer in one call. 320*f6dc9357SAndroid Build Coastguard Worker It uses Interface-2 internally. 321*f6dc9357SAndroid Build Coastguard Worker { 322*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_CodeFull() 323*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_IsStreamWasFinished() 324*f6dc9357SAndroid Build Coastguard Worker } 325*f6dc9357SAndroid Build Coastguard Worker */ 326*f6dc9357SAndroid Build Coastguard Worker 327*f6dc9357SAndroid Build Coastguard Worker /* 328*f6dc9357SAndroid Build Coastguard Worker finishMode: 329*f6dc9357SAndroid Build Coastguard Worker It has meaning only if the decoding reaches output limit (*destLen). 330*f6dc9357SAndroid Build Coastguard Worker CODER_FINISH_ANY - use smallest number of input bytes 331*f6dc9357SAndroid Build Coastguard Worker CODER_FINISH_END - read EndOfStream marker after decoding 332*f6dc9357SAndroid Build Coastguard Worker 333*f6dc9357SAndroid Build Coastguard Worker Returns: 334*f6dc9357SAndroid Build Coastguard Worker SZ_OK 335*f6dc9357SAndroid Build Coastguard Worker status: 336*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_NOT_FINISHED, 337*f6dc9357SAndroid Build Coastguard Worker CODER_STATUS_NEEDS_MORE_INPUT - the decoder can return it in two cases: 338*f6dc9357SAndroid Build Coastguard Worker 1) it needs more input data to finish current xz stream 339*f6dc9357SAndroid Build Coastguard Worker 2) xz stream was finished successfully. But the decoder supports multiple 340*f6dc9357SAndroid Build Coastguard Worker concatented xz streams. So it expects more input data for new xz streams. 341*f6dc9357SAndroid Build Coastguard Worker Call XzUnpacker_IsStreamWasFinished() to check that latest xz stream was finished successfully. 342*f6dc9357SAndroid Build Coastguard Worker 343*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_MEM - Memory allocation error 344*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_DATA - Data error 345*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_UNSUPPORTED - Unsupported method or method properties 346*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_CRC - CRC error 347*f6dc9357SAndroid Build Coastguard Worker // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). 348*f6dc9357SAndroid Build Coastguard Worker 349*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons: 350*f6dc9357SAndroid Build Coastguard Worker - xz Stream Signature failure 351*f6dc9357SAndroid Build Coastguard Worker - CRC32 of xz Stream Header is failed 352*f6dc9357SAndroid Build Coastguard Worker - The size of Stream padding is not multiple of four bytes. 353*f6dc9357SAndroid Build Coastguard Worker It's possible to get that error, if xz stream was finished and the stream 354*f6dc9357SAndroid Build Coastguard Worker contains some another data. In that case you can call XzUnpacker_GetExtraSize() 355*f6dc9357SAndroid Build Coastguard Worker function to get real size of xz stream. 356*f6dc9357SAndroid Build Coastguard Worker */ 357*f6dc9357SAndroid Build Coastguard Worker 358*f6dc9357SAndroid Build Coastguard Worker 359*f6dc9357SAndroid Build Coastguard Worker SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, 360*f6dc9357SAndroid Build Coastguard Worker const Byte *src, SizeT *srcLen, int srcFinished, 361*f6dc9357SAndroid Build Coastguard Worker ECoderFinishMode finishMode, ECoderStatus *status); 362*f6dc9357SAndroid Build Coastguard Worker 363*f6dc9357SAndroid Build Coastguard Worker SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen, 364*f6dc9357SAndroid Build Coastguard Worker const Byte *src, SizeT *srcLen, 365*f6dc9357SAndroid Build Coastguard Worker ECoderFinishMode finishMode, ECoderStatus *status); 366*f6dc9357SAndroid Build Coastguard Worker 367*f6dc9357SAndroid Build Coastguard Worker /* 368*f6dc9357SAndroid Build Coastguard Worker If you decode full xz stream(s), then you can call XzUnpacker_IsStreamWasFinished() 369*f6dc9357SAndroid Build Coastguard Worker after successful XzUnpacker_CodeFull() or after last call of XzUnpacker_Code(). 370*f6dc9357SAndroid Build Coastguard Worker */ 371*f6dc9357SAndroid Build Coastguard Worker 372*f6dc9357SAndroid Build Coastguard Worker BoolInt XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p); 373*f6dc9357SAndroid Build Coastguard Worker 374*f6dc9357SAndroid Build Coastguard Worker /* 375*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_GetExtraSize() returns then number of unconfirmed bytes, 376*f6dc9357SAndroid Build Coastguard Worker if it's in (XZ_STATE_STREAM_HEADER) state or in (XZ_STATE_STREAM_PADDING) state. 377*f6dc9357SAndroid Build Coastguard Worker These bytes can be some data after xz archive, or 378*f6dc9357SAndroid Build Coastguard Worker it can be start of new xz stream. 379*f6dc9357SAndroid Build Coastguard Worker 380*f6dc9357SAndroid Build Coastguard Worker Call XzUnpacker_GetExtraSize() after XzUnpacker_Code() function to detect real size of 381*f6dc9357SAndroid Build Coastguard Worker xz stream in two cases, if XzUnpacker_Code() returns: 382*f6dc9357SAndroid Build Coastguard Worker res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT 383*f6dc9357SAndroid Build Coastguard Worker res == SZ_ERROR_NO_ARCHIVE 384*f6dc9357SAndroid Build Coastguard Worker */ 385*f6dc9357SAndroid Build Coastguard Worker 386*f6dc9357SAndroid Build Coastguard Worker UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p); 387*f6dc9357SAndroid Build Coastguard Worker 388*f6dc9357SAndroid Build Coastguard Worker 389*f6dc9357SAndroid Build Coastguard Worker /* 390*f6dc9357SAndroid Build Coastguard Worker for random block decoding: 391*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Init(); 392*f6dc9357SAndroid Build Coastguard Worker set CXzUnpacker::streamFlags 393*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_PrepareToRandomBlockDecoding() 394*f6dc9357SAndroid Build Coastguard Worker loop 395*f6dc9357SAndroid Build Coastguard Worker { 396*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_Code() 397*f6dc9357SAndroid Build Coastguard Worker XzUnpacker_IsBlockFinished() 398*f6dc9357SAndroid Build Coastguard Worker } 399*f6dc9357SAndroid Build Coastguard Worker */ 400*f6dc9357SAndroid Build Coastguard Worker 401*f6dc9357SAndroid Build Coastguard Worker void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p); 402*f6dc9357SAndroid Build Coastguard Worker BoolInt XzUnpacker_IsBlockFinished(const CXzUnpacker *p); 403*f6dc9357SAndroid Build Coastguard Worker 404*f6dc9357SAndroid Build Coastguard Worker #define XzUnpacker_GetPackSizeForIndex(p) ((p)->packSize + (p)->blockHeaderSize + XzFlags_GetCheckSize((p)->streamFlags)) 405*f6dc9357SAndroid Build Coastguard Worker 406*f6dc9357SAndroid Build Coastguard Worker 407*f6dc9357SAndroid Build Coastguard Worker 408*f6dc9357SAndroid Build Coastguard Worker 409*f6dc9357SAndroid Build Coastguard Worker 410*f6dc9357SAndroid Build Coastguard Worker 411*f6dc9357SAndroid Build Coastguard Worker /* ---- Single-Thread and Multi-Thread xz Decoding with Input/Output Streams ---- */ 412*f6dc9357SAndroid Build Coastguard Worker 413*f6dc9357SAndroid Build Coastguard Worker /* 414*f6dc9357SAndroid Build Coastguard Worker if (CXzDecMtProps::numThreads > 1), the decoder can try to use 415*f6dc9357SAndroid Build Coastguard Worker Multi-Threading. The decoder analyses xz block header, and if 416*f6dc9357SAndroid Build Coastguard Worker there are pack size and unpack size values stored in xz block header, 417*f6dc9357SAndroid Build Coastguard Worker the decoder reads compressed data of block to internal buffers, 418*f6dc9357SAndroid Build Coastguard Worker and then it can start parallel decoding, if there are another blocks. 419*f6dc9357SAndroid Build Coastguard Worker The decoder can switch back to Single-Thread decoding after some conditions. 420*f6dc9357SAndroid Build Coastguard Worker 421*f6dc9357SAndroid Build Coastguard Worker The sequence of calls for xz decoding with in/out Streams: 422*f6dc9357SAndroid Build Coastguard Worker { 423*f6dc9357SAndroid Build Coastguard Worker XzDecMt_Create() 424*f6dc9357SAndroid Build Coastguard Worker XzDecMtProps_Init(XzDecMtProps) to set default values of properties 425*f6dc9357SAndroid Build Coastguard Worker // then you can change some XzDecMtProps parameters with required values 426*f6dc9357SAndroid Build Coastguard Worker // here you can set the number of threads and (memUseMax) - the maximum 427*f6dc9357SAndroid Build Coastguard Worker Memory usage for multithreading decoding. 428*f6dc9357SAndroid Build Coastguard Worker for() 429*f6dc9357SAndroid Build Coastguard Worker { 430*f6dc9357SAndroid Build Coastguard Worker XzDecMt_Decode() // one call per one file 431*f6dc9357SAndroid Build Coastguard Worker } 432*f6dc9357SAndroid Build Coastguard Worker XzDecMt_Destroy() 433*f6dc9357SAndroid Build Coastguard Worker } 434*f6dc9357SAndroid Build Coastguard Worker */ 435*f6dc9357SAndroid Build Coastguard Worker 436*f6dc9357SAndroid Build Coastguard Worker 437*f6dc9357SAndroid Build Coastguard Worker typedef struct 438*f6dc9357SAndroid Build Coastguard Worker { 439*f6dc9357SAndroid Build Coastguard Worker size_t inBufSize_ST; // size of input buffer for Single-Thread decoding 440*f6dc9357SAndroid Build Coastguard Worker size_t outStep_ST; // size of output buffer for Single-Thread decoding 441*f6dc9357SAndroid Build Coastguard Worker BoolInt ignoreErrors; // if set to 1, the decoder can ignore some errors and it skips broken parts of data. 442*f6dc9357SAndroid Build Coastguard Worker 443*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST 444*f6dc9357SAndroid Build Coastguard Worker unsigned numThreads; // the number of threads for Multi-Thread decoding. if (umThreads == 1) it will use Single-thread decoding 445*f6dc9357SAndroid Build Coastguard Worker size_t inBufSize_MT; // size of small input data buffers for Multi-Thread decoding. Big number of such small buffers can be created 446*f6dc9357SAndroid Build Coastguard Worker size_t memUseMax; // the limit of total memory usage for Multi-Thread decoding. 447*f6dc9357SAndroid Build Coastguard Worker // it's recommended to set (memUseMax) manually to value that is smaller of total size of RAM in computer. 448*f6dc9357SAndroid Build Coastguard Worker #endif 449*f6dc9357SAndroid Build Coastguard Worker } CXzDecMtProps; 450*f6dc9357SAndroid Build Coastguard Worker 451*f6dc9357SAndroid Build Coastguard Worker void XzDecMtProps_Init(CXzDecMtProps *p); 452*f6dc9357SAndroid Build Coastguard Worker 453*f6dc9357SAndroid Build Coastguard Worker typedef struct CXzDecMt CXzDecMt; 454*f6dc9357SAndroid Build Coastguard Worker typedef CXzDecMt * CXzDecMtHandle; 455*f6dc9357SAndroid Build Coastguard Worker // Z7_DECLARE_HANDLE(CXzDecMtHandle) 456*f6dc9357SAndroid Build Coastguard Worker 457*f6dc9357SAndroid Build Coastguard Worker /* 458*f6dc9357SAndroid Build Coastguard Worker alloc : XzDecMt uses CAlignOffsetAlloc internally for addresses allocated by (alloc). 459*f6dc9357SAndroid Build Coastguard Worker allocMid : for big allocations, aligned allocation is better 460*f6dc9357SAndroid Build Coastguard Worker */ 461*f6dc9357SAndroid Build Coastguard Worker 462*f6dc9357SAndroid Build Coastguard Worker CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid); 463*f6dc9357SAndroid Build Coastguard Worker void XzDecMt_Destroy(CXzDecMtHandle p); 464*f6dc9357SAndroid Build Coastguard Worker 465*f6dc9357SAndroid Build Coastguard Worker 466*f6dc9357SAndroid Build Coastguard Worker typedef struct 467*f6dc9357SAndroid Build Coastguard Worker { 468*f6dc9357SAndroid Build Coastguard Worker Byte UnpackSize_Defined; 469*f6dc9357SAndroid Build Coastguard Worker Byte NumStreams_Defined; 470*f6dc9357SAndroid Build Coastguard Worker Byte NumBlocks_Defined; 471*f6dc9357SAndroid Build Coastguard Worker 472*f6dc9357SAndroid Build Coastguard Worker Byte DataAfterEnd; // there are some additional data after good xz streams, and that data is not new xz stream. 473*f6dc9357SAndroid Build Coastguard Worker Byte DecodingTruncated; // Decoding was Truncated, we need only partial output data 474*f6dc9357SAndroid Build Coastguard Worker 475*f6dc9357SAndroid Build Coastguard Worker UInt64 InSize; // pack size processed. That value doesn't include the data after 476*f6dc9357SAndroid Build Coastguard Worker // end of xz stream, if that data was not correct 477*f6dc9357SAndroid Build Coastguard Worker UInt64 OutSize; 478*f6dc9357SAndroid Build Coastguard Worker 479*f6dc9357SAndroid Build Coastguard Worker UInt64 NumStreams; 480*f6dc9357SAndroid Build Coastguard Worker UInt64 NumBlocks; 481*f6dc9357SAndroid Build Coastguard Worker 482*f6dc9357SAndroid Build Coastguard Worker SRes DecodeRes; // the error code of xz streams data decoding 483*f6dc9357SAndroid Build Coastguard Worker SRes ReadRes; // error code from ISeqInStream:Read() 484*f6dc9357SAndroid Build Coastguard Worker SRes ProgressRes; // error code from ICompressProgress:Progress() 485*f6dc9357SAndroid Build Coastguard Worker 486*f6dc9357SAndroid Build Coastguard Worker SRes CombinedRes; // Combined result error code that shows main rusult 487*f6dc9357SAndroid Build Coastguard Worker // = S_OK, if there is no error. 488*f6dc9357SAndroid Build Coastguard Worker // but check also (DataAfterEnd) that can show additional minor errors. 489*f6dc9357SAndroid Build Coastguard Worker 490*f6dc9357SAndroid Build Coastguard Worker SRes CombinedRes_Type; // = SZ_ERROR_READ, if error from ISeqInStream 491*f6dc9357SAndroid Build Coastguard Worker // = SZ_ERROR_PROGRESS, if error from ICompressProgress 492*f6dc9357SAndroid Build Coastguard Worker // = SZ_ERROR_WRITE, if error from ISeqOutStream 493*f6dc9357SAndroid Build Coastguard Worker // = SZ_ERROR_* codes for decoding 494*f6dc9357SAndroid Build Coastguard Worker } CXzStatInfo; 495*f6dc9357SAndroid Build Coastguard Worker 496*f6dc9357SAndroid Build Coastguard Worker void XzStatInfo_Clear(CXzStatInfo *p); 497*f6dc9357SAndroid Build Coastguard Worker 498*f6dc9357SAndroid Build Coastguard Worker /* 499*f6dc9357SAndroid Build Coastguard Worker 500*f6dc9357SAndroid Build Coastguard Worker XzDecMt_Decode() 501*f6dc9357SAndroid Build Coastguard Worker SRes: it's combined decoding result. It also is equal to stat->CombinedRes. 502*f6dc9357SAndroid Build Coastguard Worker 503*f6dc9357SAndroid Build Coastguard Worker SZ_OK - no error 504*f6dc9357SAndroid Build Coastguard Worker check also output value in (stat->DataAfterEnd) 505*f6dc9357SAndroid Build Coastguard Worker that can show additional possible error 506*f6dc9357SAndroid Build Coastguard Worker 507*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_MEM - Memory allocation error 508*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_NO_ARCHIVE - is not xz archive 509*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_ARCHIVE - Headers error 510*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_DATA - Data Error 511*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_UNSUPPORTED - Unsupported method or method properties 512*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_CRC - CRC Error 513*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_INPUT_EOF - it needs more input data 514*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_WRITE - ISeqOutStream error 515*f6dc9357SAndroid Build Coastguard Worker (SZ_ERROR_READ) - ISeqInStream errors 516*f6dc9357SAndroid Build Coastguard Worker (SZ_ERROR_PROGRESS) - ICompressProgress errors 517*f6dc9357SAndroid Build Coastguard Worker // SZ_ERROR_THREAD - error in multi-threading functions 518*f6dc9357SAndroid Build Coastguard Worker MY_SRes_HRESULT_FROM_WRes(WRes_error) - error in multi-threading function 519*f6dc9357SAndroid Build Coastguard Worker */ 520*f6dc9357SAndroid Build Coastguard Worker 521*f6dc9357SAndroid Build Coastguard Worker SRes XzDecMt_Decode(CXzDecMtHandle p, 522*f6dc9357SAndroid Build Coastguard Worker const CXzDecMtProps *props, 523*f6dc9357SAndroid Build Coastguard Worker const UInt64 *outDataSize, // NULL means undefined 524*f6dc9357SAndroid Build Coastguard Worker int finishMode, // 0 - partial unpacking is allowed, 1 - xz stream(s) must be finished 525*f6dc9357SAndroid Build Coastguard Worker ISeqOutStreamPtr outStream, 526*f6dc9357SAndroid Build Coastguard Worker // Byte *outBuf, size_t *outBufSize, 527*f6dc9357SAndroid Build Coastguard Worker ISeqInStreamPtr inStream, 528*f6dc9357SAndroid Build Coastguard Worker // const Byte *inData, size_t inDataSize, 529*f6dc9357SAndroid Build Coastguard Worker CXzStatInfo *stat, // out: decoding results and statistics 530*f6dc9357SAndroid Build Coastguard Worker int *isMT, // out: 0 means that ST (Single-Thread) version was used 531*f6dc9357SAndroid Build Coastguard Worker // 1 means that MT (Multi-Thread) version was used 532*f6dc9357SAndroid Build Coastguard Worker ICompressProgressPtr progress); 533*f6dc9357SAndroid Build Coastguard Worker 534*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END 535*f6dc9357SAndroid Build Coastguard Worker 536*f6dc9357SAndroid Build Coastguard Worker #endif 537