Example #1
0
int
lz4_compress(void *src, uint64_t srclen, void *dst, uint64_t *dstlen,
	       int level, uchar_t chdr, void *data)
{
	int rv;
	struct lz4_params *lzdat = (struct lz4_params *)data;
	int _srclen = srclen;
	uchar_t *dst2;

	if (lzdat->level == 1) {
		rv = LZ4_compress((const char *)src, (char *)dst, _srclen);

	} else if (lzdat->level == 2) {
		rv = LZ4_compress((const char *)src, (char *)dst, _srclen);
		if (rv == 0 || rv > *dstlen) {
			return (-1);
		}
		dst2 = (uchar_t *)slab_alloc(NULL, rv + sizeof (int) + LZ4_compressBound(rv));
		*((int *)dst2) = htonl(rv);
		rv = LZ4_compressHC((const char *)dst, (char *)(dst2 + sizeof (int)), rv);
		if (rv != 0) {
			rv += sizeof (int);
			memcpy(dst, dst2, rv);
		}
		slab_free(NULL, dst2);
	} else {
		rv = LZ4_compressHC((const char *)src, (char *)dst, _srclen);
	}
	if (rv == 0) {
		return (-1);
	}
	*dstlen = rv;

	return (0);
}
Example #2
0
bool CompressStream(Serializer& dest, Deserializer& src)
{
    unsigned srcSize = src.GetSize() - src.GetPosition();
    // Prepend the source and dest. data size in the stream so that we know to buffer & uncompress the right amount
    if (!srcSize)
    {
        dest.WriteUInt(0);
        dest.WriteUInt(0);
        return true;
    }
    
    unsigned maxDestSize = LZ4_compressBound(srcSize);
    SharedArrayPtr<unsigned char> srcBuffer(new unsigned char[srcSize]);
    SharedArrayPtr<unsigned char> destBuffer(new unsigned char[maxDestSize]);
    
    if (src.Read(srcBuffer, srcSize) != srcSize)
        return false;
    
    unsigned destSize = LZ4_compressHC((const char*)srcBuffer.Get(), (char*)destBuffer.Get(), srcSize);
    bool success = true;
    success &= dest.WriteUInt(srcSize);
    success &= dest.WriteUInt(destSize);
    success &= dest.Write(destBuffer, destSize) == destSize;
    return success;
}
Example #3
0
unsigned CompressData(void* dest, const void* src, unsigned srcSize)
{
    if (!dest || !src || !srcSize)
        return 0;
    else
        return LZ4_compressHC((const char*)src, (char*)dest, srcSize);
}
Example #4
0
std::unique_ptr<IOBuf> LZ4Codec::doCompress(const IOBuf* data) {
  std::unique_ptr<IOBuf> clone;
  if (data->isChained()) {
    // LZ4 doesn't support streaming, so we have to coalesce
    clone = data->clone();
    clone->coalesce();
    data = clone.get();
  }

  uint32_t extraSize = encodeSize() ? kMaxVarintLength64 : 0;
  auto out = IOBuf::create(extraSize + LZ4_compressBound(data->length()));
  if (encodeSize()) {
    encodeVarintToIOBuf(data->length(), out.get());
  }

  int n;
  if (highCompression_) {
    n = LZ4_compressHC(reinterpret_cast<const char*>(data->data()),
                       reinterpret_cast<char*>(out->writableTail()),
                       data->length());
  } else {
    n = LZ4_compress(reinterpret_cast<const char*>(data->data()),
                     reinterpret_cast<char*>(out->writableTail()),
                     data->length());
  }

  CHECK_GE(n, 0);
  CHECK_LE(n, out->capacity());

  out->append(n);
  return out;
}
Example #5
0
        static bool compress( T2 &buffer_out, const T1 &buffer_in, bool highest_compression = true )
        {
            static const bool verbose = false;

            bool ret = false;

            if( 1 )
            {
                // resize to worst case
                buffer_out.resize( LZ4_compressBound((int)(buffer_in.size())) );

                // compress
                size_t compressed_size = highest_compression ?
                    LZ4_compressHC( &buffer_in.at(0), &buffer_out.at(0), buffer_in.size() )
                    :
                    LZ4_compress( &buffer_in.at(0), &buffer_out.at(0), buffer_in.size() );

                ret = ( compressed_size > 0 && compressed_size < buffer_in.size() );

                if( ret )
                {
                    // if ok, resize properly to unused space
                    buffer_out.resize( compressed_size );
                }

                if( verbose )
                {
//                    std::cout << moon9::echo( ret, compressed_size, buffer_in.size() );
                }
            }

            return ret;
        }
