1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Stuff shared between raw encoder and raw decoder
6 // Copyright (C) 2007 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 "raw_common.h"
24 validate_options(const lzma_options_filter *options, size_t *count)
27 return LZMA_PROG_ERROR;
29 // Number of non-last filters that may change the size of the data
30 // significantly (that is, more than 1-2 % or so).
33 // True if the last filter in the given chain is actually usable as
34 // the last filter. Only filters that support embedding End of Payload
35 // Marker can be used as the last filter in the chain.
39 for (i = 0; options[i].id != LZMA_VLI_VALUE_UNKNOWN; ++i) {
40 switch (options[i].id) {
41 // Not #ifdeffing these for simplicity.
43 case LZMA_FILTER_POWERPC:
44 case LZMA_FILTER_IA64:
46 case LZMA_FILTER_ARMTHUMB:
47 case LZMA_FILTER_SPARC:
48 case LZMA_FILTER_DELTA:
49 // These don't change the size of the data and cannot
50 // be used as the last filter in the chain.
54 #ifdef HAVE_FILTER_SUBBLOCK
55 case LZMA_FILTER_SUBBLOCK:
61 #ifdef HAVE_FILTER_LZMA
62 case LZMA_FILTER_LZMA:
68 return LZMA_HEADER_ERROR;
72 // There must be 1-4 filters and the last filter must be usable as
73 // the last filter in the chain.
74 if (i == 0 || i > 4 || !last_ok)
75 return LZMA_HEADER_ERROR;
77 // At maximum of two non-last filters are allowed to change the
80 return LZMA_HEADER_ERROR;
88 lzma_raw_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
89 const lzma_options_filter *options,
90 lzma_init_function (*get_function)(lzma_vli id),
93 // Do some basic validation and get the number of filters.
95 return_if_error(validate_options(options, &count));
97 // Set the filter functions and copy the options pointer.
98 lzma_filter_info filters[count + 1];
100 for (size_t i = 0; i < count; ++i) {
101 // The order of the filters is reversed in the
102 // encoder. It allows more efficient handling
103 // of the uncompressed data.
104 const size_t j = count - i - 1;
106 filters[j].init = get_function(options[i].id);
107 if (filters[j].init == NULL)
108 return LZMA_HEADER_ERROR;
110 filters[j].options = options[i].options;
113 for (size_t i = 0; i < count; ++i) {
114 filters[i].init = get_function(options[i].id);
115 if (filters[i].init == NULL)
116 return LZMA_HEADER_ERROR;
118 filters[i].options = options[i].options;
122 // Terminate the array.
123 filters[count].init = NULL;
125 // Initialize the filters.
126 return lzma_next_filter_init(next, allocator, filters);