| /* ZstdDec.h -- Zstd Decoder interfaces |
| 2024-01-21 : Igor Pavlov : Public domain */ |
| |
| #ifndef ZIP7_INC_ZSTD_DEC_H |
| #define ZIP7_INC_ZSTD_DEC_H |
| |
| EXTERN_C_BEGIN |
| |
| typedef struct CZstdDec CZstdDec; |
| typedef CZstdDec * CZstdDecHandle; |
| |
| CZstdDecHandle ZstdDec_Create(ISzAllocPtr alloc_Small, ISzAllocPtr alloc_Big); |
| void ZstdDec_Destroy(CZstdDecHandle p); |
| |
| typedef enum |
| { |
| ZSTD_STATUS_NOT_SPECIFIED, /* use main error code instead */ |
| ZSTD_STATUS_FINISHED_FRAME, /* data frame or skip frame was finished */ |
| ZSTD_STATUS_NOT_FINISHED, /* just finished non-empty block or unfinished RAW/RLE block */ |
| ZSTD_STATUS_NEEDS_MORE_INPUT, /* the callee needs more input bytes. It has more priority over ZSTD_STATUS_NOT_FINISHED */ |
| ZSTD_STATUS_OUT_REACHED /* is not finihed frame and ((outProcessed > outSize) || (outProcessed == outSize && unfinished RAW/RLE block) */ |
| } enum_ZstdStatus_Dummy; |
| |
| #define ZstdDecState_DOES_NEED_MORE_INPUT_OR_FINISHED_FRAME(p) \ |
| ((p)->status & ZSTD_STATUS_FINISHED_FRAME) |
| /* |
| ((p)->status == ZSTD_STATUS_NEEDS_MORE_INPUT || \ |
| (p)->status == ZSTD_STATUS_FINISHED_FRAME) |
| */ |
| |
| typedef Byte enum_ZstdStatus; |
| |
| |
| void ZstdDec_Init(CZstdDecHandle p); |
| |
| typedef struct |
| { |
| UInt64 num_Blocks; |
| Byte descriptor_OR; |
| Byte descriptor_NOT_OR; |
| Byte are_ContentSize_Unknown; |
| Byte windowDescriptor_MAX; |
| |
| // Byte are_ContentSize_Known; |
| // Byte are_SingleSegments; |
| // Byte are_WindowDescriptors; |
| Byte checksum_Defined; |
| // Byte are_Checksums; |
| // Byte are_Non_Checksums; |
| |
| // Byte are_DictionaryId; |
| Byte are_DictionaryId_Different; |
| |
| // Byte reserved[3]; |
| |
| UInt32 checksum; // checksum of last data frame |
| /// UInt32 dictionaryId_Cur; |
| UInt32 dictionaryId; // if there are non-zero dictionary IDs, then it's first dictionaryId |
| |
| UInt64 num_DataFrames; |
| UInt64 num_SkipFrames; |
| UInt64 skipFrames_Size; |
| UInt64 contentSize_Total; |
| UInt64 contentSize_MAX; |
| // UInt64 num_Checksums; |
| // UInt64 num_Non_Checksums; // frames without checksum |
| // UInt64 num_WindowDescriptors; |
| // UInt64 num_SingleSegments; |
| // UInt64 num_Frames_with_ContentSize; |
| // UInt64 num_Frames_without_ContentSize; |
| UInt64 windowSize_MAX; |
| UInt64 windowSize_Allocate_MAX; |
| // UInt64 num_DictionaryIds; |
| // UInt64 num_Blocks_forType[4]; |
| // UInt64 num_BlockBytes_forType[4]; |
| // UInt64 num_SingleSegments; |
| // UInt64 singleSegment_ContentSize_MAX; |
| } CZstdDecInfo; |
| |
| #define ZstdDecInfo_CLEAR(p) { memset(p, 0, sizeof(*(p))); } |
| |
| #define ZstdDecInfo_GET_NUM_FRAMES(p) ((p)->num_DataFrames + (p)->num_SkipFrames) |
| |
| |
| typedef struct CZstdDecState |
| { |
| enum_ZstdStatus status; // out |
| Byte disableHash; |
| // Byte mustBeFinished; |
| Byte outSize_Defined; |
| // Byte isAfterSizeMode; |
| // UInt64 inProcessed; |
| // SRes codeRes; |
| // Byte needWrite_IsStrong; |
| |
| const Byte *inBuf; |
| size_t inPos; // in/out |
| size_t inLim; |
| |
| const Byte *win; // out |
| size_t winPos; // out |
| size_t wrPos; // in/out |
| // size_t cycSize; // out : if (!outBuf_fromCaller) |
| size_t needWrite_Size; // out |
| |
| Byte *outBuf_fromCaller; |
| size_t outBufSize_fromCaller; |
| /* (outBufSize_fromCaller >= full_uncompressed_size_of_all_frames) is required |
| for success decoding. |
| If outBufSize_fromCaller < full_uncompressed_size_of_all_frames), |
| decoding can give error message, because we decode per block basis. |
| */ |
| |
| // size_t outStep; |
| UInt64 outSize; // total in all frames |
| UInt64 outProcessed; // out decoded in all frames (it can be >= outSize) |
| |
| CZstdDecInfo info; |
| } CZstdDecState; |
| |
| void ZstdDecState_Clear(CZstdDecState *p); |
| |
| /* |
| ZstdDec_Decode() |
| return: |
| SZ_OK - no error |
| SZ_ERROR_DATA - Data Error |
| SZ_ERROR_MEM - Memory allocation error |
| SZ_ERROR_UNSUPPORTED - Unsupported method or method properties |
| SZ_ERROR_CRC - XXH hash Error |
| // SZ_ERROR_ARCHIVE - Headers error (not used now) |
| */ |
| SRes ZstdDec_Decode(CZstdDecHandle dec, CZstdDecState *p); |
| |
| /* |
| ZstdDec_ReadUnusedFromInBuf(): |
| returns: the number of bytes that were read from InBuf |
| (*afterDecoding_tempPos) must be set to zero before first call of ZstdDec_ReadUnusedFromInBuf() |
| */ |
| size_t ZstdDec_ReadUnusedFromInBuf( |
| CZstdDecHandle dec, |
| size_t afterDecoding_tempPos, // in/out |
| void *data, size_t size); |
| |
| typedef struct |
| { |
| SRes decode_SRes; // error code of data decoding |
| Byte is_NonFinishedFrame; // there is unfinished decoding for data frame or skip frame |
| Byte extraSize; |
| } CZstdDecResInfo; |
| |
| /* |
| #define ZstdDecResInfo_CLEAR(p) \ |
| { (p)->decode_SRes = 0; \ |
| (p)->is_NonFinishedFrame; \ |
| (p)->extraSize = 0; \ |
| } |
| // memset(p, 0, sizeof(*p)); |
| */ |
| |
| /* |
| additional error codes for CZstdDecResInfo::decode_SRes: |
| SZ_ERROR_NO_ARCHIVE - is not zstd stream (no frames) |
| SZ_ERROR_INPUT_EOF - need more data in input stream |
| */ |
| void ZstdDec_GetResInfo(const CZstdDec *dec, |
| const CZstdDecState *p, |
| SRes res, // it's result from ZstdDec_Decode() |
| CZstdDecResInfo *info); |
| |
| EXTERN_C_END |
| |
| #endif |