1 /* Xz.h - Xz interface 2 2010-09-17 : Igor Pavlov : Public domain */ 3 4 #ifndef __XZ_H 5 #define __XZ_H 6 7 #include "Sha256.h" 8 9 EXTERN_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 21 unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); 22 unsigned 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 35 typedef struct 36 { 37 UInt64 id; 38 UInt32 propsSize; 39 Byte props[XZ_FILTER_PROPS_SIZE_MAX]; 40 } CXzFilter; 41 42 typedef 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 54 SRes XzBlock_Parse(CXzBlock *p, const Byte *header); 55 SRes 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 62 extern Byte XZ_SIG[XZ_SIG_SIZE]; 63 extern 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 77 typedef struct 78 { 79 int mode; 80 UInt32 crc; 81 UInt64 crc64; 82 CSha256 sha; 83 } CXzCheck; 84 85 void XzCheck_Init(CXzCheck *p, int mode); 86 void XzCheck_Update(CXzCheck *p, const void *data, size_t size); 87 int XzCheck_Final(CXzCheck *p, Byte *digest); 88 89 typedef 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) 94 unsigned XzFlags_GetCheckSize(CXzStreamFlags f); 95 96 SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); 97 SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream); 98 99 typedef struct 100 { 101 UInt64 unpackSize; 102 UInt64 totalSize; 103 } CXzBlockSizes; 104 105 typedef struct 106 { 107 CXzStreamFlags flags; 108 size_t numBlocks; 109 size_t numBlocksAllocated; 110 CXzBlockSizes *blocks; 111 UInt64 startOffset; 112 } CXzStream; 113 114 void Xz_Construct(CXzStream *p); 115 void Xz_Free(CXzStream *p, ISzAlloc *alloc); 116 117 #define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1) 118 119 UInt64 Xz_GetUnpackSize(const CXzStream *p); 120 UInt64 Xz_GetPackSize(const CXzStream *p); 121 122 typedef struct 123 { 124 size_t num; 125 size_t numAllocated; 126 CXzStream *streams; 127 } CXzs; 128 129 void Xzs_Construct(CXzs *p); 130 void Xzs_Free(CXzs *p, ISzAlloc *alloc); 131 SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc); 132 133 UInt64 Xzs_GetNumBlocks(const CXzs *p); 134 UInt64 Xzs_GetUnpackSize(const CXzs *p); 135 136 typedef 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 144 typedef enum 145 { 146 CODER_FINISH_ANY, /* finish at any point */ 147 CODER_FINISH_END /* block must be finished at the end */ 148 } ECoderFinishMode; 149 150 typedef 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 162 typedef 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 174 void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc); 175 void MixCoder_Free(CMixCoder *p); 176 void MixCoder_Init(CMixCoder *p); 177 SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId); 178 SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, 179 const Byte *src, SizeT *srcLen, int srcWasFinished, 180 ECoderFinishMode finishMode, ECoderStatus *status); 181 182 typedef 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 194 typedef 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 223 SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc); 224 void XzUnpacker_Free(CXzUnpacker *p); 225 226 /* 227 finishMode: 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 232 Returns: 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 244 SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, 245 const Byte *src, SizeT *srcLen, /* int srcWasFinished, */ int finishMode, 246 ECoderStatus *status); 247 248 Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p); 249 250 EXTERN_C_END 251 252 #endif 253