예제 #1
0
/* *** Initialization *** */

#define MIN(a,b)    ( ((a)<(b)) ? (a) : (b) )
#define BLOCKSIZE   (128 * 1024)   /* a bit too "magic", should come from reference */
size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, ZSTD_parameters params)
{
    size_t neededInBuffSize;

    ZSTD_validateParams(&params);
    neededInBuffSize = (size_t)1 << params.windowLog;

    /* allocate buffers */
    if (zbc->inBuffSize < neededInBuffSize)
    {
        zbc->inBuffSize = neededInBuffSize;
        free(zbc->inBuff);   /* should not be necessary */
        zbc->inBuff = (char*)malloc(neededInBuffSize);
        if (zbc->inBuff == NULL) return ERROR(memory_allocation);
    }
    zbc->blockSize = MIN(BLOCKSIZE, zbc->inBuffSize);
    if (zbc->outBuffSize < ZSTD_compressBound(zbc->blockSize)+1)
    {
        zbc->outBuffSize = ZSTD_compressBound(zbc->blockSize)+1;
        free(zbc->outBuff);   /* should not be necessary */
        zbc->outBuff = (char*)malloc(zbc->outBuffSize);
        if (zbc->outBuff == NULL) return ERROR(memory_allocation);
    }

    zbc->outBuffContentSize = ZSTD_compressBegin_advanced(zbc->zc, params);
    if (ZSTD_isError(zbc->outBuffContentSize)) return zbc->outBuffContentSize;

    zbc->inToCompress = 0;
    zbc->inBuffPos = 0;
    zbc->inBuffTarget = zbc->blockSize;
    zbc->outBuffFlushedSize = 0;
    zbc->stage = ZBUFFcs_flush;   /* starts by flushing the header */
    return 0;   /* ready to go */
}
예제 #2
0
std::unique_ptr<IOBuf> ZSTDCodec::doCompress(const IOBuf* data) {
  // Support earlier versions of the codec (working with a single IOBuf,
  // and using ZSTD_decompress which requires ZSTD frame to contain size,
  // which isn't populated by streaming API).
  if (!data->isChained()) {
    auto out = IOBuf::createCombined(ZSTD_compressBound(data->length()));
    const auto rc = ZSTD_compress(
        out->writableData(),
        out->capacity(),
        data->data(),
        data->length(),
        level_);
    zstdThrowIfError(rc);
    out->append(rc);
    return out;
  }

  auto zcs = ZSTD_createCStream();
  SCOPE_EXIT {
    ZSTD_freeCStream(zcs);
  };

  auto rc = ZSTD_initCStream(zcs, level_);
  zstdThrowIfError(rc);

  Cursor cursor(data);
  auto result = IOBuf::createCombined(ZSTD_compressBound(cursor.totalLength()));

  ZSTD_outBuffer out;
  out.dst = result->writableTail();
  out.size = result->capacity();
  out.pos = 0;

  for (auto buffer = cursor.peekBytes(); !buffer.empty();) {
    ZSTD_inBuffer in;
    in.src = buffer.data();
    in.size = buffer.size();
    for (in.pos = 0; in.pos != in.size;) {
      rc = ZSTD_compressStream(zcs, &out, &in);
      zstdThrowIfError(rc);
    }
    cursor.skip(in.size);
    buffer = cursor.peekBytes();
  }

  rc = ZSTD_endStream(zcs, &out);
  zstdThrowIfError(rc);
  CHECK_EQ(rc, 0);

  result->append(out.pos);
  return result;
}
예제 #3
0
UInt32 CompressionCodecZSTD::doCompressData(const char * source, UInt32 source_size, char * dest) const
{
    size_t compressed_size = ZSTD_compress(dest, ZSTD_compressBound(source_size), source, source_size, level);

    if (ZSTD_isError(compressed_size))
        throw Exception("Cannot compress block with ZSTD: " + std::string(ZSTD_getErrorName(compressed_size)), ErrorCodes::CANNOT_COMPRESS);

    return compressed_size;
}
예제 #4
0
void SL::Remote_Access_Library::Network::Packet::compress()
{
	if (_PacketHeader.UnCompressedlen > 0) return;//allready compressed
	auto maxsize = ZSTD_compressBound(_PacketHeader.PayloadLen);
	auto buf = Remote_Access_Library::INTERNAL::_PacketBuffer.AquireBuffer(maxsize);
	
	_PacketHeader.UnCompressedlen = _PacketHeader.PayloadLen;
	_PacketHeader.PayloadLen = static_cast<unsigned int>(ZSTD_compress(buf.data, maxsize, data(), _PacketHeader.PayloadLen));
	memcpy(data(), buf.data, _PacketHeader.PayloadLen);
	Remote_Access_Library::INTERNAL::_PacketBuffer.ReleaseBuffer(buf);
}
예제 #5
0
static PyObject *py_zstd_compress(PyObject* self, PyObject *args) {

    PyObject *result;
    const char *source;
    uint32_t source_size;
    char *dest;
    uint32_t dest_size;
    uint32_t header_size;
    size_t cSize;
    uint32_t level = 0;

#if PY_MAJOR_VERSION >= 3
    if (!PyArg_ParseTuple(args, "y#|i", &source, &source_size, &level))
        return NULL;
#else
    if (!PyArg_ParseTuple(args, "s#|i", &source, &source_size, &level))
        return NULL;
#endif

    if (level <= 0) level=1;
    if (level > 20) level=20;

    header_size = sizeof(source_size);

    dest_size = ZSTD_compressBound(source_size);
    result = PyBytes_FromStringAndSize(NULL, header_size + dest_size);
    if (result == NULL) {
        return NULL;
    }
    dest = PyBytes_AS_STRING(result);

    memcpy(dest, &source_size, header_size);

    dest += header_size;

    if (source_size > 0) {
        // Low level == old version
        cSize = ZSTD_compress(dest, dest_size, source, source_size, level);
        if (ZSTD_isError(cSize))
            PyErr_Format(ZstdError, "Compression error: %s", ZSTD_getErrorName(cSize));
        Py_SIZE(result) = cSize + sizeof(source_size);
    }
    return result;
}
예제 #6
0
		ByteArray Compress(const ByteArrayView view, const int32 compressionLevel)
		{
			const size_t bufferSize = ZSTD_compressBound(view.size());

			Array<Byte> buffer(bufferSize);

			const size_t result = ZSTD_compress(buffer.data(), buffer.size(), view.data(), view.size(), compressionLevel);

			if (ZSTD_isError(result))
			{
				return ByteArray();
			}

			buffer.resize(result);

			buffer.shrink_to_fit();

			return ByteArray(std::move(buffer));
		}
예제 #7
0
  static ezResult CompressZStd(ezArrayPtr<const ezUInt8> pUncompressedData, ezDynamicArray<ezUInt8>& out_Data)
  {
    size_t uiSizeBound = ZSTD_compressBound(pUncompressedData.GetCount());
    if(uiSizeBound > std::numeric_limits<ezUInt32>::max())
    {
      ezLog::Error("Can't compress since the output container can't hold enough elements ({0})", static_cast<ezUInt64>(uiSizeBound));
      return EZ_FAILURE;
    }

    out_Data.SetCountUninitialized(static_cast<ezUInt32>(uiSizeBound));

    size_t const cSize = ZSTD_compress(out_Data.GetData(), uiSizeBound, pUncompressedData.GetPtr(), pUncompressedData.GetCount(), 1);
    if (ZSTD_isError(cSize))
    {
      ezLog::Error("Compression failed with error: '{0}'.", ZSTD_getErrorName(cSize));
      return EZ_FAILURE;
    }

    out_Data.SetCount(static_cast<ezUInt32>(cSize));

    return EZ_SUCCESS;
  }
