blob: d30796336211987b62d2b5559f11267a8fb92242 [file] [log] [blame]
repo syncbaa38582013-07-26 17:53:31 -07001/* 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