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:
Lasse Collin 2013-03-23 21:55:13 +02:00
parent e572e123b5
commit bb117fffa8
1 changed files with 50 additions and 16 deletions

View File

@ -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;
} }