예제 #8
0
파일: demo_c.c 프로젝트: jrmarino/zstd-ada
static void compress(const char* fname, const char* oname, const ZSTD_CDict* cdict)
{
    size_t fSize;
    void* const fBuff = loadFile_orDie(fname, &fSize);
    size_t const cBuffSize = ZSTD_compressBound(fSize);
    void* const cBuff = malloc_orDie(cBuffSize);

    ZSTD_CCtx* const cctx = ZSTD_createCCtx();
    size_t const cSize = ZSTD_compress_usingCDict(cctx, cBuff, cBuffSize, fBuff, fSize, cdict);
    if (ZSTD_isError(cSize)) {
        fprintf(stderr, "error compressing %s : %s \n", fname, ZSTD_getErrorName(cSize));
        exit(7);
    }

    saveFile_orDie(oname, cBuff, cSize);

    /* success */
    printf("%25s : %6u -> %7u - %s \n", fname, (unsigned)fSize, (unsigned)cSize, oname);

    ZSTD_freeCCtx(cctx);
    free(fBuff);
    free(cBuff);
}
예제 #9
0
파일: Compression.cpp 프로젝트: 1Hgm/folly
std::unique_ptr<IOBuf> ZSTDCodec::doCompress(const IOBuf* data) {
  size_t rc;
  size_t maxCompressedLength = ZSTD_compressBound(data->length());
  auto out = IOBuf::createCombined(maxCompressedLength);

  CHECK_EQ(out->length(), 0);

  rc = ZSTD_compress(out->writableTail(),
                     out->capacity(),
                     data->data(),
                     data->length(),
                     level_);

  if (ZSTD_isError(rc)) {
    throw std::runtime_error(to<std::string>(
          "ZSTD compression returned an error: ",
          ZSTD_getErrorName(rc)));
  }

  out->append(rc);
  CHECK_EQ(out->length(), rc);

  return out;
}
예제 #10
0
UInt32 CompressionCodecZSTD::getMaxCompressedDataSize(UInt32 uncompressed_size) const
{
    return ZSTD_compressBound(uncompressed_size);
}
예제 #11
0
int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility)
{
    BYTE* cNoiseBuffer[5];
    BYTE* srcBuffer;
    BYTE* cBuffer;
    BYTE* dstBuffer;
    BYTE* mirrorBuffer;
    size_t srcBufferSize = (size_t)1<<maxSrcLog;
    size_t dstBufferSize = (size_t)1<<maxSampleLog;
    size_t cBufferSize   = ZSTD_compressBound(dstBufferSize);
    U32 result = 0;
    U32 testNb = 0;
    U32 coreSeed = seed, lseed = 0;
    ZSTD_CCtx* refCtx;
    ZSTD_CCtx* ctx;
    ZSTD_DCtx* dctx;
    U32 startTime = FUZ_GetMilliStart();

    /* allocation */
    refCtx = ZSTD_createCCtx();
    ctx = ZSTD_createCCtx();
    dctx= ZSTD_createDCtx();
    cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
    cNoiseBuffer[1] = (BYTE*)malloc (srcBufferSize);
    cNoiseBuffer[2] = (BYTE*)malloc (srcBufferSize);
    cNoiseBuffer[3] = (BYTE*)malloc (srcBufferSize);
    cNoiseBuffer[4] = (BYTE*)malloc (srcBufferSize);
    dstBuffer = (BYTE*)malloc (dstBufferSize);
    mirrorBuffer = (BYTE*)malloc (dstBufferSize);
    cBuffer   = (BYTE*)malloc (cBufferSize);
    CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !cNoiseBuffer[3] || !cNoiseBuffer[4]
           || !dstBuffer || !mirrorBuffer || !cBuffer || !refCtx || !ctx || !dctx,
           "Not enough memory, fuzzer tests cancelled");

    /* Create initial samples */
    RDG_genBuffer(cNoiseBuffer[0], srcBufferSize, 0.00, 0., coreSeed);    /* pure noise */
    RDG_genBuffer(cNoiseBuffer[1], srcBufferSize, 0.05, 0., coreSeed);    /* barely compressible */
    RDG_genBuffer(cNoiseBuffer[2], srcBufferSize, compressibility, 0., coreSeed);
    RDG_genBuffer(cNoiseBuffer[3], srcBufferSize, 0.95, 0., coreSeed);    /* highly compressible */
    RDG_genBuffer(cNoiseBuffer[4], srcBufferSize, 1.00, 0., coreSeed);    /* sparse content */
    srcBuffer = cNoiseBuffer[2];

    /* catch up testNb */
    for (testNb=1; testNb < startTest; testNb++)
        FUZ_rand(&coreSeed);

    /* test loop */
    for ( ; (testNb <= nbTests) || (FUZ_GetMilliSpan(startTime) < g_testTime); testNb++ )
    {
        size_t sampleSize, sampleStart, maxTestSize, totalTestSize;
        size_t cSize, dSize, dSupSize, errorCode, totalCSize, totalGenSize;
        U32 sampleSizeLog, buffNb, cLevelMod, nbChunks, n;
        XXH64_CREATESTATE_STATIC(xxh64);
        U64 crcOrig, crcDest;
        int cLevel;
        BYTE* sampleBuffer;
        const BYTE* dict;
        size_t dictSize;

        /* init */
        if (nbTests >= testNb)
             { DISPLAYUPDATE(2, "\r%6u/%6u    ", testNb, nbTests); }
        else { DISPLAYUPDATE(2, "\r%6u      ", testNb); }

        FUZ_rand(&coreSeed);
        lseed = coreSeed ^ prime1;
        buffNb = FUZ_rand(&lseed) & 127;
        if (buffNb & 7) buffNb=2;
        else
        {
            buffNb >>= 3;
            if (buffNb & 7)
            {
                const U32 tnb[2] = { 1, 3 };
                buffNb = tnb[buffNb >> 3];
            }
            else
            {
                const U32 tnb[2] = { 0, 4 };
                buffNb = tnb[buffNb >> 3];
            }
        }
        srcBuffer = cNoiseBuffer[buffNb];
        sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
        sampleSize = (size_t)1 << sampleSizeLog;
        sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
        sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);

        /* create sample buffer (to catch read error with valgrind & sanitizers)  */
        sampleBuffer = (BYTE*)malloc(sampleSize);
        CHECK (sampleBuffer==NULL, "not enough memory for sample buffer");
        memcpy(sampleBuffer, srcBuffer + sampleStart, sampleSize);
        crcOrig = XXH64(sampleBuffer, sampleSize, 0);

        /* compression test */
        cLevelMod = MAX(1, 38 - (int)(MAX(9, sampleSizeLog) * 2));   /* use high compression levels with small samples, for speed */
        cLevel = (FUZ_rand(&lseed) % cLevelMod) +1;
        cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, sampleBuffer, sampleSize, cLevel);
        CHECK(ZSTD_isError(cSize), "ZSTD_compressCCtx failed");

        /* compression failure test : too small dest buffer */
        if (cSize > 3)
        {
            const size_t missing = (FUZ_rand(&lseed) % (cSize-2)) + 1;   /* no problem, as cSize > 4 (frameHeaderSizer) */
            const size_t tooSmallSize = cSize - missing;
            static const U32 endMark = 0x4DC2B1A9;
            U32 endCheck;
            memcpy(dstBuffer+tooSmallSize, &endMark, 4);
            errorCode = ZSTD_compressCCtx(ctx, dstBuffer, tooSmallSize, sampleBuffer, sampleSize, cLevel);
            CHECK(!ZSTD_isError(errorCode), "ZSTD_compressCCtx should have failed ! (buffer too small : %u < %u)", (U32)tooSmallSize, (U32)cSize);
            memcpy(&endCheck, dstBuffer+tooSmallSize, 4);
            CHECK(endCheck != endMark, "ZSTD_compressCCtx : dst buffer overflow");
        }

        /* successfull decompression tests*/
        dSupSize = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1;
        dSize = ZSTD_decompress(dstBuffer, sampleSize + dSupSize, cBuffer, cSize);
        CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s) (srcSize : %u ; cSize : %u)", ZSTD_getErrorName(dSize), (U32)sampleSize, (U32)cSize);
        crcDest = XXH64(dstBuffer, sampleSize, 0);
        CHECK(crcOrig != crcDest, "decompression result corrupted (pos %u / %u)", (U32)findDiff(sampleBuffer, dstBuffer, sampleSize), (U32)sampleSize);

        free(sampleBuffer);   /* no longer useful after this point */

        /* truncated src decompression test */
        {
            const size_t missing = (FUZ_rand(&lseed) % (cSize-2)) + 1;   /* no problem, as cSize > 4 (frameHeaderSizer) */
            const size_t tooSmallSize = cSize - missing;
            void* cBufferTooSmall = malloc(tooSmallSize);   /* valgrind will catch overflows */
            CHECK(cBufferTooSmall == NULL, "not enough memory !");
            memcpy(cBufferTooSmall, cBuffer, tooSmallSize);
            errorCode = ZSTD_decompress(dstBuffer, dstBufferSize, cBufferTooSmall, tooSmallSize);
            CHECK(!ZSTD_isError(errorCode), "ZSTD_decompress should have failed ! (truncated src buffer)");
            free(cBufferTooSmall);
        }

        /* too small dst decompression test */
        if (sampleSize > 3)
        {
            const size_t missing = (FUZ_rand(&lseed) % (sampleSize-2)) + 1;   /* no problem, as cSize > 4 (frameHeaderSizer) */
            const size_t tooSmallSize = sampleSize - missing;
            static const BYTE token = 0xA9;
            dstBuffer[tooSmallSize] = token;
            errorCode = ZSTD_decompress(dstBuffer, tooSmallSize, cBuffer, cSize);
            CHECK(!ZSTD_isError(errorCode), "ZSTD_decompress should have failed : %u > %u (dst buffer too small)", (U32)errorCode, (U32)tooSmallSize);
            CHECK(dstBuffer[tooSmallSize] != token, "ZSTD_decompress : dst buffer overflow");
        }

        /* noisy src decompression test */
        if (cSize > 6)
        {
            const U32 maxNbBits = FUZ_highbit32((U32)(cSize-4));
            size_t pos = 4;   /* preserve magic number (too easy to detect) */
            U32 nbBits = FUZ_rand(&lseed) % maxNbBits;
            size_t mask = (1<<nbBits) - 1;
            size_t skipLength = FUZ_rand(&lseed) & mask;
            pos += skipLength;

            while (pos < cSize)
            {
                /* add noise */
                size_t noiseStart, noiseLength;
                nbBits = FUZ_rand(&lseed) % maxNbBits;
                if (nbBits>0) nbBits--;
                mask = (1<<nbBits) - 1;
                noiseLength = (FUZ_rand(&lseed) & mask) + 1;
                if ( pos+noiseLength > cSize ) noiseLength = cSize-pos;
                noiseStart = FUZ_rand(&lseed) % (srcBufferSize - noiseLength);
                memcpy(cBuffer + pos, srcBuffer + noiseStart, noiseLength);
                pos += noiseLength;

                /* keep some original src */
                nbBits = FUZ_rand(&lseed) % maxNbBits;
                mask = (1<<nbBits) - 1;
                skipLength = FUZ_rand(&lseed) & mask;
                pos += skipLength;
            }

            /* decompress noisy source */
            {
                U32 noiseSrc = FUZ_rand(&lseed) % 5;
                const U32 endMark = 0xA9B1C3D6;
                U32 endCheck;
                srcBuffer = cNoiseBuffer[noiseSrc];
                memcpy(dstBuffer+sampleSize, &endMark, 4);
                errorCode = ZSTD_decompress(dstBuffer, sampleSize, cBuffer, cSize);
                /* result *may* be an unlikely success, but even then, it must strictly respect dest buffer boundaries */
                CHECK((!ZSTD_isError(errorCode)) && (errorCode>sampleSize),
                      "ZSTD_decompress on noisy src : result is too large : %u > %u (dst buffer)", (U32)errorCode, (U32)sampleSize);
                memcpy(&endCheck, dstBuffer+sampleSize, 4);
                CHECK(endMark!=endCheck, "ZSTD_decompress on noisy src : dst buffer overflow");
            }
        }

        /* Streaming compression of scattered segments test */
        XXH64_reset(xxh64, 0);
        nbChunks = (FUZ_rand(&lseed) & 127) + 2;
        sampleSizeLog = FUZ_rand(&lseed) % maxSrcLog;
        maxTestSize = (size_t)1 << sampleSizeLog;
        maxTestSize += FUZ_rand(&lseed) & (maxTestSize-1);
        if (maxTestSize >= dstBufferSize) maxTestSize = dstBufferSize-1;

        sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
        sampleSize = (size_t)1 << sampleSizeLog;
        sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
        sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
        dict = srcBuffer + sampleStart;
        dictSize = sampleSize;

        errorCode = ZSTD_compressBegin(refCtx, (FUZ_rand(&lseed) % (20 - (sampleSizeLog/3))) + 1);
        CHECK (ZSTD_isError(errorCode), "start streaming error : %s", ZSTD_getErrorName(errorCode));
        errorCode = ZSTD_compress_insertDictionary(refCtx, dict, dictSize);
        CHECK (ZSTD_isError(errorCode), "dictionary insertion error : %s", ZSTD_getErrorName(errorCode));
        errorCode = ZSTD_duplicateCCtx(ctx, refCtx);
        CHECK (ZSTD_isError(errorCode), "context duplication error : %s", ZSTD_getErrorName(errorCode));
        totalTestSize = 0; cSize = 0;
        for (n=0; n<nbChunks; n++)
        {
            sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
            sampleSize = (size_t)1 << sampleSizeLog;
            sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
            sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);

            if (cBufferSize-cSize < ZSTD_compressBound(sampleSize))
                /* avoid invalid dstBufferTooSmall */
                break;
            if (totalTestSize+sampleSize > maxTestSize) break;

            errorCode = ZSTD_compressContinue(ctx, cBuffer+cSize, cBufferSize-cSize, srcBuffer+sampleStart, sampleSize);
            CHECK (ZSTD_isError(errorCode), "multi-segments compression error : %s", ZSTD_getErrorName(errorCode));
            cSize += errorCode;

            XXH64_update(xxh64, srcBuffer+sampleStart, sampleSize);
            memcpy(mirrorBuffer + totalTestSize, srcBuffer+sampleStart, sampleSize);
            totalTestSize += sampleSize;
        }
        errorCode = ZSTD_compressEnd(ctx, cBuffer+cSize, cBufferSize-cSize);
        CHECK (ZSTD_isError(errorCode), "multi-segments epilogue error : %s", ZSTD_getErrorName(errorCode));
        cSize += errorCode;
        crcOrig = XXH64_digest(xxh64);

        /* streaming decompression test */
        errorCode = ZSTD_resetDCtx(dctx);
        CHECK (ZSTD_isError(errorCode), "cannot init DCtx : %s", ZSTD_getErrorName(errorCode));
        ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
        totalCSize = 0;
        totalGenSize = 0;
        while (totalCSize < cSize)
        {
            size_t inSize = ZSTD_nextSrcSizeToDecompress(dctx);
            size_t genSize = ZSTD_decompressContinue(dctx, dstBuffer+totalGenSize, dstBufferSize-totalGenSize, cBuffer+totalCSize, inSize);
            CHECK (ZSTD_isError(genSize), "streaming decompression error : %s", ZSTD_getErrorName(genSize));
            totalGenSize += genSize;
            totalCSize += inSize;
        }
        CHECK (ZSTD_nextSrcSizeToDecompress(dctx) != 0, "frame not fully decoded");
        CHECK (totalGenSize != totalTestSize, "decompressed data : wrong size")
        CHECK (totalCSize != cSize, "compressed data should be fully read")
        crcDest = XXH64(dstBuffer, totalTestSize, 0);
        if (crcDest!=crcOrig)
            errorCode = findDiff(mirrorBuffer, dstBuffer, totalTestSize);
        CHECK (crcDest!=crcOrig, "streaming decompressed data corrupted : byte %u / %u  (%02X!=%02X)",
               (U32)errorCode, (U32)totalTestSize, dstBuffer[errorCode], mirrorBuffer[errorCode]);

    }
예제 #12
0
static int basicUnitTests(U32 seed, double compressibility)
{
    int testResult = 0;
    void* CNBuffer;
    void* compressedBuffer;
    void* decodedBuffer;
    U32 randState = seed;
    size_t result, cSize;
    U32 testNb=0;

    /* Create compressible test buffer */
    CNBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
    compressedBuffer = malloc(ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH));
    decodedBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
    if (!CNBuffer || !compressedBuffer || !decodedBuffer)
    {
        DISPLAY("Not enough memory, aborting\n");
        testResult = 1;
        goto _end;
    }
    RDG_genBuffer(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, 0., randState);

    /* Basic tests */
    DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    result = ZSTD_compress(compressedBuffer, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH), CNBuffer, COMPRESSIBLE_NOISE_LENGTH, 1);
    if (ZSTD_isError(result)) goto _output_error;
    cSize = result;
    DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);

    DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize);
    if (ZSTD_isError(result)) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    {
        size_t i;
        DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
        for (i=0; i<COMPRESSIBLE_NOISE_LENGTH; i++)
        {
            if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;;
        }
        DISPLAYLEVEL(4, "OK \n");
    }

    DISPLAYLEVEL(4, "test%3i : decompress with 1 missing byte : ", testNb++);
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize-1);
    if (!ZSTD_isError(result)) goto _output_error;
    if (result != (size_t)-ZSTD_error_srcSize_wrong) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    DISPLAYLEVEL(4, "test%3i : decompress with 1 too much byte : ", testNb++);
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize+1);
    if (!ZSTD_isError(result)) goto _output_error;
    if (result != (size_t)-ZSTD_error_srcSize_wrong) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    /* Dictionary and Duplication tests */
    {
        ZSTD_CCtx* ctxOrig = ZSTD_createCCtx();
        ZSTD_CCtx* ctxDuplicated = ZSTD_createCCtx();
        ZSTD_DCtx* dctx = ZSTD_createDCtx();
        const size_t dictSize = 500;
        size_t cSizeOrig;

        DISPLAYLEVEL(4, "test%3i : load dictionary into context : ", testNb++);
        result = ZSTD_compressBegin(ctxOrig, 2);
        if (ZSTD_isError(result)) goto _output_error;
        result = ZSTD_compress_insertDictionary(ctxOrig, CNBuffer, dictSize);
        if (ZSTD_isError(result)) goto _output_error;
        result = ZSTD_duplicateCCtx(ctxDuplicated, ctxOrig);
        if (ZSTD_isError(result)) goto _output_error;
        DISPLAYLEVEL(4, "OK \n");

        DISPLAYLEVEL(4, "test%3i : compress with dictionary : ", testNb++);
        cSize = 0;
        result = ZSTD_compressContinue(ctxOrig, compressedBuffer, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH), (const char*)CNBuffer + dictSize, COMPRESSIBLE_NOISE_LENGTH - dictSize);
        if (ZSTD_isError(result)) goto _output_error;
        cSize += result;
        result = ZSTD_compressEnd(ctxOrig, (char*)compressedBuffer+cSize, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH)-cSize);
        if (ZSTD_isError(result)) goto _output_error;
        cSize += result;
        DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);

        DISPLAYLEVEL(4, "test%3i : frame built with dictionary should be decompressible : ", testNb++);
        result = ZSTD_decompress_usingDict(dctx,
                                           decodedBuffer, COMPRESSIBLE_NOISE_LENGTH,
                                           compressedBuffer, cSize,
                                           CNBuffer, dictSize);
        if (ZSTD_isError(result)) goto _output_error;
        if (result != COMPRESSIBLE_NOISE_LENGTH - dictSize) goto _output_error;
        ZSTD_freeCCtx(ctxOrig);   /* if ctxOrig is read, will produce segfault */
        DISPLAYLEVEL(4, "OK \n");

        DISPLAYLEVEL(4, "test%3i : compress with duplicated context : ", testNb++);
        cSizeOrig = cSize;
        cSize = 0;
        result = ZSTD_compressContinue(ctxDuplicated, compressedBuffer, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH), (const char*)CNBuffer + dictSize, COMPRESSIBLE_NOISE_LENGTH - dictSize);
        if (ZSTD_isError(result)) goto _output_error;
        cSize += result;
        result = ZSTD_compressEnd(ctxDuplicated, (char*)compressedBuffer+cSize, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH)-cSize);
        if (ZSTD_isError(result)) goto _output_error;
        cSize += result;
        if (cSize != cSizeOrig) goto _output_error;   /* should be identical == have same size */
        ZSTD_freeCCtx(ctxDuplicated);
        DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);

        DISPLAYLEVEL(4, "test%3i : frame built with duplicated context should be decompressible : ", testNb++);
        result = ZSTD_decompress_usingDict(dctx,
                                           decodedBuffer, COMPRESSIBLE_NOISE_LENGTH,
                                           compressedBuffer, cSize,
                                           CNBuffer, dictSize);
        if (ZSTD_isError(result)) goto _output_error;
        if (result != COMPRESSIBLE_NOISE_LENGTH - dictSize) goto _output_error;
        ZSTD_freeDCtx(dctx);
        DISPLAYLEVEL(4, "OK \n");
    }

    /* Decompression defense tests */
    DISPLAYLEVEL(4, "test%3i : Check input length for magic number : ", testNb++);
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, CNBuffer, 3);
    if (!ZSTD_isError(result)) goto _output_error;
    if (result != (size_t)-ZSTD_error_srcSize_wrong) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    DISPLAYLEVEL(4, "test%3i : Check magic Number : ", testNb++);
    ((char*)(CNBuffer))[0] = 1;
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, CNBuffer, 4);
    if (!ZSTD_isError(result)) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    /* block API tests */
    {
        ZSTD_CCtx* const cctx = ZSTD_createCCtx();
        ZSTD_DCtx* const dctx = ZSTD_createDCtx();
        const size_t blockSize = 100 KB;
        const size_t dictSize = 16 KB;

        /* basic block compression */
        DISPLAYLEVEL(4, "test%3i : Block compression test : ", testNb++);
        result = ZSTD_compressBegin(cctx, 5);
        if (ZSTD_isError(result)) goto _output_error;
        cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize);
        if (ZSTD_isError(cSize)) goto _output_error;
        DISPLAYLEVEL(4, "OK \n");

        DISPLAYLEVEL(4, "test%3i : Block decompression test : ", testNb++);
        result = ZSTD_resetDCtx(dctx);
        if (ZSTD_isError(result)) goto _output_error;
        result = ZSTD_decompressBlock(dctx, decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize);
        if (ZSTD_isError(result)) goto _output_error;
        if (result != blockSize) goto _output_error;
        DISPLAYLEVEL(4, "OK \n");

        /* dictionary block compression */
        DISPLAYLEVEL(4, "test%3i : Dictionary Block compression test : ", testNb++);
        result = ZSTD_compressBegin(cctx, 5);
        if (ZSTD_isError(result)) goto _output_error;
        result = ZSTD_compress_insertDictionary(cctx, CNBuffer, dictSize);
        if (ZSTD_isError(result)) goto _output_error;
        cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize);
        if (ZSTD_isError(cSize)) goto _output_error;
        DISPLAYLEVEL(4, "OK \n");

        DISPLAYLEVEL(4, "test%3i : Dictionary Block decompression test : ", testNb++);
        result = ZSTD_resetDCtx(dctx);
        if (ZSTD_isError(result)) goto _output_error;
        ZSTD_decompress_insertDictionary(dctx, CNBuffer, dictSize);
        result = ZSTD_decompressBlock(dctx, decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize);
        if (ZSTD_isError(result)) goto _output_error;
        if (result != blockSize) goto _output_error;
        DISPLAYLEVEL(4, "OK \n");

        ZSTD_freeCCtx(cctx);
        ZSTD_freeDCtx(dctx);
    }

    /* long rle test */
    {
        size_t sampleSize = 0;
        DISPLAYLEVEL(4, "test%3i : Long RLE test : ", testNb++);
        RDG_genBuffer(CNBuffer, sampleSize, compressibility, 0., randState);
        memset((char*)CNBuffer+sampleSize, 'B', 256 KB - 1);
        sampleSize += 256 KB - 1;
        RDG_genBuffer((char*)CNBuffer+sampleSize, 96 KB, compressibility, 0., randState);
        sampleSize += 96 KB;
        cSize = ZSTD_compress(compressedBuffer, ZSTD_compressBound(sampleSize), CNBuffer, sampleSize, 1);
        if (ZSTD_isError(cSize)) goto _output_error;
        result = ZSTD_decompress(decodedBuffer, sampleSize, compressedBuffer, cSize);
        if (ZSTD_isError(result)) goto _output_error;
        if (result!=sampleSize) goto _output_error;
        DISPLAYLEVEL(4, "OK \n");
    }

