drm/panfrost: Remove set but not used variable 'bo'
[linux/fpc-iii.git] / lib / zlib_dfltcc / dfltcc_deflate.c
blob00c185101c6d14a145d16b54b739f8b8caa2d830
1 // SPDX-License-Identifier: Zlib
3 #include "../zlib_deflate/defutil.h"
4 #include "dfltcc_util.h"
5 #include "dfltcc.h"
6 #include <asm/setup.h>
7 #include <linux/zutil.h>
9 /*
10 * Compress.
12 int dfltcc_can_deflate(
13 z_streamp strm
16 deflate_state *state = (deflate_state *)strm->state;
17 struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
19 /* Check for kernel dfltcc command line parameter */
20 if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED ||
21 zlib_dfltcc_support == ZLIB_DFLTCC_INFLATE_ONLY)
22 return 0;
24 /* Unsupported compression settings */
25 if (!dfltcc_are_params_ok(state->level, state->w_bits, state->strategy,
26 dfltcc_state->level_mask))
27 return 0;
29 /* Unsupported hardware */
30 if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) ||
31 !is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) ||
32 !is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0))
33 return 0;
35 return 1;
38 static void dfltcc_gdht(
39 z_streamp strm
42 deflate_state *state = (deflate_state *)strm->state;
43 struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
44 size_t avail_in = avail_in = strm->avail_in;
46 dfltcc(DFLTCC_GDHT,
47 param, NULL, NULL,
48 &strm->next_in, &avail_in, NULL);
51 static dfltcc_cc dfltcc_cmpr(
52 z_streamp strm
55 deflate_state *state = (deflate_state *)strm->state;
56 struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
57 size_t avail_in = strm->avail_in;
58 size_t avail_out = strm->avail_out;
59 dfltcc_cc cc;
61 cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR,
62 param, &strm->next_out, &avail_out,
63 &strm->next_in, &avail_in, state->window);
64 strm->total_in += (strm->avail_in - avail_in);
65 strm->total_out += (strm->avail_out - avail_out);
66 strm->avail_in = avail_in;
67 strm->avail_out = avail_out;
68 return cc;
71 static void send_eobs(
72 z_streamp strm,
73 const struct dfltcc_param_v0 *param
76 deflate_state *state = (deflate_state *)strm->state;
78 zlib_tr_send_bits(
79 state,
80 bi_reverse(param->eobs >> (15 - param->eobl), param->eobl),
81 param->eobl);
82 flush_pending(strm);
83 if (state->pending != 0) {
84 /* The remaining data is located in pending_out[0:pending]. If someone
85 * calls put_byte() - this might happen in deflate() - the byte will be
86 * placed into pending_buf[pending], which is incorrect. Move the
87 * remaining data to the beginning of pending_buf so that put_byte() is
88 * usable again.
90 memmove(state->pending_buf, state->pending_out, state->pending);
91 state->pending_out = state->pending_buf;
93 #ifdef ZLIB_DEBUG
94 state->compressed_len += param->eobl;
95 #endif
98 int dfltcc_deflate(
99 z_streamp strm,
100 int flush,
101 block_state *result
104 deflate_state *state = (deflate_state *)strm->state;
105 struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
106 struct dfltcc_param_v0 *param = &dfltcc_state->param;
107 uInt masked_avail_in;
108 dfltcc_cc cc;
109 int need_empty_block;
110 int soft_bcc;
111 int no_flush;
113 if (!dfltcc_can_deflate(strm))
114 return 0;
116 again:
117 masked_avail_in = 0;
118 soft_bcc = 0;
119 no_flush = flush == Z_NO_FLUSH;
121 /* Trailing empty block. Switch to software, except when Continuation Flag
122 * is set, which means that DFLTCC has buffered some output in the
123 * parameter block and needs to be called again in order to flush it.
125 if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) {
126 if (param->bcf) {
127 /* A block is still open, and the hardware does not support closing
128 * blocks without adding data. Thus, close it manually.
130 send_eobs(strm, param);
131 param->bcf = 0;
133 return 0;
136 if (strm->avail_in == 0 && !param->cf) {
137 *result = need_more;
138 return 1;
141 /* There is an open non-BFINAL block, we are not going to close it just
142 * yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see
143 * more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new
144 * DHT in order to adapt to a possibly changed input data distribution.
146 if (param->bcf && no_flush &&
147 strm->total_in > dfltcc_state->block_threshold &&
148 strm->avail_in >= dfltcc_state->dht_threshold) {
149 if (param->cf) {
150 /* We need to flush the DFLTCC buffer before writing the
151 * End-of-block Symbol. Mask the input data and proceed as usual.
153 masked_avail_in += strm->avail_in;
154 strm->avail_in = 0;
155 no_flush = 0;
156 } else {
157 /* DFLTCC buffer is empty, so we can manually write the
158 * End-of-block Symbol right away.
160 send_eobs(strm, param);
161 param->bcf = 0;
162 dfltcc_state->block_threshold =
163 strm->total_in + dfltcc_state->block_size;
164 if (strm->avail_out == 0) {
165 *result = need_more;
166 return 1;
171 /* The caller gave us too much data. Pass only one block worth of
172 * uncompressed data to DFLTCC and mask the rest, so that on the next
173 * iteration we start a new block.
175 if (no_flush && strm->avail_in > dfltcc_state->block_size) {
176 masked_avail_in += (strm->avail_in - dfltcc_state->block_size);
177 strm->avail_in = dfltcc_state->block_size;
180 /* When we have an open non-BFINAL deflate block and caller indicates that
181 * the stream is ending, we need to close an open deflate block and open a
182 * BFINAL one.
184 need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf;
186 /* Translate stream to parameter block */
187 param->cvt = CVT_ADLER32;
188 if (!no_flush)
189 /* We need to close a block. Always do this in software - when there is
190 * no input data, the hardware will not nohor BCC. */
191 soft_bcc = 1;
192 if (flush == Z_FINISH && !param->bcf)
193 /* We are about to open a BFINAL block, set Block Header Final bit
194 * until the stream ends.
196 param->bhf = 1;
197 /* DFLTCC-CMPR will write to next_out, so make sure that buffers with
198 * higher precedence are empty.
200 Assert(state->pending == 0, "There must be no pending bytes");
201 Assert(state->bi_valid < 8, "There must be less than 8 pending bits");
202 param->sbb = (unsigned int)state->bi_valid;
203 if (param->sbb > 0)
204 *strm->next_out = (Byte)state->bi_buf;
205 if (param->hl)
206 param->nt = 0; /* Honor history */
207 param->cv = strm->adler;
209 /* When opening a block, choose a Huffman-Table Type */
210 if (!param->bcf) {
211 if (strm->total_in == 0 && dfltcc_state->block_threshold > 0) {
212 param->htt = HTT_FIXED;
214 else {
215 param->htt = HTT_DYNAMIC;
216 dfltcc_gdht(strm);
220 /* Deflate */
221 do {
222 cc = dfltcc_cmpr(strm);
223 if (strm->avail_in < 4096 && masked_avail_in > 0)
224 /* We are about to call DFLTCC with a small input buffer, which is
225 * inefficient. Since there is masked data, there will be at least
226 * one more DFLTCC call, so skip the current one and make the next
227 * one handle more data.
229 break;
230 } while (cc == DFLTCC_CC_AGAIN);
232 /* Translate parameter block to stream */
233 strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
234 state->bi_valid = param->sbb;
235 if (state->bi_valid == 0)
236 state->bi_buf = 0; /* Avoid accessing next_out */
237 else
238 state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1);
239 strm->adler = param->cv;
241 /* Unmask the input data */
242 strm->avail_in += masked_avail_in;
243 masked_avail_in = 0;
245 /* If we encounter an error, it means there is a bug in DFLTCC call */
246 Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG");
248 /* Update Block-Continuation Flag. It will be used to check whether to call
249 * GDHT the next time.
251 if (cc == DFLTCC_CC_OK) {
252 if (soft_bcc) {
253 send_eobs(strm, param);
254 param->bcf = 0;
255 dfltcc_state->block_threshold =
256 strm->total_in + dfltcc_state->block_size;
257 } else
258 param->bcf = 1;
259 if (flush == Z_FINISH) {
260 if (need_empty_block)
261 /* Make the current deflate() call also close the stream */
262 return 0;
263 else {
264 bi_windup(state);
265 *result = finish_done;
267 } else {
268 if (flush == Z_FULL_FLUSH)
269 param->hl = 0; /* Clear history */
270 *result = flush == Z_NO_FLUSH ? need_more : block_done;
272 } else {
273 param->bcf = 1;
274 *result = need_more;
276 if (strm->avail_in != 0 && strm->avail_out != 0)
277 goto again; /* deflate() must use all input or all output */
278 return 1;