OLD | NEW |
1 /////////////////////////////////////////////////////////////////////////////// | 1 /////////////////////////////////////////////////////////////////////////////// |
2 // | 2 // |
3 /// \file lzma2_decoder.c | 3 /// \file lzma2_decoder.c |
4 /// \brief LZMA2 decoder | 4 /// \brief LZMA2 decoder |
5 /// | 5 /// |
6 // Authors: Igor Pavlov | 6 // Authors: Igor Pavlov |
7 // Lasse Collin | 7 // Lasse Collin |
8 // | 8 // |
9 // This file has been put into the public domain. | 9 // This file has been put into the public domain. |
10 // You can do whatever you want with this file. | 10 // You can do whatever you want with this file. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 { | 60 { |
61 // With SEQ_LZMA it is possible that no new input is needed to do | 61 // With SEQ_LZMA it is possible that no new input is needed to do |
62 // some progress. The rest of the sequences assume that there is | 62 // some progress. The rest of the sequences assume that there is |
63 // at least one byte of input. | 63 // at least one byte of input. |
64 while (*in_pos < in_size || coder->sequence == SEQ_LZMA) | 64 while (*in_pos < in_size || coder->sequence == SEQ_LZMA) |
65 switch (coder->sequence) { | 65 switch (coder->sequence) { |
66 case SEQ_CONTROL: { | 66 case SEQ_CONTROL: { |
67 const uint32_t control = in[*in_pos]; | 67 const uint32_t control = in[*in_pos]; |
68 ++*in_pos; | 68 ++*in_pos; |
69 | 69 |
| 70 // End marker |
| 71 if (control == 0x00) |
| 72 return LZMA_STREAM_END; |
| 73 |
70 if (control >= 0xE0 || control == 1) { | 74 if (control >= 0xE0 || control == 1) { |
71 // Dictionary reset implies that next LZMA chunk has | 75 // Dictionary reset implies that next LZMA chunk has |
72 // to set new properties. | 76 // to set new properties. |
73 coder->need_properties = true; | 77 coder->need_properties = true; |
74 coder->need_dictionary_reset = true; | 78 coder->need_dictionary_reset = true; |
75 } else if (coder->need_dictionary_reset) { | 79 } else if (coder->need_dictionary_reset) { |
76 return LZMA_DATA_ERROR; | 80 return LZMA_DATA_ERROR; |
77 } | 81 } |
78 | 82 |
79 if (control >= 0x80) { | 83 if (control >= 0x80) { |
(...skipping 17 matching lines...) Expand all Loading... |
97 coder->next_sequence = SEQ_LZMA; | 101 coder->next_sequence = SEQ_LZMA; |
98 | 102 |
99 // If only state reset is wanted with old | 103 // If only state reset is wanted with old |
100 // properties, do the resetting here for | 104 // properties, do the resetting here for |
101 // simplicity. | 105 // simplicity. |
102 if (control >= 0xA0) | 106 if (control >= 0xA0) |
103 coder->lzma.reset(coder->lzma.coder, | 107 coder->lzma.reset(coder->lzma.coder, |
104 &coder->options); | 108 &coder->options); |
105 } | 109 } |
106 } else { | 110 } else { |
107 // End marker | |
108 if (control == 0x00) | |
109 return LZMA_STREAM_END; | |
110 | |
111 // Invalid control values | 111 // Invalid control values |
112 if (control > 2) | 112 if (control > 2) |
113 return LZMA_DATA_ERROR; | 113 return LZMA_DATA_ERROR; |
114 | 114 |
115 // It's uncompressed chunk | 115 // It's uncompressed chunk |
116 coder->sequence = SEQ_COMPRESSED_0; | 116 coder->sequence = SEQ_COMPRESSED_0; |
117 coder->next_sequence = SEQ_COPY; | 117 coder->next_sequence = SEQ_COPY; |
118 } | 118 } |
119 | 119 |
120 if (coder->need_dictionary_reset) { | 120 if (coder->need_dictionary_reset) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 // is checked by the LZMA decoder. | 184 // is checked by the LZMA decoder. |
185 if (coder->compressed_size != 0) | 185 if (coder->compressed_size != 0) |
186 return LZMA_DATA_ERROR; | 186 return LZMA_DATA_ERROR; |
187 | 187 |
188 coder->sequence = SEQ_CONTROL; | 188 coder->sequence = SEQ_CONTROL; |
189 break; | 189 break; |
190 } | 190 } |
191 | 191 |
192 case SEQ_COPY: { | 192 case SEQ_COPY: { |
193 // Copy from input to the dictionary as is. | 193 // Copy from input to the dictionary as is. |
194 // FIXME Can copy too much? | |
195 dict_write(dict, in, in_pos, in_size, &coder->compressed_size); | 194 dict_write(dict, in, in_pos, in_size, &coder->compressed_size); |
196 if (coder->compressed_size != 0) | 195 if (coder->compressed_size != 0) |
197 return LZMA_OK; | 196 return LZMA_OK; |
198 | 197 |
199 coder->sequence = SEQ_CONTROL; | 198 coder->sequence = SEQ_CONTROL; |
200 break; | 199 break; |
201 } | 200 } |
202 | 201 |
203 default: | 202 default: |
204 assert(0); | 203 assert(0); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 opt->dict_size <<= props[0] / 2 + 11; | 295 opt->dict_size <<= props[0] / 2 + 11; |
297 } | 296 } |
298 | 297 |
299 opt->preset_dict = NULL; | 298 opt->preset_dict = NULL; |
300 opt->preset_dict_size = 0; | 299 opt->preset_dict_size = 0; |
301 | 300 |
302 *options = opt; | 301 *options = opt; |
303 | 302 |
304 return LZMA_OK; | 303 return LZMA_OK; |
305 } | 304 } |
OLD | NEW |