1f66721d303a6141797ee1e04067a007aa0392dafYann Collet/*
2f66721d303a6141797ee1e04067a007aa0392dafYann Collet    frameTest - test tool for lz4frame
391cce757f521b99fe9bb558d80e76c9419eec6a1Yann Collet    Copyright (C) Yann Collet 2014-2016
4bbcfe2144d1021c8662ba632dfd91403060becd4Yann Collet
5f66721d303a6141797ee1e04067a007aa0392dafYann Collet    GPL v2 License
6f66721d303a6141797ee1e04067a007aa0392dafYann Collet
7f66721d303a6141797ee1e04067a007aa0392dafYann Collet    This program is free software; you can redistribute it and/or modify
8f66721d303a6141797ee1e04067a007aa0392dafYann Collet    it under the terms of the GNU General Public License as published by
9f66721d303a6141797ee1e04067a007aa0392dafYann Collet    the Free Software Foundation; either version 2 of the License, or
10f66721d303a6141797ee1e04067a007aa0392dafYann Collet    (at your option) any later version.
11f66721d303a6141797ee1e04067a007aa0392dafYann Collet
12f66721d303a6141797ee1e04067a007aa0392dafYann Collet    This program is distributed in the hope that it will be useful,
13f66721d303a6141797ee1e04067a007aa0392dafYann Collet    but WITHOUT ANY WARRANTY; without even the implied warranty of
14f66721d303a6141797ee1e04067a007aa0392dafYann Collet    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15f66721d303a6141797ee1e04067a007aa0392dafYann Collet    GNU General Public License for more details.
16f66721d303a6141797ee1e04067a007aa0392dafYann Collet
17f66721d303a6141797ee1e04067a007aa0392dafYann Collet    You should have received a copy of the GNU General Public License along
18f66721d303a6141797ee1e04067a007aa0392dafYann Collet    with this program; if not, write to the Free Software Foundation, Inc.,
19f66721d303a6141797ee1e04067a007aa0392dafYann Collet    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20f66721d303a6141797ee1e04067a007aa0392dafYann Collet
21f66721d303a6141797ee1e04067a007aa0392dafYann Collet    You can contact the author at :
2291cce757f521b99fe9bb558d80e76c9419eec6a1Yann Collet    - LZ4 homepage : http://www.lz4.org
2384cedb4632ab87fbb108b4f7ed6e9ec164b6a4d4Przemyslaw Skibinski    - LZ4 source repository : https://github.com/lz4/lz4
24f66721d303a6141797ee1e04067a007aa0392dafYann Collet*/
25f66721d303a6141797ee1e04067a007aa0392dafYann Collet
2691cce757f521b99fe9bb558d80e76c9419eec6a1Yann Collet/*-************************************
2732a85fc76d3da9345c2e49ce33a9d8d1e79dfa1fYann Collet*  Compiler specific
28f66721d303a6141797ee1e04067a007aa0392dafYann Collet**************************************/
29f66721d303a6141797ee1e04067a007aa0392dafYann Collet#ifdef _MSC_VER    /* Visual Studio */
30f66721d303a6141797ee1e04067a007aa0392dafYann Collet#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
31f66721d303a6141797ee1e04067a007aa0392dafYann Collet#  pragma warning(disable : 4146)        /* disable: C4146: minus unsigned expression */
32f66721d303a6141797ee1e04067a007aa0392dafYann Collet#endif
33f66721d303a6141797ee1e04067a007aa0392dafYann Collet
34f66721d303a6141797ee1e04067a007aa0392dafYann Collet
3591cce757f521b99fe9bb558d80e76c9419eec6a1Yann Collet/*-************************************
3632a85fc76d3da9345c2e49ce33a9d8d1e79dfa1fYann Collet*  Includes
37f66721d303a6141797ee1e04067a007aa0392dafYann Collet**************************************/
389546ba62d01a9618aab91eafe77929120653d275Przemyslaw Skibinski#include "util.h"       /* U32 */
393a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet#include <stdlib.h>     /* malloc, free */
403a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet#include <stdio.h>      /* fprintf */
413a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet#include <string.h>     /* strcmp */
42dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet#include <time.h>       /* clock_t, clock(), CLOCKS_PER_SEC */
43daa320f3f7bd9cc121462ef7a201fad87f540bd6Yann Collet#include "lz4frame_static.h"
44dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet#include "lz4.h"        /* LZ4_VERSION_STRING */
4591cce757f521b99fe9bb558d80e76c9419eec6a1Yann Collet#define XXH_STATIC_LINKING_ONLY
463a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet#include "xxhash.h"     /* XXH64 */
47f66721d303a6141797ee1e04067a007aa0392dafYann Collet
48f66721d303a6141797ee1e04067a007aa0392dafYann Collet
493a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet/* unoptimized version; solves endianess & alignment issues */
503a6832497ba02607dd4ede3a3fd30911e06f037eYann Colletstatic void FUZ_writeLE32 (void* dstVoidPtr, U32 value32)
513a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet{
523a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet    BYTE* dstPtr = (BYTE*)dstVoidPtr;
533a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet    dstPtr[0] = (BYTE)value32;
543a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet    dstPtr[1] = (BYTE)(value32 >> 8);
553a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet    dstPtr[2] = (BYTE)(value32 >> 16);
563a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet    dstPtr[3] = (BYTE)(value32 >> 24);
573a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet}
583a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet
593a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet
60b130fd59233925d6f8603d18270c3219e7672985Yann Collet/*-************************************
6132a85fc76d3da9345c2e49ce33a9d8d1e79dfa1fYann Collet*  Constants
62f66721d303a6141797ee1e04067a007aa0392dafYann Collet**************************************/
633a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet#define LZ4F_MAGIC_SKIPPABLE_START 0x184D2A50U
643a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet
65f7f67e778c9261fa5843811068f3eb3cc4e70509Yann Collet#define KB *(1U<<10)
66f7f67e778c9261fa5843811068f3eb3cc4e70509Yann Collet#define MB *(1U<<20)
67f7f67e778c9261fa5843811068f3eb3cc4e70509Yann Collet#define GB *(1U<<30)
68f7f67e778c9261fa5843811068f3eb3cc4e70509Yann Collet
69e468a4eb96ec8e2ea0fc61b5aa20f56a3b214c0eYann Colletstatic const U32 nbTestsDefault = 256 KB;
70f7f67e778c9261fa5843811068f3eb3cc4e70509Yann Collet#define COMPRESSIBLE_NOISE_LENGTH (2 MB)
71f66721d303a6141797ee1e04067a007aa0392dafYann Collet#define FUZ_COMPRESSIBILITY_DEFAULT 50
72535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Colletstatic const U32 prime1 = 2654435761U;
73535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Colletstatic const U32 prime2 = 2246822519U;
74f66721d303a6141797ee1e04067a007aa0392dafYann Collet
75f66721d303a6141797ee1e04067a007aa0392dafYann Collet
76f66721d303a6141797ee1e04067a007aa0392dafYann Collet
77b130fd59233925d6f8603d18270c3219e7672985Yann Collet/*-************************************
783a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet*  Macros
79f66721d303a6141797ee1e04067a007aa0392dafYann Collet**************************************/
80fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet#define DISPLAY(...)          fprintf(stderr, __VA_ARGS__)
81fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet#define DISPLAYLEVEL(l, ...)  if (displayLevel>=l) { DISPLAY(__VA_ARGS__); }
8203bc760af361ae95187a8d3475be362293328884Yann Collet#define DISPLAYUPDATE(l, ...) if (displayLevel>=l) { \
83dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet            if ((FUZ_GetClockSpan(g_clockTime) > refreshRate) || (displayLevel>=4)) \
84dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet            { g_clockTime = clock(); DISPLAY(__VA_ARGS__); \
8503bc760af361ae95187a8d3475be362293328884Yann Collet            if (displayLevel>=4) fflush(stdout); } }
86dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Colletstatic const clock_t refreshRate = CLOCKS_PER_SEC / 6;
87dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Colletstatic clock_t g_clockTime = 0;
88f66721d303a6141797ee1e04067a007aa0392dafYann Collet
89f66721d303a6141797ee1e04067a007aa0392dafYann Collet
90b130fd59233925d6f8603d18270c3219e7672985Yann Collet/*-***************************************
913a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet*  Local Parameters
92f66721d303a6141797ee1e04067a007aa0392dafYann Collet*****************************************/
9303bc760af361ae95187a8d3475be362293328884Yann Colletstatic U32 no_prompt = 0;
9403bc760af361ae95187a8d3475be362293328884Yann Colletstatic U32 displayLevel = 2;
9564cbc4e1dc17492d89915a9d774dc15ee438ccfePrzemyslaw Skibinskistatic U32 use_pause = 0;
96f66721d303a6141797ee1e04067a007aa0392dafYann Collet
97f66721d303a6141797ee1e04067a007aa0392dafYann Collet
98b130fd59233925d6f8603d18270c3219e7672985Yann Collet/*-*******************************************************
9932a85fc76d3da9345c2e49ce33a9d8d1e79dfa1fYann Collet*  Fuzzer functions
100f66721d303a6141797ee1e04067a007aa0392dafYann Collet*********************************************************/
101bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet#define MIN(a,b)  ( (a) < (b) ? (a) : (b) )
102bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet#define MAX(a,b)  ( (a) > (b) ? (a) : (b) )
103bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet
104dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Colletstatic clock_t FUZ_GetClockSpan(clock_t clockStart)
105f66721d303a6141797ee1e04067a007aa0392dafYann Collet{
106dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet    return clock() - clockStart;   /* works even if overflow; max span ~ 30 mn */
107f66721d303a6141797ee1e04067a007aa0392dafYann Collet}
108f66721d303a6141797ee1e04067a007aa0392dafYann Collet
10932a85fc76d3da9345c2e49ce33a9d8d1e79dfa1fYann Collet
110dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet#define FUZ_rotl32(x,r) ((x << r) | (x >> (32 - r)))
111f66721d303a6141797ee1e04067a007aa0392dafYann Colletunsigned int FUZ_rand(unsigned int* src)
112f66721d303a6141797ee1e04067a007aa0392dafYann Collet{
113f66721d303a6141797ee1e04067a007aa0392dafYann Collet    U32 rand32 = *src;
114535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet    rand32 *= prime1;
115535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet    rand32 += prime2;
116f66721d303a6141797ee1e04067a007aa0392dafYann Collet    rand32  = FUZ_rotl32(rand32, 13);
117f66721d303a6141797ee1e04067a007aa0392dafYann Collet    *src = rand32;
118fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet    return rand32 >> 5;
119f66721d303a6141797ee1e04067a007aa0392dafYann Collet}
120f66721d303a6141797ee1e04067a007aa0392dafYann Collet
121f66721d303a6141797ee1e04067a007aa0392dafYann Collet
122fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet#define FUZ_RAND15BITS  (FUZ_rand(seed) & 0x7FFF)
123fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet#define FUZ_RANDLENGTH  ( (FUZ_rand(seed) & 3) ? (FUZ_rand(seed) % 15) : (FUZ_rand(seed) % 510) + 15)
1241b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Colletstatic void FUZ_fillCompressibleNoiseBuffer(void* buffer, size_t bufferSize, double proba, U32* seed)
125f66721d303a6141797ee1e04067a007aa0392dafYann Collet{
126f66721d303a6141797ee1e04067a007aa0392dafYann Collet    BYTE* BBuffer = (BYTE*)buffer;
1271b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet    size_t pos = 0;
128f66721d303a6141797ee1e04067a007aa0392dafYann Collet    U32 P32 = (U32)(32768 * proba);
129f66721d303a6141797ee1e04067a007aa0392dafYann Collet
1303a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet    /* First Byte */
131f66721d303a6141797ee1e04067a007aa0392dafYann Collet    BBuffer[pos++] = (BYTE)(FUZ_rand(seed));
132f66721d303a6141797ee1e04067a007aa0392dafYann Collet
133b130fd59233925d6f8603d18270c3219e7672985Yann Collet    while (pos < bufferSize) {
1343a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        /* Select : Literal (noise) or copy (within 64K) */
135b130fd59233925d6f8603d18270c3219e7672985Yann Collet        if (FUZ_RAND15BITS < P32) {
1363a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            /* Copy (within 64K) */
1371b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t const lengthRand = FUZ_RANDLENGTH + 4;
1381b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t const length = MIN(lengthRand, bufferSize - pos);
1391b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t const end = pos + length;
1401b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t const offsetRand = FUZ_RAND15BITS + 1;
1411b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t const offset = MIN(offsetRand, pos);
1421b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t match = pos - offset;
1432f33c77d53793cc025ed9484870c9a2b0c879261Yann Collet            while (pos < end) BBuffer[pos++] = BBuffer[match++];
144b130fd59233925d6f8603d18270c3219e7672985Yann Collet        } else {
1453a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            /* Literal (noise) */
1461b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t const lengthRand = FUZ_RANDLENGTH + 4;
1471b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t const length = MIN(lengthRand, bufferSize - pos);
1481b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet            size_t const end = pos + length;
1492f33c77d53793cc025ed9484870c9a2b0c879261Yann Collet            while (pos < end) BBuffer[pos++] = (BYTE)(FUZ_rand(seed) >> 5);
150f66721d303a6141797ee1e04067a007aa0392dafYann Collet        }
151f66721d303a6141797ee1e04067a007aa0392dafYann Collet    }
152f66721d303a6141797ee1e04067a007aa0392dafYann Collet}
153f66721d303a6141797ee1e04067a007aa0392dafYann Collet
154f66721d303a6141797ee1e04067a007aa0392dafYann Collet
155fd8665320fe03f9f61d438a3cc81502406859c2aYann Colletstatic unsigned FUZ_highbit(U32 v32)
156fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet{
157fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet    unsigned nbBits = 0;
158fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet    if (v32==0) return 0;
1592ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    while (v32) v32 >>= 1, nbBits ++;
160fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet    return nbBits;
161fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet}
162f66721d303a6141797ee1e04067a007aa0392dafYann Collet
163fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
164bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet/*-*******************************************************
165bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet*  Tests
166bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet*********************************************************/
167b1d022fa72b75af8fb373e26ac8d2f0f14a9e6feYann Colletint basicTests(U32 seed, double compressibility)
168f66721d303a6141797ee1e04067a007aa0392dafYann Collet{
1698c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    int testResult = 0;
170bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    void* const CNBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
171bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    size_t const cBuffSize = LZ4F_compressFrameBound(COMPRESSIBLE_NOISE_LENGTH, NULL);
172bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    void* const compressedBuffer = malloc(cBuffSize);
173bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    void* const decodedBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
1748c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    U32 randState = seed;
1758c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    size_t cSize, testSize;
17662ed15319570d80690915f0d0dba0dc2e9478631Yann Collet    LZ4F_decompressionContext_t dCtx = NULL;
17762ed15319570d80690915f0d0dba0dc2e9478631Yann Collet    LZ4F_compressionContext_t cctx = NULL;
1788c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    U64 crcOrig;
1798c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
180bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    LZ4F_preferences_t prefs;
181ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet    memset(&prefs, 0, sizeof(prefs));
182bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    if (!CNBuffer || !compressedBuffer || !decodedBuffer) {
183bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        DISPLAY("allocation error, not enough memory to start fuzzer tests \n");
184bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        goto _output_error;
185bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    }
1868c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    FUZ_fillCompressibleNoiseBuffer(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, &randState);
1878c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    crcOrig = XXH64(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, 1);
1888c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
1897cf0bb97b2a988cb17435780d19e145147dd9f70Yann Collet    /* LZ4F_compressBound() : special case : srcSize == 0 */
1907cf0bb97b2a988cb17435780d19e145147dd9f70Yann Collet    DISPLAYLEVEL(3, "LZ4F_compressBound(0) = ");
1917cf0bb97b2a988cb17435780d19e145147dd9f70Yann Collet    {   size_t const cBound = LZ4F_compressBound(0, NULL);
1927cf0bb97b2a988cb17435780d19e145147dd9f70Yann Collet        if (cBound < 64 KB) goto _output_error;
1937cf0bb97b2a988cb17435780d19e145147dd9f70Yann Collet        DISPLAYLEVEL(3, " %u \n", (U32)cBound);
1947cf0bb97b2a988cb17435780d19e145147dd9f70Yann Collet    }
1957cf0bb97b2a988cb17435780d19e145147dd9f70Yann Collet
1962ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    /* Special case : null-content frame */
1972ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    testSize = 0;
1982ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    DISPLAYLEVEL(3, "LZ4F_compressFrame, compress null content : \n");
1992ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(testSize, NULL), CNBuffer, testSize, NULL);
2002ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    if (LZ4F_isError(cSize)) goto _output_error;
2012ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    DISPLAYLEVEL(3, "Compressed null content into a %i bytes frame \n", (int)cSize);
2022ac9ecec685f720876aa2e12277b06f53de03682Yann Collet
2032ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    DISPLAYLEVEL(3, "LZ4F_createDecompressionContext \n");
2042ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    { LZ4F_errorCode_t const errorCode = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
2052ac9ecec685f720876aa2e12277b06f53de03682Yann Collet      if (LZ4F_isError(errorCode)) goto _output_error; }
2062ac9ecec685f720876aa2e12277b06f53de03682Yann Collet
2072ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    DISPLAYLEVEL(3, "LZ4F_getFrameInfo on null-content frame (#157) \n");
2082ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    {   size_t avail_in = cSize;
2092ac9ecec685f720876aa2e12277b06f53de03682Yann Collet        LZ4F_frameInfo_t frame_info;
2102ac9ecec685f720876aa2e12277b06f53de03682Yann Collet        LZ4F_errorCode_t const errorCode = LZ4F_getFrameInfo(dCtx, &frame_info, compressedBuffer, &avail_in);
2112ac9ecec685f720876aa2e12277b06f53de03682Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
2122ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    }
2132ac9ecec685f720876aa2e12277b06f53de03682Yann Collet
2142ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    DISPLAYLEVEL(3, "LZ4F_freeDecompressionContext \n");
2152ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    { LZ4F_errorCode_t const errorCode = LZ4F_freeDecompressionContext(dCtx);
2162ac9ecec685f720876aa2e12277b06f53de03682Yann Collet      if (LZ4F_isError(errorCode)) goto _output_error; }
217bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    dCtx = NULL;
2182ac9ecec685f720876aa2e12277b06f53de03682Yann Collet
219bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    /* test one-pass frame compression */
2208c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    testSize = COMPRESSIBLE_NOISE_LENGTH;
2212ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    DISPLAYLEVEL(3, "LZ4F_compressFrame, using default preferences : \n");
2228c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(testSize, NULL), CNBuffer, testSize, NULL);
2238c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    if (LZ4F_isError(cSize)) goto _output_error;
224bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    DISPLAYLEVEL(3, "Compressed %u bytes into a %u bytes frame \n", (U32)testSize, (U32)cSize);
2258c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
2268c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Decompression test : \n");
2272ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    {   size_t decodedBufferSize = COMPRESSIBLE_NOISE_LENGTH;
228e619cfe8525f16d382fad1c569c1b71b25ac3d1dYann Collet        size_t compressedBufferSize = cSize;
229b03f8f0e6f40d17740685e50332b8eedb5117cecYann Collet        BYTE* ip = (BYTE*)compressedBuffer;
230b03f8f0e6f40d17740685e50332b8eedb5117cecYann Collet        BYTE* const iend = (BYTE*)compressedBuffer + cSize;
231fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
232fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet        LZ4F_errorCode_t errorCode = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
233e619cfe8525f16d382fad1c569c1b71b25ac3d1dYann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
234b03f8f0e6f40d17740685e50332b8eedb5117cecYann Collet
235bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        DISPLAYLEVEL(3, "Single Pass decompression : \n");
236bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        { size_t const decompressError = LZ4F_decompress(dCtx, decodedBuffer, &decodedBufferSize, compressedBuffer, &compressedBufferSize, NULL);
237bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet          if (LZ4F_isError(decompressError)) goto _output_error; }
238bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        { U64 const crcDest = XXH64(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, 1);
239bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet          if (crcDest != crcOrig) goto _output_error; }
240bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        DISPLAYLEVEL(3, "Regenerated %u bytes \n", (U32)decodedBufferSize);
241b03f8f0e6f40d17740685e50332b8eedb5117cecYann Collet
2422ac9ecec685f720876aa2e12277b06f53de03682Yann Collet        DISPLAYLEVEL(3, "Reusing decompression context \n");
243bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        {   size_t const missingBytes = 4;
244bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            size_t iSize = compressedBufferSize - missingBytes;
245e18aa907985da9ccbeb1684517d0f8e77e189984Yann Collet            const BYTE* cBuff = (const BYTE*) compressedBuffer;
246bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            BYTE* const ostart = (BYTE*)decodedBuffer;
247bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            BYTE* op = ostart;
248bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            BYTE* const oend = (BYTE*)decodedBuffer + COMPRESSIBLE_NOISE_LENGTH;
249bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            size_t decResult, oSize = COMPRESSIBLE_NOISE_LENGTH;
250bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            DISPLAYLEVEL(3, "Missing last %u bytes : ", (U32)missingBytes);
251bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            decResult = LZ4F_decompress(dCtx, op, &oSize, cBuff, &iSize, NULL);
2522ac9ecec685f720876aa2e12277b06f53de03682Yann Collet            if (LZ4F_isError(decResult)) goto _output_error;
253bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            if (decResult != missingBytes) {
254bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                DISPLAY("%u bytes missing != %u bytes requested \n", (U32)missingBytes, (U32)decResult);
255bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                goto _output_error;
256bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            }
257bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            DISPLAYLEVEL(3, "indeed, requests %u bytes \n", (unsigned)decResult);
258e18aa907985da9ccbeb1684517d0f8e77e189984Yann Collet            cBuff += iSize;
2592ac9ecec685f720876aa2e12277b06f53de03682Yann Collet            iSize = decResult;
260bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            op += oSize;
261bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            oSize = (size_t)(oend-op);
262bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            decResult = LZ4F_decompress(dCtx, op, &oSize, cBuff, &iSize, NULL);
2632ac9ecec685f720876aa2e12277b06f53de03682Yann Collet            if (decResult != 0) goto _output_error;   /* should finish now */
264bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            op += oSize;
265bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            if (op>oend) { DISPLAY("decompression write overflow \n"); goto _output_error; }
266bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            {   U64 const crcDest = XXH64(decodedBuffer, op-ostart, 1);
267bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                if (crcDest != crcOrig) goto _output_error;
268bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        }   }
269197982ec6cf449734f78d849ed4a845e075b2cf4Yann Collet
270b130fd59233925d6f8603d18270c3219e7672985Yann Collet        {   size_t oSize = 0;
271409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            size_t iSize = 0;
272409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            LZ4F_frameInfo_t fi;
273409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet
274409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            DISPLAYLEVEL(3, "Start by feeding 0 bytes, to get next input size : ");
275409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            errorCode = LZ4F_decompress(dCtx, NULL, &oSize, ip, &iSize, NULL);
276409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            if (LZ4F_isError(errorCode)) goto _output_error;
277409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            DISPLAYLEVEL(3, " %u  \n", (unsigned)errorCode);
278409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet
279409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            DISPLAYLEVEL(3, "get FrameInfo on null input : ");
280409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            errorCode = LZ4F_getFrameInfo(dCtx, &fi, ip, &iSize);
281409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            if (errorCode != (size_t)-LZ4F_ERROR_frameHeader_incomplete) goto _output_error;
282409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            DISPLAYLEVEL(3, " correctly failed : %s \n", LZ4F_getErrorName(errorCode));
283409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet
284409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            DISPLAYLEVEL(3, "get FrameInfo on not enough input : ");
285409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            iSize = 6;
286409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            errorCode = LZ4F_getFrameInfo(dCtx, &fi, ip, &iSize);
287409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            if (errorCode != (size_t)-LZ4F_ERROR_frameHeader_incomplete) goto _output_error;
288409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            DISPLAYLEVEL(3, " correctly failed : %s \n", LZ4F_getErrorName(errorCode));
289409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            ip += iSize;
290409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet
291409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            DISPLAYLEVEL(3, "get FrameInfo on enough input : ");
292409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            iSize = 15 - iSize;
293409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            errorCode = LZ4F_getFrameInfo(dCtx, &fi, ip, &iSize);
294409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            if (LZ4F_isError(errorCode)) goto _output_error;
295409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            DISPLAYLEVEL(3, " correctly decoded \n");
296409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet            ip += iSize;
297409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet        }
298409f816267b00e2307fabc59cc6ddffcc605a1ecYann Collet
299fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet        DISPLAYLEVEL(3, "Byte after byte : \n");
300bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        {   BYTE* const ostart = (BYTE*)decodedBuffer;
301bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            BYTE* op = ostart;
302bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            BYTE* const oend = (BYTE*)decodedBuffer + COMPRESSIBLE_NOISE_LENGTH;
303bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            while (ip < iend) {
304bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t oSize = oend-op;
305bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t iSize = 1;
306bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                errorCode = LZ4F_decompress(dCtx, op, &oSize, ip, &iSize, NULL);
307bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                if (LZ4F_isError(errorCode)) goto _output_error;
308bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                op += oSize;
309bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                ip += iSize;
310bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            }
311bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            { U64 const crcDest = XXH64(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, 1);
312bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet              if (crcDest != crcOrig) goto _output_error; }
313bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            DISPLAYLEVEL(3, "Regenerated %u/%u bytes \n", (unsigned)(op-ostart), COMPRESSIBLE_NOISE_LENGTH);
314bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            }
315b03f8f0e6f40d17740685e50332b8eedb5117cecYann Collet
316e619cfe8525f16d382fad1c569c1b71b25ac3d1dYann Collet        errorCode = LZ4F_freeDecompressionContext(dCtx);
317e619cfe8525f16d382fad1c569c1b71b25ac3d1dYann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
318bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        dCtx = NULL;
3198c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    }
3208c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
3218c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Using 64 KB block : \n");
322175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.blockSizeID = LZ4F_max64KB;
323175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled;
3248c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(testSize, &prefs), CNBuffer, testSize, &prefs);
3258c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    if (LZ4F_isError(cSize)) goto _output_error;
3268c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)cSize);
3278c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
3288c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "without checksum : \n");
329175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.contentChecksumFlag = LZ4F_noContentChecksum;
3308c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(testSize, &prefs), CNBuffer, testSize, &prefs);
3318c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    if (LZ4F_isError(cSize)) goto _output_error;
3328c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)cSize);
3338c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
3348c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Using 256 KB block : \n");
335175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.blockSizeID = LZ4F_max256KB;
336175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled;
3378c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(testSize, &prefs), CNBuffer, testSize, &prefs);
3388c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    if (LZ4F_isError(cSize)) goto _output_error;
3398c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)cSize);
3408c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
3418c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Decompression test : \n");
342bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    {   size_t const decodedBufferSize = COMPRESSIBLE_NOISE_LENGTH;
343bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        unsigned const maxBits = FUZ_highbit((U32)decodedBufferSize);
344bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        BYTE* const ostart = (BYTE*)decodedBuffer;
345bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        BYTE* op = ostart;
346bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        BYTE* const oend = ostart + COMPRESSIBLE_NOISE_LENGTH;
347bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        const BYTE* ip = (const BYTE*)compressedBuffer;
348bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        const BYTE* const iend = (const BYTE*)compressedBuffer + cSize;
349fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
350bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        { LZ4F_errorCode_t const createError = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
351bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet          if (LZ4F_isError(createError)) goto _output_error; }
352fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
353fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet        DISPLAYLEVEL(3, "random segment sizes : \n");
354b130fd59233925d6f8603d18270c3219e7672985Yann Collet        while (ip < iend) {
355bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            unsigned const nbBits = FUZ_rand(&randState) % maxBits;
356fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet            size_t iSize = (FUZ_rand(&randState) & ((1<<nbBits)-1)) + 1;
357fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet            size_t oSize = oend-op;
358fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet            if (iSize > (size_t)(iend-ip)) iSize = iend-ip;
359bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            { size_t const decompressError = LZ4F_decompress(dCtx, op, &oSize, ip, &iSize, NULL);
360bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet              if (LZ4F_isError(decompressError)) goto _output_error; }
361fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet            op += oSize;
362fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet            ip += iSize;
363fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet        }
364bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        {   size_t const decodedSize = (size_t)(op - ostart);
365bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            U64 const crcDest = XXH64(decodedBuffer, decodedSize, 1);
366bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            if (crcDest != crcOrig) goto _output_error;
367bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            DISPLAYLEVEL(3, "Regenerated %u bytes \n", (U32)decodedSize);
368bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet         }
369fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
370bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        { LZ4F_errorCode_t const freeError = LZ4F_freeDecompressionContext(dCtx);
371bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet          if (LZ4F_isError(freeError)) goto _output_error; }
372bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        dCtx = NULL;
3738c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    }
3748c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
3758c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "without checksum : \n");
376175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.contentChecksumFlag = LZ4F_noContentChecksum;
3778c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(testSize, &prefs), CNBuffer, testSize, &prefs);
3788c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    if (LZ4F_isError(cSize)) goto _output_error;
3798c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)cSize);
3808c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
3818c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Using 1 MB block : \n");
382175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.blockSizeID = LZ4F_max1MB;
383175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled;
3848c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(testSize, &prefs), CNBuffer, testSize, &prefs);
3858c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    if (LZ4F_isError(cSize)) goto _output_error;
3868c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)cSize);
3878c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
3888c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "without checksum : \n");
389175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.contentChecksumFlag = LZ4F_noContentChecksum;
3908c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(testSize, &prefs), CNBuffer, testSize, &prefs);
3918c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    if (LZ4F_isError(cSize)) goto _output_error;
3928c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)cSize);
3938c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
3948c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "Using 4 MB block : \n");
395175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.blockSizeID = LZ4F_max4MB;
396175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled;
397bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    {   size_t const dstCapacity = LZ4F_compressFrameBound(testSize, &prefs);
398bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        DISPLAYLEVEL(4, "dstCapacity = %u  \n", (U32)dstCapacity)
399bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        cSize = LZ4F_compressFrame(compressedBuffer, dstCapacity, CNBuffer, testSize, &prefs);
400bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        if (LZ4F_isError(cSize)) goto _output_error;
401bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        DISPLAYLEVEL(3, "Compressed %u bytes into a %u bytes frame \n", (U32)testSize, (U32)cSize);
402bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    }
4038c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
4048c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(3, "without checksum : \n");
405175890fe9bcd5029ffb33e2328037e0251e89ecbTakayuki MATSUOKA    prefs.frameInfo.contentChecksumFlag = LZ4F_noContentChecksum;
406bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    {   size_t const dstCapacity = LZ4F_compressFrameBound(testSize, &prefs);
407bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        DISPLAYLEVEL(4, "dstCapacity = %u  \n", (U32)dstCapacity)
408bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        cSize = LZ4F_compressFrame(compressedBuffer, dstCapacity, CNBuffer, testSize, &prefs);
409bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        if (LZ4F_isError(cSize)) goto _output_error;
410bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        DISPLAYLEVEL(3, "Compressed %u bytes into a %u bytes frame \n", (U32)testSize, (U32)cSize);
411bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    }
4128c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet
4132ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    {   size_t errorCode;
4147ee725645b58c201f11443d70210c2f986371b59Yann Collet        BYTE* const ostart = (BYTE*)compressedBuffer;
4157ee725645b58c201f11443d70210c2f986371b59Yann Collet        BYTE* op = ostart;
4167ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION);
4177ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4187ee725645b58c201f11443d70210c2f986371b59Yann Collet
4197ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "compress without frameSize : \n");
4207ee725645b58c201f11443d70210c2f986371b59Yann Collet        memset(&(prefs.frameInfo), 0, sizeof(prefs.frameInfo));
4217ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressBegin(cctx, compressedBuffer, testSize, &prefs);
4227ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4237ee725645b58c201f11443d70210c2f986371b59Yann Collet        op += errorCode;
4247ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressUpdate(cctx, op, LZ4F_compressBound(testSize, &prefs), CNBuffer, testSize, NULL);
4257ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4267ee725645b58c201f11443d70210c2f986371b59Yann Collet        op += errorCode;
4277ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressEnd(cctx, compressedBuffer, testSize, NULL);
4287ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4297ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)(op-ostart));
4307ee725645b58c201f11443d70210c2f986371b59Yann Collet
4317ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "compress with frameSize : \n");
432d5da787c1bd92a22c87b6428321668548155995fYann Collet        prefs.frameInfo.contentSize = testSize;
4337ee725645b58c201f11443d70210c2f986371b59Yann Collet        op = ostart;
4347ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressBegin(cctx, compressedBuffer, testSize, &prefs);
4357ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4367ee725645b58c201f11443d70210c2f986371b59Yann Collet        op += errorCode;
4377ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressUpdate(cctx, op, LZ4F_compressBound(testSize, &prefs), CNBuffer, testSize, NULL);
4387ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4397ee725645b58c201f11443d70210c2f986371b59Yann Collet        op += errorCode;
4407ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressEnd(cctx, compressedBuffer, testSize, NULL);
4417ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4427ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)(op-ostart));
4437ee725645b58c201f11443d70210c2f986371b59Yann Collet
4447ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "compress with wrong frameSize : \n");
445d5da787c1bd92a22c87b6428321668548155995fYann Collet        prefs.frameInfo.contentSize = testSize+1;
4467ee725645b58c201f11443d70210c2f986371b59Yann Collet        op = ostart;
4477ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressBegin(cctx, compressedBuffer, testSize, &prefs);
4487ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4497ee725645b58c201f11443d70210c2f986371b59Yann Collet        op += errorCode;
4507ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressUpdate(cctx, op, LZ4F_compressBound(testSize, &prefs), CNBuffer, testSize, NULL);
4517ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4527ee725645b58c201f11443d70210c2f986371b59Yann Collet        op += errorCode;
4537ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_compressEnd(cctx, op, testSize, NULL);
4547ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) { DISPLAYLEVEL(3, "Error correctly detected : %s \n", LZ4F_getErrorName(errorCode)); }
4557ee725645b58c201f11443d70210c2f986371b59Yann Collet        else
4567ee725645b58c201f11443d70210c2f986371b59Yann Collet            goto _output_error;
4577ee725645b58c201f11443d70210c2f986371b59Yann Collet
4587ee725645b58c201f11443d70210c2f986371b59Yann Collet        errorCode = LZ4F_freeCompressionContext(cctx);
4597ee725645b58c201f11443d70210c2f986371b59Yann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
46062ed15319570d80690915f0d0dba0dc2e9478631Yann Collet        cctx = NULL;
4617ee725645b58c201f11443d70210c2f986371b59Yann Collet    }
4627ee725645b58c201f11443d70210c2f986371b59Yann Collet
4633a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet    DISPLAYLEVEL(3, "Skippable frame test : \n");
4642ac9ecec685f720876aa2e12277b06f53de03682Yann Collet    {   size_t decodedBufferSize = COMPRESSIBLE_NOISE_LENGTH;
4653a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        unsigned maxBits = FUZ_highbit((U32)decodedBufferSize);
4663a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        BYTE* op = (BYTE*)decodedBuffer;
4673a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        BYTE* const oend = (BYTE*)decodedBuffer + COMPRESSIBLE_NOISE_LENGTH;
4683a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        BYTE* ip = (BYTE*)compressedBuffer;
4692a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet        BYTE* iend = (BYTE*)compressedBuffer + cSize + 8;
4703a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet
4713a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        LZ4F_errorCode_t errorCode = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
4723a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        if (LZ4F_isError(errorCode)) goto _output_error;
4733a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet
4743a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        /* generate skippable frame */
4753a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        FUZ_writeLE32(ip, LZ4F_MAGIC_SKIPPABLE_START);
4763a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        FUZ_writeLE32(ip+4, (U32)cSize);
4773a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet
4783a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        DISPLAYLEVEL(3, "random segment sizes : \n");
479b130fd59233925d6f8603d18270c3219e7672985Yann Collet        while (ip < iend) {
4803a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            unsigned nbBits = FUZ_rand(&randState) % maxBits;
4813a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            size_t iSize = (FUZ_rand(&randState) & ((1<<nbBits)-1)) + 1;
4823a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            size_t oSize = oend-op;
4833a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            if (iSize > (size_t)(iend-ip)) iSize = iend-ip;
4843a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            errorCode = LZ4F_decompress(dCtx, op, &oSize, ip, &iSize, NULL);
4853a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            if (LZ4F_isError(errorCode)) goto _output_error;
4863a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            op += oSize;
4873a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            ip += iSize;
4883a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        }
4893a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        DISPLAYLEVEL(3, "Skipped %i bytes \n", (int)decodedBufferSize);
4903a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet
4912a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet        /* generate zero-size skippable frame */
4927ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "zero-size skippable frame\n");
4937ee725645b58c201f11443d70210c2f986371b59Yann Collet        ip = (BYTE*)compressedBuffer;
4947ee725645b58c201f11443d70210c2f986371b59Yann Collet        op = (BYTE*)decodedBuffer;
4952a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet        FUZ_writeLE32(ip, LZ4F_MAGIC_SKIPPABLE_START+1);
4962a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet        FUZ_writeLE32(ip+4, 0);
4972a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet        iend = ip+8;
4982a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet
499b130fd59233925d6f8603d18270c3219e7672985Yann Collet        while (ip < iend) {
5002a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet            unsigned nbBits = FUZ_rand(&randState) % maxBits;
5012a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet            size_t iSize = (FUZ_rand(&randState) & ((1<<nbBits)-1)) + 1;
5022a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet            size_t oSize = oend-op;
5032a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet            if (iSize > (size_t)(iend-ip)) iSize = iend-ip;
5042a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet            errorCode = LZ4F_decompress(dCtx, op, &oSize, ip, &iSize, NULL);
5052a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet            if (LZ4F_isError(errorCode)) goto _output_error;
5062a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet            op += oSize;
5072a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet            ip += iSize;
5082a02455fdfb7250ef629a3ffde5258e95df06e7bYann Collet        }
5097ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "Skipped %i bytes \n", (int)(ip - (BYTE*)compressedBuffer - 8));
5107ee725645b58c201f11443d70210c2f986371b59Yann Collet
5117ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "Skippable frame header complete in first call \n");
5127ee725645b58c201f11443d70210c2f986371b59Yann Collet        ip = (BYTE*)compressedBuffer;
5137ee725645b58c201f11443d70210c2f986371b59Yann Collet        op = (BYTE*)decodedBuffer;
5147ee725645b58c201f11443d70210c2f986371b59Yann Collet        FUZ_writeLE32(ip, LZ4F_MAGIC_SKIPPABLE_START+2);
5157ee725645b58c201f11443d70210c2f986371b59Yann Collet        FUZ_writeLE32(ip+4, 10);
5167ee725645b58c201f11443d70210c2f986371b59Yann Collet        iend = ip+18;
517b130fd59233925d6f8603d18270c3219e7672985Yann Collet        while (ip < iend) {
5187ee725645b58c201f11443d70210c2f986371b59Yann Collet            size_t iSize = 10;
5197ee725645b58c201f11443d70210c2f986371b59Yann Collet            size_t oSize = 10;
5207ee725645b58c201f11443d70210c2f986371b59Yann Collet            if (iSize > (size_t)(iend-ip)) iSize = iend-ip;
5217ee725645b58c201f11443d70210c2f986371b59Yann Collet            errorCode = LZ4F_decompress(dCtx, op, &oSize, ip, &iSize, NULL);
5227ee725645b58c201f11443d70210c2f986371b59Yann Collet            if (LZ4F_isError(errorCode)) goto _output_error;
5237ee725645b58c201f11443d70210c2f986371b59Yann Collet            op += oSize;
5247ee725645b58c201f11443d70210c2f986371b59Yann Collet            ip += iSize;
5257ee725645b58c201f11443d70210c2f986371b59Yann Collet        }
5267ee725645b58c201f11443d70210c2f986371b59Yann Collet        DISPLAYLEVEL(3, "Skipped %i bytes \n", (int)(ip - (BYTE*)compressedBuffer - 8));
5273a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet    }
5283a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet
5298c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAY("Basic tests completed \n");
530f66721d303a6141797ee1e04067a007aa0392dafYann Collet_end:
5318c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    free(CNBuffer);
5328c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    free(compressedBuffer);
5338c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    free(decodedBuffer);
53462ed15319570d80690915f0d0dba0dc2e9478631Yann Collet    LZ4F_freeDecompressionContext(dCtx); dCtx = NULL;
53562ed15319570d80690915f0d0dba0dc2e9478631Yann Collet    LZ4F_freeCompressionContext(cctx); cctx = NULL;
5368c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    return testResult;
537f66721d303a6141797ee1e04067a007aa0392dafYann Collet
538f66721d303a6141797ee1e04067a007aa0392dafYann Collet_output_error:
5398c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    testResult = 1;
5408c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAY("Error detected ! \n");
5418c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    goto _end;
542f66721d303a6141797ee1e04067a007aa0392dafYann Collet}
543f66721d303a6141797ee1e04067a007aa0392dafYann Collet
544f66721d303a6141797ee1e04067a007aa0392dafYann Collet
545eeb9011467d4064eca754bd32e629e88fa5ec8f3Yann Colletstatic void locateBuffDiff(const void* buff1, const void* buff2, size_t size, unsigned nonContiguous)
546b1d022fa72b75af8fb373e26ac8d2f0f14a9e6feYann Collet{
547b1d022fa72b75af8fb373e26ac8d2f0f14a9e6feYann Collet    int p=0;
5481c3e633c48766c58df949887297dc5838170a33fYann Collet    const BYTE* b1=(const BYTE*)buff1;
5491c3e633c48766c58df949887297dc5838170a33fYann Collet    const BYTE* b2=(const BYTE*)buff2;
550b130fd59233925d6f8603d18270c3219e7672985Yann Collet    if (nonContiguous) {
5518c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet        DISPLAY("Non-contiguous output test (%i bytes)\n", (int)size);
5528c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet        return;
5538c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    }
554b1d022fa72b75af8fb373e26ac8d2f0f14a9e6feYann Collet    while (b1[p]==b2[p]) p++;
555eeb9011467d4064eca754bd32e629e88fa5ec8f3Yann Collet    DISPLAY("Error at pos %i/%i : %02X != %02X \n", p, (int)size, b1[p], b2[p]);
5568c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet}
557b1d022fa72b75af8fb373e26ac8d2f0f14a9e6feYann Collet
558b1d022fa72b75af8fb373e26ac8d2f0f14a9e6feYann Collet
559dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Colletint fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressibility, U32 duration_s)
560fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet{
5618c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    unsigned testResult = 0;
5628c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    unsigned testNb = 0;
563bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    size_t const srcDataLength = 9 MB;  /* needs to be > 2x4MB to test large blocks */
5648c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    void* srcBuffer = NULL;
565bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    size_t const compressedBufferSize = LZ4F_compressFrameBound(srcDataLength, NULL);
5668c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    void* compressedBuffer = NULL;
5678c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    void* decodedBuffer = NULL;
5688c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    U32 coreRand = seed;
5698c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    LZ4F_decompressionContext_t dCtx = NULL;
5708c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    LZ4F_compressionContext_t cCtx = NULL;
571d1d1f8835de315ce401c8d1309ba648539878a64Yann Collet    size_t result;
572dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet    clock_t const startClock = clock();
573dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet    clock_t const clockDuration = duration_s * CLOCKS_PER_SEC;
57403bc760af361ae95187a8d3475be362293328884Yann Collet#   define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \
5758c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                            DISPLAY(" (seed %u, test nb %u)  \n", seed, testNb); goto _output_error; }
576fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
57745b0642bf54718d2b57dd61cb606b154afc0ab26Yann Collet    /* Create buffers */
5788c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    result = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
579d1d1f8835de315ce401c8d1309ba648539878a64Yann Collet    CHECK(LZ4F_isError(result), "Allocation failed (error %i)", (int)result);
5808c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    result = LZ4F_createCompressionContext(&cCtx, LZ4F_VERSION);
581d1d1f8835de315ce401c8d1309ba648539878a64Yann Collet    CHECK(LZ4F_isError(result), "Allocation failed (error %i)", (int)result);
5828c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    srcBuffer = malloc(srcDataLength);
583d1d1f8835de315ce401c8d1309ba648539878a64Yann Collet    CHECK(srcBuffer==NULL, "srcBuffer Allocation failed");
584bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    compressedBuffer = malloc(compressedBufferSize);
585d1d1f8835de315ce401c8d1309ba648539878a64Yann Collet    CHECK(compressedBuffer==NULL, "compressedBuffer Allocation failed");
58645b0642bf54718d2b57dd61cb606b154afc0ab26Yann Collet    decodedBuffer = calloc(1, srcDataLength);   /* calloc avoids decodedBuffer being considered "garbage" by scan-build */
587d1d1f8835de315ce401c8d1309ba648539878a64Yann Collet    CHECK(decodedBuffer==NULL, "decodedBuffer Allocation failed");
5888c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    FUZ_fillCompressibleNoiseBuffer(srcBuffer, srcDataLength, compressibility, &coreRand);
589cf28c27809df4ce4d6822d8fbb503922b4cfc9a8Yann Collet
59045b0642bf54718d2b57dd61cb606b154afc0ab26Yann Collet    /* jump to requested testNb */
591bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    for (testNb =0; (testNb < startTest); testNb++) (void)FUZ_rand(&coreRand);   /* sync randomizer */
592fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
59345b0642bf54718d2b57dd61cb606b154afc0ab26Yann Collet    /* main fuzzer test loop */
594dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet    for ( ; (testNb < nbTests) || (clockDuration > FUZ_GetClockSpan(startClock)) ; testNb++) {
595cf28c27809df4ce4d6822d8fbb503922b4cfc9a8Yann Collet        U32 randState = coreRand ^ prime1;
5961b24cc115595f7cd2f8f5f6de0a9d44a70bdf827Yann Collet        unsigned const srcBits = (FUZ_rand(&randState) % (FUZ_highbit((U32)(srcDataLength-1)) - 1)) + 1;
597bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        size_t const srcSize = (FUZ_rand(&randState) & ((1<<srcBits)-1)) + 1;
598bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        size_t const srcStartId = FUZ_rand(&randState) % (srcDataLength - srcSize);
599bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        const BYTE* const srcStart = (const BYTE*)srcBuffer + srcStartId;
600bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        unsigned const neverFlush = (FUZ_rand(&randState) & 15) == 1;
601bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        U64 const crcOrig = XXH64(srcStart, srcSize, 1);
602ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet        LZ4F_preferences_t prefs;
603bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        const LZ4F_preferences_t* prefsPtr = &prefs;
604535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet        size_t cSize;
605e6d9a17188efa591b79cb8c269ed81ec6e9b817aYann Collet
6063a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        (void)FUZ_rand(&coreRand);   /* update seed */
607ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet        memset(&prefs, 0, sizeof(prefs));
608bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        prefs.frameInfo.blockMode = (LZ4F_blockMode_t)(FUZ_rand(&randState) & 1);
609bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        prefs.frameInfo.blockSizeID = (LZ4F_blockSizeID_t)(4 + (FUZ_rand(&randState) & 3));
610bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        prefs.frameInfo.contentChecksumFlag = (LZ4F_contentChecksum_t)(FUZ_rand(&randState) & 1);
611bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        prefs.frameInfo.contentSize = ((FUZ_rand(&randState) & 0xF) == 1) ? srcSize : 0;
612bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        prefs.autoFlush = neverFlush ? 0 : (FUZ_rand(&randState) & 7) == 2;
6137a677a77a683a6716307034a176228075ce9fea5Yann Collet        prefs.compressionLevel = FUZ_rand(&randState) % 5;
6143a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet        if ((FUZ_rand(&randState) & 0xF) == 1) prefsPtr = NULL;
615bd704cf70ad7b935db0d1baaee902b28e6394bbaYann Collet
6168c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet        DISPLAYUPDATE(2, "\r%5u   ", testNb);
617535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet
618b130fd59233925d6f8603d18270c3219e7672985Yann Collet        if ((FUZ_rand(&randState) & 0xFFF) == 0) {
6193a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            /* create a skippable frame (rare case) */
6203a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            BYTE* op = (BYTE*)compressedBuffer;
6213a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            FUZ_writeLE32(op, LZ4F_MAGIC_SKIPPABLE_START + (FUZ_rand(&randState) & 15));
6228437a0e43aa5086ec2c23591909e118a85c3d8ddYann Collet            FUZ_writeLE32(op+4, (U32)srcSize);
6233a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            cSize = srcSize+8;
624bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        } else if ((FUZ_rand(&randState) & 0xF) == 2) {  /* single pass compression (simple) */
625bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            cSize = LZ4F_compressFrame(compressedBuffer, LZ4F_compressFrameBound(srcSize, prefsPtr), srcStart, srcSize, prefsPtr);
6266e1049872ae2606cfb3820464c850c694275ae59Yann Collet            CHECK(LZ4F_isError(cSize), "LZ4F_compressFrame failed : error %i (%s)", (int)cSize, LZ4F_getErrorName(cSize));
627bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        } else {   /* multi-segments compression */
628bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            const BYTE* ip = srcStart;
629bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            const BYTE* const iend = srcStart + srcSize;
6307a677a77a683a6716307034a176228075ce9fea5Yann Collet            BYTE* op = (BYTE*)compressedBuffer;
631bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            BYTE* const oend = op + (neverFlush ? LZ4F_compressFrameBound(srcSize, prefsPtr) : compressedBufferSize);  /* when flushes are possible, can't guarantee a max compressed size */
632bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            unsigned const maxBits = FUZ_highbit((U32)srcSize);
633bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            LZ4F_compressOptions_t cOptions;
634bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            memset(&cOptions, 0, sizeof(cOptions));
635c14a342cc2ed5c963213571ab412657bdcf2b899Yann Collet            result = LZ4F_compressBegin(cCtx, op, oend-op, prefsPtr);
636535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet            CHECK(LZ4F_isError(result), "Compression header failed (error %i)", (int)result);
637535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet            op += result;
638b130fd59233925d6f8603d18270c3219e7672985Yann Collet            while (ip < iend) {
639bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                unsigned const nbBitsSeg = FUZ_rand(&randState) % maxBits;
640bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t const sampleMax = (FUZ_rand(&randState) & ((1<<nbBitsSeg)-1)) + 1;
641bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t const iSize = MIN(sampleMax, (size_t)(iend-ip));
642bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t const oSize = LZ4F_compressBound(iSize, prefsPtr);
6438c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                cOptions.stableSrc = ((FUZ_rand(&randState) & 3) == 1);
644bd704cf70ad7b935db0d1baaee902b28e6394bbaYann Collet
645d71b9e25b729e92871cd6a9791170e334d5199d1Yann Collet                result = LZ4F_compressUpdate(cCtx, op, oSize, ip, iSize, &cOptions);
646bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                CHECK(LZ4F_isError(result), "Compression failed (error %i : %s)", (int)result, LZ4F_getErrorName(result));
647535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet                op += result;
648535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet                ip += iSize;
649bd704cf70ad7b935db0d1baaee902b28e6394bbaYann Collet
650bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                {   unsigned const forceFlush = neverFlush ? 0 : ((FUZ_rand(&randState) & 3) == 1);
651bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                    if (forceFlush) {
652bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                        result = LZ4F_flush(cCtx, op, oend-op, &cOptions);
653bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                        CHECK(LZ4F_isError(result), "Compression failed (error %i)", (int)result);
654bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                        op += result;
655bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                }   }
656535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet            }
657bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            CHECK(op>=oend, "LZ4F_compressFrameBound overflow");
658d71b9e25b729e92871cd6a9791170e334d5199d1Yann Collet            result = LZ4F_compressEnd(cCtx, op, oend-op, &cOptions);
659bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            CHECK(LZ4F_isError(result), "Compression completion failed (error %i : %s)", (int)result, LZ4F_getErrorName(result));
660535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet            op += result;
661cdececa38dbc45df93a71007781988af789108e8Yann Collet            cSize = op-(BYTE*)compressedBuffer;
662bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            DISPLAYLEVEL(5, "\nCompressed %u bytes into %u \n", (U32)srcSize, (U32)cSize);
663535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet        }
66404f5b17b7227bbc3ee788f869b55641f6c776b08Yann Collet
665bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        /* multi-segments decompression */
6662ac9ecec685f720876aa2e12277b06f53de03682Yann Collet        {   const BYTE* ip = (const BYTE*)compressedBuffer;
66704f5b17b7227bbc3ee788f869b55641f6c776b08Yann Collet            const BYTE* const iend = ip + cSize;
6687a677a77a683a6716307034a176228075ce9fea5Yann Collet            BYTE* op = (BYTE*)decodedBuffer;
66904f5b17b7227bbc3ee788f869b55641f6c776b08Yann Collet            BYTE* const oend = op + srcDataLength;
670bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            unsigned const suggestedBits = FUZ_highbit((U32)cSize);
671bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            unsigned const maxBits = MAX(3, suggestedBits);
672bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            unsigned const nonContiguousDst = FUZ_rand(&randState) % 3;   /* 0 : contiguous; 1 : non-contiguous; 2 : dst overwritten */
6733a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            size_t totalOut = 0;
674bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet            XXH64_state_t xxh64;
675c14a342cc2ed5c963213571ab412657bdcf2b899Yann Collet            XXH64_reset(&xxh64, 1);
676b130fd59233925d6f8603d18270c3219e7672985Yann Collet            while (ip < iend) {
677c8a78dba1fc21f64dec72cf217c21fe8784c42bfYann Collet                unsigned const nbBitsI = (FUZ_rand(&randState) % (maxBits-1)) + 1;
678c8a78dba1fc21f64dec72cf217c21fe8784c42bfYann Collet                unsigned const nbBitsO = (FUZ_rand(&randState) % (maxBits)) + 1;
679bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t const iSizeMax = (FUZ_rand(&randState) & ((1<<nbBitsI)-1)) + 1;
680bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t iSize = MIN(iSizeMax, (size_t)(iend-ip));
681bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t const oSizeMax = (FUZ_rand(&randState) & ((1<<nbBitsO)-1)) + 2;
682bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                size_t oSize = MIN(oSizeMax, (size_t)(oend-op));
683bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                LZ4F_decompressOptions_t dOptions;
684bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                memset(&dOptions, 0, sizeof(dOptions));
685d71b9e25b729e92871cd6a9791170e334d5199d1Yann Collet                dOptions.stableDst = FUZ_rand(&randState) & 1;
686bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                if (nonContiguousDst==2) dOptions.stableDst = 0;   /* overwrite mode */
687d71b9e25b729e92871cd6a9791170e334d5199d1Yann Collet                result = LZ4F_decompress(dCtx, op, &oSize, ip, &iSize, &dOptions);
688bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                if (LZ4F_getErrorCode(result) == LZ4F_ERROR_contentChecksum_invalid) locateBuffDiff(srcStart, decodedBuffer, srcSize, nonContiguousDst);
689bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                CHECK(LZ4F_isError(result), "Decompression failed (error %i:%s)", (int)result, LZ4F_getErrorName(result));
690eeb9011467d4064eca754bd32e629e88fa5ec8f3Yann Collet                XXH64_update(&xxh64, op, (U32)oSize);
6913a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet                totalOut += oSize;
69204f5b17b7227bbc3ee788f869b55641f6c776b08Yann Collet                op += oSize;
69304f5b17b7227bbc3ee788f869b55641f6c776b08Yann Collet                ip += iSize;
694eeb9011467d4064eca754bd32e629e88fa5ec8f3Yann Collet                op += nonContiguousDst;
695ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet                if (nonContiguousDst==2) op = (BYTE*)decodedBuffer;   /* overwritten destination */
69604f5b17b7227bbc3ee788f869b55641f6c776b08Yann Collet            }
697658ab6cfca598b65b017e1ab784703add927ae0dYann Collet            CHECK(result != 0, "Frame decompression failed (error %i)", (int)result);
698b130fd59233925d6f8603d18270c3219e7672985Yann Collet            if (totalOut) {  /* otherwise, it's a skippable frame */
699c8a78dba1fc21f64dec72cf217c21fe8784c42bfYann Collet                U64 const crcDecoded = XXH64_digest(&xxh64);
700bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                if (crcDecoded != crcOrig) locateBuffDiff(srcStart, decodedBuffer, srcSize, nonContiguousDst);
7013a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet                CHECK(crcDecoded != crcOrig, "Decompression corruption");
7023a6832497ba02607dd4ede3a3fd30911e06f037eYann Collet            }
70304f5b17b7227bbc3ee788f869b55641f6c776b08Yann Collet        }
704fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet    }
705fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
7068c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAYLEVEL(2, "\rAll tests completed   \n");
707fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
708fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet_end:
70903bc760af361ae95187a8d3475be362293328884Yann Collet    LZ4F_freeDecompressionContext(dCtx);
710d1d1f8835de315ce401c8d1309ba648539878a64Yann Collet    LZ4F_freeCompressionContext(cCtx);
7118c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    free(srcBuffer);
7128c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    free(compressedBuffer);
7138c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    free(decodedBuffer);
714eeb9011467d4064eca754bd32e629e88fa5ec8f3Yann Collet
71564cbc4e1dc17492d89915a9d774dc15ee438ccfePrzemyslaw Skibinski    if (use_pause) {
716eeb9011467d4064eca754bd32e629e88fa5ec8f3Yann Collet        DISPLAY("press enter to finish \n");
71762ed15319570d80690915f0d0dba0dc2e9478631Yann Collet        (void)getchar();
718eeb9011467d4064eca754bd32e629e88fa5ec8f3Yann Collet    }
7198c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    return testResult;
720fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
721fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet_output_error:
7228c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    testResult = 1;
7238c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    goto _end;
724fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet}
725fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
726fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet
727bf6dda69e683f981bc966bd86c01f78936b39689Yann Colletint FUZ_usage(const char* programName)
728f66721d303a6141797ee1e04067a007aa0392dafYann Collet{
729f66721d303a6141797ee1e04067a007aa0392dafYann Collet    DISPLAY( "Usage :\n");
730f66721d303a6141797ee1e04067a007aa0392dafYann Collet    DISPLAY( "      %s [args]\n", programName);
731f66721d303a6141797ee1e04067a007aa0392dafYann Collet    DISPLAY( "\n");
732f66721d303a6141797ee1e04067a007aa0392dafYann Collet    DISPLAY( "Arguments :\n");
7338c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet    DISPLAY( " -i#    : Nb of tests (default:%u) \n", nbTestsDefault);
7342c7988761dcd7e5435c519eeffef32a90eed93adYann Collet    DISPLAY( " -T#    : Duration of tests, in seconds (default: use Nb of tests) \n");
735f66721d303a6141797ee1e04067a007aa0392dafYann Collet    DISPLAY( " -s#    : Select seed (default:prompt user)\n");
736f66721d303a6141797ee1e04067a007aa0392dafYann Collet    DISPLAY( " -t#    : Select starting test number (default:0)\n");
737bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    DISPLAY( " -P#    : Select compressibility in %% (default:%i%%)\n", FUZ_COMPRESSIBILITY_DEFAULT);
738f66721d303a6141797ee1e04067a007aa0392dafYann Collet    DISPLAY( " -v     : verbose\n");
739f66721d303a6141797ee1e04067a007aa0392dafYann Collet    DISPLAY( " -h     : display help and exit\n");
740f66721d303a6141797ee1e04067a007aa0392dafYann Collet    return 0;
741f66721d303a6141797ee1e04067a007aa0392dafYann Collet}
742f66721d303a6141797ee1e04067a007aa0392dafYann Collet
743f66721d303a6141797ee1e04067a007aa0392dafYann Collet
744bf6dda69e683f981bc966bd86c01f78936b39689Yann Colletint main(int argc, const char** argv)
745f7f67e778c9261fa5843811068f3eb3cc4e70509Yann Collet{
746f66721d303a6141797ee1e04067a007aa0392dafYann Collet    U32 seed=0;
747f66721d303a6141797ee1e04067a007aa0392dafYann Collet    int seedset=0;
748f66721d303a6141797ee1e04067a007aa0392dafYann Collet    int argNb;
749535120bbe3ebedb5ad5f53bb179242624e7c2828Yann Collet    int nbTests = nbTestsDefault;
750f66721d303a6141797ee1e04067a007aa0392dafYann Collet    int testNb = 0;
751f66721d303a6141797ee1e04067a007aa0392dafYann Collet    int proba = FUZ_COMPRESSIBILITY_DEFAULT;
752b1d022fa72b75af8fb373e26ac8d2f0f14a9e6feYann Collet    int result=0;
753c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet    U32 duration=0;
754bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    const char* const programName = argv[0];
755f66721d303a6141797ee1e04067a007aa0392dafYann Collet
7568cb06d5b9922b16854b05081ce829c223a8129fdYann Collet    /* Check command line */
757bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    for (argNb=1; argNb<argc; argNb++) {
758bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        const char* argument = argv[argNb];
759f66721d303a6141797ee1e04067a007aa0392dafYann Collet
760c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet        if(!argument) continue;   /* Protection if argument empty */
761f66721d303a6141797ee1e04067a007aa0392dafYann Collet
762bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet        /* Decode command (note : aggregated short commands are allowed) */
763b130fd59233925d6f8603d18270c3219e7672985Yann Collet        if (argument[0]=='-') {
764b130fd59233925d6f8603d18270c3219e7672985Yann Collet            if (!strcmp(argument, "--no-prompt")) {
7658c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                no_prompt=1;
7668c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                seedset=1;
7678c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                displayLevel=1;
7688c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                continue;
7698c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet            }
770eeb9011467d4064eca754bd32e629e88fa5ec8f3Yann Collet            argument++;
771f66721d303a6141797ee1e04067a007aa0392dafYann Collet
772b130fd59233925d6f8603d18270c3219e7672985Yann Collet            while (*argument!=0) {
773f66721d303a6141797ee1e04067a007aa0392dafYann Collet                switch(*argument)
774f66721d303a6141797ee1e04067a007aa0392dafYann Collet                {
775f66721d303a6141797ee1e04067a007aa0392dafYann Collet                case 'h':
776bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                    return FUZ_usage(programName);
777f66721d303a6141797ee1e04067a007aa0392dafYann Collet                case 'v':
778f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    argument++;
779bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                    displayLevel++;
780f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    break;
781fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet                case 'q':
782fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet                    argument++;
783fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet                    displayLevel--;
784fd8665320fe03f9f61d438a3cc81502406859c2aYann Collet                    break;
785e468a4eb96ec8e2ea0fc61b5aa20f56a3b214c0eYann Collet                case 'p': /* pause at the end */
786e468a4eb96ec8e2ea0fc61b5aa20f56a3b214c0eYann Collet                    argument++;
78764cbc4e1dc17492d89915a9d774dc15ee438ccfePrzemyslaw Skibinski                    use_pause = 1;
788e468a4eb96ec8e2ea0fc61b5aa20f56a3b214c0eYann Collet                    break;
789e468a4eb96ec8e2ea0fc61b5aa20f56a3b214c0eYann Collet
7907a677a77a683a6716307034a176228075ce9fea5Yann Collet                case 'i':
791f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    argument++;
792c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                    nbTests=0; duration=0;
793b130fd59233925d6f8603d18270c3219e7672985Yann Collet                    while ((*argument>='0') && (*argument<='9')) {
794f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        nbTests *= 10;
795f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        nbTests += *argument - '0';
796f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        argument++;
797f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    }
798f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    break;
799c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet
800c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                case 'T':
801c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                    argument++;
802c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                    nbTests = 0; duration = 0;
803b130fd59233925d6f8603d18270c3219e7672985Yann Collet                    for (;;) {
8042c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                        switch(*argument)
805c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                        {
8062c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case 'm': duration *= 60; argument++; continue;
8072c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case 's':
8082c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case 'n': argument++; continue;
8092c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '0':
8102c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '1':
8112c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '2':
8122c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '3':
8132c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '4':
8142c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '5':
8152c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '6':
8162c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '7':
8172c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '8':
8182c7988761dcd7e5435c519eeffef32a90eed93adYann Collet                            case '9': duration *= 10; duration += *argument++ - '0'; continue;
819c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                        }
820c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                        break;
821c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                    }
822c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet                    break;
823c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet
824f66721d303a6141797ee1e04067a007aa0392dafYann Collet                case 's':
825f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    argument++;
8268c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                    seed=0;
8278c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                    seedset=1;
828b130fd59233925d6f8603d18270c3219e7672985Yann Collet                    while ((*argument>='0') && (*argument<='9')) {
829f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        seed *= 10;
830f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        seed += *argument - '0';
831f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        argument++;
832f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    }
833f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    break;
834f66721d303a6141797ee1e04067a007aa0392dafYann Collet                case 't':
835f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    argument++;
836f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    testNb=0;
837b130fd59233925d6f8603d18270c3219e7672985Yann Collet                    while ((*argument>='0') && (*argument<='9')) {
838f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        testNb *= 10;
839f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        testNb += *argument - '0';
840f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        argument++;
841f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    }
842f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    break;
843e468a4eb96ec8e2ea0fc61b5aa20f56a3b214c0eYann Collet                case 'P':   /* compressibility % */
844f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    argument++;
845f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    proba=0;
846b130fd59233925d6f8603d18270c3219e7672985Yann Collet                    while ((*argument>='0') && (*argument<='9')) {
847f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        proba *= 10;
848f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        proba += *argument - '0';
849f66721d303a6141797ee1e04067a007aa0392dafYann Collet                        argument++;
850f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    }
851f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    if (proba<0) proba=0;
852f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    if (proba>100) proba=100;
853f66721d303a6141797ee1e04067a007aa0392dafYann Collet                    break;
8548c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                default:
8558c1ae998379bce4a0e719aaac43a777713ab5c00Yann Collet                    ;
856bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet                    return FUZ_usage(programName);
857f66721d303a6141797ee1e04067a007aa0392dafYann Collet                }
858f66721d303a6141797ee1e04067a007aa0392dafYann Collet            }
859f66721d303a6141797ee1e04067a007aa0392dafYann Collet        }
860f66721d303a6141797ee1e04067a007aa0392dafYann Collet    }
861f66721d303a6141797ee1e04067a007aa0392dafYann Collet
8628cb06d5b9922b16854b05081ce829c223a8129fdYann Collet    /* Get Seed */
863bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    DISPLAY("Starting lz4frame tester (%i-bits, %s)\n", (int)(sizeof(size_t)*8), LZ4_VERSION_STRING);
864f66721d303a6141797ee1e04067a007aa0392dafYann Collet
865dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet    if (!seedset) {
866dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet        time_t const t = time(NULL);
867dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet        U32 const h = XXH32(&t, sizeof(t), 1);
868dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet        seed = h % 10000;
869dd51ca63004b4d373f90071d12fbe8c06ef0ae1aYann Collet    }
870bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    DISPLAY("Seed = %u\n", seed);
871bf6dda69e683f981bc966bd86c01f78936b39689Yann Collet    if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) DISPLAY("Compressibility : %i%%\n", proba);
872f66721d303a6141797ee1e04067a007aa0392dafYann Collet
873f66721d303a6141797ee1e04067a007aa0392dafYann Collet    if (nbTests<=0) nbTests=1;
874f66721d303a6141797ee1e04067a007aa0392dafYann Collet
875326cada9fadeedccef8934e11144f343ecdcabcbYann Collet    if (testNb==0) result = basicTests(seed, ((double)proba) / 100);
876eac83cd850d2f69a82ef9af344be9b7f3925681aYann Collet    if (result) return 1;
877c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16Yann Collet    return fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100, duration);
878f66721d303a6141797ee1e04067a007aa0392dafYann Collet}
879