diff --git a/src/expand_inmem.c b/src/expand_inmem.c index 3902aea..c3fd715 100644 --- a/src/expand_inmem.c +++ b/src/expand_inmem.c @@ -93,22 +93,27 @@ size_t lzsa_get_max_decompressed_size_inmem(const unsigned char *pFileData, size * @param pOutBuffer buffer for decompressed data * @param nFileSize compressed size in bytes * @param nMaxOutBufferSize maximum capacity of decompression buffer + * @param nFlags compression flags (LZSA_FLAG_xxx) * @param pFormatVersion pointer to format version, updated if this function is successful * * @return actual decompressed size, or -1 for error */ -size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOutBuffer, size_t nFileSize, size_t nMaxOutBufferSize, int *pFormatVersion) { +size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOutBuffer, size_t nFileSize, size_t nMaxOutBufferSize, const unsigned int nFlags, int *pFormatVersion) { const unsigned char *pCurFileData = pFileData; const unsigned char *pEndFileData = pCurFileData + nFileSize; unsigned char *pCurOutBuffer = pOutBuffer; const unsigned char *pEndOutBuffer = pCurOutBuffer + nMaxOutBufferSize; - int nFormatVersion = 0; int nPreviousBlockSize; const int nHeaderSize = lzsa_get_header_size(); + if (nFlags & LZSA_FLAG_RAW_BLOCK) { + int nEODBytes = (*pFormatVersion == 2) ? 2 : 4; + return (size_t)lzsa_decompressor_expand_block(pFileData, (int)nFileSize - nEODBytes /* EOD marker */, pOutBuffer, 0, (int)nMaxOutBufferSize, *pFormatVersion); + } + /* Check header */ if ((pCurFileData + nHeaderSize) > pEndFileData || - lzsa_decode_header(pCurFileData, nHeaderSize, &nFormatVersion) != 0) + lzsa_decode_header(pCurFileData, nHeaderSize, pFormatVersion) != 0) return -1; pCurFileData += nHeaderSize; @@ -135,7 +140,7 @@ size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOut if ((pCurFileData + nBlockDataSize) > pEndFileData) return -1; - nDecompressedSize = lzsa_decompressor_expand_block(pCurFileData, nBlockDataSize, pCurOutBuffer - nPreviousBlockSize, nPreviousBlockSize, (int)(pEndOutBuffer - pCurOutBuffer + nPreviousBlockSize), nFormatVersion); + nDecompressedSize = lzsa_decompressor_expand_block(pCurFileData, nBlockDataSize, pCurOutBuffer - nPreviousBlockSize, nPreviousBlockSize, (int)(pEndOutBuffer - pCurOutBuffer + nPreviousBlockSize), *pFormatVersion); if (nDecompressedSize < 0) return -1; @@ -155,6 +160,5 @@ size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOut pCurFileData += nBlockDataSize; } - *pFormatVersion = nFormatVersion; return (int)(pCurOutBuffer - pOutBuffer); } diff --git a/src/expand_inmem.h b/src/expand_inmem.h index 44d30b7..bd95ff0 100644 --- a/src/expand_inmem.h +++ b/src/expand_inmem.h @@ -56,11 +56,12 @@ size_t lzsa_get_max_decompressed_size_inmem(const unsigned char *pFileData, size * @param pOutBuffer buffer for decompressed data * @param nFileSize compressed size in bytes * @param nMaxOutBufferSize maximum capacity of decompression buffer + * @param nFlags compression flags (LZSA_FLAG_xxx) * @param pFormatVersion pointer to format version, updated if this function is successful * * @return actual decompressed size, or -1 for error */ -size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOutBuffer, size_t nFileSize, size_t nMaxOutBufferSize, int *pFormatVersion); +size_t lzsa_decompress_inmem(const unsigned char *pFileData, unsigned char *pOutBuffer, size_t nFileSize, size_t nMaxOutBufferSize, const unsigned int nFlags, int *pFormatVersion); #ifdef __cplusplus } diff --git a/src/lzsa.c b/src/lzsa.c index f9f6543..856a02f 100755 --- a/src/lzsa.c +++ b/src/lzsa.c @@ -470,11 +470,11 @@ static int do_self_test(const unsigned int nOptions, const int nMinMatchSize, in size_t nDataSizeStep = 128; float fProbabilitySizeStep = 0.0005f; - for (nGeneratedDataSize = 1024; nGeneratedDataSize <= (4 * BLOCK_SIZE); nGeneratedDataSize += nDataSizeStep) { + for (nGeneratedDataSize = 1024; nGeneratedDataSize <= ((nOptions & OPT_RAW) ? BLOCK_SIZE : (4 * BLOCK_SIZE)); nGeneratedDataSize += nDataSizeStep) { float fMatchProbability; fprintf(stdout, "size %zd", nGeneratedDataSize); - for (fMatchProbability = 0; fMatchProbability <= 0.995f; fMatchProbability += fProbabilitySizeStep) { + for (fMatchProbability = ((nOptions & OPT_RAW) ? 0.5f : 0.1f); fMatchProbability <= 0.995f; fMatchProbability += fProbabilitySizeStep) { int nNumLiteralValues[12] = { 1, 2, 3, 15, 30, 56, 96, 137, 178, 191, 255, 256 }; float fXorProbability; @@ -504,8 +504,8 @@ static int do_self_test(const unsigned int nOptions, const int nMinMatchSize, in /* Try to decompress it, expected to succeed */ size_t nActualDecompressedSize; - int nDecFormatVersion = 0; - nActualDecompressedSize = lzsa_decompress_inmem(pCompressedData, pTmpDecompressedData, nActualCompressedSize, nGeneratedDataSize, &nDecFormatVersion); + int nDecFormatVersion = nFormatVersion; + nActualDecompressedSize = lzsa_decompress_inmem(pCompressedData, pTmpDecompressedData, nActualCompressedSize, nGeneratedDataSize, nFlags, &nDecFormatVersion); if (nActualDecompressedSize == -1) { free(pTmpDecompressedData); pTmpDecompressedData = NULL; @@ -538,7 +538,8 @@ static int do_self_test(const unsigned int nOptions, const int nMinMatchSize, in for (fXorProbability = 0.05f; fXorProbability <= 0.5f; fXorProbability += 0.05f) { memcpy(pTmpCompressedData, pCompressedData, nActualCompressedSize); xor_data(pTmpCompressedData + lzsa_get_header_size() + lzsa_get_frame_size(), nActualCompressedSize - lzsa_get_header_size() - lzsa_get_frame_size() - lzsa_get_frame_size() /* footer */, nSeed, fXorProbability); - lzsa_decompress_inmem(pTmpCompressedData, pGeneratedData, nActualCompressedSize, nGeneratedDataSize, &nDecFormatVersion); + nDecFormatVersion = nFormatVersion; + lzsa_decompress_inmem(pTmpCompressedData, pGeneratedData, nActualCompressedSize, nGeneratedDataSize, nFlags, &nDecFormatVersion); } } @@ -710,8 +711,13 @@ static int do_dec_benchmark(const char *pszInFilename, const char *pszOutFilenam size_t nFileSize, nMaxDecompressedSize; unsigned char *pFileData; unsigned char *pDecompressedData; + int nFlags; int i; + nFlags = 0; + if (nOptions & OPT_RAW) + nFlags |= LZSA_FLAG_RAW_BLOCK; + if (pszDictionaryFilename) { fprintf(stderr, "in-memory benchmarking does not support dictionaries\n"); return 100; @@ -771,10 +777,7 @@ static int do_dec_benchmark(const char *pszInFilename, const char *pszOutFilenam size_t nActualDecompressedSize = 0; for (i = 0; i < 50; i++) { long long t0 = do_get_time(); - if (nOptions & OPT_RAW) - nActualDecompressedSize = lzsa_decompressor_expand_block(pFileData, (int)nFileSize - 4 /* EOD marker */, pDecompressedData, 0, (int)nMaxDecompressedSize, nFormatVersion); - else - nActualDecompressedSize = lzsa_decompress_inmem(pFileData, pDecompressedData, nFileSize, nMaxDecompressedSize, &nFormatVersion); + nActualDecompressedSize = lzsa_decompress_inmem(pFileData, pDecompressedData, nFileSize, nMaxDecompressedSize, nFlags, &nFormatVersion); long long t1 = do_get_time(); if (nActualDecompressedSize == -1) { free(pDecompressedData); diff --git a/src/shrink_inmem.c b/src/shrink_inmem.c index f456b4f..0ead0e4 100644 --- a/src/shrink_inmem.c +++ b/src/shrink_inmem.c @@ -102,11 +102,17 @@ size_t lzsa_compress_inmem(const unsigned char *pInputData, unsigned char *pOutB int nOutDataSize; int nOutDataEnd = (int)(nMaxOutBufferSize - (lzsa_get_frame_size() + nCompressedSize + lzsa_get_frame_size() /* footer */)); + int nFrameSize = lzsa_get_frame_size(); + + if ((nFlags & LZSA_FLAG_RAW_BLOCK) != 0) { + nFrameSize = 0; + nOutDataEnd = (int)(nMaxOutBufferSize); + } if (nOutDataEnd > BLOCK_SIZE) nOutDataEnd = BLOCK_SIZE; - nOutDataSize = lzsa_compressor_shrink_block(&compressor, pInputData + nOriginalSize - nPreviousBlockSize, nPreviousBlockSize, nInDataSize, pOutBuffer + lzsa_get_frame_size() + nCompressedSize, nOutDataEnd); + nOutDataSize = lzsa_compressor_shrink_block(&compressor, pInputData + nOriginalSize - nPreviousBlockSize, nPreviousBlockSize, nInDataSize, pOutBuffer + nFrameSize + nCompressedSize, nOutDataEnd); if (nOutDataSize >= 0) { /* Write compressed block */ @@ -116,11 +122,13 @@ size_t lzsa_compress_inmem(const unsigned char *pInputData, unsigned char *pOutB nError = LZSA_ERROR_COMPRESSION; else { nCompressedSize += nBlockheaderSize; - - nOriginalSize += nInDataSize; - nCompressedSize += nOutDataSize; } } + + if (!nError) { + nOriginalSize += nInDataSize; + nCompressedSize += nOutDataSize; + } } else { /* Write uncompressible, literal block */