Example #6
0
static ZEND_FUNCTION(lz4_compress)
{
    zval *data;
    char *output;
    int output_len, data_len;
    zend_bool high = 0;
    char *extra = NULL;
    int extra_len = -1;
    int offset = 0;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                              "z|bs", &data, &high,
                              &extra, &extra_len) == FAILURE) {
        RETURN_FALSE;
    }

    if (Z_TYPE_P(data) != IS_STRING) {
        zend_error(E_WARNING,
                   "lz4_compress : expects parameter to be string.");
        RETURN_FALSE;
    }

    if (extra && extra_len > 0) {
        offset = extra_len;
    } else {
        offset = sizeof(int);
    }

    data_len = Z_STRLEN_P(data);

    output = (char *)emalloc(LZ4_compressBound(data_len) + offset);
    if (!output) {
        zend_error(E_WARNING, "lz4_compress : memory error");
        RETURN_FALSE;
    }

    if (extra && extra_len > 0) {
        memcpy(output, extra, offset);
    } else {
        /* Set the data length */
        memcpy(output, &data_len, offset);
    }

    if (high) {
        output_len = LZ4_compressHC(Z_STRVAL_P(data), output + offset, data_len);
    } else {
        output_len = LZ4_compress(Z_STRVAL_P(data), output + offset, data_len);
    }

    if (output_len <= 0) {
        RETVAL_FALSE;
    } else {
        RETVAL_STRINGL(output, output_len + offset, 1);
    }

    efree(output);
}
Example #7
0
/* compression backend for LZ4 */
static int lz4_backend_compress(int level, const void* input, int length,
                                void* output) {
  if (level == Z_BEST_COMPRESSION) {
    return LZ4_compressHC(input, output, length);
  }
  else {
    return LZ4_compress(input, output, length);
  }
}
Example #8
0
	static inline void compress(I begin,I end,O out)
	{
		unsigned int bufLen = LZ4_compressBound(ZT_COMPRESSION_BLOCK_SIZE);
		char *buf = new char[bufLen * 2];
		char *buf2 = buf + bufLen;

		try {
			I inp(begin);
			for(;;) {
				unsigned int readLen = 0;
				while ((readLen < ZT_COMPRESSION_BLOCK_SIZE)&&(inp != end)) {
					buf[readLen++] = (char)*inp;
					++inp;
				}
				if (!readLen)
					break;

				uint32_t l = hton((uint32_t)readLen);
				out((const void *)&l,4); // original size

				if (readLen < 32) { // don't bother compressing itty bitty blocks
					l = 0; // stored
					out((const void *)&l,4);
					out((const void *)buf,readLen);
					continue;
				}

				int lz4CompressedLen = LZ4_compressHC(buf,buf2,(int)readLen);
				if ((lz4CompressedLen <= 0)||(lz4CompressedLen >= (int)readLen)) {
					l = 0; // stored
					out((const void *)&l,4);
					out((const void *)buf,readLen);
					continue;
				}

				l = hton((uint32_t)lz4CompressedLen); // lz4 only
				out((const void *)&l,4);
				out((const void *)buf2,(unsigned int)lz4CompressedLen);
			}

			delete [] buf;
		} catch ( ... ) {
			delete [] buf;
			throw;
		}
	}
