1*f6dc9357SAndroid Build Coastguard Worker /* ZstdDec.h -- Zstd Decoder interfaces 2*f6dc9357SAndroid Build Coastguard Worker 2024-01-21 : Igor Pavlov : Public domain */ 3*f6dc9357SAndroid Build Coastguard Worker 4*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_ZSTD_DEC_H 5*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_ZSTD_DEC_H 6*f6dc9357SAndroid Build Coastguard Worker 7*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN 8*f6dc9357SAndroid Build Coastguard Worker 9*f6dc9357SAndroid Build Coastguard Worker typedef struct CZstdDec CZstdDec; 10*f6dc9357SAndroid Build Coastguard Worker typedef CZstdDec * CZstdDecHandle; 11*f6dc9357SAndroid Build Coastguard Worker 12*f6dc9357SAndroid Build Coastguard Worker CZstdDecHandle ZstdDec_Create(ISzAllocPtr alloc_Small, ISzAllocPtr alloc_Big); 13*f6dc9357SAndroid Build Coastguard Worker void ZstdDec_Destroy(CZstdDecHandle p); 14*f6dc9357SAndroid Build Coastguard Worker 15*f6dc9357SAndroid Build Coastguard Worker typedef enum 16*f6dc9357SAndroid Build Coastguard Worker { 17*f6dc9357SAndroid Build Coastguard Worker ZSTD_STATUS_NOT_SPECIFIED, /* use main error code instead */ 18*f6dc9357SAndroid Build Coastguard Worker ZSTD_STATUS_FINISHED_FRAME, /* data frame or skip frame was finished */ 19*f6dc9357SAndroid Build Coastguard Worker ZSTD_STATUS_NOT_FINISHED, /* just finished non-empty block or unfinished RAW/RLE block */ 20*f6dc9357SAndroid Build Coastguard Worker ZSTD_STATUS_NEEDS_MORE_INPUT, /* the callee needs more input bytes. It has more priority over ZSTD_STATUS_NOT_FINISHED */ 21*f6dc9357SAndroid Build Coastguard Worker ZSTD_STATUS_OUT_REACHED /* is not finihed frame and ((outProcessed > outSize) || (outProcessed == outSize && unfinished RAW/RLE block) */ 22*f6dc9357SAndroid Build Coastguard Worker } enum_ZstdStatus_Dummy; 23*f6dc9357SAndroid Build Coastguard Worker 24*f6dc9357SAndroid Build Coastguard Worker #define ZstdDecState_DOES_NEED_MORE_INPUT_OR_FINISHED_FRAME(p) \ 25*f6dc9357SAndroid Build Coastguard Worker ((p)->status & ZSTD_STATUS_FINISHED_FRAME) 26*f6dc9357SAndroid Build Coastguard Worker /* 27*f6dc9357SAndroid Build Coastguard Worker ((p)->status == ZSTD_STATUS_NEEDS_MORE_INPUT || \ 28*f6dc9357SAndroid Build Coastguard Worker (p)->status == ZSTD_STATUS_FINISHED_FRAME) 29*f6dc9357SAndroid Build Coastguard Worker */ 30*f6dc9357SAndroid Build Coastguard Worker 31*f6dc9357SAndroid Build Coastguard Worker typedef Byte enum_ZstdStatus; 32*f6dc9357SAndroid Build Coastguard Worker 33*f6dc9357SAndroid Build Coastguard Worker 34*f6dc9357SAndroid Build Coastguard Worker void ZstdDec_Init(CZstdDecHandle p); 35*f6dc9357SAndroid Build Coastguard Worker 36*f6dc9357SAndroid Build Coastguard Worker typedef struct 37*f6dc9357SAndroid Build Coastguard Worker { 38*f6dc9357SAndroid Build Coastguard Worker UInt64 num_Blocks; 39*f6dc9357SAndroid Build Coastguard Worker Byte descriptor_OR; 40*f6dc9357SAndroid Build Coastguard Worker Byte descriptor_NOT_OR; 41*f6dc9357SAndroid Build Coastguard Worker Byte are_ContentSize_Unknown; 42*f6dc9357SAndroid Build Coastguard Worker Byte windowDescriptor_MAX; 43*f6dc9357SAndroid Build Coastguard Worker 44*f6dc9357SAndroid Build Coastguard Worker // Byte are_ContentSize_Known; 45*f6dc9357SAndroid Build Coastguard Worker // Byte are_SingleSegments; 46*f6dc9357SAndroid Build Coastguard Worker // Byte are_WindowDescriptors; 47*f6dc9357SAndroid Build Coastguard Worker Byte checksum_Defined; 48*f6dc9357SAndroid Build Coastguard Worker // Byte are_Checksums; 49*f6dc9357SAndroid Build Coastguard Worker // Byte are_Non_Checksums; 50*f6dc9357SAndroid Build Coastguard Worker 51*f6dc9357SAndroid Build Coastguard Worker // Byte are_DictionaryId; 52*f6dc9357SAndroid Build Coastguard Worker Byte are_DictionaryId_Different; 53*f6dc9357SAndroid Build Coastguard Worker 54*f6dc9357SAndroid Build Coastguard Worker // Byte reserved[3]; 55*f6dc9357SAndroid Build Coastguard Worker 56*f6dc9357SAndroid Build Coastguard Worker UInt32 checksum; // checksum of last data frame 57*f6dc9357SAndroid Build Coastguard Worker /// UInt32 dictionaryId_Cur; 58*f6dc9357SAndroid Build Coastguard Worker UInt32 dictionaryId; // if there are non-zero dictionary IDs, then it's first dictionaryId 59*f6dc9357SAndroid Build Coastguard Worker 60*f6dc9357SAndroid Build Coastguard Worker UInt64 num_DataFrames; 61*f6dc9357SAndroid Build Coastguard Worker UInt64 num_SkipFrames; 62*f6dc9357SAndroid Build Coastguard Worker UInt64 skipFrames_Size; 63*f6dc9357SAndroid Build Coastguard Worker UInt64 contentSize_Total; 64*f6dc9357SAndroid Build Coastguard Worker UInt64 contentSize_MAX; 65*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_Checksums; 66*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_Non_Checksums; // frames without checksum 67*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_WindowDescriptors; 68*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_SingleSegments; 69*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_Frames_with_ContentSize; 70*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_Frames_without_ContentSize; 71*f6dc9357SAndroid Build Coastguard Worker UInt64 windowSize_MAX; 72*f6dc9357SAndroid Build Coastguard Worker UInt64 windowSize_Allocate_MAX; 73*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_DictionaryIds; 74*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_Blocks_forType[4]; 75*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_BlockBytes_forType[4]; 76*f6dc9357SAndroid Build Coastguard Worker // UInt64 num_SingleSegments; 77*f6dc9357SAndroid Build Coastguard Worker // UInt64 singleSegment_ContentSize_MAX; 78*f6dc9357SAndroid Build Coastguard Worker } CZstdDecInfo; 79*f6dc9357SAndroid Build Coastguard Worker 80*f6dc9357SAndroid Build Coastguard Worker #define ZstdDecInfo_CLEAR(p) { memset(p, 0, sizeof(*(p))); } 81*f6dc9357SAndroid Build Coastguard Worker 82*f6dc9357SAndroid Build Coastguard Worker #define ZstdDecInfo_GET_NUM_FRAMES(p) ((p)->num_DataFrames + (p)->num_SkipFrames) 83*f6dc9357SAndroid Build Coastguard Worker 84*f6dc9357SAndroid Build Coastguard Worker 85*f6dc9357SAndroid Build Coastguard Worker typedef struct CZstdDecState 86*f6dc9357SAndroid Build Coastguard Worker { 87*f6dc9357SAndroid Build Coastguard Worker enum_ZstdStatus status; // out 88*f6dc9357SAndroid Build Coastguard Worker Byte disableHash; 89*f6dc9357SAndroid Build Coastguard Worker // Byte mustBeFinished; 90*f6dc9357SAndroid Build Coastguard Worker Byte outSize_Defined; 91*f6dc9357SAndroid Build Coastguard Worker // Byte isAfterSizeMode; 92*f6dc9357SAndroid Build Coastguard Worker // UInt64 inProcessed; 93*f6dc9357SAndroid Build Coastguard Worker // SRes codeRes; 94*f6dc9357SAndroid Build Coastguard Worker // Byte needWrite_IsStrong; 95*f6dc9357SAndroid Build Coastguard Worker 96*f6dc9357SAndroid Build Coastguard Worker const Byte *inBuf; 97*f6dc9357SAndroid Build Coastguard Worker size_t inPos; // in/out 98*f6dc9357SAndroid Build Coastguard Worker size_t inLim; 99*f6dc9357SAndroid Build Coastguard Worker 100*f6dc9357SAndroid Build Coastguard Worker const Byte *win; // out 101*f6dc9357SAndroid Build Coastguard Worker size_t winPos; // out 102*f6dc9357SAndroid Build Coastguard Worker size_t wrPos; // in/out 103*f6dc9357SAndroid Build Coastguard Worker // size_t cycSize; // out : if (!outBuf_fromCaller) 104*f6dc9357SAndroid Build Coastguard Worker size_t needWrite_Size; // out 105*f6dc9357SAndroid Build Coastguard Worker 106*f6dc9357SAndroid Build Coastguard Worker Byte *outBuf_fromCaller; 107*f6dc9357SAndroid Build Coastguard Worker size_t outBufSize_fromCaller; 108*f6dc9357SAndroid Build Coastguard Worker /* (outBufSize_fromCaller >= full_uncompressed_size_of_all_frames) is required 109*f6dc9357SAndroid Build Coastguard Worker for success decoding. 110*f6dc9357SAndroid Build Coastguard Worker If outBufSize_fromCaller < full_uncompressed_size_of_all_frames), 111*f6dc9357SAndroid Build Coastguard Worker decoding can give error message, because we decode per block basis. 112*f6dc9357SAndroid Build Coastguard Worker */ 113*f6dc9357SAndroid Build Coastguard Worker 114*f6dc9357SAndroid Build Coastguard Worker // size_t outStep; 115*f6dc9357SAndroid Build Coastguard Worker UInt64 outSize; // total in all frames 116*f6dc9357SAndroid Build Coastguard Worker UInt64 outProcessed; // out decoded in all frames (it can be >= outSize) 117*f6dc9357SAndroid Build Coastguard Worker 118*f6dc9357SAndroid Build Coastguard Worker CZstdDecInfo info; 119*f6dc9357SAndroid Build Coastguard Worker } CZstdDecState; 120*f6dc9357SAndroid Build Coastguard Worker 121*f6dc9357SAndroid Build Coastguard Worker void ZstdDecState_Clear(CZstdDecState *p); 122*f6dc9357SAndroid Build Coastguard Worker 123*f6dc9357SAndroid Build Coastguard Worker /* 124*f6dc9357SAndroid Build Coastguard Worker ZstdDec_Decode() 125*f6dc9357SAndroid Build Coastguard Worker return: 126*f6dc9357SAndroid Build Coastguard Worker SZ_OK - no error 127*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_DATA - Data Error 128*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_MEM - Memory allocation error 129*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_UNSUPPORTED - Unsupported method or method properties 130*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_CRC - XXH hash Error 131*f6dc9357SAndroid Build Coastguard Worker // SZ_ERROR_ARCHIVE - Headers error (not used now) 132*f6dc9357SAndroid Build Coastguard Worker */ 133*f6dc9357SAndroid Build Coastguard Worker SRes ZstdDec_Decode(CZstdDecHandle dec, CZstdDecState *p); 134*f6dc9357SAndroid Build Coastguard Worker 135*f6dc9357SAndroid Build Coastguard Worker /* 136*f6dc9357SAndroid Build Coastguard Worker ZstdDec_ReadUnusedFromInBuf(): 137*f6dc9357SAndroid Build Coastguard Worker returns: the number of bytes that were read from InBuf 138*f6dc9357SAndroid Build Coastguard Worker (*afterDecoding_tempPos) must be set to zero before first call of ZstdDec_ReadUnusedFromInBuf() 139*f6dc9357SAndroid Build Coastguard Worker */ 140*f6dc9357SAndroid Build Coastguard Worker size_t ZstdDec_ReadUnusedFromInBuf( 141*f6dc9357SAndroid Build Coastguard Worker CZstdDecHandle dec, 142*f6dc9357SAndroid Build Coastguard Worker size_t afterDecoding_tempPos, // in/out 143*f6dc9357SAndroid Build Coastguard Worker void *data, size_t size); 144*f6dc9357SAndroid Build Coastguard Worker 145*f6dc9357SAndroid Build Coastguard Worker typedef struct 146*f6dc9357SAndroid Build Coastguard Worker { 147*f6dc9357SAndroid Build Coastguard Worker SRes decode_SRes; // error code of data decoding 148*f6dc9357SAndroid Build Coastguard Worker Byte is_NonFinishedFrame; // there is unfinished decoding for data frame or skip frame 149*f6dc9357SAndroid Build Coastguard Worker Byte extraSize; 150*f6dc9357SAndroid Build Coastguard Worker } CZstdDecResInfo; 151*f6dc9357SAndroid Build Coastguard Worker 152*f6dc9357SAndroid Build Coastguard Worker /* 153*f6dc9357SAndroid Build Coastguard Worker #define ZstdDecResInfo_CLEAR(p) \ 154*f6dc9357SAndroid Build Coastguard Worker { (p)->decode_SRes = 0; \ 155*f6dc9357SAndroid Build Coastguard Worker (p)->is_NonFinishedFrame; \ 156*f6dc9357SAndroid Build Coastguard Worker (p)->extraSize = 0; \ 157*f6dc9357SAndroid Build Coastguard Worker } 158*f6dc9357SAndroid Build Coastguard Worker // memset(p, 0, sizeof(*p)); 159*f6dc9357SAndroid Build Coastguard Worker */ 160*f6dc9357SAndroid Build Coastguard Worker 161*f6dc9357SAndroid Build Coastguard Worker /* 162*f6dc9357SAndroid Build Coastguard Worker additional error codes for CZstdDecResInfo::decode_SRes: 163*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_NO_ARCHIVE - is not zstd stream (no frames) 164*f6dc9357SAndroid Build Coastguard Worker SZ_ERROR_INPUT_EOF - need more data in input stream 165*f6dc9357SAndroid Build Coastguard Worker */ 166*f6dc9357SAndroid Build Coastguard Worker void ZstdDec_GetResInfo(const CZstdDec *dec, 167*f6dc9357SAndroid Build Coastguard Worker const CZstdDecState *p, 168*f6dc9357SAndroid Build Coastguard Worker SRes res, // it's result from ZstdDec_Decode() 169*f6dc9357SAndroid Build Coastguard Worker CZstdDecResInfo *info); 170*f6dc9357SAndroid Build Coastguard Worker 171*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END 172*f6dc9357SAndroid Build Coastguard Worker 173*f6dc9357SAndroid Build Coastguard Worker #endif 174