1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file filter_buffer_decoder.c
4 /// \brief Single-call raw decoding
6 // Copyright (C) 2009 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"
23 extern LZMA_API(lzma_ret)
24 lzma_raw_buffer_decode(const lzma_filter *filters, lzma_allocator *allocator,
25 const uint8_t *in, size_t *in_pos, size_t in_size,
26 uint8_t *out, size_t *out_pos, size_t out_size)
28 // Validate what isn't validated later in filter_common.c.
29 if (in == NULL || in_pos == NULL || *in_pos > in_size || out == NULL
30 || out_pos == NULL || *out_pos > out_size)
31 return LZMA_PROG_ERROR;
33 // Initialize the decoer.
34 lzma_next_coder next = LZMA_NEXT_CODER_INIT;
35 return_if_error(lzma_raw_decoder_init(&next, allocator, filters));
37 // Store the positions so that we can restore them if something
39 const size_t in_start = *in_pos;
40 const size_t out_start = *out_pos;
42 // Do the actual decoding and free decoder's memory.
43 lzma_ret ret = next.code(next.coder, allocator, in, in_pos, in_size,
44 out, out_pos, out_size, LZMA_FINISH);
46 if (ret == LZMA_STREAM_END) {
50 // Either the input was truncated or the
51 // output buffer was too small.
52 assert(*in_pos == in_size || *out_pos == out_size);
54 if (*in_pos != in_size) {
55 // Since input wasn't consumed completely,
56 // the output buffer became full and is
60 } else if (*out_pos != out_size) {
61 // Since output didn't became full, the input
62 // has to be truncated.
63 ret = LZMA_DATA_ERROR;
66 // All the input was consumed and output
67 // buffer is full. Now we don't immediatelly
68 // know the reason for the error. Try
69 // decoding one more byte. If it succeeds,
70 // then the output buffer was too small. If
71 // we cannot get a new output byte, the input
75 (void)next.code(next.coder, allocator,
77 tmp, &tmp_pos, 1, LZMA_FINISH);
82 ret = LZMA_DATA_ERROR;
86 // Restore the positions.
91 lzma_next_end(&next, allocator);