]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/lz/lz_encoder.h
Fix wrong return type (uint32_t -> bool).
[icculus/xz.git] / src / liblzma / lz / lz_encoder.h
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       lz_encoder.h
4 /// \brief      LZ in window and match finder API
5 //
6 //  Copyright (C) 1999-2006 Igor Pavlov
7 //  Copyright (C) 2007 Lasse Collin
8 //
9 //  This library is free software; you can redistribute it and/or
10 //  modify it under the terms of the GNU Lesser General Public
11 //  License as published by the Free Software Foundation; either
12 //  version 2.1 of the License, or (at your option) any later version.
13 //
14 //  This library is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 //  Lesser General Public License for more details.
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20
21 #ifndef LZMA_LZ_ENCODER_H
22 #define LZMA_LZ_ENCODER_H
23
24 #include "common.h"
25
26
27 #define LZMA_LZ_TEMP_SIZE 64
28
29
30 typedef struct lzma_lz_encoder_s lzma_lz_encoder;
31 struct lzma_lz_encoder_s {
32         enum {
33                 SEQ_START,
34                 SEQ_RUN,
35                 SEQ_FLUSH,
36                 SEQ_FLUSH_END,
37                 SEQ_FINISH,
38                 SEQ_END
39         } sequence;
40
41         bool (*process)(lzma_coder *coder, uint8_t *restrict out,
42                         size_t *restrict out_pos, size_t out_size);
43
44         /// Uncompressed Size or LZMA_VLI_VALUE_UNKNOWN if using EOPM. We need
45         /// to track Uncompressed Size to prevent writing flush marker to the
46         /// very end of stream that doesn't use EOPM.
47         lzma_vli uncompressed_size;
48
49         /// Temporary buffer for range encoder.
50         uint8_t temp[LZMA_LZ_TEMP_SIZE];
51         size_t temp_size;
52
53         ///////////////
54         // In Window //
55         ///////////////
56
57         /// Pointer to buffer with data to be compressed
58         uint8_t *buffer;
59
60         /// Total size of the allocated buffer (that is, including all
61         /// the extra space)
62         size_t size;
63
64         /// Match finders store locations of matches using 32-bit integers.
65         /// To avoid adjusting several megabytes of integers every time the
66         /// input window is moved with move_window(), we only adjust the
67         /// offset of the buffer. Thus, buffer[match_finder_pos - offset]
68         /// is the byte pointed by match_finder_pos.
69         size_t offset;
70
71         /// buffer[read_pos] is the current byte.
72         size_t read_pos;
73
74         /// As long as read_pos is less than read_limit, there is enough
75         /// input available in buffer for at least one encoding loop.
76         ///
77         /// Because of the stateful API, read_limit may and will get greater
78         /// than read_pos quite often. This is taken into account when
79         /// calculating the value for keep_size_after.
80         size_t read_limit;
81
82         /// buffer[write_pos] is the first byte that doesn't contain valid
83         /// uncompressed data; that is, the next input byte will be copied
84         /// to buffer[write_pos].
85         size_t write_pos;
86
87         /// Number of bytes not hashed before read_pos. This is needed to
88         /// restart the match finder after LZMA_SYNC_FLUSH.
89         size_t pending;
90
91         /// Number of bytes that must be kept available in our input history.
92         /// That is, once keep_size_before bytes have been processed,
93         /// buffer[read_pos - keep_size_before] is the oldest byte that
94         /// must be available for reading.
95         size_t keep_size_before;
96
97         /// Number of bytes that must be kept in buffer after read_pos.
98         /// That is, read_pos <= write_pos - keep_size_after as long as
99         /// stream_end_was_reached is false (once it is true, read_pos
100         /// is allowed to reach write_pos).
101         size_t keep_size_after;
102
103         //////////////////
104         // Match Finder //
105         //////////////////
106
107         // Pointers to match finder functions
108         void (*get_matches)(lzma_lz_encoder *restrict lz,
109                         uint32_t *restrict distances);
110         void (*skip)(lzma_lz_encoder *restrict lz, uint32_t num);
111
112         // Match finder data
113         uint32_t *hash; // TODO: Check if hash aliases son
114         uint32_t *son;  //       and add 'restrict' if possible.
115         uint32_t cyclic_buffer_pos;
116         uint32_t cyclic_buffer_size; // Must be dictionary_size + 1.
117         uint32_t hash_mask;
118         uint32_t cut_value;
119         uint32_t hash_size_sum;
120         uint32_t num_items;
121         uint32_t match_max_len;
122 };
123
124
125 #define LZMA_LZ_ENCODER_INIT \
126         (lzma_lz_encoder){ \
127                 .buffer = NULL, \
128                 .size = 0, \
129                 .hash = NULL, \
130                 .num_items = 0, \
131         }
132
133
134 /// Calculates
135 extern bool lzma_lz_encoder_hash_properties(lzma_match_finder match_finder,
136                 uint32_t history_size, uint32_t *restrict hash_mask,
137                 uint32_t *restrict hash_size_sum,
138                 uint32_t *restrict num_items);
139
140 // NOTE: liblzma doesn't use callback API like LZMA SDK does. The caller
141 // must make sure that keep_size_after is big enough for single encoding pass
142 // i.e. keep_size_after >= maximum number of bytes possibly needed after
143 // the current position between calls to lzma_lz_read().
144 extern lzma_ret lzma_lz_encoder_reset(lzma_lz_encoder *lz,
145                 lzma_allocator *allocator,
146                 bool (*process)(lzma_coder *coder, uint8_t *restrict out,
147                         size_t *restrict out_pos, size_t out_size),
148                 lzma_vli uncompressed_size,
149                 size_t history_size, size_t additional_buffer_before,
150                 size_t match_max_len, size_t additional_buffer_after,
151                 lzma_match_finder match_finder, uint32_t match_finder_cycles,
152                 const uint8_t *preset_dictionary,
153                 size_t preset_dictionary_size);
154
155 /// Frees memory allocated for in window and match finder buffers.
156 extern void lzma_lz_encoder_end(
157                 lzma_lz_encoder *lz, lzma_allocator *allocator);
158
159 extern lzma_ret lzma_lz_encode(lzma_coder *coder,
160                 lzma_allocator *allocator lzma_attribute((unused)),
161                 const uint8_t *restrict in, size_t *restrict in_pos,
162                 size_t in_size, uint8_t *restrict out,
163                 size_t *restrict out_pos, size_t out_size,
164                 lzma_action action);
165
166 /// This should not be called directly, but only via move_pos() macro.
167 extern void lzma_lz_encoder_normalize(lzma_lz_encoder *lz);
168
169 #endif