1 /* xdelta 3 - delta compression tools and library
2 * Copyright (C) 2012, 2013. Joshua P. MacDonald
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /* Note: The use of the _easy_ decoder means we're not calling the
20 * xd3_stream malloc hooks. TODO(jmacd) Fix if anyone cares. */
22 #ifndef _XDELTA3_LZMA_H_
23 #define _XDELTA3_LZMA_H_
27 typedef struct _xd3_lzma_stream xd3_lzma_stream;
29 struct _xd3_lzma_stream {
31 lzma_options_lzma options;
32 lzma_filter filters[2];
36 xd3_lzma_alloc (xd3_stream *stream)
38 return (xd3_sec_stream*) xd3_alloc (stream, sizeof (xd3_lzma_stream), 1);
42 xd3_lzma_destroy (xd3_stream *stream, xd3_sec_stream *sec_stream)
44 xd3_lzma_stream *ls = (xd3_lzma_stream*) sec_stream;
46 xd3_free (stream, ls);
50 xd3_lzma_init (xd3_stream *stream, xd3_lzma_stream *sec, int is_encode)
54 memset (&sec->lzma, 0, sizeof(sec->lzma));
58 int preset = (stream->flags & XD3_COMPLEVEL_MASK) >> XD3_COMPLEVEL_SHIFT;
60 if (lzma_lzma_preset(&sec->options, preset))
62 stream->msg = "invalid lzma preset";
66 sec->filters[0].id = LZMA_FILTER_LZMA2;
67 sec->filters[0].options = &sec->options;
68 sec->filters[1].id = LZMA_VLI_UNKNOWN;
70 ret = lzma_stream_encoder (&sec->lzma, &sec->filters[0], LZMA_CHECK_NONE);
74 ret = lzma_stream_decoder (&sec->lzma, UINT64_MAX, LZMA_TELL_NO_CHECK);
79 stream->msg = "lzma stream init failed";
86 int xd3_decode_lzma (xd3_stream *stream, xd3_lzma_stream *sec,
87 const uint8_t **input_pos,
88 const uint8_t *const input_end,
90 const uint8_t *const output_end)
92 uint8_t *output = *output_pos;
93 const uint8_t *input = *input_pos;
94 size_t avail_in = input_end - input;
95 size_t avail_out = output_end - output;
97 sec->lzma.avail_in = avail_in;
98 sec->lzma.next_in = input;
99 sec->lzma.avail_out = avail_out;
100 sec->lzma.next_out = output;
104 int lret = lzma_code (&sec->lzma, LZMA_RUN);
110 if (sec->lzma.avail_out == 0)
112 (*output_pos) = sec->lzma.next_out;
113 (*input_pos) = sec->lzma.next_in;
119 stream->msg = "lzma decoding error";
127 int xd3_encode_lzma (xd3_stream *stream,
128 xd3_lzma_stream *sec,
134 lzma_action action = LZMA_RUN;
136 cfg->inefficient = 1; /* Can't skip windows */
137 sec->lzma.next_in = NULL;
138 sec->lzma.avail_in = 0;
139 sec->lzma.next_out = (output->base + output->next);
140 sec->lzma.avail_out = (output->avail - output->next);
146 if (sec->lzma.avail_in == 0 && input != NULL)
148 sec->lzma.avail_in = input->next;
149 sec->lzma.next_in = input->base;
151 if ((input = input->next_page) == NULL)
153 action = LZMA_SYNC_FLUSH;
157 lret = lzma_code (&sec->lzma, action);
159 nwrite = (output->avail - output->next) - sec->lzma.avail_out;
163 output->next += nwrite;
165 if (output->next == output->avail)
167 if ((output = xd3_alloc_output (stream, output)) == NULL)
172 sec->lzma.next_out = output->base;
173 sec->lzma.avail_out = output->avail;
182 case LZMA_STREAM_END:
186 stream->msg = "lzma encoding error";
194 #endif /* XD3_ENCODER */
196 #endif /* _XDELTA3_LZMA_H_ */