1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file filter_decoder.c 4207753Smm/// \brief Filter ID mapping to filter-specific functions 5207753Smm// 6207753Smm// Author: Lasse Collin 7207753Smm// 8207753Smm// This file has been put into the public domain. 9207753Smm// You can do whatever you want with this file. 10207753Smm// 11207753Smm/////////////////////////////////////////////////////////////////////////////// 12207753Smm 13207753Smm#include "filter_decoder.h" 14207753Smm#include "filter_common.h" 15207753Smm#include "lzma_decoder.h" 16207753Smm#include "lzma2_decoder.h" 17207753Smm#include "simple_decoder.h" 18207753Smm#include "delta_decoder.h" 19207753Smm 20207753Smm 21207753Smmtypedef struct { 22207753Smm /// Filter ID 23207753Smm lzma_vli id; 24207753Smm 25207753Smm /// Initializes the filter encoder and calls lzma_next_filter_init() 26207753Smm /// for filters + 1. 27207753Smm lzma_init_function init; 28207753Smm 29207753Smm /// Calculates memory usage of the encoder. If the options are 30207753Smm /// invalid, UINT64_MAX is returned. 31207753Smm uint64_t (*memusage)(const void *options); 32207753Smm 33207753Smm /// Decodes Filter Properties. 34207753Smm /// 35207753Smm /// \return - LZMA_OK: Properties decoded successfully. 36207753Smm /// - LZMA_OPTIONS_ERROR: Unsupported properties 37207753Smm /// - LZMA_MEM_ERROR: Memory allocation failed. 38278433Srpaulo lzma_ret (*props_decode)( 39278433Srpaulo void **options, const lzma_allocator *allocator, 40207753Smm const uint8_t *props, size_t props_size); 41207753Smm 42207753Smm} lzma_filter_decoder; 43207753Smm 44207753Smm 45207753Smmstatic const lzma_filter_decoder decoders[] = { 46207753Smm#ifdef HAVE_DECODER_LZMA1 47207753Smm { 48207753Smm .id = LZMA_FILTER_LZMA1, 49207753Smm .init = &lzma_lzma_decoder_init, 50207753Smm .memusage = &lzma_lzma_decoder_memusage, 51207753Smm .props_decode = &lzma_lzma_props_decode, 52207753Smm }, 53207753Smm#endif 54207753Smm#ifdef HAVE_DECODER_LZMA2 55207753Smm { 56207753Smm .id = LZMA_FILTER_LZMA2, 57207753Smm .init = &lzma_lzma2_decoder_init, 58207753Smm .memusage = &lzma_lzma2_decoder_memusage, 59207753Smm .props_decode = &lzma_lzma2_props_decode, 60207753Smm }, 61207753Smm#endif 62207753Smm#ifdef HAVE_DECODER_X86 63207753Smm { 64207753Smm .id = LZMA_FILTER_X86, 65207753Smm .init = &lzma_simple_x86_decoder_init, 66207753Smm .memusage = NULL, 67207753Smm .props_decode = &lzma_simple_props_decode, 68207753Smm }, 69207753Smm#endif 70207753Smm#ifdef HAVE_DECODER_POWERPC 71207753Smm { 72207753Smm .id = LZMA_FILTER_POWERPC, 73207753Smm .init = &lzma_simple_powerpc_decoder_init, 74207753Smm .memusage = NULL, 75207753Smm .props_decode = &lzma_simple_props_decode, 76207753Smm }, 77207753Smm#endif 78207753Smm#ifdef HAVE_DECODER_IA64 79207753Smm { 80207753Smm .id = LZMA_FILTER_IA64, 81207753Smm .init = &lzma_simple_ia64_decoder_init, 82207753Smm .memusage = NULL, 83207753Smm .props_decode = &lzma_simple_props_decode, 84207753Smm }, 85207753Smm#endif 86207753Smm#ifdef HAVE_DECODER_ARM 87207753Smm { 88207753Smm .id = LZMA_FILTER_ARM, 89207753Smm .init = &lzma_simple_arm_decoder_init, 90207753Smm .memusage = NULL, 91207753Smm .props_decode = &lzma_simple_props_decode, 92207753Smm }, 93207753Smm#endif 94207753Smm#ifdef HAVE_DECODER_ARMTHUMB 95207753Smm { 96207753Smm .id = LZMA_FILTER_ARMTHUMB, 97207753Smm .init = &lzma_simple_armthumb_decoder_init, 98207753Smm .memusage = NULL, 99207753Smm .props_decode = &lzma_simple_props_decode, 100207753Smm }, 101207753Smm#endif 102207753Smm#ifdef HAVE_DECODER_SPARC 103207753Smm { 104207753Smm .id = LZMA_FILTER_SPARC, 105207753Smm .init = &lzma_simple_sparc_decoder_init, 106207753Smm .memusage = NULL, 107207753Smm .props_decode = &lzma_simple_props_decode, 108207753Smm }, 109207753Smm#endif 110207753Smm#ifdef HAVE_DECODER_DELTA 111207753Smm { 112207753Smm .id = LZMA_FILTER_DELTA, 113207753Smm .init = &lzma_delta_decoder_init, 114207753Smm .memusage = &lzma_delta_coder_memusage, 115207753Smm .props_decode = &lzma_delta_props_decode, 116207753Smm }, 117207753Smm#endif 118207753Smm}; 119207753Smm 120207753Smm 121207753Smmstatic const lzma_filter_decoder * 122207753Smmdecoder_find(lzma_vli id) 123207753Smm{ 124207753Smm for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) 125207753Smm if (decoders[i].id == id) 126207753Smm return decoders + i; 127207753Smm 128207753Smm return NULL; 129207753Smm} 130207753Smm 131207753Smm 132207753Smmextern LZMA_API(lzma_bool) 133207753Smmlzma_filter_decoder_is_supported(lzma_vli id) 134207753Smm{ 135207753Smm return decoder_find(id) != NULL; 136207753Smm} 137207753Smm 138207753Smm 139207753Smmextern lzma_ret 140278433Srpaulolzma_raw_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, 141207753Smm const lzma_filter *options) 142207753Smm{ 143207753Smm return lzma_raw_coder_init(next, allocator, 144207753Smm options, (lzma_filter_find)(&decoder_find), false); 145207753Smm} 146207753Smm 147207753Smm 148207753Smmextern LZMA_API(lzma_ret) 149207753Smmlzma_raw_decoder(lzma_stream *strm, const lzma_filter *options) 150207753Smm{ 151207753Smm lzma_next_strm_init(lzma_raw_decoder_init, strm, options); 152207753Smm 153207753Smm strm->internal->supported_actions[LZMA_RUN] = true; 154207753Smm strm->internal->supported_actions[LZMA_FINISH] = true; 155207753Smm 156207753Smm return LZMA_OK; 157207753Smm} 158207753Smm 159207753Smm 160207753Smmextern LZMA_API(uint64_t) 161207753Smmlzma_raw_decoder_memusage(const lzma_filter *filters) 162207753Smm{ 163207753Smm return lzma_raw_coder_memusage( 164207753Smm (lzma_filter_find)(&decoder_find), filters); 165207753Smm} 166207753Smm 167207753Smm 168207753Smmextern LZMA_API(lzma_ret) 169278433Srpaulolzma_properties_decode(lzma_filter *filter, const lzma_allocator *allocator, 170207753Smm const uint8_t *props, size_t props_size) 171207753Smm{ 172207753Smm // Make it always NULL so that the caller can always safely free() it. 173207753Smm filter->options = NULL; 174207753Smm 175207753Smm const lzma_filter_decoder *const fd = decoder_find(filter->id); 176207753Smm if (fd == NULL) 177207753Smm return LZMA_OPTIONS_ERROR; 178207753Smm 179207753Smm if (fd->props_decode == NULL) 180207753Smm return props_size == 0 ? LZMA_OK : LZMA_OPTIONS_ERROR; 181207753Smm 182207753Smm return fd->props_decode( 183207753Smm &filter->options, allocator, props, props_size); 184207753Smm} 185