Add options to brotli and implement clean brotli .br support

- allow to specify brotli window size
  - parameter -m0=brotli:long=n, BROTLI_MAX_WINDOW_BITS (24) used by default in brotli-mt, smaller == faster
  - note that :long can be set up to BROTLI_LARGE_MAX_WINDOW_BITS (30), whereas :wlog can be set up to BROTLI_MAX_WINDOW_BITS (24) only...
  - todo: check whether set of BROTLI_PARAM_LARGE_WINDOW to BROTLI_TRUE is needed if (lgwin > BROTLI_MAX_WINDOW_BITS)

- implementation of single-threaded brotli compression / decompression for .br data

Signed-off-by: Sergey G. Brester <info@sebres.de>
Reviewed-by: Tino Reichardt <milky-7zip@mcmilk.de>
This commit is contained in:
sebres
2021-08-30 17:16:08 +02:00
committed by Tino Reichardt
parent 9bb11a56b6
commit eeae03eaa1
8 changed files with 660 additions and 40 deletions

View File

@@ -12,8 +12,10 @@ CEncoder::CEncoder():
_processedIn(0),
_processedOut(0),
_inputSize(0),
_ctx(NULL),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
_numThreads(NWindows::NSystem::GetNumberOfProcessors()),
_Long(-1),
_WindowLog(-1),
_ctx(NULL)
{
_props.clear();
}
@@ -52,6 +54,37 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARI
SetNumberOfThreads(v);
break;
}
case NCoderPropID::kLong:
{
/* like --long in zstd cli program */
_Long = 1;
if (v == 0) {
if (prop.vt == VT_EMPTY) {
// m0=brotli:long -> long=default
_WindowLog = BROTLI_MAX_WINDOW_BITS; //BROTLI_DEFAULT_WINDOW;
} else {
// m0=brotli:long=0 -> long=auto
_WindowLog = 0;
}
} else if (v < BROTLI_MIN_WINDOW_BITS) {
// m0=brotli:long=9 -> long=10
_WindowLog = BROTLI_MIN_WINDOW_BITS;
} else if (v > BROTLI_LARGE_MAX_WINDOW_BITS) {
// m0=brotli:long=33 -> long=max
_WindowLog = BROTLI_LARGE_MAX_WINDOW_BITS;
} else {
// m0=brotli:long=15 -> long=value
_WindowLog = v;
}
break;
}
case NCoderPropID::kWindowLog:
{
if (v < BROTLI_MIN_WINDOW_BITS) v = BROTLI_MIN_WINDOW_BITS;
if (v > BROTLI_MAX_WINDOW_BITS) v = BROTLI_MAX_WINDOW_BITS;
_WindowLog = v;
break;
}
default:
{
break;
@@ -102,11 +135,12 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
/* 2) create compression context, if needed */
if (!_ctx)
_ctx = BROTLIMT_createCCtx(_numThreads, _props._level, _inputSize);
_ctx = BROTLIMT_createCCtx(_numThreads, unpackSize, _props._level, _inputSize,
_WindowLog >= 0 ? _WindowLog : BROTLI_MAX_WINDOW_BITS);
if (!_ctx)
return S_FALSE;
/* 3) compress */
/* 4) compress */
result = BROTLIMT_compressCCtx(_ctx, &rdwr);
if (BROTLIMT_isError(result)) {
if (result == (size_t)-BROTLIMT_error_canceled)
@@ -120,7 +154,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
{
const UInt32 kNumThreadsMax = BROTLIMT_THREAD_MAX;
if (numThreads < 1) numThreads = 1;
if (numThreads < 0) numThreads = 0;
if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
_numThreads = numThreads;
return S_OK;