_end:
    free(CNBuffer);
    free(compressedBuffer);
    free(decodedBuffer);
    return testResult;

_output_error:
    testResult = 1;
    DISPLAY("Error detected in Unit tests ! \n");
    goto _end;
}
예제 #13
0
파일: platform.c 프로젝트: Anjali05/linux
static int zbufsize_zstd(size_t size)
{
	return ZSTD_compressBound(size);
}
예제 #14
0
파일: zstd_buffered.c 프로젝트: 7AC/beats
size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_compressBound(BLOCKSIZE) + ZBUFF_blockHeaderSize + ZBUFF_endFrameSize; }
예제 #15
0
static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
                              void* dst, size_t* maxDstSizePtr,
                        const void* src, size_t* srcSizePtr,
                              int flush)   /* aggregate : wait for full block before compressing */
{
    U32 notDone = 1;
    const char* const istart = (const char*)src;
    const char* ip = istart;
    const char* const iend = istart + *srcSizePtr;
    char* const ostart = (char*)dst;
    char* op = ostart;
    char* const oend = ostart + *maxDstSizePtr;

    while (notDone)
    {
        switch(zbc->stage)
        {
        case ZBUFFcs_init: return ERROR(init_missing);   /* call ZBUFF_compressInit() first ! */

        case ZBUFFcs_load:
            /* complete inBuffer */
            {
                size_t toLoad = zbc->inBuffTarget - zbc->inBuffPos;
                size_t loaded = ZBUFF_limitCopy(zbc->inBuff + zbc->inBuffPos, toLoad, ip, iend-ip);
                zbc->inBuffPos += loaded;
                ip += loaded;
                if ( (zbc->inBuffPos==zbc->inToCompress) || (!flush && (toLoad != loaded)) )
                    { notDone = 0; break; }  /* not enough input to get a full block : stop there, wait for more */
            }
            /* compress current block (note : this stage cannot be stopped in the middle) */
            {
                void* cDst;
                size_t cSize;
                size_t iSize = zbc->inBuffPos - zbc->inToCompress;
                size_t oSize = oend-op;
                if (oSize >= ZSTD_compressBound(iSize))
                    cDst = op;   /* compress directly into output buffer (avoid flush stage) */
                else
                    cDst = zbc->outBuff, oSize = zbc->outBuffSize;
                cSize = ZSTD_compressContinue(zbc->zc, cDst, oSize, zbc->inBuff + zbc->inToCompress, iSize);
                if (ZSTD_isError(cSize)) return cSize;
                /* prepare next block */
                zbc->inBuffTarget = zbc->inBuffPos + zbc->blockSize;
                if (zbc->inBuffTarget > zbc->inBuffSize)
                    { zbc->inBuffPos = 0; zbc->inBuffTarget = zbc->blockSize; }   /* note : inBuffSize >= blockSize */
                zbc->inToCompress = zbc->inBuffPos;
                if (cDst == op) { op += cSize; break; }   /* no need to flush */
                zbc->outBuffContentSize = cSize;
                zbc->outBuffFlushedSize = 0;
                zbc->stage = ZBUFFcs_flush;
                // break;   /* flush stage follows */
            }

        case ZBUFFcs_flush:
            /* flush into dst */
            {
                size_t toFlush = zbc->outBuffContentSize - zbc->outBuffFlushedSize;
                size_t flushed = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outBuffFlushedSize, toFlush);
                op += flushed;
                zbc->outBuffFlushedSize += flushed;
                if (toFlush!=flushed)
                    { notDone = 0; break; } /* not enough space within dst to store compressed block : stop there */
                zbc->outBuffContentSize = 0;
                zbc->outBuffFlushedSize = 0;
                zbc->stage = ZBUFFcs_load;
                break;
            }
        }
    }

    *srcSizePtr = ip - istart;
    *maxDstSizePtr = op - ostart;
    {
        size_t hintInSize = zbc->inBuffTarget - zbc->inBuffPos;
        if (hintInSize==0) hintInSize = zbc->blockSize;
        return hintInSize;
    }
}
예제 #16
0
size_t ZBUFF_recommendedCOutSize() { return ZSTD_compressBound(BLOCKSIZE) + 6; }
예제 #17
0
static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsigned endFrame)
{
    size_t const dstBufferCapacity = ZSTD_compressBound(srcSize);
    buffer_t const dstBuffer = ZSTDMT_getBuffer(zcs->buffPool, dstBufferCapacity);
    ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(zcs->cctxPool);
    unsigned const jobID = zcs->nextJobID & zcs->jobIDMask;

    if ((cctx==NULL) || (dstBuffer.start==NULL)) {
        zcs->jobs[jobID].jobCompleted = 1;
        zcs->nextJobID++;
        ZSTDMT_waitForAllJobsCompleted(zcs);
        ZSTDMT_releaseAllJobResources(zcs);
        return ERROR(memory_allocation);
    }

    DEBUGLOG(4, "preparing job %u to compress %u bytes with %u preload ", zcs->nextJobID, (U32)srcSize, (U32)zcs->dictSize);
    zcs->jobs[jobID].src = zcs->inBuff.buffer;
    zcs->jobs[jobID].srcStart = zcs->inBuff.buffer.start;
    zcs->jobs[jobID].srcSize = srcSize;
    zcs->jobs[jobID].dictSize = zcs->dictSize;   /* note : zcs->inBuff.filled is presumed >= srcSize + dictSize */
    zcs->jobs[jobID].params = zcs->params;
    if (zcs->nextJobID) zcs->jobs[jobID].params.fParams.checksumFlag = 0;  /* do not calculate checksum within sections, just keep it in header for first section */
    zcs->jobs[jobID].cdict = zcs->nextJobID==0 ? zcs->cdict : NULL;
    zcs->jobs[jobID].fullFrameSize = zcs->frameContentSize;
    zcs->jobs[jobID].dstBuff = dstBuffer;
    zcs->jobs[jobID].cctx = cctx;
    zcs->jobs[jobID].firstChunk = (zcs->nextJobID==0);
    zcs->jobs[jobID].lastChunk = endFrame;
    zcs->jobs[jobID].jobCompleted = 0;
    zcs->jobs[jobID].dstFlushed = 0;
    zcs->jobs[jobID].jobCompleted_mutex = &zcs->jobCompleted_mutex;
    zcs->jobs[jobID].jobCompleted_cond = &zcs->jobCompleted_cond;

    /* get a new buffer for next input */
    if (!endFrame) {
        size_t const newDictSize = MIN(srcSize + zcs->dictSize, zcs->targetDictSize);
        zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize);
        if (zcs->inBuff.buffer.start == NULL) {   /* not enough memory to allocate next input buffer */
            zcs->jobs[jobID].jobCompleted = 1;
            zcs->nextJobID++;
            ZSTDMT_waitForAllJobsCompleted(zcs);
            ZSTDMT_releaseAllJobResources(zcs);
            return ERROR(memory_allocation);
        }
        DEBUGLOG(5, "inBuff filled to %u", (U32)zcs->inBuff.filled);
        zcs->inBuff.filled -= srcSize + zcs->dictSize - newDictSize;
        DEBUGLOG(5, "new job : filled to %u, with %u dict and %u src", (U32)zcs->inBuff.filled, (U32)newDictSize, (U32)(zcs->inBuff.filled - newDictSize));
        memmove(zcs->inBuff.buffer.start, (const char*)zcs->jobs[jobID].srcStart + zcs->dictSize + srcSize - newDictSize, zcs->inBuff.filled);
        DEBUGLOG(5, "new inBuff pre-filled");
        zcs->dictSize = newDictSize;
    } else {
        zcs->inBuff.buffer = g_nullBuffer;
        zcs->inBuff.filled = 0;
        zcs->dictSize = 0;
        zcs->frameEnded = 1;
        if (zcs->nextJobID == 0)
            zcs->params.fParams.checksumFlag = 0;   /* single chunk : checksum is calculated directly within worker thread */
    }

    DEBUGLOG(3, "posting job %u : %u bytes  (end:%u) (note : doneJob = %u=>%u)", zcs->nextJobID, (U32)zcs->jobs[jobID].srcSize, zcs->jobs[jobID].lastChunk, zcs->doneJobID, zcs->doneJobID & zcs->jobIDMask);
    POOL_add(zcs->factory, ZSTDMT_compressChunk, &zcs->jobs[jobID]);   /* this call is blocking when thread worker pool is exhausted */
    zcs->nextJobID++;
    return 0;
}
예제 #18
0
gboolean
rspamd_client_command (struct rspamd_client_connection *conn,
                       const gchar *command, GQueue *attrs,
                       FILE *in, rspamd_client_callback cb,
                       gpointer ud, gboolean compressed,
                       const gchar *comp_dictionary,
                       GError **err)
{
    struct rspamd_client_request *req;
    struct rspamd_http_client_header *nh;
    gchar *p;
    gsize remain, old_len;
    GList *cur;
    GString *input = NULL;
    rspamd_fstring_t *body;
    guint dict_id = 0;
    gsize dict_len = 0;
    void *dict = NULL;
    ZSTD_CCtx *zctx;

    req = g_slice_alloc0 (sizeof (struct rspamd_client_request));
    req->conn = conn;
    req->cb = cb;
    req->ud = ud;

    req->msg = rspamd_http_new_message (HTTP_REQUEST);
    if (conn->key) {
        req->msg->peer_key = rspamd_pubkey_ref (conn->key);
    }

    if (in != NULL) {
        /* Read input stream */
        input = g_string_sized_new (BUFSIZ);

        while (!feof (in)) {
            p = input->str + input->len;
            remain = input->allocated_len - input->len - 1;
            if (remain == 0) {
                old_len = input->len;
                g_string_set_size (input, old_len * 2);
                input->len = old_len;
                continue;
            }
            remain = fread (p, 1, remain, in);
            if (remain > 0) {
                input->len += remain;
                input->str[input->len] = '\0';
            }
        }
        if (ferror (in) != 0) {
            g_set_error (err, RCLIENT_ERROR, ferror (
                             in), "input IO error: %s", strerror (ferror (in)));
            g_slice_free1 (sizeof (struct rspamd_client_request), req);
            g_string_free (input, TRUE);
            return FALSE;
        }

        if (!compressed) {
            body = rspamd_fstring_new_init (input->str, input->len);
        }
        else {
            if (comp_dictionary) {
                dict = rspamd_file_xmap (comp_dictionary, PROT_READ, &dict_len);

                if (dict == NULL) {
                    g_set_error (err, RCLIENT_ERROR, errno,
                                 "cannot open dictionary %s: %s",
                                 comp_dictionary,
                                 strerror (errno));
                    g_slice_free1 (sizeof (struct rspamd_client_request), req);
                    g_string_free (input, TRUE);

                    return FALSE;
                }

                dict_id = ZDICT_getDictID (comp_dictionary, dict_len);

                if (dict_id == 0) {
                    g_set_error (err, RCLIENT_ERROR, errno,
                                 "cannot open dictionary %s: %s",
                                 comp_dictionary,
                                 strerror (errno));
                    g_slice_free1 (sizeof (struct rspamd_client_request), req);
                    g_string_free (input, TRUE);
                    munmap (dict, dict_len);

                    return FALSE;
                }
            }

            body = rspamd_fstring_sized_new (ZSTD_compressBound (input->len));
            zctx = ZSTD_createCCtx ();
            body->len = ZSTD_compress_usingDict (zctx, body->str, body->allocated,
                                                 input->str, input->len,
                                                 dict, dict_len,
                                                 1);

            munmap (dict, dict_len);

            if (ZSTD_isError (body->len)) {
                g_set_error (err, RCLIENT_ERROR, ferror (
                                 in), "compression error");
                g_slice_free1 (sizeof (struct rspamd_client_request), req);
                g_string_free (input, TRUE);
                rspamd_fstring_free (body);
                ZSTD_freeCCtx (zctx);

                return FALSE;
            }

            ZSTD_freeCCtx (zctx);
        }

        rspamd_http_message_set_body_from_fstring_steal (req->msg, body);
        req->input = input;
    }
    else {
        req->input = NULL;
    }

    /* Convert headers */
    cur = attrs->head;
    while (cur != NULL) {
        nh = cur->data;

        rspamd_http_message_add_header (req->msg, nh->name, nh->value);
        cur = g_list_next (cur);
    }

    if (compressed) {
        rspamd_http_message_add_header (req->msg, "Compression", "zstd");

        if (dict_id != 0) {
            gchar dict_str[32];

            rspamd_snprintf (dict_str, sizeof (dict_str), "%ud", dict_id);
            rspamd_http_message_add_header (req->msg, "Dictionary", dict_str);
        }
    }

    req->msg->url = rspamd_fstring_append (req->msg->url, "/", 1);
    req->msg->url = rspamd_fstring_append (req->msg->url, command, strlen (command));

    conn->req = req;

    if (compressed) {
        rspamd_http_connection_write_message (conn->http_conn, req->msg, NULL,
                                              "application/x-compressed", req, conn->fd,
                                              &conn->timeout, conn->ev_base);
    }
    else {
        rspamd_http_connection_write_message (conn->http_conn, req->msg, NULL,
                                              "text/plain", req, conn->fd, &conn->timeout, conn->ev_base);
    }

    return TRUE;
}
예제 #19
0
SL::Remote_Access_Library::Network::Packet::Packet(Packet_Impl& priv) {
	_PacketHeader = priv.h;
	_Data= Remote_Access_Library::INTERNAL::_PacketBuffer.AquireBuffer(ZSTD_compressBound(std::max(_PacketHeader.PayloadLen, _PacketHeader.UnCompressedlen)));
}
예제 #20
0
파일: zbufftest.c 프로젝트: peterh/zstd
static int basicUnitTests(U32 seed, double compressibility)
{
    int testResult = 0;
    void* CNBuffer;
    size_t CNBufferSize = COMPRESSIBLE_NOISE_LENGTH;
    void* compressedBuffer;
    size_t compressedBufferSize = ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH);
    void* decodedBuffer;
    size_t decodedBufferSize = CNBufferSize;
    U32 randState = seed;
    size_t result, cSize, readSize, genSize;
    U32 testNb=0;
    ZBUFF_CCtx* zc = ZBUFF_createCCtx();
    ZBUFF_DCtx* zd = ZBUFF_createDCtx();

    /* Create compressible test buffer */
    CNBuffer = malloc(CNBufferSize);
    compressedBuffer = malloc(compressedBufferSize);
    decodedBuffer = malloc(decodedBufferSize);
    if (!CNBuffer || !compressedBuffer || !decodedBuffer || !zc || !zd)
    {
        DISPLAY("Not enough memory, aborting\n");
        goto _output_error;
    }
    RDG_genBuffer(CNBuffer, CNBufferSize, compressibility, 0., randState);

    /* Basic compression test */
    DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    ZBUFF_compressInit(zc, 1);
    readSize = CNBufferSize;
    genSize = compressedBufferSize;
    result = ZBUFF_compressContinue(zc, compressedBuffer, &genSize, CNBuffer, &readSize);
    if (ZBUFF_isError(result)) goto _output_error;
    if (readSize != CNBufferSize) goto _output_error;   /* entire input should be consumed */
    cSize = genSize;
    genSize = compressedBufferSize - cSize;
    result = ZBUFF_compressEnd(zc, ((char*)compressedBuffer)+cSize, &genSize);
    if (result != 0) goto _output_error;   /* error, or some data not flushed */
    cSize += genSize;
    DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);

    /* Basic decompression test */
    DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    ZBUFF_decompressInit(zd);
    readSize = cSize;
    genSize = CNBufferSize;
    result = ZBUFF_decompressContinue(zd, decodedBuffer, &genSize, compressedBuffer, &readSize);
    if (result != 0) goto _output_error;  /* should reach end of frame == 0; otherwise, some data left, or an error */
    if (genSize != CNBufferSize) goto _output_error;   /* should regenerate the same amount */
    if (readSize != cSize) goto _output_error;   /* should have read the entire frame */
    DISPLAYLEVEL(4, "OK \n");

    /* check regenerated data is byte exact */
    {
        size_t i;
        DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
        for (i=0; i<CNBufferSize; i++)
        {
            if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;;
        }
        DISPLAYLEVEL(4, "OK \n");
    }

