(root)/
xz-5.4.5/
src/
liblzma/
common/
filter_decoder.c
       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  {
     138  	for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i)
     139  		if (decoders[i].id == id)
     140  			return decoders + i;
     141  
     142  	return NULL;
     143  }
     144  
     145  
     146  extern LZMA_API(lzma_bool)
     147  lzma_filter_decoder_is_supported(lzma_vli id)
     148  {
     149  	return decoder_find(id) != NULL;
     150  }
     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  {
     157  	return lzma_raw_coder_init(next, allocator,
     158  			options, (lzma_filter_find)(&decoder_find), false);
     159  }
     160  
     161  
     162  extern LZMA_API(lzma_ret)
     163  lzma_raw_decoder(lzma_stream *strm, const lzma_filter *options)
     164  {
     165  	lzma_next_strm_init(lzma_raw_decoder_init, strm, options);
     166  
     167  	strm->internal->supported_actions[LZMA_RUN] = true;
     168  	strm->internal->supported_actions[LZMA_FINISH] = true;
     169  
     170  	return LZMA_OK;
     171  }
     172  
     173  
     174  extern LZMA_API(uint64_t)
     175  lzma_raw_decoder_memusage(const lzma_filter *filters)
     176  {
     177  	return lzma_raw_coder_memusage(
     178  			(lzma_filter_find)(&decoder_find), filters);
     179  }
     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  {
     186  	// Make it always NULL so that the caller can always safely free() it.
     187  	filter->options = NULL;
     188  
     189  	const lzma_filter_decoder *const fd = decoder_find(filter->id);
     190  	if (fd == NULL)
     191  		return LZMA_OPTIONS_ERROR;
     192  
     193  	if (fd->props_decode == NULL)
     194  		return props_size == 0 ? LZMA_OK : LZMA_OPTIONS_ERROR;
     195  
     196  	return fd->props_decode(
     197  			&filter->options, allocator, props, props_size);
     198  }