0001
0002
0003 #include "../zlib_inflate/inflate.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_inflate(
0014 z_streamp strm
0015 )
0016 {
0017 struct inflate_state *state = (struct inflate_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_DEFLATE_ONLY)
0023 return 0;
0024
0025
0026 if (state->wbits != HB_BITS)
0027 return 0;
0028
0029
0030 return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) &&
0031 is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0);
0032 }
0033 EXPORT_SYMBOL(dfltcc_can_inflate);
0034
0035 static int dfltcc_was_inflate_used(
0036 z_streamp strm
0037 )
0038 {
0039 struct inflate_state *state = (struct inflate_state *)strm->state;
0040 struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
0041
0042 return !param->nt;
0043 }
0044
0045 static int dfltcc_inflate_disable(
0046 z_streamp strm
0047 )
0048 {
0049 struct inflate_state *state = (struct inflate_state *)strm->state;
0050 struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
0051
0052 if (!dfltcc_can_inflate(strm))
0053 return 0;
0054 if (dfltcc_was_inflate_used(strm))
0055
0056
0057
0058
0059 return 1;
0060
0061 memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
0062 return 0;
0063 }
0064
0065 static dfltcc_cc dfltcc_xpnd(
0066 z_streamp strm
0067 )
0068 {
0069 struct inflate_state *state = (struct inflate_state *)strm->state;
0070 struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param;
0071 size_t avail_in = strm->avail_in;
0072 size_t avail_out = strm->avail_out;
0073 dfltcc_cc cc;
0074
0075 cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR,
0076 param, &strm->next_out, &avail_out,
0077 &strm->next_in, &avail_in, state->window);
0078 strm->avail_in = avail_in;
0079 strm->avail_out = avail_out;
0080 return cc;
0081 }
0082
0083 dfltcc_inflate_action dfltcc_inflate(
0084 z_streamp strm,
0085 int flush,
0086 int *ret
0087 )
0088 {
0089 struct inflate_state *state = (struct inflate_state *)strm->state;
0090 struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state);
0091 struct dfltcc_param_v0 *param = &dfltcc_state->param;
0092 dfltcc_cc cc;
0093
0094 if (flush == Z_BLOCK) {
0095
0096 if (dfltcc_inflate_disable(strm)) {
0097 *ret = Z_STREAM_ERROR;
0098 return DFLTCC_INFLATE_BREAK;
0099 } else
0100 return DFLTCC_INFLATE_SOFTWARE;
0101 }
0102
0103 if (state->last) {
0104 if (state->bits != 0) {
0105 strm->next_in++;
0106 strm->avail_in--;
0107 state->bits = 0;
0108 }
0109 state->mode = CHECK;
0110 return DFLTCC_INFLATE_CONTINUE;
0111 }
0112
0113 if (strm->avail_in == 0 && !param->cf)
0114 return DFLTCC_INFLATE_BREAK;
0115
0116 if (!state->window || state->wsize == 0) {
0117 state->mode = MEM;
0118 return DFLTCC_INFLATE_CONTINUE;
0119 }
0120
0121
0122 param->cvt = CVT_ADLER32;
0123 param->sbb = state->bits;
0124 param->hl = state->whave;
0125 param->ho = (state->write - state->whave) & ((1 << HB_BITS) - 1);
0126 if (param->hl)
0127 param->nt = 0;
0128 param->cv = state->check;
0129
0130
0131 do {
0132 cc = dfltcc_xpnd(strm);
0133 } while (cc == DFLTCC_CC_AGAIN);
0134
0135
0136 strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
0137 state->last = cc == DFLTCC_CC_OK;
0138 state->bits = param->sbb;
0139 state->whave = param->hl;
0140 state->write = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
0141 state->check = param->cv;
0142 if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
0143
0144 state->mode = BAD;
0145 return DFLTCC_INFLATE_CONTINUE;
0146 }
0147 state->mode = TYPEDO;
0148
0149 return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ?
0150 DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE;
0151 }
0152 EXPORT_SYMBOL(dfltcc_inflate);