1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file filter_decoder.c
4 /// \brief Filter ID mapping to filter-specific functions
6 // Copyright (C) 2008 Lasse Collin
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.
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.
18 ///////////////////////////////////////////////////////////////////////////////
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"
31 /// Initializes the filter encoder and calls lzma_next_filter_init()
33 lzma_init_function init;
35 /// Calculates memory usage of the encoder. If the options are
36 /// invalid, UINT64_MAX is returned.
37 uint64_t (*memusage)(const void *options);
39 /// Decodes Filter Properties.
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);
47 } lzma_filter_decoder;
50 static const lzma_vli ids[] = {
51 #ifdef HAVE_DECODER_LZMA
55 #ifdef HAVE_DECODER_LZMA2
59 #ifdef HAVE_DECODER_SUBBLOCK
61 LZMA_FILTER_SUBBLOCK_HELPER,
64 #ifdef HAVE_DECODER_X86
68 #ifdef HAVE_DECODER_POWERPC
72 #ifdef HAVE_DECODER_IA64
76 #ifdef HAVE_DECODER_ARM
80 #ifdef HAVE_DECODER_ARMTHUMB
84 #ifdef HAVE_DECODER_SPARC
88 #ifdef HAVE_DECODER_DELTA
92 LZMA_VLI_VALUE_UNKNOWN
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;
100 // These must be in the same order as ids[].
101 static const lzma_filter_decoder funcs[] = {
102 #ifdef HAVE_DECODER_LZMA
104 .init = &lzma_lzma_decoder_init,
105 .memusage = &lzma_lzma_decoder_memusage,
106 .props_decode = &lzma_lzma_props_decode,
109 #ifdef HAVE_DECODER_LZMA2
111 .init = &lzma_lzma2_decoder_init,
112 .memusage = &lzma_lzma2_decoder_memusage,
113 .props_decode = &lzma_lzma2_props_decode,
116 #ifdef HAVE_DECODER_SUBBLOCK
118 .init = &lzma_subblock_decoder_init,
119 // .memusage = &lzma_subblock_decoder_memusage,
120 .props_decode = NULL,
123 .init = &lzma_subblock_decoder_helper_init,
125 .props_decode = NULL,
128 #ifdef HAVE_DECODER_X86
130 .init = &lzma_simple_x86_decoder_init,
132 .props_decode = &lzma_simple_props_decode,
135 #ifdef HAVE_DECODER_POWERPC
137 .init = &lzma_simple_powerpc_decoder_init,
139 .props_decode = &lzma_simple_props_decode,
142 #ifdef HAVE_DECODER_IA64
144 .init = &lzma_simple_ia64_decoder_init,
146 .props_decode = &lzma_simple_props_decode,
149 #ifdef HAVE_DECODER_ARM
151 .init = &lzma_simple_arm_decoder_init,
153 .props_decode = &lzma_simple_props_decode,
156 #ifdef HAVE_DECODER_ARMTHUMB
158 .init = &lzma_simple_armthumb_decoder_init,
160 .props_decode = &lzma_simple_props_decode,
163 #ifdef HAVE_DECODER_SPARC
165 .init = &lzma_simple_sparc_decoder_init,
167 .props_decode = &lzma_simple_props_decode,
170 #ifdef HAVE_DECODER_DELTA
172 .init = &lzma_delta_decoder_init,
174 .props_decode = &lzma_delta_props_decode,
180 static const lzma_filter_decoder *
181 decoder_find(lzma_vli id)
183 for (size_t i = 0; ids[i] != LZMA_VLI_VALUE_UNKNOWN; ++i)
192 lzma_raw_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
193 const lzma_filter *options)
195 return lzma_raw_coder_init(next, allocator,
196 options, (lzma_filter_find)(&decoder_find), false);
200 extern LZMA_API lzma_ret
201 lzma_raw_decoder(lzma_stream *strm, const lzma_filter *options)
203 lzma_next_strm_init(lzma_raw_decoder_init, strm, options);
205 strm->internal->supported_actions[LZMA_RUN] = true;
206 strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
212 extern LZMA_API uint64_t
213 lzma_memusage_decoder(const lzma_filter *filters)
215 return lzma_memusage_coder(
216 (lzma_filter_find)(&decoder_find), filters);
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)
224 // Make it always NULL so that the caller can always safely free() it.
225 filter->options = NULL;
227 const lzma_filter_decoder *const fd = decoder_find(filter->id);
229 return LZMA_HEADER_ERROR;
231 if (fd->props_decode == NULL)
232 return props_size == 0 ? LZMA_OK : LZMA_HEADER_ERROR;
234 return fd->props_decode(
235 &filter->options, allocator, props, props_size);