diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2008-01-19 15:19:21 +0200 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2008-01-19 15:19:21 +0200 |
commit | 23c227a864a3b69f38c6a74306161d4e6918d1cc (patch) | |
tree | 49bfe24e15c1df35589635f8630a9e44dc7604a2 /src/liblzma/common/delta_common.c | |
parent | Added the debug directory and the first debug tool (diff) | |
download | xz-23c227a864a3b69f38c6a74306161d4e6918d1cc.tar.xz |
Revised the Delta filter implementation. The initialization
function is still shared between encoder and decoder, but the
actual coding is in separate files for encoder and decoder.
There are now separate functions for the actual delta
calculation depending on if Delta is the last filter in the
chain or not. If it is the last, the new code copies the
data from input to output buffer and does the delta
calculation at the same time. The old code first copied the
data, then did the delta in the target buffer, which required
reading through the data twice.
Support for LZMA_SYNC_FLUSH was added to the Delta encoder.
This doesn't change anything in the file format.
Diffstat (limited to 'src/liblzma/common/delta_common.c')
-rw-r--r-- | src/liblzma/common/delta_common.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/liblzma/common/delta_common.c b/src/liblzma/common/delta_common.c new file mode 100644 index 00000000..de27b5a6 --- /dev/null +++ b/src/liblzma/common/delta_common.c @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file delta_common.c +/// \brief Common stuff for Delta encoder and decoder +// +// Copyright (C) 2007 Lasse Collin +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "delta_common.h" + + +static void +delta_coder_end(lzma_coder *coder, lzma_allocator *allocator) +{ + lzma_next_coder_end(&coder->next, allocator); + lzma_free(coder, allocator); + return; +} + + +extern lzma_ret +lzma_delta_coder_init(lzma_next_coder *next, lzma_allocator *allocator, + const lzma_filter_info *filters, lzma_code_function code) +{ + // Allocate memory for the decoder if needed. + if (next->coder == NULL) { + next->coder = lzma_alloc(sizeof(lzma_coder), allocator); + if (next->coder == NULL) + return LZMA_MEM_ERROR; + + // End function is the same for encoder and decoder. + next->end = &delta_coder_end; + next->coder->next = LZMA_NEXT_CODER_INIT; + } + + // Coding function is different for encoder and decoder. + next->code = code; + + // Copy Uncompressed Size which is used to limit the output size + // in the Delta decoder. + next->coder->uncompressed_size = filters[0].uncompressed_size; + + // Set the delta distance. + if (filters[0].options == NULL) + return LZMA_PROG_ERROR; + next->coder->distance = ((lzma_options_delta *)(filters[0].options)) + ->distance; + if (next->coder->distance < LZMA_DELTA_DISTANCE_MIN + || next->coder->distance > LZMA_DELTA_DISTANCE_MAX) + return LZMA_HEADER_ERROR; + + // Initialize the rest of the variables. + next->coder->pos = 0; + memzero(next->coder->history, LZMA_DELTA_DISTANCE_MAX); + + // Initialize the next decoder in the chain, if any. + return lzma_next_filter_init(&next->coder->next, + allocator, filters + 1); +} |