Example #9
0
void hh_save(value out_filename) {
  CAMLparam1(out_filename);
  FILE* fp = fopen(String_val(out_filename), "wb");

  fwrite_no_fail(&MAGIC_CONSTANT, sizeof MAGIC_CONSTANT, 1, fp);

  size_t revlen = strlen(BuildInfo_kRevision);
  fwrite_no_fail(&revlen, sizeof revlen, 1, fp);
  fwrite_no_fail(BuildInfo_kRevision, sizeof(char), revlen, fp);

  fwrite_no_fail(&heap_init_size, sizeof heap_init_size, 1, fp);

  /*
   * Format of the compressed shared memory:
   * LZ4 can only work in chunks of 2GB, so we compress each chunk individually,
   * and write out each one as
   * [compressed size of chunk][uncompressed size of chunk][chunk]
   * A compressed size of zero indicates the end of the compressed section.
   */
  char* chunk_start = save_start();
  int compressed_size = 0;
  while (chunk_start < *heap) {
    uintptr_t remaining = *heap - chunk_start;
    uintptr_t chunk_size = LZ4_MAX_INPUT_SIZE < remaining ?
      LZ4_MAX_INPUT_SIZE : remaining;

    char* compressed = malloc(chunk_size * sizeof(char));
    assert(compressed != NULL);

    compressed_size = LZ4_compressHC(chunk_start, compressed,
      chunk_size);
    assert(compressed_size > 0);

    fwrite_no_fail(&compressed_size, sizeof compressed_size, 1, fp);
    fwrite_no_fail(&chunk_size, sizeof chunk_size, 1, fp);
    fwrite_no_fail((void*)compressed, 1, compressed_size, fp);

    chunk_start += chunk_size;
    free(compressed);
  }
  compressed_size = 0;
  fwrite_no_fail(&compressed_size, sizeof compressed_size, 1, fp);

  fclose(fp);
  CAMLreturn0;
}
Example #10
0
static ZEND_FUNCTION(horde_lz4_compress)
{
    zval *data;
    char *output;
    int header_offset = (sizeof(headerid) + sizeof(int));
    int output_len, data_len;
    zend_bool high = 0;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                              "z|b", &data, &high) == FAILURE) {
        RETURN_FALSE;
    }

    if (Z_TYPE_P(data) != IS_STRING) {
        zend_error(E_WARNING,
                   "horde_lz4_compress: uncompressed data must be a string.");
        RETURN_FALSE;
    }

    data_len = Z_STRLEN_P(data);

    output = (char *)emalloc(LZ4_compressBound(data_len) + header_offset);
    if (!output) {
        zend_error(E_WARNING, "horde_lz4_compress: memory error");
        RETURN_FALSE;
    }

    *output = headerid;
    memcpy(output + sizeof(headerid), &data_len, sizeof(int));

    if (high) {
        output_len = LZ4_compressHC(Z_STRVAL_P(data), output + header_offset, data_len);
    } else {
        output_len = LZ4_compress(Z_STRVAL_P(data), output + header_offset, data_len);
    }

    if (output_len <= 0) {
        RETVAL_FALSE;
    } else {
        RETVAL_STRINGL(output, output_len + header_offset, 1);
    }

    efree(output);
}
Example #11
0
void hh_save_dep_table(value out_filename) {
  CAMLparam1(out_filename);
  FILE* fp = fopen(String_val(out_filename), "wb");

  fwrite_header(fp);

  int compressed_size = 0;

  assert(LZ4_MAX_INPUT_SIZE >= DEP_SIZE_B);
  char* compressed = malloc(DEP_SIZE_B);
  assert(compressed != NULL);

  compressed_size = LZ4_compressHC((char*)deptbl, compressed, DEP_SIZE_B);
  assert(compressed_size > 0);

  fwrite_no_fail(&compressed_size, sizeof compressed_size, 1, fp);
  fwrite_no_fail((void*)compressed, 1, compressed_size, fp);
  free(compressed);

  fclose(fp);
  CAMLreturn0;
}
Example #12
0
/*
 * Class:     net_jpountz_lz4_LZ4
 * Method:    LZ4_compressHC
 * Signature: ([BII[BI)I
 */
JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1compressHC
(JNIEnv *env, jclass cls, jbyteArray src, jint srcOff, jint srcLen, jbyteArray dest, jint destOff) {

    char* in = (char*) (*env)->GetPrimitiveArrayCritical(env, src, 0);
    if (in == NULL) {
        throw_OOM(env);
        return 0;
    }
    char* out = (char*) (*env)->GetPrimitiveArrayCritical(env, dest, 0);
    if (out == NULL) {
        throw_OOM(env);
        return 0;
    }

    jint compressed = LZ4_compressHC(in + srcOff, out + destOff, srcLen);

    (*env)->ReleasePrimitiveArrayCritical(env, src, in, 0);
    (*env)->ReleasePrimitiveArrayCritical(env, src, out, 0);

    return compressed;

}
Example #13
0
	bool compress(Compression compression, char *&data, std::uint32_t in_size, std::uint32_t &out_size)
	{
		if (data == nullptr)
		{
			return false;
		}

		switch (compression)
		{
		case COMPRESS_NONE:
			{
				out_size = in_size;
				return true;
			}
#ifdef ZAP_COMPRESS_LZ4
		case COMPRESS_LZ4:
			{
				char *out_data = new char[LZ4_compressBound(in_size)];
				out_size = LZ4_compressHC(data, out_data, in_size);
				if (out_size > 0)
				{
					delete[] data;
					data = out_data;
					return true;
				}
				else
				{
					return false;
				}
			}
#endif
		default:
			{
				return false;
			}
		}
	}
Example #14
0
int FUZ_test(U32 seed, int nbCycles, int startCycle, double compressibility) {
        unsigned long long bytes = 0;
        unsigned long long cbytes = 0;
        unsigned long long hcbytes = 0;
        unsigned long long ccbytes = 0;
        void* CNBuffer;
        char* compressedBuffer;
        char* decodedBuffer;
#       define FUZ_max   LZ4_COMPRESSBOUND(LEN)
        unsigned int randState=seed;
        int ret, cycleNb;
#       define FUZ_CHECKTEST(cond, ...) if (cond) { printf("Test %i : ", testNb); printf(__VA_ARGS__); \
                                        printf(" (seed %u, cycle %i) \n", seed, cycleNb); goto _output_error; }
