all repos — mgba @ 2dc710feeb0e36fc2179ec7c5f90b3d0430dd00c

mGBA Game Boy Advance Emulator

src/third-party/lzma/Xz.h (view raw)

  1/* Xz.h - Xz interface
  22014-12-30 : 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 numStartedStreams;
213  UInt64 numFinishedStreams;
214  UInt64 numTotalBlocks;
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
225void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc);
226void XzUnpacker_Init(CXzUnpacker *p);
227void XzUnpacker_Free(CXzUnpacker *p);
228
229/*
230finishMode:
231  It has meaning only if the decoding reaches output limit (*destLen).
232  CODER_FINISH_ANY - use smallest number of input bytes
233  CODER_FINISH_END - read EndOfStream marker after decoding
234
235Returns:
236  SZ_OK
237    status:
238      CODER_STATUS_NOT_FINISHED,
239      CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams,
240                                      call XzUnpacker_IsStreamWasFinished to check that current stream was finished
241  SZ_ERROR_MEM  - Memory allocation error
242  SZ_ERROR_DATA - Data error
243  SZ_ERROR_UNSUPPORTED - Unsupported method or method properties
244  SZ_ERROR_CRC  - CRC error
245  // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
246
247  SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons:
248     - xz Stream Signature failure
249     - CRC32 of xz Stream Header is failed
250     - The size of Stream padding is not multiple of four bytes.
251    It's possible to get that error, if xz stream was finished and the stream
252    contains some another data. In that case you can call XzUnpacker_GetExtraSize()
253    function to get real size of xz stream.
254*/
255
256
257SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
258    const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode,
259    ECoderStatus *status);
260
261Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
262
263/*
264Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of
265xz stream in two cases:
266XzUnpacker_Code() returns:
267  res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT
268  res == SZ_ERROR_NO_ARCHIVE
269*/
270
271UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p);
272
273EXTERN_C_END
274
275#endif