_end:
    ZBUFF_freeCCtx(zc);
    ZBUFF_freeDCtx(zd);
    free(CNBuffer);
    free(compressedBuffer);
    free(decodedBuffer);
    return testResult;

_output_error:
    testResult = 1;
    DISPLAY("Error detected in Unit tests ! \n");
    goto _end;
}
예제 #21
0
파일: fuzzer.c 프로젝트: mthiesen/zstd
int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility)
{
    BYTE* srcBuffer;
    BYTE* cBuffer;
    BYTE* dstBuffer;
    size_t srcBufferSize = (size_t)1<<maxSrcLog;
    size_t dstBufferSize = (size_t)1<<maxSampleLog;
    size_t cBufferSize   = ZSTD_compressBound(dstBufferSize);
    U32 result = 0;
    U32 testNb = 0;
    U32 coreSeed = seed, lseed = 0;
    (void)startTest; (void)compressibility;

    /* allocation */
    srcBuffer = malloc (srcBufferSize);
    dstBuffer = malloc (dstBufferSize);
    cBuffer   = malloc (cBufferSize);
    CHECK (!srcBuffer || !dstBuffer || !cBuffer, "Not enough memory, fuzzer tests cancelled");

    /* Create initial sample */
    FUZ_generateSynthetic(srcBuffer, srcBufferSize, 0.50, &coreSeed);

    /* catch up testNb */
    for (testNb=0; testNb < startTest; testNb++)
        FUZ_rand(&coreSeed);

    /* test loop */
    for (testNb=startTest; testNb < nbTests; testNb++)
    {
        size_t sampleSize, sampleStart;
        size_t cSize, dSize, dSupSize;
        U32 sampleSizeLog;
        U64 crcOrig, crcDest;

        /* init */
        DISPLAYUPDATE(2, "\r%6u/%6u   ", testNb, nbTests);
        FUZ_rand(&coreSeed);
        lseed = coreSeed ^ prime1;
        sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
        sampleSize = (size_t)1<<sampleSizeLog;
        sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
        sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
        crcOrig = XXH64(srcBuffer + sampleStart, sampleSize, 0);

        /* compression tests*/
        cSize = ZSTD_compress(cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize);
        CHECK(ZSTD_isError(cSize), "ZSTD_compress failed");

        /* decompression tests*/
        dSupSize = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1;
        dSize = ZSTD_decompress(dstBuffer, sampleSize + dSupSize, cBuffer, cSize);
        CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s)", ZSTD_getErrorName(dSize));
        crcDest = XXH64(dstBuffer, sampleSize, 0);
        CHECK(crcOrig != crcDest, "dstBuffer corrupted (pos %u / %u)", (U32)findDiff(srcBuffer+sampleStart, dstBuffer, sampleSize), (U32)sampleSize);
    }
    DISPLAY("\rAll fuzzer tests completed   \n");

