0001
0002
0003 #include "../zlib_deflate/defutil.h"
0004 #include "dfltcc_util.h"
0005 #include "dfltcc.h"
0006 #include <asm/setup.h>
0007 #include <linux/export.h>
0008 #include <linux/zutil.h>
0009
0010
0011
0012
0013 int dfltcc_can_deflate(
0014 z_streamp strm
0015 )
0016 {
0017 deflate_state *state = (deflate_state *)strm->state;
0018 struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
0019
0020
0021 if (zlib_dfltcc_support == ZLIB_DFLTCC_DISABLED ||
0022 zlib_dfltcc_support == ZLIB_DFLTCC_INFLATE_ONLY)
0023 return 0;
0024
0025
0026 if (!dfltcc_are_params_ok(state->level, state->w_bits, state->strategy,
0027 dfltcc_state->level_mask))
0028 return 0;
0029
0030
0031 if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) ||
0032 !is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) ||
0033 !is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0))
0034 return 0;
0035
0036 return 1;
0037 }
0038 EXPORT_SYMBOL(dfltcc_can_deflate);
0039
0040 static void dfltcc_gdht(
0041 z_streamp strm
0042 )
0043 {
0044 deflate_state *state = (deflate_state *)strm->state;
0045 struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
0046 size_t avail_in = avail_in = strm->avail_in;
0047
0048 dfltcc(DFLTCC_GDHT,
0049 param, NULL, NULL,
0050 &strm->next_in, &avail_in, NULL);
0051 }
0052
0053 static dfltcc_cc dfltcc_cmpr(
0054 z_streamp strm
0055 )
0056 {
0057 deflate_state *state = (deflate_state *)strm->state;
0058 struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
0059 size_t avail_in = strm->avail_in;
0060 size_t avail_out = strm->avail_out;
0061 dfltcc_cc cc;
0062
0063 cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR,
0064 param, &strm->next_out, &avail_out,
0065 &strm->next_in, &avail_in, state->window);
0066 strm->total_in += (strm->avail_in - avail_in);
0067 strm->total_out += (strm->avail_out - avail_out);
0068 strm->avail_in = avail_in;
0069 strm->avail_out = avail_out;
0070 return cc;
0071 }
0072
0073 static void send_eobs(
0074 z_streamp strm,
0075 const struct dfltcc_param_v0 *param
0076 )
0077 {
0078 deflate_state *state = (deflate_state *)strm->state;
0079
0080 zlib_tr_send_bits(
0081 state,
0082 bi_reverse(param->eobs >> (15 - param->eobl), param->eobl),
0083 param->eobl);
0084 flush_pending(strm);
0085 if (state->pending != 0) {
0086
0087
0088
0089
0090
0091
0092 memmove(state->pending_buf, state->pending_out, state->pending);
0093 state->pending_out = state->pending_buf;
0094 }
0095 #ifdef ZLIB_DEBUG
0096 state->compressed_len += param->eobl;
0097 #endif
0098 }
0099
0100 int dfltcc_deflate(
0101 z_streamp strm,
0102 int flush,
0103 block_state *result
0104 )
0105 {
0106 deflate_state *state = (deflate_state *)strm->state;
0107 struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
0108 struct dfltcc_param_v0 *param = &dfltcc_state->param;
0109 uInt masked_avail_in;
0110 dfltcc_cc cc;
0111 int need_empty_block;
0112 int soft_bcc;
0113 int no_flush;
0114
0115 if (!dfltcc_can_deflate(strm))
0116 return 0;
0117
0118 again:
0119 masked_avail_in = 0;
0120 soft_bcc = 0;
0121 no_flush = flush == Z_NO_FLUSH;
0122
0123
0124
0125
0126
0127 if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) {
0128 if (param->bcf) {
0129
0130
0131
0132 send_eobs(strm, param);
0133 param->bcf = 0;
0134 }
0135 return 0;
0136 }
0137
0138 if (strm->avail_in == 0 && !param->cf) {
0139 *result = need_more;
0140 return 1;
0141 }
0142
0143
0144
0145
0146
0147
0148 if (param->bcf && no_flush &&
0149 strm->total_in > dfltcc_state->block_threshold &&
0150 strm->avail_in >= dfltcc_state->dht_threshold) {
0151 if (param->cf) {
0152
0153
0154
0155 masked_avail_in += strm->avail_in;
0156 strm->avail_in = 0;
0157 no_flush = 0;
0158 } else {
0159
0160
0161
0162 send_eobs(strm, param);
0163 param->bcf = 0;
0164 dfltcc_state->block_threshold =
0165 strm->total_in + dfltcc_state->block_size;
0166 if (strm->avail_out == 0) {
0167 *result = need_more;
0168 return 1;
0169 }
0170 }
0171 }
0172
0173
0174
0175
0176
0177 if (no_flush && strm->avail_in > dfltcc_state->block_size) {
0178 masked_avail_in += (strm->avail_in - dfltcc_state->block_size);
0179 strm->avail_in = dfltcc_state->block_size;
0180 }
0181
0182
0183
0184
0185
0186 need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf;
0187
0188
0189 param->cvt = CVT_ADLER32;
0190 if (!no_flush)
0191
0192
0193 soft_bcc = 1;
0194 if (flush == Z_FINISH && !param->bcf)
0195
0196
0197
0198 param->bhf = 1;
0199
0200
0201
0202 Assert(state->pending == 0, "There must be no pending bytes");
0203 Assert(state->bi_valid < 8, "There must be less than 8 pending bits");
0204 param->sbb = (unsigned int)state->bi_valid;
0205 if (param->sbb > 0)
0206 *strm->next_out = (Byte)state->bi_buf;
0207 if (param->hl)
0208 param->nt = 0;
0209 param->cv = strm->adler;
0210
0211
0212 if (!param->bcf) {
0213 if (strm->total_in == 0 && dfltcc_state->block_threshold > 0) {
0214 param->htt = HTT_FIXED;
0215 }
0216 else {
0217 param->htt = HTT_DYNAMIC;
0218 dfltcc_gdht(strm);
0219 }
0220 }
0221
0222
0223 do {
0224 cc = dfltcc_cmpr(strm);
0225 if (strm->avail_in < 4096 && masked_avail_in > 0)
0226
0227
0228
0229
0230
0231 break;
0232 } while (cc == DFLTCC_CC_AGAIN);
0233
0234
0235 strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
0236 state->bi_valid = param->sbb;
0237 if (state->bi_valid == 0)
0238 state->bi_buf = 0;
0239 else
0240 state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1);
0241 strm->adler = param->cv;
0242
0243
0244 strm->avail_in += masked_avail_in;
0245 masked_avail_in = 0;
0246
0247
0248 Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG");
0249
0250
0251
0252
0253 if (cc == DFLTCC_CC_OK) {
0254 if (soft_bcc) {
0255 send_eobs(strm, param);
0256 param->bcf = 0;
0257 dfltcc_state->block_threshold =
0258 strm->total_in + dfltcc_state->block_size;
0259 } else
0260 param->bcf = 1;
0261 if (flush == Z_FINISH) {
0262 if (need_empty_block)
0263
0264 return 0;
0265 else {
0266 bi_windup(state);
0267 *result = finish_done;
0268 }
0269 } else {
0270 if (flush == Z_FULL_FLUSH)
0271 param->hl = 0;
0272 *result = flush == Z_NO_FLUSH ? need_more : block_done;
0273 }
0274 } else {
0275 param->bcf = 1;
0276 *result = need_more;
0277 }
0278 if (strm->avail_in != 0 && strm->avail_out != 0)
0279 goto again;
0280 return 1;
0281 }
0282 EXPORT_SYMBOL(dfltcc_deflate);