mirror of
				https://github.com/facebook/zstd.git
				synced 2025-10-31 16:47:48 +02:00 
			
		
		
		
	added v0.4 legacy support
This commit is contained in:
		| @@ -53,7 +53,7 @@ LIBDIR ?= $(PREFIX)/lib | ||||
| INCLUDEDIR=$(PREFIX)/include | ||||
|  | ||||
| ZSTD_FILES := zstd_compress.c zstd_decompress.c fse.c huff0.c | ||||
| ZSTD_LEGACY:= legacy/zstd_v01.c legacy/zstd_v02.c legacy/zstd_v03.c | ||||
| ZSTD_LEGACY:= legacy/zstd_v01.c legacy/zstd_v02.c legacy/zstd_v03.c legacy/zstd_v04.c | ||||
|  | ||||
| ifeq ($(ZSTD_LEGACY_SUPPORT), 0) | ||||
| CPPFLAGS  += -DZSTD_LEGACY_SUPPORT=0 | ||||
|   | ||||
| @@ -45,6 +45,7 @@ extern "C" { | ||||
| #include "zstd_v01.h" | ||||
| #include "zstd_v02.h" | ||||
| #include "zstd_v03.h" | ||||
| #include "zstd_v04.h" | ||||
|  | ||||
| MEM_STATIC unsigned ZSTD_isLegacy (U32 magicNumberLE) | ||||
| { | ||||
| @@ -52,7 +53,8 @@ MEM_STATIC unsigned ZSTD_isLegacy (U32 magicNumberLE) | ||||
| 	{ | ||||
| 		case ZSTDv01_magicNumberLE : | ||||
| 		case ZSTDv02_magicNumber : | ||||
| 		case ZSTDv03_magicNumber : return 1; | ||||
| 		case ZSTDv03_magicNumber :  | ||||
| 		case ZSTDv04_magicNumber : return 1; | ||||
| 		default : return 0; | ||||
| 	} | ||||
| } | ||||
| @@ -71,6 +73,8 @@ MEM_STATIC size_t ZSTD_decompressLegacy( | ||||
| 			return ZSTDv02_decompress(dst, maxOriginalSize, src, compressedSize); | ||||
| 		case ZSTDv03_magicNumber : | ||||
| 			return ZSTDv03_decompress(dst, maxOriginalSize, src, compressedSize); | ||||
| 		case ZSTDv04_magicNumber : | ||||
| 			return ZSTDv04_decompress(dst, maxOriginalSize, src, compressedSize); | ||||
| 		default : | ||||
| 		    return ERROR(prefix_unknown); | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										4431
									
								
								lib/legacy/zstd_v04.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4431
									
								
								lib/legacy/zstd_v04.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										148
									
								
								lib/legacy/zstd_v04.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								lib/legacy/zstd_v04.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| /* | ||||
|     zstd_v04 - decoder for 0.4 format | ||||
|     Header File | ||||
|     Copyright (C) 2016, Yann Collet. | ||||
|  | ||||
|     BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) | ||||
|  | ||||
|     Redistribution and use in source and binary forms, with or without | ||||
|     modification, are permitted provided that the following conditions are | ||||
|     met: | ||||
|     * Redistributions of source code must retain the above copyright | ||||
|     notice, this list of conditions and the following disclaimer. | ||||
|     * Redistributions in binary form must reproduce the above | ||||
|     copyright notice, this list of conditions and the following disclaimer | ||||
|     in the documentation and/or other materials provided with the | ||||
|     distribution. | ||||
|     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
|     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
|     A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
|     OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
|     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
|     LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
|     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
|     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
|     You can contact the author at : | ||||
|     - zstd source repository : https://github.com/Cyan4973/zstd | ||||
|     - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c | ||||
| */ | ||||
| #pragma once | ||||
|  | ||||
| #if defined (__cplusplus) | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| /* ************************************* | ||||
| *  Includes | ||||
| ***************************************/ | ||||
| #include <stddef.h>   /* size_t */ | ||||
|  | ||||
|  | ||||
| /* ************************************* | ||||
| *  Simple one-step function | ||||
| ***************************************/ | ||||
| /** | ||||
| ZSTDv04_decompress() : decompress ZSTD frames compliant with v0.4.x format | ||||
|     compressedSize : is the exact source size | ||||
|     maxOriginalSize : is the size of the 'dst' buffer, which must be already allocated. | ||||
|                       It must be equal or larger than originalSize, otherwise decompression will fail. | ||||
|     return : the number of bytes decompressed into destination buffer (originalSize) | ||||
|              or an errorCode if it fails (which can be tested using ZSTDv01_isError()) | ||||
| */ | ||||
| size_t ZSTDv04_decompress( void* dst, size_t maxOriginalSize, | ||||
|                      const void* src, size_t compressedSize); | ||||
|  | ||||
| /** | ||||
| ZSTDv04_isError() : tells if the result of ZSTDv04_decompress() is an error | ||||
| */ | ||||
| unsigned ZSTDv04_isError(size_t code); | ||||
|  | ||||
|  | ||||
| /* ************************************* | ||||
| *  Advanced functions | ||||
| ***************************************/ | ||||
| typedef struct ZSTDv04_Dctx_s ZSTDv04_Dctx; | ||||
| ZSTDv04_Dctx* ZSTDv04_createDCtx(void); | ||||
| size_t ZSTDv04_freeDCtx(ZSTDv04_Dctx* dctx); | ||||
|  | ||||
| size_t ZSTDv04_decompressDCtx(ZSTDv04_Dctx* dctx, | ||||
|                               void* dst, size_t maxOriginalSize, | ||||
|                         const void* src, size_t compressedSize); | ||||
|  | ||||
|  | ||||
| /* ************************************* | ||||
| *  Direct Streaming | ||||
| ***************************************/ | ||||
| size_t ZSTDv04_resetDCtx(ZSTDv04_Dctx* dctx); | ||||
|  | ||||
| size_t ZSTDv04_nextSrcSizeToDecompress(ZSTDv04_Dctx* dctx); | ||||
| size_t ZSTDv04_decompressContinue(ZSTDv04_Dctx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize); | ||||
| /** | ||||
|   Use above functions alternatively. | ||||
|   ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue(). | ||||
|   ZSTD_decompressContinue() will use previous data blocks to improve compression if they are located prior to current block. | ||||
|   Result is the number of bytes regenerated within 'dst'. | ||||
|   It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header. | ||||
| */ | ||||
|  | ||||
|  | ||||
| /* ************************************* | ||||
| *  Buffered Streaming | ||||
| ***************************************/ | ||||
| typedef struct ZBUFFv04_DCtx_s ZBUFFv04_DCtx; | ||||
| ZBUFFv04_DCtx* ZBUFFv04_createDCtx(void); | ||||
| size_t      ZBUFFv04_freeDCtx(ZBUFFv04_DCtx* dctx); | ||||
|  | ||||
| size_t ZBUFFv04_decompressInit(ZBUFFv04_DCtx* dctx); | ||||
| size_t ZBUFFv04_decompressWithDictionary(ZBUFFv04_DCtx* dctx, const void* dict, size_t dictSize); | ||||
|  | ||||
| size_t ZBUFFv04_decompressContinue(ZBUFFv04_DCtx* dctx, void* dst, size_t* maxDstSizePtr, const void* src, size_t* srcSizePtr); | ||||
|  | ||||
| /** ************************************************ | ||||
| *  Streaming decompression | ||||
| * | ||||
| *  A ZBUFF_DCtx object is required to track streaming operation. | ||||
| *  Use ZBUFF_createDCtx() and ZBUFF_freeDCtx() to create/release resources. | ||||
| *  Use ZBUFF_decompressInit() to start a new decompression operation. | ||||
| *  ZBUFF_DCtx objects can be reused multiple times. | ||||
| * | ||||
| *  Optionally, a reference to a static dictionary can be set, using ZBUFF_decompressWithDictionary() | ||||
| *  It must be the same content as the one set during compression phase. | ||||
| *  Dictionary content must remain accessible during the decompression process. | ||||
| * | ||||
| *  Use ZBUFF_decompressContinue() repetitively to consume your input. | ||||
| *  *srcSizePtr and *maxDstSizePtr can be any size. | ||||
| *  The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr. | ||||
| *  Note that it may not consume the entire input, in which case it's up to the caller to present remaining input again. | ||||
| *  The content of dst will be overwritten (up to *maxDstSizePtr) at each function call, so save its content if it matters or change dst. | ||||
| *  @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to improve latency) | ||||
| *            or 0 when a frame is completely decoded | ||||
| *            or an error code, which can be tested using ZBUFF_isError(). | ||||
| * | ||||
| *  Hint : recommended buffer sizes (not compulsory) : ZBUFF_recommendedDInSize / ZBUFF_recommendedDOutSize | ||||
| *  output : ZBUFF_recommendedDOutSize==128 KB block size is the internal unit, it ensures it's always possible to write a full block when it's decoded. | ||||
| *  input : ZBUFF_recommendedDInSize==128Kb+3; just follow indications from ZBUFF_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 . | ||||
| * **************************************************/ | ||||
| unsigned ZBUFFv04_isError(size_t errorCode); | ||||
| const char* ZBUFFv04_getErrorName(size_t errorCode); | ||||
|  | ||||
|  | ||||
| /** The below functions provide recommended buffer sizes for Compression or Decompression operations. | ||||
| *   These sizes are not compulsory, they just tend to offer better latency */ | ||||
| size_t ZBUFFv04_recommendedDInSize(void); | ||||
| size_t ZBUFFv04_recommendedDOutSize(void); | ||||
|  | ||||
|  | ||||
| /* ************************************* | ||||
| *  Prefix - version detection | ||||
| ***************************************/ | ||||
| #define ZSTDv04_magicNumber 0xFD2FB524   /* v0.4 */ | ||||
|  | ||||
|  | ||||
| #if defined (__cplusplus) | ||||
| } | ||||
| #endif | ||||
| @@ -53,7 +53,7 @@ MANDIR  = $(PREFIX)/share/man/man1 | ||||
| ZSTDDIR = ../lib | ||||
|  | ||||
| ZSTD_FILES := $(ZSTDDIR)/zstd_compress.c $(ZSTDDIR)/zstd_decompress.c $(ZSTDDIR)/fse.c $(ZSTDDIR)/huff0.c | ||||
| ZSTD_LEGACY:= $(ZSTDDIR)/legacy/zstd_v01.c $(ZSTDDIR)/legacy/zstd_v02.c $(ZSTDDIR)/legacy/zstd_v03.c | ||||
| ZSTD_LEGACY:= $(ZSTDDIR)/legacy/zstd_v01.c $(ZSTDDIR)/legacy/zstd_v02.c $(ZSTDDIR)/legacy/zstd_v03.c $(ZSTDDIR)/legacy/zstd_v04.c | ||||
|  | ||||
| ifeq ($(ZSTD_LEGACY_SUPPORT), 0) | ||||
| CPPFLAGS  += -DZSTD_LEGACY_SUPPORT=0 | ||||
|   | ||||
| @@ -568,7 +568,7 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit | ||||
|         errorCode = ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, (FUZ_rand(&lseed) % (20 - (sampleSizeLog/3))) + 1); | ||||
|         CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_usingDict error : %s", ZSTD_getErrorName(errorCode)); | ||||
|         errorCode = ZSTD_copyCCtx(ctx, refCtx); | ||||
|         CHECK (ZSTD_isError(errorCode), "context duplication error : %s", ZSTD_getErrorName(errorCode)); | ||||
|         CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode)); | ||||
|         totalTestSize = 0; cSize = 0; | ||||
|         for (n=0; n<nbChunks; n++) | ||||
|         { | ||||
|   | ||||
| @@ -329,6 +329,86 @@ unsigned long long FIOv03_decompressFrame(FILE* foutput, FILE* finput) | ||||
| } | ||||
|  | ||||
|  | ||||
| /*- v0.4.x -*/ | ||||
|  | ||||
| typedef struct { | ||||
|     void*  srcBuffer; | ||||
|     size_t srcBufferSize; | ||||
|     void*  dstBuffer; | ||||
|     size_t dstBufferSize; | ||||
|     void*  dictBuffer; | ||||
|     size_t dictBufferSize; | ||||
|     ZBUFFv04_DCtx* dctx; | ||||
| } dRessv04_t; | ||||
|  | ||||
| static dRessv04_t FIOv04_createDResources(void) | ||||
| { | ||||
|     dRessv04_t ress; | ||||
|  | ||||
|     /* init */ | ||||
|     ress.dctx = ZBUFFv04_createDCtx(); | ||||
|     if (ress.dctx==NULL) EXM_THROW(60, "Can't create ZBUFF decompression context"); | ||||
|     ress.dictBuffer = NULL; ress.dictBufferSize=0; | ||||
|  | ||||
|     /* Allocate Memory */ | ||||
|     ress.srcBufferSize = ZBUFFv04_recommendedDInSize(); | ||||
|     ress.srcBuffer = malloc(ress.srcBufferSize); | ||||
|     ress.dstBufferSize = ZBUFFv04_recommendedDOutSize(); | ||||
|     ress.dstBuffer = malloc(ress.dstBufferSize); | ||||
|     if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(61, "Allocation error : not enough memory"); | ||||
|  | ||||
|     return ress; | ||||
| } | ||||
|  | ||||
| static void FIOv04_freeDResources(dRessv04_t ress) | ||||
| { | ||||
|     size_t errorCode = ZBUFFv04_freeDCtx(ress.dctx); | ||||
|     if (ZBUFFv04_isError(errorCode)) EXM_THROW(69, "Error : can't free ZBUFF context resource : %s", ZBUFFv04_getErrorName(errorCode)); | ||||
|     free(ress.srcBuffer); | ||||
|     free(ress.dstBuffer); | ||||
|     free(ress.dictBuffer); | ||||
| } | ||||
|  | ||||
|  | ||||
| unsigned long long FIOv04_decompressFrame(dRessv04_t ress, | ||||
|                                           FILE* foutput, FILE* finput) | ||||
| { | ||||
|     U64    frameSize = 0; | ||||
|     size_t readSize = 4; | ||||
|  | ||||
|     MEM_writeLE32(ress.srcBuffer, ZSTDv04_magicNumber); | ||||
|     ZBUFFv04_decompressInit(ress.dctx); | ||||
|     ZBUFFv04_decompressWithDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize); | ||||
|  | ||||
|     while (1) | ||||
|     { | ||||
|         /* Decode */ | ||||
|         size_t sizeCheck; | ||||
|         size_t inSize=readSize, decodedSize=ress.dstBufferSize; | ||||
|         size_t toRead = ZBUFFv04_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &inSize); | ||||
|         if (ZBUFFv04_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZBUFFv04_getErrorName(toRead)); | ||||
|         readSize -= inSize; | ||||
|  | ||||
|         /* Write block */ | ||||
|         sizeCheck = fwrite(ress.dstBuffer, 1, decodedSize, foutput); | ||||
|         if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block to destination file"); | ||||
|         frameSize += decodedSize; | ||||
|         DISPLAYUPDATE(2, "\rDecoded : %u MB...     ", (U32)(frameSize>>20) ); | ||||
|  | ||||
|         if (toRead == 0) break; | ||||
|         if (readSize) EXM_THROW(38, "Decoding error : should consume entire input"); | ||||
|  | ||||
|         /* Fill input buffer */ | ||||
|         if (toRead > ress.srcBufferSize) EXM_THROW(34, "too large block"); | ||||
|         readSize = fread(ress.srcBuffer, 1, toRead, finput); | ||||
|         if (readSize != toRead) EXM_THROW(35, "Read error"); | ||||
|     } | ||||
|  | ||||
|     FIOv04_freeDResources(ress); | ||||
|     return frameSize; | ||||
| } | ||||
|  | ||||
|  | ||||
| unsigned long long FIO_decompressLegacyFrame(FILE* foutput, FILE* finput, U32 magicNumberLE) | ||||
| { | ||||
| 	switch(magicNumberLE) | ||||
| @@ -339,6 +419,8 @@ unsigned long long FIO_decompressLegacyFrame(FILE* foutput, FILE* finput, U32 ma | ||||
| 			return FIOv02_decompressFrame(foutput, finput); | ||||
| 		case ZSTDv03_magicNumber : | ||||
| 			return FIOv03_decompressFrame(foutput, finput); | ||||
| 		case ZSTDv04_magicNumber : | ||||
| 			return FIOv04_decompressFrame(FIOv04_createDResources(), foutput, finput); | ||||
| 		default : | ||||
| 		    return ERROR(prefix_unknown); | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user