_cleanup:
    free(srcBuffer);
    free(cBuffer);
    free(dstBuffer);
    return result;

_output_error:
    result = 1;
    goto _cleanup;
}
예제 #22
0
파일: fuzzer.c 프로젝트: mthiesen/zstd
static int basicUnitTests(U32 seed, double compressibility)
{
    int testResult = 0;
    void* CNBuffer;
    void* compressedBuffer;
    void* decodedBuffer;
    U32 randState = seed;
    size_t result, cSize;
    U32 testNb=0;

    // Create compressible test buffer
    CNBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
    compressedBuffer = malloc(ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH));
    decodedBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
    FUZ_generateSynthetic(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, &randState);

    // Basic tests
    DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    result = ZSTD_compress(compressedBuffer, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH), CNBuffer, COMPRESSIBLE_NOISE_LENGTH);
    if (ZSTD_isError(result)) goto _output_error;
    cSize = result;
    DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);

    DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize);
    if (ZSTD_isError(result)) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    {
        size_t i;
        DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
        for (i=0; i<COMPRESSIBLE_NOISE_LENGTH; i++)
        {
            if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;;
        }
        DISPLAYLEVEL(4, "OK \n");
    }

    DISPLAYLEVEL(4, "test%3i : decompress with 1 missing byte : ", testNb++);
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize-1);
    if (!ZSTD_isError(result)) goto _output_error;
    if (result != (size_t)-ZSTD_ERROR_wrongSrcSize) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    DISPLAYLEVEL(4, "test%3i : decompress with 1 too much byte : ", testNb++);
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize+1);
    if (!ZSTD_isError(result)) goto _output_error;
    if (result != (size_t)-ZSTD_ERROR_wrongSrcSize) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    /* Decompression defense tests */
    DISPLAYLEVEL(4, "test%3i : Check input length for magic number : ", testNb++);
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, CNBuffer, 3);
    if (!ZSTD_isError(result)) goto _output_error;
    if (result != (size_t)-ZSTD_ERROR_wrongSrcSize) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

    DISPLAYLEVEL(4, "test%3i : Check magic Number : ", testNb++);
    ((char*)(CNBuffer))[0] = 1;
    result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, CNBuffer, 4);
    if (!ZSTD_isError(result)) goto _output_error;
    if (result != (size_t)-ZSTD_ERROR_wrongMagicNumber) goto _output_error;
    DISPLAYLEVEL(4, "OK \n");

_end:
    free(CNBuffer);
    free(compressedBuffer);
    free(decodedBuffer);
    return testResult;