#       define FUZ_DISPLAYTEST          { testNb++; ((displayLevel<3) || no_prompt) ? 0 : printf("%2i\b\b", testNb); if (displayLevel==4) fflush(stdout); }
        void* stateLZ4   = malloc(LZ4_sizeofState());
        void* stateLZ4HC = malloc(LZ4_sizeofStateHC());
        void* LZ4continue;
        LZ4_stream_t LZ4dict;
        U32 crcOrig, crcCheck;
        int displayRefresh;


        // init
        memset(&LZ4dict, 0, sizeof(LZ4dict));

        // Create compressible test buffer
        CNBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
        FUZ_fillCompressibleNoiseBuffer(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, &randState);
        compressedBuffer = malloc(LZ4_compressBound(FUZ_MAX_BLOCK_SIZE));
        decodedBuffer = malloc(FUZ_MAX_DICT_SIZE + FUZ_MAX_BLOCK_SIZE);

        // display refresh rate
        switch(displayLevel)
        {
        case 0: displayRefresh = nbCycles+1; break;
        case 1: displayRefresh=FUZ_MAX(1, nbCycles / 100); break;
        case 2: displayRefresh=89; break;
        default : displayRefresh=1;
        }

        // move to startCycle
        for (cycleNb = 0; cycleNb < startCycle; cycleNb++)
        {
            // synd rand & dict
            int dictSize, blockSize, blockStart;
            char* dict;
            char* block;

            blockSize  = FUZ_rand(&randState) % FUZ_MAX_BLOCK_SIZE;
            blockStart = FUZ_rand(&randState) % (COMPRESSIBLE_NOISE_LENGTH - blockSize);
            dictSize   = FUZ_rand(&randState) % FUZ_MAX_DICT_SIZE;
            if (dictSize > blockStart) dictSize = blockStart;
            block = ((char*)CNBuffer) + blockStart;
            dict = block - dictSize;
            LZ4_loadDict(&LZ4dict, dict, dictSize);
            LZ4_compress_continue(&LZ4dict, block, compressedBuffer, blockSize);
            LZ4_loadDict(&LZ4dict, dict, dictSize);
            LZ4_compress_continue(&LZ4dict, block, compressedBuffer, blockSize);
            LZ4_loadDict(&LZ4dict, dict, dictSize);
            LZ4_compress_continue(&LZ4dict, block, compressedBuffer, blockSize);
        }

        // Test loop
        for (cycleNb = startCycle; cycleNb < nbCycles; cycleNb++)
        {
            int testNb = 0;
            char* dict;
            char* block;
            int dictSize, blockSize, blockStart, compressedSize, HCcompressedSize;
            int blockContinueCompressedSize;

            if ((cycleNb%displayRefresh) == 0)
            {
                printf("\r%7i /%7i   - ", cycleNb, nbCycles);
                fflush(stdout);
            }

            // Select block to test
            blockSize  = FUZ_rand(&randState) % FUZ_MAX_BLOCK_SIZE;
            blockStart = FUZ_rand(&randState) % (COMPRESSIBLE_NOISE_LENGTH - blockSize);
            dictSize   = FUZ_rand(&randState) % FUZ_MAX_DICT_SIZE;
            if (dictSize > blockStart) dictSize = blockStart;
            block = ((char*)CNBuffer) + blockStart;
            dict = block - dictSize;

            /* Compression tests */

            // Test compression HC
            FUZ_DISPLAYTEST;
            ret = LZ4_compressHC(block, compressedBuffer, blockSize);
            FUZ_CHECKTEST(ret==0, "LZ4_compressHC() failed");
            HCcompressedSize = ret;

            // Test compression HC using external state
            FUZ_DISPLAYTEST;
            ret = LZ4_compressHC_withStateHC(stateLZ4HC, block, compressedBuffer, blockSize);
            FUZ_CHECKTEST(ret==0, "LZ4_compressHC_withStateHC() failed");

            // Test compression using external state
            FUZ_DISPLAYTEST;
            ret = LZ4_compress_withState(stateLZ4, block, compressedBuffer, blockSize);
            FUZ_CHECKTEST(ret==0, "LZ4_compress_withState() failed");

            // Test compression
            FUZ_DISPLAYTEST;
            ret = LZ4_compress(block, compressedBuffer, blockSize);
            FUZ_CHECKTEST(ret==0, "LZ4_compress() failed");
            compressedSize = ret;

            /* Decompression tests */

            crcOrig = XXH32(block, blockSize, 0);

            // Test decoding with output size being exactly what's necessary => must work
            FUZ_DISPLAYTEST;
            ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize);
            FUZ_CHECKTEST(ret<0, "LZ4_decompress_fast failed despite correct space");
            FUZ_CHECKTEST(ret!=compressedSize, "LZ4_decompress_fast failed : did not fully read compressed data");
            crcCheck = XXH32(decodedBuffer, blockSize, 0);
            FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast corrupted decoded data");

            // Test decoding with one byte missing => must fail
            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize-1] = 0;
            ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize-1);
            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too small");
            FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_fast overrun specified output buffer");

            // Test decoding with one byte too much => must fail
            FUZ_DISPLAYTEST;
            ret = LZ4_decompress_fast(compressedBuffer, decodedBuffer, blockSize+1);
            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too large");

            // Test decoding with output size exactly what's necessary => must work
            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize] = 0;
            ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize);
            FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe failed despite sufficient space");
            FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe did not regenerate original data");
            FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size");
            crcCheck = XXH32(decodedBuffer, blockSize, 0);
            FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data");

            // Test decoding with more than enough output size => must work
            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize] = 0;
            decodedBuffer[blockSize+1] = 0;
            ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize+1);
            FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe failed despite amply sufficient space");
            FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe did not regenerate original data");
            //FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe wrote more than (unknown) target size");   // well, is that an issue ?
            FUZ_CHECKTEST(decodedBuffer[blockSize+1], "LZ4_decompress_safe overrun specified output buffer size");
            crcCheck = XXH32(decodedBuffer, blockSize, 0);
            FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe corrupted decoded data");

            // Test decoding with output size being one byte too short => must fail
            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize-1] = 0;
            ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize-1);
            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to Output Size being one byte too short");
            FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe overrun specified output buffer size");

            // Test decoding with output size being 10 bytes too short => must fail
            FUZ_DISPLAYTEST;
            if (blockSize>10)
            {
                decodedBuffer[blockSize-10] = 0;
                ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize, blockSize-10);
                FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to Output Size being 10 bytes too short");
                FUZ_CHECKTEST(decodedBuffer[blockSize-10], "LZ4_decompress_safe overrun specified output buffer size");
            }

            // Test decoding with input size being one byte too short => must fail
            FUZ_DISPLAYTEST;
            ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize-1, blockSize);
            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being one byte too short (blockSize=%i, ret=%i, compressedSize=%i)", blockSize, ret, compressedSize);

            // Test decoding with input size being one byte too large => must fail
            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize] = 0;
            ret = LZ4_decompress_safe(compressedBuffer, decodedBuffer, compressedSize+1, blockSize);
            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being too large");
            FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe overrun specified output buffer size");

            // Test partial decoding with target output size being max/2 => must work
            FUZ_DISPLAYTEST;
            ret = LZ4_decompress_safe_partial(compressedBuffer, decodedBuffer, compressedSize, blockSize/2, blockSize);
            FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe_partial failed despite sufficient space");

            // Test partial decoding with target output size being just below max => must work
            FUZ_DISPLAYTEST;
            ret = LZ4_decompress_safe_partial(compressedBuffer, decodedBuffer, compressedSize, blockSize-3, blockSize);
            FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe_partial failed despite sufficient space");

            /* Test Compression with limited output size */

            // Test compression with output size being exactly what's necessary (should work)
            FUZ_DISPLAYTEST;
            ret = LZ4_compress_limitedOutput(block, compressedBuffer, blockSize, compressedSize);
            FUZ_CHECKTEST(ret==0, "LZ4_compress_limitedOutput() failed despite sufficient space");

            // Test compression with output size being exactly what's necessary and external state (should work)
            FUZ_DISPLAYTEST;
            ret = LZ4_compress_limitedOutput_withState(stateLZ4, block, compressedBuffer, blockSize, compressedSize);
            FUZ_CHECKTEST(ret==0, "LZ4_compress_limitedOutput_withState() failed despite sufficient space");

            // Test HC compression with output size being exactly what's necessary (should work)
            FUZ_DISPLAYTEST;
            ret = LZ4_compressHC_limitedOutput(block, compressedBuffer, blockSize, HCcompressedSize);
            FUZ_CHECKTEST(ret==0, "LZ4_compressHC_limitedOutput() failed despite sufficient space");

            // Test HC compression with output size being exactly what's necessary (should work)
            FUZ_DISPLAYTEST;
            ret = LZ4_compressHC_limitedOutput_withStateHC(stateLZ4HC, block, compressedBuffer, blockSize, HCcompressedSize);
            FUZ_CHECKTEST(ret==0, "LZ4_compressHC_limitedOutput_withStateHC() failed despite sufficient space");

            // Test compression with just one missing byte into output buffer => must fail
            FUZ_DISPLAYTEST;
            compressedBuffer[compressedSize-1] = 0;
            ret = LZ4_compress_limitedOutput(block, compressedBuffer, blockSize, compressedSize-1);
            FUZ_CHECKTEST(ret, "LZ4_compress_limitedOutput should have failed (output buffer too small by 1 byte)");
            FUZ_CHECKTEST(compressedBuffer[compressedSize-1], "LZ4_compress_limitedOutput overran output buffer")

            // Test HC compression with just one missing byte into output buffer => must fail
            FUZ_DISPLAYTEST;
            compressedBuffer[compressedSize-1] = 0;
            ret = LZ4_compressHC_limitedOutput(block, compressedBuffer, blockSize, HCcompressedSize-1);
            FUZ_CHECKTEST(ret, "LZ4_compressHC_limitedOutput should have failed (output buffer too small by 1 byte)");
            FUZ_CHECKTEST(compressedBuffer[compressedSize-1], "LZ4_compressHC_limitedOutput overran output buffer")

            /* Dictionary tests */

            // Compress using dictionary
            FUZ_DISPLAYTEST;
            LZ4continue = LZ4_create (dict);
            LZ4_compress_continue (LZ4continue, dict, compressedBuffer, dictSize);   // Just to fill hash tables
            blockContinueCompressedSize = LZ4_compress_continue (LZ4continue, block, compressedBuffer, blockSize);
            FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_continue failed");
            LZ4_free (LZ4continue);

            // Decompress with dictionary as prefix
            FUZ_DISPLAYTEST;
            memcpy(decodedBuffer, dict, dictSize);
            ret = LZ4_decompress_fast_withPrefix64k(compressedBuffer, decodedBuffer+dictSize, blockSize);
            FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_withPrefix64k did not read all compressed block input");
            crcCheck = XXH32(decodedBuffer+dictSize, blockSize, 0);
            if (crcCheck!=crcOrig)
            {
                int i=0;
                while (block[i]==decodedBuffer[i]) i++;
                printf("Wrong Byte at position %i/%i\n", i, blockSize);

            }
            FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast_withPrefix64k corrupted decoded data (dict %i)", dictSize);

            FUZ_DISPLAYTEST;
            ret = LZ4_decompress_safe_withPrefix64k(compressedBuffer, decodedBuffer+dictSize, blockContinueCompressedSize, blockSize);
            FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_withPrefix64k did not regenerate original data");
            crcCheck = XXH32(decodedBuffer+dictSize, blockSize, 0);
            FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_withPrefix64k corrupted decoded data");

            // Compress using External dictionary
            FUZ_DISPLAYTEST;
            dict -= 9;   // Separation, so it is an ExtDict
            if (dict < (char*)CNBuffer) dict = (char*)CNBuffer;
            LZ4_loadDict(&LZ4dict, dict, dictSize);
            blockContinueCompressedSize = LZ4_compress_continue(&LZ4dict, block, compressedBuffer, blockSize);
            FUZ_CHECKTEST(blockContinueCompressedSize==0, "LZ4_compress_continue failed");

            FUZ_DISPLAYTEST;
            LZ4_loadDict(&LZ4dict, dict, dictSize);
            ret = LZ4_compress_limitedOutput_continue(&LZ4dict, block, compressedBuffer, blockSize, blockContinueCompressedSize-1);
            FUZ_CHECKTEST(ret>0, "LZ4_compress_limitedOutput_continue using ExtDict should fail : one missing byte for output buffer");

            FUZ_DISPLAYTEST;
            LZ4_loadDict(&LZ4dict, dict, dictSize);
            ret = LZ4_compress_limitedOutput_continue(&LZ4dict, block, compressedBuffer, blockSize, blockContinueCompressedSize);
            FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_compress_limitedOutput_compressed size is different (%i != %i)", ret, blockContinueCompressedSize);
            FUZ_CHECKTEST(ret<=0, "LZ4_compress_limitedOutput_continue should work : enough size available within output buffer");

            // Decompress with dictionary as external
            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize] = 0;
            ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize, dict, dictSize);
            FUZ_CHECKTEST(ret!=blockContinueCompressedSize, "LZ4_decompress_fast_usingDict did not read all compressed block input");
            FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_fast_usingDict overrun specified output buffer size")
            crcCheck = XXH32(decodedBuffer, blockSize, 0);
            if (crcCheck!=crcOrig)
            {
                int i=0;
                while (block[i]==decodedBuffer[i]) i++;
                printf("Wrong Byte at position %i/%i\n", i, blockSize);

            }
            FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_fast_usingDict corrupted decoded data (dict %i)", dictSize);

            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize] = 0;
            ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize, dict, dictSize);
            FUZ_CHECKTEST(ret!=blockSize, "LZ4_decompress_safe_usingDict did not regenerate original data");
            FUZ_CHECKTEST(decodedBuffer[blockSize], "LZ4_decompress_safe_usingDict overrun specified output buffer size")
            crcCheck = XXH32(decodedBuffer, blockSize, 0);
            FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data");

            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize-1] = 0;
            ret = LZ4_decompress_fast_usingDict(compressedBuffer, decodedBuffer, blockSize-1, dict, dictSize);
            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast_withDict should have failed : wrong original size (-1 byte)");
            FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_fast_usingDict overrun specified output buffer size");

            FUZ_DISPLAYTEST;
            decodedBuffer[blockSize-1] = 0;
            ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize-1, dict, dictSize);
            FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe_usingDict should have failed : not enough output size (-1 byte)");
            FUZ_CHECKTEST(decodedBuffer[blockSize-1], "LZ4_decompress_safe_usingDict overrun specified output buffer size");

            FUZ_DISPLAYTEST;
            if (blockSize > 10)
            {
                decodedBuffer[blockSize-10] = 0;
                ret = LZ4_decompress_safe_usingDict(compressedBuffer, decodedBuffer, blockContinueCompressedSize, blockSize-10, dict, dictSize);
                FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe_usingDict should have failed : output buffer too small (-10 byte)");
                FUZ_CHECKTEST(decodedBuffer[blockSize-10], "LZ4_decompress_safe_usingDict overrun specified output buffer size (-10 byte) (blockSize=%i)", blockSize);
            }


            // Fill stats
            bytes += blockSize;
            cbytes += compressedSize;
            hcbytes += HCcompressedSize;
            ccbytes += blockContinueCompressedSize;
        }

        printf("\r%7i /%7i   - ", cycleNb, nbCycles);
        printf("all tests completed successfully \n");
        printf("compression ratio: %0.3f%%\n", (double)cbytes/bytes*100);
        printf("HC compression ratio: %0.3f%%\n", (double)hcbytes/bytes*100);
        printf("ratio with dict: %0.3f%%\n", (double)ccbytes/bytes*100);

        // unalloc
        if(!no_prompt) getchar();
        free(CNBuffer);
        free(compressedBuffer);
        free(decodedBuffer);
        free(stateLZ4);
        free(stateLZ4HC);
        return 0;

