]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/delta/delta_decoder.c
Some API changes, bug fixes, cleanups etc.
[icculus/xz.git] / src / liblzma / delta / delta_decoder.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       delta_decoder.c
4 /// \brief      Delta filter decoder
5 //
6 //  Copyright (C) 2007, 2008 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "delta_decoder.h"
21 #include "delta_common.h"
22
23
24 static void
25 decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size)
26 {
27         const size_t distance = coder->distance;
28
29         for (size_t i = 0; i < size; ++i) {
30                 buffer[i] += coder->history[(distance + coder->pos) & 0xFF];
31                 coder->history[coder->pos-- & 0xFF] = buffer[i];
32         }
33 }
34
35
36 static lzma_ret
37 delta_decode(lzma_coder *coder, lzma_allocator *allocator,
38                 const uint8_t *restrict in, size_t *restrict in_pos,
39                 size_t in_size, uint8_t *restrict out,
40                 size_t *restrict out_pos, size_t out_size, lzma_action action)
41 {
42         assert(coder->next.code != NULL);
43
44         const size_t out_start = *out_pos;
45
46         const lzma_ret ret = coder->next.code(coder->next.coder, allocator,
47                         in, in_pos, in_size, out, out_pos, out_size,
48                         action);
49
50         decode_buffer(coder, out + out_start, *out_pos - out_start);
51
52         return ret;
53 }
54
55
56 extern lzma_ret
57 lzma_delta_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
58                 const lzma_filter_info *filters)
59 {
60         return lzma_delta_coder_init(next, allocator, filters, &delta_decode);
61 }
62
63
64 extern lzma_ret
65 lzma_delta_props_decode(void **options, lzma_allocator *allocator,
66                 const uint8_t *props, size_t props_size)
67 {
68         if (props_size != 1)
69                 return LZMA_OPTIONS_ERROR;
70
71         lzma_options_delta *opt
72                         = lzma_alloc(sizeof(lzma_options_delta), allocator);
73         if (opt == NULL)
74                 return LZMA_MEM_ERROR;
75
76         opt->type = LZMA_DELTA_TYPE_BYTE;
77         opt->dist = props[0] + 1;
78
79         *options = opt;
80
81         return LZMA_OK;
82 }