_output_error:
    testResult = 1;
    DISPLAY("Error detected in Unit tests ! \n");
    goto _end;
}
예제 #23
0
void CompressedWriteBuffer::nextImpl()
{
	if (!offset())
		return;

	size_t uncompressed_size = offset();
	size_t compressed_size = 0;
	char * compressed_buffer_ptr = nullptr;

	/** Формат сжатого блока - см. CompressedStream.h
		*/

	switch (method)
	{
		case CompressionMethod::QuickLZ:
		{
		#ifdef USE_QUICKLZ
			compressed_buffer.resize(uncompressed_size + QUICKLZ_ADDITIONAL_SPACE);

			compressed_size = qlz_compress(
				working_buffer.begin(),
				&compressed_buffer[0],
				uncompressed_size,
				qlz_state.get());

			compressed_buffer[0] &= 3;
			compressed_buffer_ptr = &compressed_buffer[0];
			break;
		#else
			throw Exception("QuickLZ compression method is disabled", ErrorCodes::UNKNOWN_COMPRESSION_METHOD);
		#endif
		}
		case CompressionMethod::LZ4:
		case CompressionMethod::LZ4HC:
		{
			static constexpr size_t header_size = 1 + sizeof(UInt32) + sizeof(UInt32);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
			compressed_buffer.resize(header_size + LZ4_COMPRESSBOUND(uncompressed_size));
#pragma GCC diagnostic pop

			compressed_buffer[0] = static_cast<UInt8>(CompressionMethodByte::LZ4);

			if (method == CompressionMethod::LZ4)
				compressed_size = header_size + LZ4_compress(
					working_buffer.begin(),
					&compressed_buffer[header_size],
					uncompressed_size);
			else
				compressed_size = header_size + LZ4_compressHC(
					working_buffer.begin(),
					&compressed_buffer[header_size],
					uncompressed_size);

			UInt32 compressed_size_32 = compressed_size;
			UInt32 uncompressed_size_32 = uncompressed_size;

			unalignedStore(&compressed_buffer[1], compressed_size_32);
			unalignedStore(&compressed_buffer[5], uncompressed_size_32);

			compressed_buffer_ptr = &compressed_buffer[0];
			break;
		}
		case CompressionMethod::ZSTD:
		{
			static constexpr size_t header_size = 1 + sizeof(UInt32) + sizeof(UInt32);

			compressed_buffer.resize(header_size + ZSTD_compressBound(uncompressed_size));

			compressed_buffer[0] = static_cast<UInt8>(CompressionMethodByte::ZSTD);

			size_t res = ZSTD_compress(
				&compressed_buffer[header_size],
				compressed_buffer.size(),
				working_buffer.begin(),
				uncompressed_size,
				1);

			if (ZSTD_isError(res))
				throw Exception("Cannot compress block with ZSTD: " + std::string(ZSTD_getErrorName(res)), ErrorCodes::CANNOT_COMPRESS);

			compressed_size = header_size + res;

			UInt32 compressed_size_32 = compressed_size;
			UInt32 uncompressed_size_32 = uncompressed_size;

			unalignedStore(&compressed_buffer[1], compressed_size_32);
			unalignedStore(&compressed_buffer[5], uncompressed_size_32);

			compressed_buffer_ptr = &compressed_buffer[0];
			break;
		}
		default:
			throw Exception("Unknown compression method", ErrorCodes::UNKNOWN_COMPRESSION_METHOD);
	}

	uint128 checksum = CityHash128(compressed_buffer_ptr, compressed_size);
	out.write(reinterpret_cast<const char *>(&checksum), sizeof(checksum));

	out.write(compressed_buffer_ptr, compressed_size);
}
예제 #24
0
파일: zbufftest.c 프로젝트: peterh/zstd
int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility)
{
    BYTE* cNoiseBuffer[5];
    BYTE* srcBuffer;
    size_t srcBufferSize = (size_t)1<<maxSrcLog;
    BYTE* copyBuffer;
    size_t copyBufferSize = srcBufferSize + (1<<maxSampleLog);
    BYTE* cBuffer;
    size_t cBufferSize   = ZSTD_compressBound(srcBufferSize);
    BYTE* dstBuffer;
    size_t dstBufferSize = srcBufferSize;
    U32 result = 0;
    U32 testNb = 0;
    U32 coreSeed = seed, lseed = 0;
    ZBUFF_CCtx* zc;
    ZBUFF_DCtx* zd;
    XXH64_state_t crc64;
    U32 startTime = FUZ_GetMilliStart();

    /* allocation */
    zc = ZBUFF_createCCtx();
    zd = ZBUFF_createDCtx();
    cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
    cNoiseBuffer[1] = (BYTE*)malloc (srcBufferSize);
    cNoiseBuffer[2] = (BYTE*)malloc (srcBufferSize);
    cNoiseBuffer[3] = (BYTE*)malloc (srcBufferSize);
    cNoiseBuffer[4] = (BYTE*)malloc (srcBufferSize);
    copyBuffer= (BYTE*)malloc (copyBufferSize);
    dstBuffer = (BYTE*)malloc (dstBufferSize);
    cBuffer   = (BYTE*)malloc (cBufferSize);
    CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !cNoiseBuffer[3] || !cNoiseBuffer[4] ||
           !copyBuffer || !dstBuffer || !cBuffer || !zc || !zd,
           "Not enough memory, fuzzer tests cancelled");

    /* Create initial samples */
    RDG_genBuffer(cNoiseBuffer[0], srcBufferSize, 0.00, 0., coreSeed);    /* pure noise */
    RDG_genBuffer(cNoiseBuffer[1], srcBufferSize, 0.05, 0., coreSeed);    /* barely compressible */
    RDG_genBuffer(cNoiseBuffer[2], srcBufferSize, compressibility, 0., coreSeed);
    RDG_genBuffer(cNoiseBuffer[3], srcBufferSize, 0.95, 0., coreSeed);    /* highly compressible */
    RDG_genBuffer(cNoiseBuffer[4], srcBufferSize, 1.00, 0., coreSeed);    /* sparse content */
    srcBuffer = cNoiseBuffer[2];
    memset(copyBuffer, 0x65, copyBufferSize);
    memcpy(copyBuffer, srcBuffer, MIN(copyBufferSize,srcBufferSize));   /* make copyBuffer considered initialized */

    /* catch up testNb */
    for (testNb=1; testNb < startTest; testNb++)
        FUZ_rand(&coreSeed);

    /* test loop */
    for ( ; (testNb <= nbTests) || (FUZ_GetMilliSpan(startTime) < g_testTime); testNb++ )
    {
        size_t sampleSize, sampleStart;
        size_t cSize;
        size_t maxTestSize, totalTestSize, readSize, totalCSize, genSize, totalGenSize;
        size_t errorCode;
        U32 sampleSizeLog, buffNb, n, nbChunks;
        U64 crcOrig, crcDest;

        /* init */
        DISPLAYUPDATE(2, "\r%6u", testNb);
        if (nbTests >= testNb) DISPLAYUPDATE(2, "/%6u   ", nbTests);
        FUZ_rand(&coreSeed);
        lseed = coreSeed ^ prime1;
        buffNb = FUZ_rand(&lseed) & 127;
        if (buffNb & 7) buffNb=2;   /* select buffer */
        else
        {
            buffNb >>= 3;
            if (buffNb & 7)
            {
                const U32 tnb[2] = { 1, 3 };
                buffNb = tnb[buffNb >> 3];
            }
            else
            {
                const U32 tnb[2] = { 0, 4 };
                buffNb = tnb[buffNb >> 3];
            }
        }
        srcBuffer = cNoiseBuffer[buffNb];

        /* Multi - segments compression test */
        XXH64_reset(&crc64, 0);
        nbChunks = (FUZ_rand(&lseed) & 127) + 2;
        sampleSizeLog = FUZ_rand(&lseed) % maxSrcLog;
        maxTestSize = (size_t)1 << sampleSizeLog;
        maxTestSize += FUZ_rand(&lseed) & (maxTestSize-1);
        ZBUFF_compressInit(zc, (FUZ_rand(&lseed) % (20 - (sampleSizeLog/3))) + 1);
        totalTestSize = 0;
        cSize = 0;
        for (n=0; n<nbChunks; n++)
        {
            sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
            sampleSize = (size_t)1 << sampleSizeLog;
            sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
            sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
            readSize = sampleSize;

            /* random size output buffer */
            sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
            sampleSize = (size_t)1 << sampleSizeLog;
            sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
            genSize = MIN (cBufferSize - cSize, sampleSize);

            errorCode = ZBUFF_compressContinue(zc, cBuffer+cSize, &genSize, srcBuffer+sampleStart, &readSize);
            CHECK (ZBUFF_isError(errorCode), "compression error : %s", ZBUFF_getErrorName(errorCode));

            XXH64_update(&crc64, srcBuffer+sampleStart, readSize);
            memcpy(copyBuffer+totalTestSize, srcBuffer+sampleStart, readSize);
            cSize += genSize;
            totalTestSize += readSize;

            if ((FUZ_rand(&lseed) & 15) == 0)
            {
                /* add a few random flushes operations, to mess around */
                sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
                sampleSize = (size_t)1 << sampleSizeLog;
                sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
                genSize = MIN (cBufferSize - cSize, sampleSize);
                errorCode = ZBUFF_compressFlush(zc, cBuffer+cSize, &genSize);
                CHECK (ZBUFF_isError(errorCode), "flush error : %s", ZBUFF_getErrorName(errorCode));
                cSize += genSize;
            }

            if (totalTestSize > maxTestSize) break;
        }
        genSize = cBufferSize - cSize;
        errorCode = ZBUFF_compressEnd(zc, cBuffer+cSize, &genSize);
        CHECK (ZBUFF_isError(errorCode), "compression error : %s", ZBUFF_getErrorName(errorCode));
        CHECK (errorCode != 0, "frame epilogue not fully consumed");
        cSize += genSize;
        crcOrig = XXH64_digest(&crc64);

        /* multi - fragments decompression test */
        ZBUFF_decompressInit(zd);
        totalCSize = 0;
        totalGenSize = 0;
        while (totalCSize < cSize)
        {
            sampleSizeLog  = FUZ_rand(&lseed) % maxSampleLog;
            sampleSize  = (size_t)1 << sampleSizeLog;
            sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
            readSize = sampleSize;
            sampleSizeLog  = FUZ_rand(&lseed) % maxSampleLog;
            sampleSize  = (size_t)1 << sampleSizeLog;
            sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
            genSize = MIN(sampleSize, dstBufferSize - totalGenSize);
            errorCode = ZBUFF_decompressContinue(zd, dstBuffer+totalGenSize, &genSize, cBuffer+totalCSize, &readSize);
            CHECK (ZBUFF_isError(errorCode), "decompression error : %s", ZBUFF_getErrorName(errorCode));
            totalGenSize += genSize;
            totalCSize += readSize;
        }
        CHECK (errorCode != 0, "frame not fully decoded");
        CHECK (totalGenSize != totalTestSize, "decompressed data : wrong size")
        CHECK (totalCSize != cSize, "compressed data should be fully read")
        crcDest = XXH64(dstBuffer, totalTestSize, 0);
        if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize);
        CHECK (crcDest!=crcOrig, "decompressed data corrupted");

        /* noisy/erroneous src decompression test */
        /* add some noise */
        nbChunks = (FUZ_rand(&lseed) & 7) + 2;
        for (n=0; n<nbChunks; n++)
        {
            size_t cStart;

            sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
            sampleSize = (size_t)1 << sampleSizeLog;
            sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
            if (sampleSize > cSize/3) sampleSize = cSize/3;
            sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
            cStart = FUZ_rand(&lseed) % (cSize - sampleSize);

            memcpy(cBuffer+cStart, srcBuffer+sampleStart, sampleSize);
        }

        /* try decompression on noisy data */
        ZBUFF_decompressInit(zd);
        totalCSize = 0;
        totalGenSize = 0;
        while ( (totalCSize < cSize) && (totalGenSize < dstBufferSize) )
        {
            sampleSizeLog  = FUZ_rand(&lseed) % maxSampleLog;
            sampleSize  = (size_t)1 << sampleSizeLog;
            sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
            readSize = sampleSize;
            sampleSizeLog  = FUZ_rand(&lseed) % maxSampleLog;
            sampleSize  = (size_t)1 << sampleSizeLog;
            sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
            genSize = MIN(sampleSize, dstBufferSize - totalGenSize);
            errorCode = ZBUFF_decompressContinue(zd, dstBuffer+totalGenSize, &genSize, cBuffer+totalCSize, &readSize);
            if (ZBUFF_isError(errorCode)) break;   /* error correctly detected */
            totalGenSize += genSize;
            totalCSize += readSize;
        }
    }
