1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file delta_decoder.c 4207753Smm/// \brief Delta filter decoder 5207753Smm// 6207753Smm// Author: Lasse Collin 7207753Smm// 8207753Smm// This file has been put into the public domain. 9207753Smm// You can do whatever you want with this file. 10207753Smm// 11207753Smm/////////////////////////////////////////////////////////////////////////////// 12207753Smm 13207753Smm#include "delta_decoder.h" 14207753Smm#include "delta_private.h" 15207753Smm 16207753Smm 17207753Smmstatic void 18312518Sdelphijdecode_buffer(lzma_delta_coder *coder, uint8_t *buffer, size_t size) 19207753Smm{ 20207753Smm const size_t distance = coder->distance; 21207753Smm 22207753Smm for (size_t i = 0; i < size; ++i) { 23207753Smm buffer[i] += coder->history[(distance + coder->pos) & 0xFF]; 24207753Smm coder->history[coder->pos-- & 0xFF] = buffer[i]; 25207753Smm } 26207753Smm} 27207753Smm 28207753Smm 29207753Smmstatic lzma_ret 30312518Sdelphijdelta_decode(void *coder_ptr, const lzma_allocator *allocator, 31207753Smm const uint8_t *restrict in, size_t *restrict in_pos, 32207753Smm size_t in_size, uint8_t *restrict out, 33207753Smm size_t *restrict out_pos, size_t out_size, lzma_action action) 34207753Smm{ 35312518Sdelphij lzma_delta_coder *coder = coder_ptr; 36312518Sdelphij 37207753Smm assert(coder->next.code != NULL); 38207753Smm 39207753Smm const size_t out_start = *out_pos; 40207753Smm 41207753Smm const lzma_ret ret = coder->next.code(coder->next.coder, allocator, 42207753Smm in, in_pos, in_size, out, out_pos, out_size, 43207753Smm action); 44207753Smm 45207753Smm decode_buffer(coder, out + out_start, *out_pos - out_start); 46207753Smm 47207753Smm return ret; 48207753Smm} 49207753Smm 50207753Smm 51207753Smmextern lzma_ret 52292588Sdelphijlzma_delta_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, 53207753Smm const lzma_filter_info *filters) 54207753Smm{ 55207753Smm next->code = &delta_decode; 56207753Smm return lzma_delta_coder_init(next, allocator, filters); 57207753Smm} 58207753Smm 59207753Smm 60207753Smmextern lzma_ret 61292588Sdelphijlzma_delta_props_decode(void **options, const lzma_allocator *allocator, 62207753Smm const uint8_t *props, size_t props_size) 63207753Smm{ 64207753Smm if (props_size != 1) 65207753Smm return LZMA_OPTIONS_ERROR; 66207753Smm 67207753Smm lzma_options_delta *opt 68207753Smm = lzma_alloc(sizeof(lzma_options_delta), allocator); 69207753Smm if (opt == NULL) 70207753Smm return LZMA_MEM_ERROR; 71207753Smm 72207753Smm opt->type = LZMA_DELTA_TYPE_BYTE; 73207753Smm opt->dist = props[0] + 1; 74207753Smm 75207753Smm *options = opt; 76207753Smm 77207753Smm return LZMA_OK; 78207753Smm} 79