_output_error:
        if(!no_prompt) getchar();
        free(CNBuffer);
        free(compressedBuffer);
        free(decodedBuffer);
        free(stateLZ4);
        free(stateLZ4HC);
        return 1;
}
bool ResourcePackager::WritePackageFile(const String& destFilePath)
{
    buildBase_->BuildLog("Writing package");

    SharedPtr<File> dest(new File(context_, destFilePath, FILE_WRITE));
    if (!dest->IsOpen())
    {
        buildBase_->BuildError("Could not open output file " + destFilePath);
        return false;
    }

    // Write ID, number of files & placeholder for checksum
    WriteHeader(dest);

    for (unsigned i = 0; i < resourceEntries_.Size(); i++)
    {
        BuildResourceEntry* entry = resourceEntries_[i];

        // Write entry (correct offset is still unknown, will be filled in later)
        dest->WriteString(entry->packagePath_);
        dest->WriteUInt(entry->offset_);
        dest->WriteUInt(entry->size_);
        dest->WriteUInt(entry->checksum_);
    }

    unsigned totalDataSize = 0;

    // Write file data, calculate checksums & correct offsets
    for (unsigned i = 0; i < resourceEntries_.Size(); i++)
    {
        BuildResourceEntry* entry = resourceEntries_[i];

        entry->offset_ = dest->GetSize();

        File srcFile(context_, entry->absolutePath_);
        if (!srcFile.IsOpen())
        {
            buildBase_->BuildError("Could not open input file " + entry->absolutePath_);
            return false;
        }

        unsigned dataSize = entry->size_;
        totalDataSize += dataSize;
        SharedArrayPtr<unsigned char> buffer(new unsigned char[dataSize]);

        if (srcFile.Read(&buffer[0], dataSize) != dataSize)
        {
            buildBase_->BuildError("Could not read input file " + entry->absolutePath_);
            return false;
        }

        srcFile.Close();

        for (unsigned j = 0; j < dataSize; ++j)
        {
            checksum_ = SDBMHash(checksum_, buffer[j]);
            entry->checksum_ = SDBMHash(entry->checksum_, buffer[j]);
        }

        // might not want to compress for WebGL
        //if (!compress_)
        //{
        //    PrintLine(entries_[i].name_ + " size " + String(dataSize));
        //    dest.Write(&buffer[0], entries_[i].size_);
        //}
        //else
        //{

        unsigned compressedBlockSize_ = 32768;

        SharedArrayPtr<unsigned char> compressBuffer(new unsigned char[LZ4_compressBound(compressedBlockSize_)]);

        unsigned pos = 0;
        unsigned totalPackedBytes = 0;

        while (pos < dataSize)
        {
            unsigned unpackedSize = compressedBlockSize_;
            if (pos + unpackedSize > dataSize)
                unpackedSize = dataSize - pos;

            unsigned packedSize = LZ4_compressHC((const char*)&buffer[pos], (char*)compressBuffer.Get(), unpackedSize);
            if (!packedSize)
            {
                buildBase_->BuildError("LZ4 compression failed for file " + entry->absolutePath_ + " at offset " + pos);
                return false;
            }

            dest->WriteUShort(unpackedSize);
            dest->WriteUShort(packedSize);
            dest->Write(compressBuffer.Get(), packedSize);
            totalPackedBytes += 6 + packedSize;

            pos += unpackedSize;
        }

        buildBase_->BuildLog(entry->absolutePath_ + " in " + String(dataSize) + " out " + String(totalPackedBytes));
        }
    //}

    // Write package size to the end of file to allow finding it linked to an executable file
    unsigned currentSize = dest->GetSize();
    dest->WriteUInt(currentSize + sizeof(unsigned));

    // Write header again with correct offsets & checksums
    dest->Seek(0);
    WriteHeader(dest);

    for (unsigned i = 0; i < resourceEntries_.Size(); i++)
    {
        BuildResourceEntry* entry = resourceEntries_[i];

        dest->WriteString(entry->packagePath_);
        dest->WriteUInt(entry->offset_);
        dest->WriteUInt(entry->size_);
        dest->WriteUInt(entry->checksum_);
    }

    buildBase_->BuildLog("Number of files " + String(resourceEntries_.Size()));
    buildBase_->BuildLog("File data size " + String(totalDataSize));
    buildBase_->BuildLog("Package size " + String(dest->GetSize()));

    return true;
}
Example #16
0
static int
_save_direct_tgv(RGBA_Image *im, const char *file, int compress)
{
   // TODO: Add block by block compression.

   int image_width, image_height, planes = 1;
   uint32_t width, height;
   uint8_t header[8] = "TGV1";
   int etc_block_size, etc_data_size, buffer_size, data_size, remain;
   uint8_t *buffer = NULL;
   uint8_t *data, *ptr;
   FILE *f;

   if (!im->cache_entry.borders.l || !im->cache_entry.borders.t ||
       !im->cache_entry.borders.r || !im->cache_entry.borders.b)
     WRN("No im->cache_entry.borders on ETC image. Final image may have wrong dimensions.");

   image_width = im->cache_entry.w + im->cache_entry.borders.l + im->cache_entry.borders.r;
   image_height = im->cache_entry.h + im->cache_entry.borders.t + im->cache_entry.borders.b;
   data = im->image.data8;
   width = htonl(image_width);
   height = htonl(image_height);
   compress = !!compress;

   if ((image_width & 0x3) || (image_height & 0x3))
     return 0;

   // header[4]: block size info, unused
   header[4] = 0;

   // header[5]: 0 for ETC1
   switch (im->cache_entry.space)
     {
      case EVAS_COLORSPACE_ETC1:
        etc_block_size = 8;
        header[5] = 0;
        break;
      case EVAS_COLORSPACE_RGB8_ETC2:
        etc_block_size = 8;
        header[5] = 1;
        break;
      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
        etc_block_size = 16;
        header[5] = 2;
        break;
      case EVAS_COLORSPACE_ETC1_ALPHA:
        // FIXME: Properly handle premul vs. unpremul data
        etc_block_size = 8;
        header[5] = 3;
        planes = 2;
        break;
      default:
        return 0;
     }

   // header[6]: 0 for raw, 1, for LZ4 compressed, 2 for block-less mode
   header[6] = compress | 0x2;

   // header[7]: options (unused)
   header[7] = 0;

   f = fopen(file, "wb");
   if (!f) return 0;

   // Write header
   if (fwrite(header, sizeof (uint8_t), 8, f) != 8) goto on_error;
   if (fwrite(&width, sizeof (uint32_t), 1, f) != 1) goto on_error;
   if (fwrite(&height, sizeof (uint32_t), 1, f) != 1) goto on_error;

   etc_data_size = image_width * image_height * etc_block_size * planes / 16;
   if (compress)
     {
        buffer_size = LZ4_compressBound(etc_data_size);
        buffer = malloc(buffer_size);
        if (!buffer) goto on_error;
        data_size = LZ4_compressHC((char *) data, (char *) buffer, etc_data_size);
     }
   else
     {
        data_size = buffer_size = etc_data_size;
        buffer = data;
     }

   // Write block length header -- We keep this even in block-less mode
   if (data_size > 0)
     {
        unsigned int blen = data_size;

        while (blen)
          {
             unsigned char plen;

             plen = blen & 0x7F;
             blen = blen >> 7;

             if (blen) plen = 0x80 | plen;
             if (fwrite(&plen, 1, 1, f) != 1) goto on_error;
          }
     }
Example #17
0
extern __declspec(dllexport) int dll_LZ4_compressHC (const char* source, char* dest, int isize)
{
	return LZ4_compressHC (source, dest, isize);
}
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);
}