예제 #25
0
void CompressedWriteBuffer::nextImpl()
{
    if (!offset())
        return;

    size_t uncompressed_size = offset();
    size_t compressed_size = 0;
    char * compressed_buffer_ptr = nullptr;

    /** The format of compressed block - see CompressedStream.h
      */

    switch (method)
    {
        case CompressionMethod::LZ4:
        case CompressionMethod::LZ4HC:
        {
            static constexpr size_t header_size = 1 + sizeof(UInt32) + sizeof(UInt32);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
            compressed_buffer.resize(header_size + LZ4_COMPRESSBOUND(uncompressed_size));
#pragma GCC diagnostic pop

            compressed_buffer[0] = static_cast<UInt8>(CompressionMethodByte::LZ4);

            if (method == CompressionMethod::LZ4)
                compressed_size = header_size + LZ4_compress_default(
                    working_buffer.begin(),
                    &compressed_buffer[header_size],
                    uncompressed_size,
                    LZ4_COMPRESSBOUND(uncompressed_size));
            else
                compressed_size = header_size + LZ4_compress_HC(
                    working_buffer.begin(),
                    &compressed_buffer[header_size],
                    uncompressed_size,
                    LZ4_COMPRESSBOUND(uncompressed_size),
                    0);

            UInt32 compressed_size_32 = compressed_size;
            UInt32 uncompressed_size_32 = uncompressed_size;

            unalignedStore(&compressed_buffer[1], compressed_size_32);
            unalignedStore(&compressed_buffer[5], uncompressed_size_32);

            compressed_buffer_ptr = &compressed_buffer[0];
            break;
        }
        case CompressionMethod::ZSTD:
        {
            static constexpr size_t header_size = 1 + sizeof(UInt32) + sizeof(UInt32);

            compressed_buffer.resize(header_size + ZSTD_compressBound(uncompressed_size));

            compressed_buffer[0] = static_cast<UInt8>(CompressionMethodByte::ZSTD);

            size_t res = ZSTD_compress(
                &compressed_buffer[header_size],
                compressed_buffer.size(),
                working_buffer.begin(),
                uncompressed_size,
                1);

            if (ZSTD_isError(res))
                throw Exception("Cannot compress block with ZSTD: " + std::string(ZSTD_getErrorName(res)), ErrorCodes::CANNOT_COMPRESS);

            compressed_size = header_size + res;

            UInt32 compressed_size_32 = compressed_size;
            UInt32 uncompressed_size_32 = uncompressed_size;

            unalignedStore(&compressed_buffer[1], compressed_size_32);
            unalignedStore(&compressed_buffer[5], uncompressed_size_32);

            compressed_buffer_ptr = &compressed_buffer[0];
            break;
        }
        default:
            throw Exception("Unknown compression method", ErrorCodes::UNKNOWN_COMPRESSION_METHOD);
    }

    CityHash_v1_0_2::uint128 checksum = CityHash_v1_0_2::CityHash128(compressed_buffer_ptr, compressed_size);
    out.write(reinterpret_cast<const char *>(&checksum), sizeof(checksum));

    out.write(compressed_buffer_ptr, compressed_size);
}
예제 #26
0
static int SetupUncompressedBuffer(TIFF* tif, LERCState* sp,
                                   const char* module)
{
    TIFFDirectory *td = &tif->tif_dir;
    uint64 new_size_64;
    uint64 new_alloc_64;
    unsigned int new_size;
    unsigned int new_alloc;

    sp->uncompressed_offset = 0;

    if (isTiled(tif)) {
            sp->segment_width = td->td_tilewidth;
            sp->segment_height = td->td_tilelength;
    } else {
            sp->segment_width = td->td_imagewidth;
            sp->segment_height = td->td_imagelength - tif->tif_row;
            if (sp->segment_height > td->td_rowsperstrip)
                sp->segment_height = td->td_rowsperstrip;
    }

    new_size_64 = (uint64)sp->segment_width * sp->segment_height *
                                        (td->td_bitspersample / 8);
    if( td->td_planarconfig == PLANARCONFIG_CONTIG )
    {
        new_size_64 *= td->td_samplesperpixel;
    }

    new_size = (unsigned int)new_size_64;
    sp->uncompressed_size = new_size;

    /* add some margin as we are going to use it also to store deflate/zstd compressed data */
    new_alloc_64 = 100 + new_size_64 + new_size_64 / 3;
#ifdef ZSTD_SUPPORT
    {
        size_t zstd_max = ZSTD_compressBound((size_t)new_size_64);
        if( new_alloc_64 < zstd_max )
        {
            new_alloc_64 = zstd_max;
        }
    }
#endif
    new_alloc = (unsigned int)new_alloc_64;
    if( new_alloc != new_alloc_64 )
    {
        TIFFErrorExt(tif->tif_clientdata, module,
                        "Too large uncompressed strip/tile");
        _TIFFfree(sp->uncompressed_buffer);
        sp->uncompressed_buffer = 0;
        sp->uncompressed_alloc = 0;
        return 0;
    }

    if( sp->uncompressed_alloc < new_alloc )
    {
        _TIFFfree(sp->uncompressed_buffer);
        sp->uncompressed_buffer = _TIFFmalloc(new_alloc);
        if( !sp->uncompressed_buffer )
        {
            TIFFErrorExt(tif->tif_clientdata, module,
                            "Cannot allocate buffer");
            _TIFFfree(sp->uncompressed_buffer);
            sp->uncompressed_buffer = 0;
            sp->uncompressed_alloc = 0;
            return 0;
        }
        sp->uncompressed_alloc = new_alloc;
    }

    if( td->td_planarconfig == PLANARCONFIG_CONTIG &&
        td->td_extrasamples > 0 &&
        td->td_sampleinfo[td->td_extrasamples-1] == EXTRASAMPLE_UNASSALPHA &&
        GetLercDataType(tif) == 1 )
    {
        unsigned int mask_size = sp->segment_width * sp->segment_height;
        if( sp->mask_size < mask_size )
        {
            _TIFFfree(sp->mask_buffer);
            sp->mask_buffer = _TIFFmalloc(mask_size);
            if( !sp->mask_buffer )
            {
                TIFFErrorExt(tif->tif_clientdata, module,
                                "Cannot allocate buffer");
                sp->mask_size = 0;
                _TIFFfree(sp->uncompressed_buffer);
                sp->uncompressed_buffer = 0;
                sp->uncompressed_alloc = 0;
                return 0;
            }
            sp->mask_size = mask_size;
        }
    }

    return 1;
}
예제 #27
0
size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
                           void* dst, size_t dstCapacity,
                     const void* src, size_t srcSize,
                           int compressionLevel)
{
    ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0);
    U32 const overlapLog = (compressionLevel >= ZSTD_maxCLevel()) ? 0 : 3;
    size_t const overlapSize = (size_t)1 << (params.cParams.windowLog - overlapLog);
    size_t const chunkTargetSize = (size_t)1 << (params.cParams.windowLog + 2);
    unsigned const nbChunksMax = (unsigned)(srcSize / chunkTargetSize) + 1;
    unsigned nbChunks = MIN(nbChunksMax, mtctx->nbThreads);
    size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks;
    size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0xFFFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize;   /* avoid too small last block */
    size_t remainingSrcSize = srcSize;
    const char* const srcStart = (const char*)src;
    unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize));  /* presumes avgChunkSize >= 256 KB, which should be the case */
    size_t frameStartPos = 0, dstBufferPos = 0;

    DEBUGLOG(3, "windowLog : %2u => chunkTargetSize : %u bytes  ", params.cParams.windowLog, (U32)chunkTargetSize);
    DEBUGLOG(2, "nbChunks  : %2u   (chunkSize : %u bytes)   ", nbChunks, (U32)avgChunkSize);
    params.fParams.contentSizeFlag = 1;

    if (nbChunks==1) {   /* fallback to single-thread mode */
        ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
        return ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel);
    }

    {   unsigned u;
        for (u=0; u<nbChunks; u++) {
            size_t const chunkSize = MIN(remainingSrcSize, avgChunkSize);
            size_t const dstBufferCapacity = ZSTD_compressBound(chunkSize);
            buffer_t const dstAsBuffer = { (char*)dst + dstBufferPos, dstBufferCapacity };
            buffer_t const dstBuffer = u < compressWithinDst ? dstAsBuffer : ZSTDMT_getBuffer(mtctx->buffPool, dstBufferCapacity);
            ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(mtctx->cctxPool);
            size_t dictSize = u ? overlapSize : 0;

            if ((cctx==NULL) || (dstBuffer.start==NULL)) {
                mtctx->jobs[u].cSize = ERROR(memory_allocation);   /* job result */
                mtctx->jobs[u].jobCompleted = 1;
                nbChunks = u+1;
                break;   /* let's wait for previous jobs to complete, but don't start new ones */
            }

            mtctx->jobs[u].srcStart = srcStart + frameStartPos - dictSize;
            mtctx->jobs[u].dictSize = dictSize;
            mtctx->jobs[u].srcSize = chunkSize;
            mtctx->jobs[u].fullFrameSize = srcSize;
            mtctx->jobs[u].params = params;
            mtctx->jobs[u].dstBuff = dstBuffer;
            mtctx->jobs[u].cctx = cctx;
            mtctx->jobs[u].firstChunk = (u==0);
            mtctx->jobs[u].lastChunk = (u==nbChunks-1);
            mtctx->jobs[u].jobCompleted = 0;
            mtctx->jobs[u].jobCompleted_mutex = &mtctx->jobCompleted_mutex;
            mtctx->jobs[u].jobCompleted_cond = &mtctx->jobCompleted_cond;

            DEBUGLOG(3, "posting job %u   (%u bytes)", u, (U32)chunkSize);
            DEBUG_PRINTHEX(3, mtctx->jobs[u].srcStart, 12);
            POOL_add(mtctx->factory, ZSTDMT_compressChunk, &mtctx->jobs[u]);

            frameStartPos += chunkSize;
            dstBufferPos += dstBufferCapacity;
            remainingSrcSize -= chunkSize;
    }   }
    /* note : since nbChunks <= nbThreads, all jobs should be running immediately in parallel */

    {   unsigned chunkID;
        size_t error = 0, dstPos = 0;
        for (chunkID=0; chunkID<nbChunks; chunkID++) {
            DEBUGLOG(3, "waiting for chunk %u ", chunkID);
            PTHREAD_MUTEX_LOCK(&mtctx->jobCompleted_mutex);
            while (mtctx->jobs[chunkID].jobCompleted==0) {
                DEBUGLOG(4, "waiting for jobCompleted signal from chunk %u", chunkID);
                pthread_cond_wait(&mtctx->jobCompleted_cond, &mtctx->jobCompleted_mutex);
            }
            pthread_mutex_unlock(&mtctx->jobCompleted_mutex);
            DEBUGLOG(3, "ready to write chunk %u ", chunkID);

            ZSTDMT_releaseCCtx(mtctx->cctxPool, mtctx->jobs[chunkID].cctx);
            mtctx->jobs[chunkID].cctx = NULL;
            mtctx->jobs[chunkID].srcStart = NULL;
            {   size_t const cSize = mtctx->jobs[chunkID].cSize;
                if (ZSTD_isError(cSize)) error = cSize;
                if ((!error) && (dstPos + cSize > dstCapacity)) error = ERROR(dstSize_tooSmall);
                if (chunkID) {   /* note : chunk 0 is already written directly into dst */
                    if (!error)
                        memmove((char*)dst + dstPos, mtctx->jobs[chunkID].dstBuff.start, cSize);  /* may overlap if chunk decompressed within dst */
                    if (chunkID >= compressWithinDst)   /* otherwise, it decompresses within dst */
                        ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[chunkID].dstBuff);
                    mtctx->jobs[chunkID].dstBuff = g_nullBuffer;
                }
                dstPos += cSize ;
            }
        }
        if (!error) DEBUGLOG(3, "compressed size : %u  ", (U32)dstPos);
        return error ? error : dstPos;
    }

}