aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/common
diff options
context:
space:
mode:
authorJia Tan <jiat0218@gmail.com>2023-05-09 20:20:06 +0800
committerJia Tan <jiat0218@gmail.com>2023-05-11 23:54:44 +0800
commit8f236574986e7c414c0ea059f441982d1387e6a4 (patch)
treea7f93f05e0905183658a452528c9d4bb9a4ebd81 /src/liblzma/common
parentliblzma: Creates IS_ENC_DICT_SIZE_VALID() macro. (diff)
downloadxz-8f236574986e7c414c0ea059f441982d1387e6a4.tar.xz
liblzma: Exports lzma_mt_block_size() as an API function.
The lzma_mt_block_size() was previously just an internal function for the multithreaded .xz encoder. It is used to provide a recommended Block size for a given filter chain. This function is helpful to determine the maximum Block size for the multithreaded .xz encoder when one wants to change the filters between blocks. Then, this determined Block size can be provided to lzma_stream_encoder_mt() in the lzma_mt options parameter when intializing the coder. This requires one to know all the filter chains they are using before starting to encode (or at least the filter chain that will need the largest Block size), but that isn't a bad limitation.
Diffstat (limited to 'src/liblzma/common')
-rw-r--r--src/liblzma/common/filter_encoder.c16
-rw-r--r--src/liblzma/common/filter_encoder.h6
-rw-r--r--src/liblzma/common/stream_encoder_mt.c20
3 files changed, 20 insertions, 22 deletions
diff --git a/src/liblzma/common/filter_encoder.c b/src/liblzma/common/filter_encoder.c
index 46fe8af1..0699bcee 100644
--- a/src/liblzma/common/filter_encoder.c
+++ b/src/liblzma/common/filter_encoder.c
@@ -33,7 +33,8 @@ typedef struct {
/// Calculates the recommended Uncompressed Size for .xz Blocks to
/// which the input data can be split to make multithreaded
/// encoding possible. If this is NULL, it is assumed that
- /// the encoder is fast enough with single thread.
+ /// the encoder is fast enough with single thread. If the options
+ /// are invalid, UINT64_MAX is returned.
uint64_t (*block_size)(const void *options);
/// Tells the size of the Filter Properties field. If options are
@@ -248,26 +249,29 @@ lzma_raw_encoder_memusage(const lzma_filter *filters)
}
-extern uint64_t
+extern LZMA_API(uint64_t)
lzma_mt_block_size(const lzma_filter *filters)
{
+ if (filters == NULL)
+ return UINT64_MAX;
+
uint64_t max = 0;
for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
const lzma_filter_encoder *const fe
= encoder_find(filters[i].id);
+ if (fe == NULL)
+ return UINT64_MAX;
+
if (fe->block_size != NULL) {
const uint64_t size
= fe->block_size(filters[i].options);
- if (size == 0)
- return 0;
-
if (size > max)
max = size;
}
}
- return max;
+ return max == 0 ? UINT64_MAX : max;
}
diff --git a/src/liblzma/common/filter_encoder.h b/src/liblzma/common/filter_encoder.h
index f1d5683f..da92be8b 100644
--- a/src/liblzma/common/filter_encoder.h
+++ b/src/liblzma/common/filter_encoder.h
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
-/// \file filter_encoder.c
+/// \file filter_encoder.h
/// \brief Filter ID mapping to filter-specific functions
//
// Author: Lasse Collin
@@ -16,10 +16,6 @@
#include "common.h"
-// FIXME: Might become a part of the public API.
-extern uint64_t lzma_mt_block_size(const lzma_filter *filters);
-
-
extern lzma_ret lzma_raw_encoder_init(
lzma_next_coder *next, const lzma_allocator *allocator,
const lzma_filter *filters);
diff --git a/src/liblzma/common/stream_encoder_mt.c b/src/liblzma/common/stream_encoder_mt.c
index 5990742b..703b794e 100644
--- a/src/liblzma/common/stream_encoder_mt.c
+++ b/src/liblzma/common/stream_encoder_mt.c
@@ -979,20 +979,18 @@ get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
*filters = opt_easy->filters;
}
- // Block size
- if (options->block_size > 0) {
- if (options->block_size > BLOCK_SIZE_MAX)
- return LZMA_OPTIONS_ERROR;
-
+ // If the Block size is not set, determine it from the filter chain.
+ if (options->block_size > 0)
*block_size = options->block_size;
- } else {
- // Determine the Block size from the filter chain.
+ else
*block_size = lzma_mt_block_size(*filters);
- if (*block_size == 0)
- return LZMA_OPTIONS_ERROR;
- assert(*block_size <= BLOCK_SIZE_MAX);
- }
+ // UINT64_MAX > BLOCK_SIZE_MAX, so the second condition
+ // should be optimized out by any reasonable compiler.
+ // The second condition should be there in the unlikely event that
+ // the macros change and UINT64_MAX < BLOCK_SIZE_MAX.
+ if (*block_size > BLOCK_SIZE_MAX || *block_size == UINT64_MAX)
+ return LZMA_OPTIONS_ERROR;
// Calculate the maximum amount output that a single output buffer
// may need to hold. This is the same as the maximum total size of