liblzma: Use lzma_block_buffer_bound64() in threaded encoder.
Now it uses lzma_block_uncomp_encode() if the data doesn't fit into the space calculated by lzma_block_buffer_bound64().
This commit is contained in:
parent
e572e123b5
commit
bb117fffa8
|
@ -13,6 +13,7 @@
|
||||||
#include "filter_encoder.h"
|
#include "filter_encoder.h"
|
||||||
#include "easy_preset.h"
|
#include "easy_preset.h"
|
||||||
#include "block_encoder.h"
|
#include "block_encoder.h"
|
||||||
|
#include "block_buffer_encoder.h"
|
||||||
#include "index_encoder.h"
|
#include "index_encoder.h"
|
||||||
#include "outqueue.h"
|
#include "outqueue.h"
|
||||||
|
|
||||||
|
@ -279,19 +280,55 @@ worker_encode(worker_thread *thr, worker_state state)
|
||||||
thr->block_encoder.coder, thr->allocator,
|
thr->block_encoder.coder, thr->allocator,
|
||||||
thr->in, &in_pos, in_limit, thr->outbuf->buf,
|
thr->in, &in_pos, in_limit, thr->outbuf->buf,
|
||||||
&thr->outbuf->size, out_size, action);
|
&thr->outbuf->size, out_size, action);
|
||||||
} while (ret == LZMA_OK);
|
} while (ret == LZMA_OK && thr->outbuf->size < out_size);
|
||||||
|
|
||||||
if (ret != LZMA_STREAM_END) {
|
switch (ret) {
|
||||||
worker_error(thr, ret);
|
case LZMA_STREAM_END:
|
||||||
return THR_STOP;
|
assert(state == THR_FINISH);
|
||||||
}
|
|
||||||
|
|
||||||
assert(state == THR_FINISH);
|
// Encode the Block Header. By doing it after
|
||||||
|
// the compression, we can store the Compressed Size
|
||||||
|
// and Uncompressed Size fields.
|
||||||
|
ret = lzma_block_header_encode(&thr->block_options,
|
||||||
|
thr->outbuf->buf);
|
||||||
|
if (ret != LZMA_OK) {
|
||||||
|
worker_error(thr, ret);
|
||||||
|
return THR_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
// Encode the Block Header. By doing it after the compression,
|
break;
|
||||||
// we can store the Compressed Size and Uncompressed Size fields.
|
|
||||||
ret = lzma_block_header_encode(&thr->block_options, thr->outbuf->buf);
|
case LZMA_OK:
|
||||||
if (ret != LZMA_OK) {
|
// The data was incompressible. Encode it using uncompressed
|
||||||
|
// LZMA2 chunks.
|
||||||
|
//
|
||||||
|
// First wait that we have gotten all the input.
|
||||||
|
mythread_sync(thr->mutex) {
|
||||||
|
while (thr->state == THR_RUN)
|
||||||
|
pthread_cond_wait(&thr->cond, &thr->mutex);
|
||||||
|
|
||||||
|
state = thr->state;
|
||||||
|
in_size = thr->in_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state >= THR_STOP)
|
||||||
|
return state;
|
||||||
|
|
||||||
|
// Do the encoding. This takes care of the Block Header too.
|
||||||
|
thr->outbuf->size = 0;
|
||||||
|
ret = lzma_block_uncomp_encode(&thr->block_options,
|
||||||
|
thr->in, in_size, thr->outbuf->buf,
|
||||||
|
&thr->outbuf->size, out_size);
|
||||||
|
|
||||||
|
// It shouldn't fail.
|
||||||
|
if (ret != LZMA_OK) {
|
||||||
|
worker_error(thr, LZMA_PROG_ERROR);
|
||||||
|
return THR_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
worker_error(thr, ret);
|
worker_error(thr, ret);
|
||||||
return THR_STOP;
|
return THR_STOP;
|
||||||
}
|
}
|
||||||
|
@ -842,12 +879,9 @@ get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
|
||||||
// Calculate the maximum amount output that a single output buffer
|
// Calculate the maximum amount output that a single output buffer
|
||||||
// may need to hold. This is the same as the maximum total size of
|
// may need to hold. This is the same as the maximum total size of
|
||||||
// a Block.
|
// a Block.
|
||||||
//
|
*outbuf_size_max = lzma_block_buffer_bound64(*block_size);
|
||||||
// FIXME: As long as the encoder keeps the whole input buffer
|
if (*outbuf_size_max == 0)
|
||||||
// available and doesn't start writing output before finishing
|
return LZMA_MEM_ERROR;
|
||||||
// the Block, it could use lzma_stream_buffer_bound() and use
|
|
||||||
// uncompressed LZMA2 chunks if the data doesn't compress.
|
|
||||||
*outbuf_size_max = *block_size + *block_size / 16 + 16384;
|
|
||||||
|
|
||||||
return LZMA_OK;
|
return LZMA_OK;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue