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