/src/xz/src/liblzma/common/filter_decoder.c
Line | Count | Source (jump to first uncovered line) |
1 | | /////////////////////////////////////////////////////////////////////////////// |
2 | | // |
3 | | /// \file filter_decoder.c |
4 | | /// \brief Filter ID mapping to filter-specific functions |
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 "filter_decoder.h" |
14 | | #include "filter_common.h" |
15 | | #include "lzma_decoder.h" |
16 | | #include "lzma2_decoder.h" |
17 | | #include "simple_decoder.h" |
18 | | #include "delta_decoder.h" |
19 | | |
20 | | |
21 | | typedef struct { |
22 | | /// Filter ID |
23 | | lzma_vli id; |
24 | | |
25 | | /// Initializes the filter encoder and calls lzma_next_filter_init() |
26 | | /// for filters + 1. |
27 | | lzma_init_function init; |
28 | | |
29 | | /// Calculates memory usage of the encoder. If the options are |
30 | | /// invalid, UINT64_MAX is returned. |
31 | | uint64_t (*memusage)(const void *options); |
32 | | |
33 | | /// Decodes Filter Properties. |
34 | | /// |
35 | | /// \return - LZMA_OK: Properties decoded successfully. |
36 | | /// - LZMA_OPTIONS_ERROR: Unsupported properties |
37 | | /// - LZMA_MEM_ERROR: Memory allocation failed. |
38 | | lzma_ret (*props_decode)( |
39 | | void **options, const lzma_allocator *allocator, |
40 | | const uint8_t *props, size_t props_size); |
41 | | |
42 | | } lzma_filter_decoder; |
43 | | |
44 | | |
45 | | static const lzma_filter_decoder decoders[] = { |
46 | | #ifdef HAVE_DECODER_LZMA1 |
47 | | { |
48 | | .id = LZMA_FILTER_LZMA1, |
49 | | .init = &lzma_lzma_decoder_init, |
50 | | .memusage = &lzma_lzma_decoder_memusage, |
51 | | .props_decode = &lzma_lzma_props_decode, |
52 | | }, |
53 | | { |
54 | | .id = LZMA_FILTER_LZMA1EXT, |
55 | | .init = &lzma_lzma_decoder_init, |
56 | | .memusage = &lzma_lzma_decoder_memusage, |
57 | | .props_decode = &lzma_lzma_props_decode, |
58 | | }, |
59 | | #endif |
60 | | #ifdef HAVE_DECODER_LZMA2 |
61 | | { |
62 | | .id = LZMA_FILTER_LZMA2, |
63 | | .init = &lzma_lzma2_decoder_init, |
64 | | .memusage = &lzma_lzma2_decoder_memusage, |
65 | | .props_decode = &lzma_lzma2_props_decode, |
66 | | }, |
67 | | #endif |
68 | | #ifdef HAVE_DECODER_X86 |
69 | | { |
70 | | .id = LZMA_FILTER_X86, |
71 | | .init = &lzma_simple_x86_decoder_init, |
72 | | .memusage = NULL, |
73 | | .props_decode = &lzma_simple_props_decode, |
74 | | }, |
75 | | #endif |
76 | | #ifdef HAVE_DECODER_POWERPC |
77 | | { |
78 | | .id = LZMA_FILTER_POWERPC, |
79 | | .init = &lzma_simple_powerpc_decoder_init, |
80 | | .memusage = NULL, |
81 | | .props_decode = &lzma_simple_props_decode, |
82 | | }, |
83 | | #endif |
84 | | #ifdef HAVE_DECODER_IA64 |
85 | | { |
86 | | .id = LZMA_FILTER_IA64, |
87 | | .init = &lzma_simple_ia64_decoder_init, |
88 | | .memusage = NULL, |
89 | | .props_decode = &lzma_simple_props_decode, |
90 | | }, |
91 | | #endif |
92 | | #ifdef HAVE_DECODER_ARM |
93 | | { |
94 | | .id = LZMA_FILTER_ARM, |
95 | | .init = &lzma_simple_arm_decoder_init, |
96 | | .memusage = NULL, |
97 | | .props_decode = &lzma_simple_props_decode, |
98 | | }, |
99 | | #endif |
100 | | #ifdef HAVE_DECODER_ARMTHUMB |
101 | | { |
102 | | .id = LZMA_FILTER_ARMTHUMB, |
103 | | .init = &lzma_simple_armthumb_decoder_init, |
104 | | .memusage = NULL, |
105 | | .props_decode = &lzma_simple_props_decode, |
106 | | }, |
107 | | #endif |
108 | | #ifdef HAVE_DECODER_ARM64 |
109 | | { |
110 | | .id = LZMA_FILTER_ARM64, |
111 | | .init = &lzma_simple_arm64_decoder_init, |
112 | | .memusage = NULL, |
113 | | .props_decode = &lzma_simple_props_decode, |
114 | | }, |
115 | | #endif |
116 | | #ifdef HAVE_DECODER_SPARC |
117 | | { |
118 | | .id = LZMA_FILTER_SPARC, |
119 | | .init = &lzma_simple_sparc_decoder_init, |
120 | | .memusage = NULL, |
121 | | .props_decode = &lzma_simple_props_decode, |
122 | | }, |
123 | | #endif |
124 | | #ifdef HAVE_DECODER_DELTA |
125 | | { |
126 | | .id = LZMA_FILTER_DELTA, |
127 | | .init = &lzma_delta_decoder_init, |
128 | | .memusage = &lzma_delta_coder_memusage, |
129 | | .props_decode = &lzma_delta_props_decode, |
130 | | }, |
131 | | #endif |
132 | | }; |
133 | | |
134 | | |
135 | | static const lzma_filter_decoder * |
136 | | decoder_find(lzma_vli id) |
137 | 1.70M | { |
138 | 7.79M | for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) |
139 | 7.79M | if (decoders[i].id == id) |
140 | 1.70M | return decoders + i; |
141 | | |
142 | 142 | return NULL; |
143 | 1.70M | } |
144 | | |
145 | | |
146 | | extern LZMA_API(lzma_bool) |
147 | | lzma_filter_decoder_is_supported(lzma_vli id) |
148 | 0 | { |
149 | 0 | return decoder_find(id) != NULL; |
150 | 0 | } |
151 | | |
152 | | |
153 | | extern lzma_ret |
154 | | lzma_raw_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, |
155 | | const lzma_filter *options) |
156 | 280k | { |
157 | 280k | return lzma_raw_coder_init(next, allocator, |
158 | 280k | options, (lzma_filter_find)(&decoder_find), false); |
159 | 280k | } |
160 | | |
161 | | |
162 | | extern LZMA_API(lzma_ret) |
163 | | lzma_raw_decoder(lzma_stream *strm, const lzma_filter *options) |
164 | 0 | { |
165 | 0 | lzma_next_strm_init(lzma_raw_decoder_init, strm, options); |
166 | | |
167 | 0 | strm->internal->supported_actions[LZMA_RUN] = true; |
168 | 0 | strm->internal->supported_actions[LZMA_FINISH] = true; |
169 | |
|
170 | 0 | return LZMA_OK; |
171 | 0 | } |
172 | | |
173 | | |
174 | | extern LZMA_API(uint64_t) |
175 | | lzma_raw_decoder_memusage(const lzma_filter *filters) |
176 | 280k | { |
177 | 280k | return lzma_raw_coder_memusage( |
178 | 280k | (lzma_filter_find)(&decoder_find), filters); |
179 | 280k | } |
180 | | |
181 | | |
182 | | extern LZMA_API(lzma_ret) |
183 | | lzma_properties_decode(lzma_filter *filter, const lzma_allocator *allocator, |
184 | | const uint8_t *props, size_t props_size) |
185 | 567k | { |
186 | | // Make it always NULL so that the caller can always safely free() it. |
187 | 567k | filter->options = NULL; |
188 | | |
189 | 567k | const lzma_filter_decoder *const fd = decoder_find(filter->id); |
190 | 567k | if (fd == NULL) |
191 | 142 | return LZMA_OPTIONS_ERROR; |
192 | | |
193 | 567k | if (fd->props_decode == NULL) |
194 | 0 | return props_size == 0 ? LZMA_OK : LZMA_OPTIONS_ERROR; |
195 | | |
196 | 567k | return fd->props_decode( |
197 | 567k | &filter->options, allocator, props, props_size); |
198 | 567k | } |