Mercurial > hg
comparison contrib/python-zstandard/zstd/decompress/zstd_decompress.c @ 30822:b54a2984cdd4
zstd: vendor python-zstandard 0.6.0
Commit 63c68d6f5fc8de4afd9bde81b13b537beb4e47e8 from
https://github.com/indygreg/python-zstandard is imported without
modifications (other than removing unwanted files).
This includes minor performance and feature improvements. It also
changes the vendored zstd library from 1.1.1 to 1.1.2.
# no-check-commit
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 14 Jan 2017 19:41:43 -0800 |
parents | 2e484bdea8c4 |
children | c32454d69b85 |
comparison
equal
deleted
inserted
replaced
30821:7005c03f7387 | 30822:b54a2984cdd4 |
---|---|
53 | 53 |
54 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) | 54 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) |
55 # include "zstd_legacy.h" | 55 # include "zstd_legacy.h" |
56 #endif | 56 #endif |
57 | 57 |
58 | |
59 #if defined(_MSC_VER) | |
60 # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ | |
61 # define ZSTD_PREFETCH(ptr) _mm_prefetch((const char*)ptr, _MM_HINT_T0) | |
62 #elif defined(__GNUC__) | |
63 # define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0) | |
64 #else | |
65 # define ZSTD_PREFETCH(ptr) /* disabled */ | |
66 #endif | |
58 | 67 |
59 /*-************************************* | 68 /*-************************************* |
60 * Macros | 69 * Macros |
61 ***************************************/ | 70 ***************************************/ |
62 #define ZSTD_isError ERR_isError /* for inlining */ | 71 #define ZSTD_isError ERR_isError /* for inlining */ |
102 XXH64_state_t xxhState; | 111 XXH64_state_t xxhState; |
103 size_t headerSize; | 112 size_t headerSize; |
104 U32 dictID; | 113 U32 dictID; |
105 const BYTE* litPtr; | 114 const BYTE* litPtr; |
106 ZSTD_customMem customMem; | 115 ZSTD_customMem customMem; |
107 size_t litBufSize; | |
108 size_t litSize; | 116 size_t litSize; |
109 size_t rleSize; | 117 size_t rleSize; |
110 BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH]; | 118 BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH]; |
111 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; | 119 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; |
112 }; /* typedef'd to ZSTD_DCtx within "zstd.h" */ | 120 }; /* typedef'd to ZSTD_DCtx within "zstd.h" */ |
191 | 199 |
192 /*-************************************************************* | 200 /*-************************************************************* |
193 * Decompression section | 201 * Decompression section |
194 ***************************************************************/ | 202 ***************************************************************/ |
195 | 203 |
196 /* See compression format details in : doc/zstd_compression_format.md */ | 204 /*! ZSTD_isFrame() : |
205 * Tells if the content of `buffer` starts with a valid Frame Identifier. | |
206 * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. | |
207 * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. | |
208 * Note 3 : Skippable Frame Identifiers are considered valid. */ | |
209 unsigned ZSTD_isFrame(const void* buffer, size_t size) | |
210 { | |
211 if (size < 4) return 0; | |
212 { U32 const magic = MEM_readLE32(buffer); | |
213 if (magic == ZSTD_MAGICNUMBER) return 1; | |
214 if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1; | |
215 } | |
216 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) | |
217 if (ZSTD_isLegacy(buffer, size)) return 1; | |
218 #endif | |
219 return 0; | |
220 } | |
221 | |
197 | 222 |
198 /** ZSTD_frameHeaderSize() : | 223 /** ZSTD_frameHeaderSize() : |
199 * srcSize must be >= ZSTD_frameHeaderSize_prefix. | 224 * srcSize must be >= ZSTD_frameHeaderSize_prefix. |
200 * @return : size of the Frame Header */ | 225 * @return : size of the Frame Header */ |
201 static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) | 226 static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) |
410 HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) : | 435 HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) : |
411 HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) )) | 436 HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) )) |
412 return ERROR(corruption_detected); | 437 return ERROR(corruption_detected); |
413 | 438 |
414 dctx->litPtr = dctx->litBuffer; | 439 dctx->litPtr = dctx->litBuffer; |
415 dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH; | |
416 dctx->litSize = litSize; | 440 dctx->litSize = litSize; |
417 dctx->litEntropy = 1; | 441 dctx->litEntropy = 1; |
418 if (litEncType==set_compressed) dctx->HUFptr = dctx->hufTable; | 442 if (litEncType==set_compressed) dctx->HUFptr = dctx->hufTable; |
443 memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); | |
419 return litCSize + lhSize; | 444 return litCSize + lhSize; |
420 } | 445 } |
421 | 446 |
422 case set_basic: | 447 case set_basic: |
423 { size_t litSize, lhSize; | 448 { size_t litSize, lhSize; |
440 | 465 |
441 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ | 466 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ |
442 if (litSize+lhSize > srcSize) return ERROR(corruption_detected); | 467 if (litSize+lhSize > srcSize) return ERROR(corruption_detected); |
443 memcpy(dctx->litBuffer, istart+lhSize, litSize); | 468 memcpy(dctx->litBuffer, istart+lhSize, litSize); |
444 dctx->litPtr = dctx->litBuffer; | 469 dctx->litPtr = dctx->litBuffer; |
445 dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+8; | |
446 dctx->litSize = litSize; | 470 dctx->litSize = litSize; |
471 memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); | |
447 return lhSize+litSize; | 472 return lhSize+litSize; |
448 } | 473 } |
449 /* direct reference into compressed stream */ | 474 /* direct reference into compressed stream */ |
450 dctx->litPtr = istart+lhSize; | 475 dctx->litPtr = istart+lhSize; |
451 dctx->litBufSize = srcSize-lhSize; | |
452 dctx->litSize = litSize; | 476 dctx->litSize = litSize; |
453 return lhSize+litSize; | 477 return lhSize+litSize; |
454 } | 478 } |
455 | 479 |
456 case set_rle: | 480 case set_rle: |
471 litSize = MEM_readLE24(istart) >> 4; | 495 litSize = MEM_readLE24(istart) >> 4; |
472 if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */ | 496 if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */ |
473 break; | 497 break; |
474 } | 498 } |
475 if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected); | 499 if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected); |
476 memset(dctx->litBuffer, istart[lhSize], litSize); | 500 memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); |
477 dctx->litPtr = dctx->litBuffer; | 501 dctx->litPtr = dctx->litBuffer; |
478 dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH; | |
479 dctx->litSize = litSize; | 502 dctx->litSize = litSize; |
480 return lhSize+1; | 503 return lhSize+1; |
481 } | 504 } |
482 default: | 505 default: |
483 return ERROR(corruption_detected); /* impossible */ | 506 return ERROR(corruption_detected); /* impossible */ |
759 | 782 |
760 typedef struct { | 783 typedef struct { |
761 size_t litLength; | 784 size_t litLength; |
762 size_t matchLength; | 785 size_t matchLength; |
763 size_t offset; | 786 size_t offset; |
787 const BYTE* match; | |
764 } seq_t; | 788 } seq_t; |
765 | 789 |
766 typedef struct { | 790 typedef struct { |
767 BIT_DStream_t DStream; | 791 BIT_DStream_t DStream; |
768 FSE_DState_t stateLL; | 792 FSE_DState_t stateLL; |
769 FSE_DState_t stateOffb; | 793 FSE_DState_t stateOffb; |
770 FSE_DState_t stateML; | 794 FSE_DState_t stateML; |
771 size_t prevOffset[ZSTD_REP_NUM]; | 795 size_t prevOffset[ZSTD_REP_NUM]; |
796 const BYTE* base; | |
797 size_t pos; | |
798 iPtrDiff gotoDict; | |
772 } seqState_t; | 799 } seqState_t; |
800 | |
801 | |
802 FORCE_NOINLINE | |
803 size_t ZSTD_execSequenceLast7(BYTE* op, | |
804 BYTE* const oend, seq_t sequence, | |
805 const BYTE** litPtr, const BYTE* const litLimit, | |
806 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) | |
807 { | |
808 BYTE* const oLitEnd = op + sequence.litLength; | |
809 size_t const sequenceLength = sequence.litLength + sequence.matchLength; | |
810 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ | |
811 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; | |
812 const BYTE* const iLitEnd = *litPtr + sequence.litLength; | |
813 const BYTE* match = oLitEnd - sequence.offset; | |
814 | |
815 /* check */ | |
816 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ | |
817 if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ | |
818 if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */ | |
819 | |
820 /* copy literals */ | |
821 if (op < oend_w) { | |
822 ZSTD_wildcopy(op, *litPtr, oend_w - op); | |
823 *litPtr += oend_w - op; | |
824 op = oend_w; | |
825 } | |
826 while (op < oLitEnd) *op++ = *(*litPtr)++; | |
827 | |
828 /* copy Match */ | |
829 if (sequence.offset > (size_t)(oLitEnd - base)) { | |
830 /* offset beyond prefix */ | |
831 if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); | |
832 match = dictEnd - (base-match); | |
833 if (match + sequence.matchLength <= dictEnd) { | |
834 memmove(oLitEnd, match, sequence.matchLength); | |
835 return sequenceLength; | |
836 } | |
837 /* span extDict & currentPrefixSegment */ | |
838 { size_t const length1 = dictEnd - match; | |
839 memmove(oLitEnd, match, length1); | |
840 op = oLitEnd + length1; | |
841 sequence.matchLength -= length1; | |
842 match = base; | |
843 } } | |
844 while (op < oMatchEnd) *op++ = *match++; | |
845 return sequenceLength; | |
846 } | |
847 | |
848 | |
773 | 849 |
774 | 850 |
775 static seq_t ZSTD_decodeSequence(seqState_t* seqState) | 851 static seq_t ZSTD_decodeSequence(seqState_t* seqState) |
776 { | 852 { |
777 seq_t seq; | 853 seq_t seq; |
795 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, | 871 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, |
796 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, | 872 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, |
797 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; | 873 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; |
798 | 874 |
799 static const U32 OF_base[MaxOff+1] = { | 875 static const U32 OF_base[MaxOff+1] = { |
800 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, | 876 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, |
801 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, | 877 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, |
802 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, | 878 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, |
803 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; | 879 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; |
804 | 880 |
805 /* sequence */ | 881 /* sequence */ |
806 { size_t offset; | 882 { size_t offset; |
807 if (!ofCode) | 883 if (!ofCode) |
808 offset = 0; | 884 offset = 0; |
809 else { | 885 else { |
810 offset = OF_base[ofCode] + BIT_readBits(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ | 886 offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ |
811 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); | 887 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); |
812 } | 888 } |
813 | 889 |
814 if (ofCode <= 1) { | 890 if (ofCode <= 1) { |
815 offset += (llCode==0); | 891 offset += (llCode==0); |
828 seqState->prevOffset[0] = offset; | 904 seqState->prevOffset[0] = offset; |
829 } | 905 } |
830 seq.offset = offset; | 906 seq.offset = offset; |
831 } | 907 } |
832 | 908 |
833 seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ | 909 seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ |
834 if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); | 910 if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); |
835 | 911 |
836 seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&seqState->DStream, llBits) : 0); /* <= 16 bits */ | 912 seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ |
837 if (MEM_32bits() || | 913 if (MEM_32bits() || |
838 (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); | 914 (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); |
839 | 915 |
840 /* ANS state update */ | 916 /* ANS state update */ |
841 FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ | 917 FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ |
845 | 921 |
846 return seq; | 922 return seq; |
847 } | 923 } |
848 | 924 |
849 | 925 |
850 FORCE_NOINLINE | 926 FORCE_INLINE |
851 size_t ZSTD_execSequenceLast7(BYTE* op, | 927 size_t ZSTD_execSequence(BYTE* op, |
852 BYTE* const oend, seq_t sequence, | 928 BYTE* const oend, seq_t sequence, |
853 const BYTE** litPtr, const BYTE* const litLimit_w, | 929 const BYTE** litPtr, const BYTE* const litLimit, |
854 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) | 930 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) |
855 { | 931 { |
856 BYTE* const oLitEnd = op + sequence.litLength; | 932 BYTE* const oLitEnd = op + sequence.litLength; |
857 size_t const sequenceLength = sequence.litLength + sequence.matchLength; | 933 size_t const sequenceLength = sequence.litLength + sequence.matchLength; |
858 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ | 934 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ |
859 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; | 935 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; |
860 const BYTE* const iLitEnd = *litPtr + sequence.litLength; | 936 const BYTE* const iLitEnd = *litPtr + sequence.litLength; |
861 const BYTE* match = oLitEnd - sequence.offset; | 937 const BYTE* match = oLitEnd - sequence.offset; |
862 | 938 |
863 /* check */ | 939 /* check */ |
864 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ | 940 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ |
865 if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */ | 941 if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ |
866 if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */ | 942 if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); |
867 | 943 |
868 /* copy literals */ | 944 /* copy Literals */ |
869 if (op < oend_w) { | 945 ZSTD_copy8(op, *litPtr); |
870 ZSTD_wildcopy(op, *litPtr, oend_w - op); | 946 if (sequence.litLength > 8) |
871 *litPtr += oend_w - op; | 947 ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ |
872 op = oend_w; | 948 op = oLitEnd; |
873 } | 949 *litPtr = iLitEnd; /* update for next sequence */ |
874 while (op < oLitEnd) *op++ = *(*litPtr)++; | |
875 | 950 |
876 /* copy Match */ | 951 /* copy Match */ |
877 if (sequence.offset > (size_t)(oLitEnd - base)) { | 952 if (sequence.offset > (size_t)(oLitEnd - base)) { |
878 /* offset beyond prefix */ | 953 /* offset beyond prefix */ |
879 if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); | 954 if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); |
880 match = dictEnd - (base-match); | 955 match += (dictEnd-base); |
881 if (match + sequence.matchLength <= dictEnd) { | 956 if (match + sequence.matchLength <= dictEnd) { |
882 memmove(oLitEnd, match, sequence.matchLength); | 957 memmove(oLitEnd, match, sequence.matchLength); |
883 return sequenceLength; | 958 return sequenceLength; |
884 } | 959 } |
885 /* span extDict & currentPrefixSegment */ | 960 /* span extDict & currentPrefixSegment */ |
886 { size_t const length1 = dictEnd - match; | 961 { size_t const length1 = dictEnd - match; |
887 memmove(oLitEnd, match, length1); | 962 memmove(oLitEnd, match, length1); |
888 op = oLitEnd + length1; | 963 op = oLitEnd + length1; |
889 sequence.matchLength -= length1; | 964 sequence.matchLength -= length1; |
890 match = base; | 965 match = base; |
891 } } | 966 if (op > oend_w || sequence.matchLength < MINMATCH) { |
892 while (op < oMatchEnd) *op++ = *match++; | |
893 return sequenceLength; | |
894 } | |
895 | |
896 | |
897 FORCE_INLINE | |
898 size_t ZSTD_execSequence(BYTE* op, | |
899 BYTE* const oend, seq_t sequence, | |
900 const BYTE** litPtr, const BYTE* const litLimit_w, | |
901 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) | |
902 { | |
903 BYTE* const oLitEnd = op + sequence.litLength; | |
904 size_t const sequenceLength = sequence.litLength + sequence.matchLength; | |
905 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ | |
906 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; | |
907 const BYTE* const iLitEnd = *litPtr + sequence.litLength; | |
908 const BYTE* match = oLitEnd - sequence.offset; | |
909 | |
910 /* check */ | |
911 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ | |
912 if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */ | |
913 if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit_w, base, vBase, dictEnd); | |
914 | |
915 /* copy Literals */ | |
916 ZSTD_copy8(op, *litPtr); | |
917 if (sequence.litLength > 8) | |
918 ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ | |
919 op = oLitEnd; | |
920 *litPtr = iLitEnd; /* update for next sequence */ | |
921 | |
922 /* copy Match */ | |
923 if (sequence.offset > (size_t)(oLitEnd - base)) { | |
924 /* offset beyond prefix */ | |
925 if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); | |
926 match = dictEnd - (base-match); | |
927 if (match + sequence.matchLength <= dictEnd) { | |
928 memmove(oLitEnd, match, sequence.matchLength); | |
929 return sequenceLength; | |
930 } | |
931 /* span extDict & currentPrefixSegment */ | |
932 { size_t const length1 = dictEnd - match; | |
933 memmove(oLitEnd, match, length1); | |
934 op = oLitEnd + length1; | |
935 sequence.matchLength -= length1; | |
936 match = base; | |
937 if (op > oend_w) { | |
938 U32 i; | 967 U32 i; |
939 for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; | 968 for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; |
940 return sequenceLength; | 969 return sequenceLength; |
941 } | 970 } |
942 } } | 971 } } |
943 /* Requirement: op <= oend_w */ | 972 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ |
944 | 973 |
945 /* match within prefix */ | 974 /* match within prefix */ |
946 if (sequence.offset < 8) { | 975 if (sequence.offset < 8) { |
947 /* close range match, overlap */ | 976 /* close range match, overlap */ |
948 static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ | 977 static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ |
966 match += oend_w - op; | 995 match += oend_w - op; |
967 op = oend_w; | 996 op = oend_w; |
968 } | 997 } |
969 while (op < oMatchEnd) *op++ = *match++; | 998 while (op < oMatchEnd) *op++ = *match++; |
970 } else { | 999 } else { |
971 ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ | 1000 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ |
972 } | 1001 } |
973 return sequenceLength; | 1002 return sequenceLength; |
974 } | 1003 } |
975 | 1004 |
976 | 1005 |
983 const BYTE* const iend = ip + seqSize; | 1012 const BYTE* const iend = ip + seqSize; |
984 BYTE* const ostart = (BYTE* const)dst; | 1013 BYTE* const ostart = (BYTE* const)dst; |
985 BYTE* const oend = ostart + maxDstSize; | 1014 BYTE* const oend = ostart + maxDstSize; |
986 BYTE* op = ostart; | 1015 BYTE* op = ostart; |
987 const BYTE* litPtr = dctx->litPtr; | 1016 const BYTE* litPtr = dctx->litPtr; |
988 const BYTE* const litLimit_w = litPtr + dctx->litBufSize - WILDCOPY_OVERLENGTH; | |
989 const BYTE* const litEnd = litPtr + dctx->litSize; | 1017 const BYTE* const litEnd = litPtr + dctx->litSize; |
990 const BYTE* const base = (const BYTE*) (dctx->base); | 1018 const BYTE* const base = (const BYTE*) (dctx->base); |
991 const BYTE* const vBase = (const BYTE*) (dctx->vBase); | 1019 const BYTE* const vBase = (const BYTE*) (dctx->vBase); |
992 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); | 1020 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); |
993 int nbSeq; | 1021 int nbSeq; |
1009 FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); | 1037 FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); |
1010 | 1038 |
1011 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { | 1039 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { |
1012 nbSeq--; | 1040 nbSeq--; |
1013 { seq_t const sequence = ZSTD_decodeSequence(&seqState); | 1041 { seq_t const sequence = ZSTD_decodeSequence(&seqState); |
1014 size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_w, base, vBase, dictEnd); | 1042 size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); |
1015 if (ZSTD_isError(oneSeqSize)) return oneSeqSize; | 1043 if (ZSTD_isError(oneSeqSize)) return oneSeqSize; |
1016 op += oneSeqSize; | 1044 op += oneSeqSize; |
1017 } } | 1045 } } |
1018 | 1046 |
1019 /* check if reached exact end */ | 1047 /* check if reached exact end */ |
1031 | 1059 |
1032 return op-ostart; | 1060 return op-ostart; |
1033 } | 1061 } |
1034 | 1062 |
1035 | 1063 |
1064 static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) | |
1065 { | |
1066 seq_t seq; | |
1067 | |
1068 U32 const llCode = FSE_peekSymbol(&seqState->stateLL); | |
1069 U32 const mlCode = FSE_peekSymbol(&seqState->stateML); | |
1070 U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */ | |
1071 | |
1072 U32 const llBits = LL_bits[llCode]; | |
1073 U32 const mlBits = ML_bits[mlCode]; | |
1074 U32 const ofBits = ofCode; | |
1075 U32 const totalBits = llBits+mlBits+ofBits; | |
1076 | |
1077 static const U32 LL_base[MaxLL+1] = { | |
1078 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | |
1079 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, | |
1080 0x2000, 0x4000, 0x8000, 0x10000 }; | |
1081 | |
1082 static const U32 ML_base[MaxML+1] = { | |
1083 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, | |
1084 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, | |
1085 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, | |
1086 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; | |
1087 | |
1088 static const U32 OF_base[MaxOff+1] = { | |
1089 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, | |
1090 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, | |
1091 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, | |
1092 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; | |
1093 | |
1094 /* sequence */ | |
1095 { size_t offset; | |
1096 if (!ofCode) | |
1097 offset = 0; | |
1098 else { | |
1099 offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ | |
1100 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); | |
1101 } | |
1102 | |
1103 if (ofCode <= 1) { | |
1104 offset += (llCode==0); | |
1105 if (offset) { | |
1106 size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; | |
1107 temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ | |
1108 if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; | |
1109 seqState->prevOffset[1] = seqState->prevOffset[0]; | |
1110 seqState->prevOffset[0] = offset = temp; | |
1111 } else { | |
1112 offset = seqState->prevOffset[0]; | |
1113 } | |
1114 } else { | |
1115 seqState->prevOffset[2] = seqState->prevOffset[1]; | |
1116 seqState->prevOffset[1] = seqState->prevOffset[0]; | |
1117 seqState->prevOffset[0] = offset; | |
1118 } | |
1119 seq.offset = offset; | |
1120 } | |
1121 | |
1122 seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ | |
1123 if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); | |
1124 | |
1125 seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ | |
1126 if (MEM_32bits() || | |
1127 (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); | |
1128 | |
1129 { size_t const pos = seqState->pos + seq.litLength; | |
1130 seq.match = seqState->base + pos - seq.offset; /* single memory segment */ | |
1131 if (seq.offset > pos) seq.match += seqState->gotoDict; /* separate memory segment */ | |
1132 seqState->pos = pos + seq.matchLength; | |
1133 } | |
1134 | |
1135 /* ANS state update */ | |
1136 FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ | |
1137 FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ | |
1138 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ | |
1139 FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ | |
1140 | |
1141 return seq; | |
1142 } | |
1143 | |
1144 FORCE_INLINE | |
1145 size_t ZSTD_execSequenceLong(BYTE* op, | |
1146 BYTE* const oend, seq_t sequence, | |
1147 const BYTE** litPtr, const BYTE* const litLimit, | |
1148 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) | |
1149 { | |
1150 BYTE* const oLitEnd = op + sequence.litLength; | |
1151 size_t const sequenceLength = sequence.litLength + sequence.matchLength; | |
1152 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ | |
1153 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; | |
1154 const BYTE* const iLitEnd = *litPtr + sequence.litLength; | |
1155 const BYTE* match = sequence.match; | |
1156 | |
1157 /* check */ | |
1158 #if 1 | |
1159 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ | |
1160 if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ | |
1161 if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); | |
1162 #endif | |
1163 | |
1164 /* copy Literals */ | |
1165 ZSTD_copy8(op, *litPtr); | |
1166 if (sequence.litLength > 8) | |
1167 ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ | |
1168 op = oLitEnd; | |
1169 *litPtr = iLitEnd; /* update for next sequence */ | |
1170 | |
1171 /* copy Match */ | |
1172 #if 1 | |
1173 if (sequence.offset > (size_t)(oLitEnd - base)) { | |
1174 /* offset beyond prefix */ | |
1175 if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); | |
1176 if (match + sequence.matchLength <= dictEnd) { | |
1177 memmove(oLitEnd, match, sequence.matchLength); | |
1178 return sequenceLength; | |
1179 } | |
1180 /* span extDict & currentPrefixSegment */ | |
1181 { size_t const length1 = dictEnd - match; | |
1182 memmove(oLitEnd, match, length1); | |
1183 op = oLitEnd + length1; | |
1184 sequence.matchLength -= length1; | |
1185 match = base; | |
1186 if (op > oend_w || sequence.matchLength < MINMATCH) { | |
1187 U32 i; | |
1188 for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; | |
1189 return sequenceLength; | |
1190 } | |
1191 } } | |
1192 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ | |
1193 #endif | |
1194 | |
1195 /* match within prefix */ | |
1196 if (sequence.offset < 8) { | |
1197 /* close range match, overlap */ | |
1198 static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ | |
1199 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */ | |
1200 int const sub2 = dec64table[sequence.offset]; | |
1201 op[0] = match[0]; | |
1202 op[1] = match[1]; | |
1203 op[2] = match[2]; | |
1204 op[3] = match[3]; | |
1205 match += dec32table[sequence.offset]; | |
1206 ZSTD_copy4(op+4, match); | |
1207 match -= sub2; | |
1208 } else { | |
1209 ZSTD_copy8(op, match); | |
1210 } | |
1211 op += 8; match += 8; | |
1212 | |
1213 if (oMatchEnd > oend-(16-MINMATCH)) { | |
1214 if (op < oend_w) { | |
1215 ZSTD_wildcopy(op, match, oend_w - op); | |
1216 match += oend_w - op; | |
1217 op = oend_w; | |
1218 } | |
1219 while (op < oMatchEnd) *op++ = *match++; | |
1220 } else { | |
1221 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ | |
1222 } | |
1223 return sequenceLength; | |
1224 } | |
1225 | |
1226 static size_t ZSTD_decompressSequencesLong( | |
1227 ZSTD_DCtx* dctx, | |
1228 void* dst, size_t maxDstSize, | |
1229 const void* seqStart, size_t seqSize) | |
1230 { | |
1231 const BYTE* ip = (const BYTE*)seqStart; | |
1232 const BYTE* const iend = ip + seqSize; | |
1233 BYTE* const ostart = (BYTE* const)dst; | |
1234 BYTE* const oend = ostart + maxDstSize; | |
1235 BYTE* op = ostart; | |
1236 const BYTE* litPtr = dctx->litPtr; | |
1237 const BYTE* const litEnd = litPtr + dctx->litSize; | |
1238 const BYTE* const base = (const BYTE*) (dctx->base); | |
1239 const BYTE* const vBase = (const BYTE*) (dctx->vBase); | |
1240 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); | |
1241 int nbSeq; | |
1242 | |
1243 /* Build Decoding Tables */ | |
1244 { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); | |
1245 if (ZSTD_isError(seqHSize)) return seqHSize; | |
1246 ip += seqHSize; | |
1247 } | |
1248 | |
1249 /* Regen sequences */ | |
1250 if (nbSeq) { | |
1251 #define STORED_SEQS 4 | |
1252 #define STOSEQ_MASK (STORED_SEQS-1) | |
1253 #define ADVANCED_SEQS 4 | |
1254 seq_t sequences[STORED_SEQS]; | |
1255 int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); | |
1256 seqState_t seqState; | |
1257 int seqNb; | |
1258 dctx->fseEntropy = 1; | |
1259 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; } | |
1260 seqState.base = base; | |
1261 seqState.pos = (size_t)(op-base); | |
1262 seqState.gotoDict = (iPtrDiff)(dictEnd - base); | |
1263 CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); | |
1264 FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); | |
1265 FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); | |
1266 FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); | |
1267 | |
1268 /* prepare in advance */ | |
1269 for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb<seqAdvance; seqNb++) { | |
1270 sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState); | |
1271 } | |
1272 if (seqNb<seqAdvance) return ERROR(corruption_detected); | |
1273 | |
1274 /* decode and decompress */ | |
1275 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNb<nbSeq ; seqNb++) { | |
1276 seq_t const sequence = ZSTD_decodeSequenceLong(&seqState); | |
1277 size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd); | |
1278 if (ZSTD_isError(oneSeqSize)) return oneSeqSize; | |
1279 ZSTD_PREFETCH(sequence.match); | |
1280 sequences[seqNb&STOSEQ_MASK] = sequence; | |
1281 op += oneSeqSize; | |
1282 } | |
1283 if (seqNb<nbSeq) return ERROR(corruption_detected); | |
1284 | |
1285 /* finish queue */ | |
1286 seqNb -= seqAdvance; | |
1287 for ( ; seqNb<nbSeq ; seqNb++) { | |
1288 size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[seqNb&STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd); | |
1289 if (ZSTD_isError(oneSeqSize)) return oneSeqSize; | |
1290 op += oneSeqSize; | |
1291 } | |
1292 | |
1293 /* save reps for next block */ | |
1294 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); } | |
1295 } | |
1296 | |
1297 /* last literal segment */ | |
1298 { size_t const lastLLSize = litEnd - litPtr; | |
1299 if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); | |
1300 memcpy(op, litPtr, lastLLSize); | |
1301 op += lastLLSize; | |
1302 } | |
1303 | |
1304 return op-ostart; | |
1305 } | |
1306 | |
1307 | |
1308 static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, | |
1309 void* dst, size_t dstCapacity, | |
1310 const void* src, size_t srcSize) | |
1311 { /* blockType == blockCompressed */ | |
1312 const BYTE* ip = (const BYTE*)src; | |
1313 | |
1314 if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong); | |
1315 | |
1316 /* Decode literals sub-block */ | |
1317 { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); | |
1318 if (ZSTD_isError(litCSize)) return litCSize; | |
1319 ip += litCSize; | |
1320 srcSize -= litCSize; | |
1321 } | |
1322 if (dctx->fParams.windowSize > (1<<23)) return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize); | |
1323 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize); | |
1324 } | |
1325 | |
1326 | |
1036 static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) | 1327 static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) |
1037 { | 1328 { |
1038 if (dst != dctx->previousDstEnd) { /* not contiguous */ | 1329 if (dst != dctx->previousDstEnd) { /* not contiguous */ |
1039 dctx->dictEnd = dctx->previousDstEnd; | 1330 dctx->dictEnd = dctx->previousDstEnd; |
1040 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base)); | 1331 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base)); |
1041 dctx->base = dst; | 1332 dctx->base = dst; |
1042 dctx->previousDstEnd = dst; | 1333 dctx->previousDstEnd = dst; |
1043 } | 1334 } |
1044 } | 1335 } |
1045 | |
1046 | |
1047 static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, | |
1048 void* dst, size_t dstCapacity, | |
1049 const void* src, size_t srcSize) | |
1050 { /* blockType == blockCompressed */ | |
1051 const BYTE* ip = (const BYTE*)src; | |
1052 | |
1053 if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong); | |
1054 | |
1055 /* Decode literals sub-block */ | |
1056 { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); | |
1057 if (ZSTD_isError(litCSize)) return litCSize; | |
1058 ip += litCSize; | |
1059 srcSize -= litCSize; | |
1060 } | |
1061 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize); | |
1062 } | |
1063 | |
1064 | 1336 |
1065 size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, | 1337 size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, |
1066 void* dst, size_t dstCapacity, | 1338 void* dst, size_t dstCapacity, |
1067 const void* src, size_t srcSize) | 1339 const void* src, size_t srcSize) |
1068 { | 1340 { |
1504 { | 1776 { |
1505 if (ddict==NULL) return 0; /* support sizeof on NULL */ | 1777 if (ddict==NULL) return 0; /* support sizeof on NULL */ |
1506 return sizeof(*ddict) + sizeof(ddict->refContext) + ddict->dictSize; | 1778 return sizeof(*ddict) + sizeof(ddict->refContext) + ddict->dictSize; |
1507 } | 1779 } |
1508 | 1780 |
1781 /*! ZSTD_getDictID_fromDict() : | |
1782 * Provides the dictID stored within dictionary. | |
1783 * if @return == 0, the dictionary is not conformant with Zstandard specification. | |
1784 * It can still be loaded, but as a content-only dictionary. */ | |
1785 unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize) | |
1786 { | |
1787 if (dictSize < 8) return 0; | |
1788 if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return 0; | |
1789 return MEM_readLE32((const char*)dict + 4); | |
1790 } | |
1791 | |
1792 /*! ZSTD_getDictID_fromDDict() : | |
1793 * Provides the dictID of the dictionary loaded into `ddict`. | |
1794 * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. | |
1795 * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ | |
1796 unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict) | |
1797 { | |
1798 if (ddict==NULL) return 0; | |
1799 return ZSTD_getDictID_fromDict(ddict->dict, ddict->dictSize); | |
1800 } | |
1801 | |
1802 /*! ZSTD_getDictID_fromFrame() : | |
1803 * Provides the dictID required to decompressed the frame stored within `src`. | |
1804 * If @return == 0, the dictID could not be decoded. | |
1805 * This could for one of the following reasons : | |
1806 * - The frame does not require a dictionary to be decoded (most common case). | |
1807 * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. | |
1808 * Note : this use case also happens when using a non-conformant dictionary. | |
1809 * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). | |
1810 * - This is not a Zstandard frame. | |
1811 * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */ | |
1812 unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize) | |
1813 { | |
1814 ZSTD_frameParams zfp = { 0 , 0 , 0 , 0 }; | |
1815 size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize); | |
1816 if (ZSTD_isError(hError)) return 0; | |
1817 return zfp.dictID; | |
1818 } | |
1819 | |
1509 | 1820 |
1510 /*! ZSTD_decompress_usingDDict() : | 1821 /*! ZSTD_decompress_usingDDict() : |
1511 * Decompression using a pre-digested Dictionary | 1822 * Decompression using a pre-digested Dictionary |
1512 * Use dictionary without significant overhead. */ | 1823 * Use dictionary without significant overhead. */ |
1513 size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, | 1824 size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, |
1685 | 1996 |
1686 while (someMoreWork) { | 1997 while (someMoreWork) { |
1687 switch(zds->stage) | 1998 switch(zds->stage) |
1688 { | 1999 { |
1689 case zdss_init : | 2000 case zdss_init : |
1690 return ERROR(init_missing); | 2001 ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ |
2002 /* fall-through */ | |
1691 | 2003 |
1692 case zdss_loadHeader : | 2004 case zdss_loadHeader : |
1693 { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize); | 2005 { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize); |
1694 if (ZSTD_isError(hSize)) | 2006 if (ZSTD_isError(hSize)) |
1695 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) | 2007 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) |