1/* Xz.h - Xz interface 22010-09-17 : Igor Pavlov : Public domain */ 3 4#ifndef __XZ_H 5#define __XZ_H 6 7#include "Sha256.h" 8 9EXTERN_C_BEGIN 10 11#define XZ_ID_Subblock 1 12#define XZ_ID_Delta 3 13#define XZ_ID_X86 4 14#define XZ_ID_PPC 5 15#define XZ_ID_IA64 6 16#define XZ_ID_ARM 7 17#define XZ_ID_ARMT 8 18#define XZ_ID_SPARC 9 19#define XZ_ID_LZMA2 0x21 20 21unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); 22unsigned Xz_WriteVarInt(Byte *buf, UInt64 v); 23 24/* ---------- xz block ---------- */ 25 26#define XZ_BLOCK_HEADER_SIZE_MAX 1024 27 28#define XZ_NUM_FILTERS_MAX 4 29#define XZ_BF_NUM_FILTERS_MASK 3 30#define XZ_BF_PACK_SIZE (1 << 6) 31#define XZ_BF_UNPACK_SIZE (1 << 7) 32 33#define XZ_FILTER_PROPS_SIZE_MAX 20 34 35typedef struct 36{ 37 UInt64 id; 38 UInt32 propsSize; 39 Byte props[XZ_FILTER_PROPS_SIZE_MAX]; 40} CXzFilter; 41 42typedef struct 43{ 44 UInt64 packSize; 45 UInt64 unpackSize; 46 Byte flags; 47 CXzFilter filters[XZ_NUM_FILTERS_MAX]; 48} CXzBlock; 49 50#define XzBlock_GetNumFilters(p) (((p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1) 51#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0) 52#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0) 53 54SRes XzBlock_Parse(CXzBlock *p, const Byte *header); 55SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes); 56 57/* ---------- xz stream ---------- */ 58 59#define XZ_SIG_SIZE 6 60#define XZ_FOOTER_SIG_SIZE 2 61 62extern Byte XZ_SIG[XZ_SIG_SIZE]; 63extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE]; 64 65#define XZ_STREAM_FLAGS_SIZE 2 66#define XZ_STREAM_CRC_SIZE 4 67 68#define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE) 69#define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4) 70 71#define XZ_CHECK_MASK 0xF 72#define XZ_CHECK_NO 0 73#define XZ_CHECK_CRC32 1 74#define XZ_CHECK_CRC64 4 75#define XZ_CHECK_SHA256 10 76 77typedef struct 78{ 79 int mode; 80 UInt32 crc; 81 UInt64 crc64; 82 CSha256 sha; 83} CXzCheck; 84 85void XzCheck_Init(CXzCheck *p, int mode); 86void XzCheck_Update(CXzCheck *p, const void *data, size_t size); 87int XzCheck_Final(CXzCheck *p, Byte *digest); 88 89typedef UInt16 CXzStreamFlags; 90 91#define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK) 92#define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK) 93#define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32) 94unsigned XzFlags_GetCheckSize(CXzStreamFlags f); 95 96SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); 97SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream); 98 99typedef struct 100{ 101 UInt64 unpackSize; 102 UInt64 totalSize; 103} CXzBlockSizes; 104 105typedef struct 106{ 107 CXzStreamFlags flags; 108 size_t numBlocks; 109 size_t numBlocksAllocated; 110 CXzBlockSizes *blocks; 111 UInt64 startOffset; 112} CXzStream; 113 114void Xz_Construct(CXzStream *p); 115void Xz_Free(CXzStream *p, ISzAlloc *alloc); 116 117#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1) 118 119UInt64 Xz_GetUnpackSize(const CXzStream *p); 120UInt64 Xz_GetPackSize(const CXzStream *p); 121 122typedef struct 123{ 124 size_t num; 125 size_t numAllocated; 126 CXzStream *streams; 127} CXzs; 128 129void Xzs_Construct(CXzs *p); 130void Xzs_Free(CXzs *p, ISzAlloc *alloc); 131SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc); 132 133UInt64 Xzs_GetNumBlocks(const CXzs *p); 134UInt64 Xzs_GetUnpackSize(const CXzs *p); 135 136typedef enum 137{ 138 CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */ 139 CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ 140 CODER_STATUS_NOT_FINISHED, /* stream was not finished */ 141 CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */ 142} ECoderStatus; 143 144typedef enum 145{ 146 CODER_FINISH_ANY, /* finish at any point */ 147 CODER_FINISH_END /* block must be finished at the end */ 148} ECoderFinishMode; 149 150typedef struct _IStateCoder 151{ 152 void *p; 153 void (*Free)(void *p, ISzAlloc *alloc); 154 SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc); 155 void (*Init)(void *p); 156 SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 157 int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished); 158} IStateCoder; 159 160#define MIXCODER_NUM_FILTERS_MAX 4 161 162typedef struct 163{ 164 ISzAlloc *alloc; 165 Byte *buf; 166 int numCoders; 167 int finished[MIXCODER_NUM_FILTERS_MAX - 1]; 168 size_t pos[MIXCODER_NUM_FILTERS_MAX - 1]; 169 size_t size[MIXCODER_NUM_FILTERS_MAX - 1]; 170 UInt64 ids[MIXCODER_NUM_FILTERS_MAX]; 171 IStateCoder coders[MIXCODER_NUM_FILTERS_MAX]; 172} CMixCoder; 173 174void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc); 175void MixCoder_Free(CMixCoder *p); 176void MixCoder_Init(CMixCoder *p); 177SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId); 178SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, 179 const Byte *src, SizeT *srcLen, int srcWasFinished, 180 ECoderFinishMode finishMode, ECoderStatus *status); 181 182typedef enum 183{ 184 XZ_STATE_STREAM_HEADER, 185 XZ_STATE_STREAM_INDEX, 186 XZ_STATE_STREAM_INDEX_CRC, 187 XZ_STATE_STREAM_FOOTER, 188 XZ_STATE_STREAM_PADDING, 189 XZ_STATE_BLOCK_HEADER, 190 XZ_STATE_BLOCK, 191 XZ_STATE_BLOCK_FOOTER 192} EXzState; 193 194typedef struct 195{ 196 EXzState state; 197 UInt32 pos; 198 unsigned alignPos; 199 unsigned indexPreSize; 200 201 CXzStreamFlags streamFlags; 202 203 UInt32 blockHeaderSize; 204 UInt64 packSize; 205 UInt64 unpackSize; 206 207 UInt64 numBlocks; 208 UInt64 indexSize; 209 UInt64 indexPos; 210 UInt64 padSize; 211 212 UInt64 numStreams; 213 214 UInt32 crc; 215 CMixCoder decoder; 216 CXzBlock block; 217 CXzCheck check; 218 CSha256 sha; 219 Byte shaDigest[SHA256_DIGEST_SIZE]; 220 Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; 221} CXzUnpacker; 222 223SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc); 224void XzUnpacker_Free(CXzUnpacker *p); 225 226/* 227finishMode: 228 It has meaning only if the decoding reaches output limit (*destLen). 229 LZMA_FINISH_ANY - use smallest number of input bytes 230 LZMA_FINISH_END - read EndOfStream marker after decoding 231 232Returns: 233 SZ_OK 234 status: 235 LZMA_STATUS_FINISHED_WITH_MARK 236 LZMA_STATUS_NOT_FINISHED 237 SZ_ERROR_DATA - Data error 238 SZ_ERROR_MEM - Memory allocation error 239 SZ_ERROR_UNSUPPORTED - Unsupported properties 240 SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). 241*/ 242 243 244SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, 245 const Byte *src, SizeT *srcLen, /* int srcWasFinished, */ int finishMode, 246 ECoderStatus *status); 247 248Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p); 249 250EXTERN_C_END 251 252#endif 253