]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/common/filter_decoder.c
Sort of garbage collection commit. :-| Many things are still
[icculus/xz.git] / src / liblzma / common / filter_decoder.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       filter_decoder.c
4 /// \brief      Filter ID mapping to filter-specific functions
5 //
6 //  Copyright (C) 2008 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "filter_decoder.h"
21 #include "filter_common.h"
22 #include "lzma_decoder.h"
23 #include "lzma2_decoder.h"
24 #include "subblock_decoder.h"
25 #include "subblock_decoder_helper.h"
26 #include "simple_decoder.h"
27 #include "delta_decoder.h"
28
29
30 typedef struct {
31         /// Initializes the filter encoder and calls lzma_next_filter_init()
32         /// for filters + 1.
33         lzma_init_function init;
34
35         /// Calculates memory usage of the encoder. If the options are
36         /// invalid, UINT64_MAX is returned.
37         uint64_t (*memusage)(const void *options);
38
39         /// Decodes Filter Properties.
40         ///
41         /// \return     - LZMA_OK: Properties decoded successfully.
42         ///             - LZMA_HEADER_ERROR: Unsupported properties
43         ///             - LZMA_MEM_ERROR: Memory allocation failed.
44         lzma_ret (*props_decode)(void **options, lzma_allocator *allocator,
45                         const uint8_t *props, size_t props_size);
46
47 } lzma_filter_decoder;
48
49
50 static const lzma_vli ids[] = {
51 #ifdef HAVE_DECODER_LZMA
52         LZMA_FILTER_LZMA,
53 #endif
54
55 #ifdef HAVE_DECODER_LZMA2
56         LZMA_FILTER_LZMA2,
57 #endif
58
59 #ifdef HAVE_DECODER_SUBBLOCK
60         LZMA_FILTER_SUBBLOCK,
61         LZMA_FILTER_SUBBLOCK_HELPER,
62 #endif
63
64 #ifdef HAVE_DECODER_X86
65         LZMA_FILTER_X86,
66 #endif
67
68 #ifdef HAVE_DECODER_POWERPC
69         LZMA_FILTER_POWERPC,
70 #endif
71
72 #ifdef HAVE_DECODER_IA64
73         LZMA_FILTER_IA64,
74 #endif
75
76 #ifdef HAVE_DECODER_ARM
77         LZMA_FILTER_ARM,
78 #endif
79
80 #ifdef HAVE_DECODER_ARMTHUMB
81         LZMA_FILTER_ARMTHUMB,
82 #endif
83
84 #ifdef HAVE_DECODER_SPARC
85         LZMA_FILTER_SPARC,
86 #endif
87
88 #ifdef HAVE_DECODER_DELTA
89         LZMA_FILTER_DELTA,
90 #endif
91
92         LZMA_VLI_VALUE_UNKNOWN
93 };
94
95
96 // Using a pointer to avoid putting the size of the array to API/ABI.
97 LZMA_API const lzma_vli *const lzma_filter_decoders = ids;
98
99
100 // These must be in the same order as ids[].
101 static const lzma_filter_decoder funcs[] = {
102 #ifdef HAVE_DECODER_LZMA
103         {
104                 .init = &lzma_lzma_decoder_init,
105                 .memusage = &lzma_lzma_decoder_memusage,
106                 .props_decode = &lzma_lzma_props_decode,
107         },
108 #endif
109 #ifdef HAVE_DECODER_LZMA2
110         {
111                 .init = &lzma_lzma2_decoder_init,
112                 .memusage = &lzma_lzma2_decoder_memusage,
113                 .props_decode = &lzma_lzma2_props_decode,
114         },
115 #endif
116 #ifdef HAVE_DECODER_SUBBLOCK
117         {
118                 .init = &lzma_subblock_decoder_init,
119 //              .memusage = &lzma_subblock_decoder_memusage,
120                 .props_decode = NULL,
121         },
122         {
123                 .init = &lzma_subblock_decoder_helper_init,
124                 .memusage = NULL,
125                 .props_decode = NULL,
126         },
127 #endif
128 #ifdef HAVE_DECODER_X86
129         {
130                 .init = &lzma_simple_x86_decoder_init,
131                 .memusage = NULL,
132                 .props_decode = &lzma_simple_props_decode,
133         },
134 #endif
135 #ifdef HAVE_DECODER_POWERPC
136         {
137                 .init = &lzma_simple_powerpc_decoder_init,
138                 .memusage = NULL,
139                 .props_decode = &lzma_simple_props_decode,
140         },
141 #endif
142 #ifdef HAVE_DECODER_IA64
143         {
144                 .init = &lzma_simple_ia64_decoder_init,
145                 .memusage = NULL,
146                 .props_decode = &lzma_simple_props_decode,
147         },
148 #endif
149 #ifdef HAVE_DECODER_ARM
150         {
151                 .init = &lzma_simple_arm_decoder_init,
152                 .memusage = NULL,
153                 .props_decode = &lzma_simple_props_decode,
154         },
155 #endif
156 #ifdef HAVE_DECODER_ARMTHUMB
157         {
158                 .init = &lzma_simple_armthumb_decoder_init,
159                 .memusage = NULL,
160                 .props_decode = &lzma_simple_props_decode,
161         },
162 #endif
163 #ifdef HAVE_DECODER_SPARC
164         {
165                 .init = &lzma_simple_sparc_decoder_init,
166                 .memusage = NULL,
167                 .props_decode = &lzma_simple_props_decode,
168         },
169 #endif
170 #ifdef HAVE_DECODER_DELTA
171         {
172                 .init = &lzma_delta_decoder_init,
173                 .memusage = NULL,
174                 .props_decode = &lzma_delta_props_decode,
175         },
176 #endif
177 };
178
179
180 static const lzma_filter_decoder *
181 decoder_find(lzma_vli id)
182 {
183         for (size_t i = 0; ids[i] != LZMA_VLI_VALUE_UNKNOWN; ++i)
184                 if (ids[i] == id)
185                         return funcs + i;
186
187         return NULL;
188 }
189
190
191 extern lzma_ret
192 lzma_raw_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
193                 const lzma_filter *options)
194 {
195         return lzma_raw_coder_init(next, allocator,
196                         options, (lzma_filter_find)(&decoder_find), false);
197 }
198
199
200 extern LZMA_API lzma_ret
201 lzma_raw_decoder(lzma_stream *strm, const lzma_filter *options)
202 {
203         lzma_next_strm_init(lzma_raw_decoder_init, strm, options);
204
205         strm->internal->supported_actions[LZMA_RUN] = true;
206         strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
207
208         return LZMA_OK;
209 }
210
211
212 extern LZMA_API uint64_t
213 lzma_memusage_decoder(const lzma_filter *filters)
214 {
215         return lzma_memusage_coder(
216                         (lzma_filter_find)(&decoder_find), filters);
217 }
218
219
220 extern LZMA_API lzma_ret
221 lzma_properties_decode(lzma_filter *filter, lzma_allocator *allocator,
222                 const uint8_t *props, size_t props_size)
223 {
224         // Make it always NULL so that the caller can always safely free() it.
225         filter->options = NULL;
226
227         const lzma_filter_decoder *const fd = decoder_find(filter->id);
228         if (fd == NULL)
229                 return LZMA_HEADER_ERROR;
230
231         if (fd->props_decode == NULL)
232                 return props_size == 0 ? LZMA_OK : LZMA_HEADER_ERROR;
233
234         return fd->props_decode(
235                         &filter->options, allocator, props, props_size);
236 }