Home | History | Annotate | Download | only in C
      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