diff --git a/src/lzsa.c b/src/lzsa.c index ebdcefb..ff2e684 100755 --- a/src/lzsa.c +++ b/src/lzsa.c @@ -100,7 +100,7 @@ static void compression_progress(long long nOriginalSize, long long nCompressedS static int do_compress(const char *pszInFilename, const char *pszOutFilename, const char *pszDictionaryFilename, const unsigned int nOptions, const int nMinMatchSize, const int nFormatVersion) { long long nStartTime = 0LL, nEndTime = 0LL; long long nOriginalSize = 0LL, nCompressedSize = 0LL; - int nCommandCount = 0; + int nCommandCount = 0, nSafeDist = 0; int nFlags; lzsa_status_t nStatus; @@ -114,7 +114,7 @@ static int do_compress(const char *pszInFilename, const char *pszOutFilename, co nStartTime = do_get_time(); } - nStatus = lzsa_compress_file(pszInFilename, pszOutFilename, pszDictionaryFilename, nFlags, nMinMatchSize, nFormatVersion, compression_progress, &nOriginalSize, &nCompressedSize, &nCommandCount); + nStatus = lzsa_compress_file(pszInFilename, pszOutFilename, pszDictionaryFilename, nFlags, nMinMatchSize, nFormatVersion, compression_progress, &nOriginalSize, &nCompressedSize, &nCommandCount, &nSafeDist); if ((nOptions & OPT_VERBOSE)) { nEndTime = do_get_time(); @@ -141,6 +141,9 @@ static int do_compress(const char *pszInFilename, const char *pszOutFilename, co fprintf(stdout, "\rCompressed '%s' in %g seconds, %.02g Mb/s, %d tokens (%g bytes/token), %lld into %lld bytes ==> %g %%\n", pszInFilename, fDelta, fSpeed, nCommandCount, (double)nOriginalSize / (double)nCommandCount, nOriginalSize, nCompressedSize, (double)(nCompressedSize * 100.0 / nOriginalSize)); + if (nOptions & OPT_RAW) { + fprintf(stdout, "Safe distance: %d (0x%X)\n", nSafeDist, nSafeDist); + } } return 0; diff --git a/src/shrink_block_v1.c b/src/shrink_block_v1.c index f22e7ec..1a21cb3 100644 --- a/src/shrink_block_v1.c +++ b/src/shrink_block_v1.c @@ -386,6 +386,12 @@ static int lzsa_write_block_v1(lzsa_compressor *pCompressor, const unsigned char nOutOffset = lzsa_write_match_varlen_v1(pOutData, nOutOffset, nEncodedMatchLen); i += nMatchLen; + if (pCompressor->flags & LZSA_FLAG_RAW_BLOCK) { + int nCurSafeDist = (i - nStartOffset) - nOutOffset; + if (nCurSafeDist >= 0 && pCompressor->safe_dist < nCurSafeDist) + pCompressor->safe_dist = nCurSafeDist; + } + pCompressor->num_commands++; } else { @@ -415,6 +421,12 @@ static int lzsa_write_block_v1(lzsa_compressor *pCompressor, const unsigned char nNumLiterals = 0; } + if (pCompressor->flags & LZSA_FLAG_RAW_BLOCK) { + int nCurSafeDist = (i - nStartOffset) - nOutOffset; + if (nCurSafeDist >= 0 && pCompressor->safe_dist < nCurSafeDist) + pCompressor->safe_dist = nCurSafeDist; + } + pCompressor->num_commands++; } diff --git a/src/shrink_block_v2.c b/src/shrink_block_v2.c index d98ccb3..cb7a510 100644 --- a/src/shrink_block_v2.c +++ b/src/shrink_block_v2.c @@ -915,6 +915,12 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa i += nMatchLen; + if (pCompressor->flags & LZSA_FLAG_RAW_BLOCK) { + int nCurSafeDist = (i - nStartOffset) - nOutOffset; + if (nCurSafeDist >= 0 && pCompressor->safe_dist < nCurSafeDist) + pCompressor->safe_dist = nCurSafeDist; + } + pCompressor->num_commands++; } else { @@ -945,6 +951,12 @@ static int lzsa_write_block_v2(lzsa_compressor *pCompressor, lzsa_match *pBestMa nNumLiterals = 0; } + if (pCompressor->flags & LZSA_FLAG_RAW_BLOCK) { + int nCurSafeDist = (i - nStartOffset) - nOutOffset; + if (nCurSafeDist >= 0 && pCompressor->safe_dist < nCurSafeDist) + pCompressor->safe_dist = nCurSafeDist; + } + pCompressor->num_commands++; } diff --git a/src/shrink_context.c b/src/shrink_context.c index 2ccce8e..26a5d04 100644 --- a/src/shrink_context.c +++ b/src/shrink_context.c @@ -71,6 +71,7 @@ int lzsa_compressor_init(lzsa_compressor *pCompressor, const int nMaxWindowSize, pCompressor->max_forward_depth = 0; pCompressor->format_version = nFormatVersion; pCompressor->flags = nFlags; + pCompressor->safe_dist = 0; pCompressor->num_commands = 0; if (!nResult) { diff --git a/src/shrink_context.h b/src/shrink_context.h index 46c695c..4bbf6ec 100644 --- a/src/shrink_context.h +++ b/src/shrink_context.h @@ -87,6 +87,7 @@ typedef struct _lzsa_compressor { int max_forward_depth; int format_version; int flags; + int safe_dist; int num_commands; lzsa_hashmap_t cost_map; } lzsa_compressor; diff --git a/src/shrink_streaming.c b/src/shrink_streaming.c index 37ba0f3..63dc89f 100644 --- a/src/shrink_streaming.c +++ b/src/shrink_streaming.c @@ -74,7 +74,7 @@ static void lzsa_delete_file(const char *pszInFilename) { * @return LZSA_OK for success, or an error value from lzsa_status_t */ lzsa_status_t lzsa_compress_file(const char *pszInFilename, const char *pszOutFilename, const char *pszDictionaryFilename, const unsigned int nFlags, const int nMinMatchSize, const int nFormatVersion, - void(*progress)(long long nOriginalSize, long long nCompressedSize), long long *pOriginalSize, long long *pCompressedSize, int *pCommandCount) { + void(*progress)(long long nOriginalSize, long long nCompressedSize), long long *pOriginalSize, long long *pCompressedSize, int *pCommandCount, int *pSafeDist) { lzsa_stream_t inStream, outStream; void *pDictionaryData = NULL; int nDictionaryDataSize = 0; @@ -98,7 +98,7 @@ lzsa_status_t lzsa_compress_file(const char *pszInFilename, const char *pszOutFi return nStatus; } - nStatus = lzsa_compress_stream(&inStream, &outStream, pDictionaryData, nDictionaryDataSize, nFlags, nMinMatchSize, nFormatVersion, progress, pOriginalSize, pCompressedSize, pCommandCount); + nStatus = lzsa_compress_stream(&inStream, &outStream, pDictionaryData, nDictionaryDataSize, nFlags, nMinMatchSize, nFormatVersion, progress, pOriginalSize, pCompressedSize, pCommandCount, pSafeDist); lzsa_dictionary_free(&pDictionaryData); outStream.close(&outStream); @@ -132,7 +132,7 @@ lzsa_status_t lzsa_compress_file(const char *pszInFilename, const char *pszOutFi */ lzsa_status_t lzsa_compress_stream(lzsa_stream_t *pInStream, lzsa_stream_t *pOutStream, const void *pDictionaryData, int nDictionaryDataSize, const unsigned int nFlags, const int nMinMatchSize, const int nFormatVersion, - void(*progress)(long long nOriginalSize, long long nCompressedSize), long long *pOriginalSize, long long *pCompressedSize, int *pCommandCount) { + void(*progress)(long long nOriginalSize, long long nCompressedSize), long long *pOriginalSize, long long *pCompressedSize, int *pCommandCount, int *pSafeDist) { unsigned char *pInData, *pOutData; lzsa_compressor compressor; long long nOriginalSize = 0LL, nCompressedSize = 0LL; @@ -301,6 +301,7 @@ lzsa_status_t lzsa_compress_stream(lzsa_stream_t *pInStream, lzsa_stream_t *pOut progress(nOriginalSize, nCompressedSize); int nCommandCount = lzsa_compressor_get_command_count(&compressor); + int nSafeDist = compressor.safe_dist; lzsa_compressor_destroy(&compressor); free(pOutData); @@ -319,6 +320,8 @@ lzsa_status_t lzsa_compress_stream(lzsa_stream_t *pInStream, lzsa_stream_t *pOut *pCompressedSize = nCompressedSize; if (pCommandCount) *pCommandCount = nCommandCount; + if (pSafeDist) + *pSafeDist = nSafeDist; return LZSA_OK; } } diff --git a/src/shrink_streaming.h b/src/shrink_streaming.h index d962a1a..2d2186e 100644 --- a/src/shrink_streaming.h +++ b/src/shrink_streaming.h @@ -62,7 +62,7 @@ typedef enum _lzsa_status_t lzsa_status_t; */ lzsa_status_t lzsa_compress_file(const char *pszInFilename, const char *pszOutFilename, const char *pszDictionaryFilename, const unsigned int nFlags, const int nMinMatchSize, const int nFormatVersion, - void(*progress)(long long nOriginalSize, long long nCompressedSize), long long *pOriginalSize, long long *pCompressedSize, int *pCommandCount); + void(*progress)(long long nOriginalSize, long long nCompressedSize), long long *pOriginalSize, long long *pCompressedSize, int *pCommandCount, int *pSafeDist); /*-------------- Streaming API -------------- */ @@ -85,7 +85,7 @@ lzsa_status_t lzsa_compress_file(const char *pszInFilename, const char *pszOutFi */ lzsa_status_t lzsa_compress_stream(lzsa_stream_t *pInStream, lzsa_stream_t *pOutStream, const void *pDictionaryData, int nDictionaryDataSize, const unsigned int nFlags, const int nMinMatchSize, const int nFormatVersion, - void(*progress)(long long nOriginalSize, long long nCompressedSize), long long *pOriginalSize, long long *pCompressedSize, int *pCommandCount); + void(*progress)(long long nOriginalSize, long long nCompressedSize), long long *pOriginalSize, long long *pCompressedSize, int *pCommandCount, int *pSafeDist); #ifdef __cplusplus }