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