OLD | NEW |
(Empty) | |
| 1 /////////////////////////////////////////////////////////////////////////////// |
| 2 // |
| 3 /// \file delta_decoder.c |
| 4 /// \brief Delta filter decoder |
| 5 // |
| 6 // Author: Lasse Collin |
| 7 // |
| 8 // This file has been put into the public domain. |
| 9 // You can do whatever you want with this file. |
| 10 // |
| 11 /////////////////////////////////////////////////////////////////////////////// |
| 12 |
| 13 #include "delta_decoder.h" |
| 14 #include "delta_private.h" |
| 15 |
| 16 |
| 17 static void |
| 18 decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size) |
| 19 { |
| 20 const size_t distance = coder->distance; |
| 21 |
| 22 for (size_t i = 0; i < size; ++i) { |
| 23 buffer[i] += coder->history[(distance + coder->pos) & 0xFF]; |
| 24 coder->history[coder->pos-- & 0xFF] = buffer[i]; |
| 25 } |
| 26 } |
| 27 |
| 28 |
| 29 static lzma_ret |
| 30 delta_decode(lzma_coder *coder, lzma_allocator *allocator, |
| 31 const uint8_t *restrict in, size_t *restrict in_pos, |
| 32 size_t in_size, uint8_t *restrict out, |
| 33 size_t *restrict out_pos, size_t out_size, lzma_action action) |
| 34 { |
| 35 assert(coder->next.code != NULL); |
| 36 |
| 37 const size_t out_start = *out_pos; |
| 38 |
| 39 const lzma_ret ret = coder->next.code(coder->next.coder, allocator, |
| 40 in, in_pos, in_size, out, out_pos, out_size, |
| 41 action); |
| 42 |
| 43 decode_buffer(coder, out + out_start, *out_pos - out_start); |
| 44 |
| 45 return ret; |
| 46 } |
| 47 |
| 48 |
| 49 extern lzma_ret |
| 50 lzma_delta_decoder_init(lzma_next_coder *next, lzma_allocator *allocator, |
| 51 const lzma_filter_info *filters) |
| 52 { |
| 53 next->code = &delta_decode; |
| 54 return lzma_delta_coder_init(next, allocator, filters); |
| 55 } |
| 56 |
| 57 |
| 58 extern lzma_ret |
| 59 lzma_delta_props_decode(void **options, lzma_allocator *allocator, |
| 60 const uint8_t *props, size_t props_size) |
| 61 { |
| 62 if (props_size != 1) |
| 63 return LZMA_OPTIONS_ERROR; |
| 64 |
| 65 lzma_options_delta *opt |
| 66 = lzma_alloc(sizeof(lzma_options_delta), allocator); |
| 67 if (opt == NULL) |
| 68 return LZMA_MEM_ERROR; |
| 69 |
| 70 opt->type = LZMA_DELTA_TYPE_BYTE; |
| 71 opt->dist = props[0] + 1; |
| 72 |
| 73 *options = opt; |
| 74 |
| 75 return LZMA_OK; |
| 76 } |
OLD | NEW |