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