1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file delta_encoder.c
4 /// \brief Delta filter encoder
6 // Author: Lasse Collin
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
11 ///////////////////////////////////////////////////////////////////////////////
13 #include "delta_encoder.h"
14 #include "delta_private.h"
17 /// Copies and encodes the data at the same time. This is used when Delta
18 /// is the first filter in the chain (and thus the last filter in the
19 /// encoder's filter stack).
21 copy_and_encode(lzma_coder
*coder
,
22 const uint8_t *restrict in
, uint8_t *restrict out
, size_t size
)
24 const size_t distance
= coder
->distance
;
26 for (size_t i
= 0; i
< size
; ++i
) {
27 const uint8_t tmp
= coder
->history
[
28 (distance
+ coder
->pos
) & 0xFF];
29 coder
->history
[coder
->pos
-- & 0xFF] = in
[i
];
35 /// Encodes the data in place. This is used when we are the last filter
36 /// in the chain (and thus non-last filter in the encoder's filter stack).
38 encode_in_place(lzma_coder
*coder
, uint8_t *buffer
, size_t size
)
40 const size_t distance
= coder
->distance
;
42 for (size_t i
= 0; i
< size
; ++i
) {
43 const uint8_t tmp
= coder
->history
[
44 (distance
+ coder
->pos
) & 0xFF];
45 coder
->history
[coder
->pos
-- & 0xFF] = buffer
[i
];
52 delta_encode(lzma_coder
*coder
, const lzma_allocator
*allocator
,
53 const uint8_t *restrict in
, size_t *restrict in_pos
,
54 size_t in_size
, uint8_t *restrict out
,
55 size_t *restrict out_pos
, size_t out_size
, lzma_action action
)
59 if (coder
->next
.code
== NULL
) {
60 const size_t in_avail
= in_size
- *in_pos
;
61 const size_t out_avail
= out_size
- *out_pos
;
62 const size_t size
= my_min(in_avail
, out_avail
);
64 copy_and_encode(coder
, in
+ *in_pos
, out
+ *out_pos
, size
);
69 ret
= action
!= LZMA_RUN
&& *in_pos
== in_size
70 ? LZMA_STREAM_END
: LZMA_OK
;
73 const size_t out_start
= *out_pos
;
75 ret
= coder
->next
.code(coder
->next
.coder
, allocator
,
76 in
, in_pos
, in_size
, out
, out_pos
, out_size
,
79 encode_in_place(coder
, out
+ out_start
, *out_pos
- out_start
);
87 delta_encoder_update(lzma_coder
*coder
, const lzma_allocator
*allocator
,
88 const lzma_filter
*filters_null
lzma_attribute((__unused__
)),
89 const lzma_filter
*reversed_filters
)
91 // Delta doesn't and will never support changing the options in
92 // the middle of encoding. If the app tries to change them, we
93 // simply ignore them.
94 return lzma_next_filter_update(
95 &coder
->next
, allocator
, reversed_filters
+ 1);
100 lzma_delta_encoder_init(lzma_next_coder
*next
, const lzma_allocator
*allocator
,
101 const lzma_filter_info
*filters
)
103 next
->code
= &delta_encode
;
104 next
->update
= &delta_encoder_update
;
105 return lzma_delta_coder_init(next
, allocator
, filters
);
110 lzma_delta_props_encode(const void *options
, uint8_t *out
)
112 // The caller must have already validated the options, so it's
113 // LZMA_PROG_ERROR if they are invalid.
114 if (lzma_delta_coder_memusage(options
) == UINT64_MAX
)
115 return LZMA_PROG_ERROR
;
117 const lzma_options_delta
*opt
= options
;
118 out
[0] = opt
->dist
- LZMA_DELTA_DIST_MIN
;