1 // SPDX-License-Identifier: 0BSD
3 ///////////////////////////////////////////////////////////////////////////////
5 /// \file delta_decoder.c
6 /// \brief Delta filter decoder
8 // Author: Lasse Collin
10 ///////////////////////////////////////////////////////////////////////////////
12 #include "delta_decoder.h"
13 #include "delta_private.h"
17 decode_buffer(lzma_delta_coder
*coder
, uint8_t *buffer
, size_t size
)
19 const size_t distance
= coder
->distance
;
21 for (size_t i
= 0; i
< size
; ++i
) {
22 buffer
[i
] += coder
->history
[(distance
+ coder
->pos
) & 0xFF];
23 coder
->history
[coder
->pos
-- & 0xFF] = buffer
[i
];
28 // For an unknown reason NVIDIA HPC Compiler needs this pragma
29 // to produce working code.
31 # pragma routine novector
34 delta_decode(void *coder_ptr
, const lzma_allocator
*allocator
,
35 const uint8_t *restrict in
, size_t *restrict in_pos
,
36 size_t in_size
, uint8_t *restrict out
,
37 size_t *restrict out_pos
, size_t out_size
, lzma_action action
)
39 lzma_delta_coder
*coder
= coder_ptr
;
41 assert(coder
->next
.code
!= NULL
);
43 const size_t out_start
= *out_pos
;
45 const lzma_ret ret
= coder
->next
.code(coder
->next
.coder
, allocator
,
46 in
, in_pos
, in_size
, out
, out_pos
, out_size
,
49 // out might be NULL. In that case size == 0. Null pointer + 0 is
50 // undefined behavior so skip the call in that case as it would
52 const size_t size
= *out_pos
- out_start
;
54 decode_buffer(coder
, out
+ out_start
, size
);
61 lzma_delta_decoder_init(lzma_next_coder
*next
, const lzma_allocator
*allocator
,
62 const lzma_filter_info
*filters
)
64 next
->code
= &delta_decode
;
65 return lzma_delta_coder_init(next
, allocator
, filters
);
70 lzma_delta_props_decode(void **options
, const lzma_allocator
*allocator
,
71 const uint8_t *props
, size_t props_size
)
74 return LZMA_OPTIONS_ERROR
;
76 lzma_options_delta
*opt
77 = lzma_alloc(sizeof(lzma_options_delta
), allocator
);
79 return LZMA_MEM_ERROR
;
81 opt
->type
= LZMA_DELTA_TYPE_BYTE
;
82 opt
->dist
= props
[0] + 1U;