📄 deflate.c
字号:
/* ========================================================================= */
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
{
deflate_state *s;
uInt length = dictLength;
uInt n;
IPos hash_head = 0;
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
strm->state->wrap == 2 ||
(strm->state->wrap == 1 && strm->state->status != INIT_STATE))
return Z_STREAM_ERROR;
s = strm->state;
if (s->wrap)
strm->adler = adler32(strm->adler, dictionary, dictLength);
if (length < MIN_MATCH) return Z_OK;
if (length > MAX_DIST(s)) {
length = MAX_DIST(s);
dictionary += dictLength - length; /* use the tail of the dictionary */
}
zmemcpy(s->window, dictionary, length);
s->strstart = length;
s->block_start = (long)length;
/* Insert all strings in the hash table (except for the last two bytes).
* s->lookahead stays null, so s->ins_h will be recomputed at the next
* call of fill_window.
*/
s->ins_h = s->window[0];
UPDATE_HASH(s, s->ins_h, s->window[1]);
for (n = 0; n <= length - MIN_MATCH; n++) {
INSERT_STRING(s, n, hash_head);
}
if (hash_head) hash_head = 0; /* to make compiler happy */
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflateReset (strm)
z_streamp strm;
{
deflate_state *s;
IppLZ77State_8u *pLZ77State;
IppLZ77DeflateStatus deflateStatus;
if (strm == Z_NULL || strm->state == Z_NULL || strm->state->ipp_state == Z_NULL ||
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
return Z_STREAM_ERROR;
}
strm->total_in = strm->total_out = 0;
strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
strm->data_type = Z_UNKNOWN;
s = (deflate_state *)strm->state;
s->pending = 0;
s->pending_out = s->pending_buf;
if (s->wrap < 0) {
s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
}
s->status = s->wrap ? INIT_STATE : BUSY_STATE;
pLZ77State = strm->state->ipp_state;
if(s->wrap == 0)
deflateStatus = IppLZ77StatusLZ77Process;
else
deflateStatus = IppLZ77StatusInit;
ippsEncodeLZ77SetStatus_8u(deflateStatus, pLZ77State);
strm->adler =
#ifdef GZIP
s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
#endif
adler32(0L, Z_NULL, 0);
s->last_flush = Z_NO_FLUSH;
_tr_init(s);
lm_init(s);
if(ippsEncodeLZ77Reset_8u(pLZ77State) < 0)
return Z_STREAM_ERROR;
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflateSetHeader (strm, head)
z_streamp strm;
gz_headerp head;
{
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
if (strm->state->wrap != 2) return Z_STREAM_ERROR;
strm->state->gzhead = head;
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflatePrime (strm, bits, value)
z_streamp strm;
int bits;
int value;
{
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
strm->state->bi_valid = bits;
strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflateParams(strm, level, strategy)
z_streamp strm;
int level;
int strategy;
{
deflate_state *s;
compress_func func;
int err = Z_OK;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
s = strm->state;
#ifdef FASTEST
if (level != 0) level = 1;
#else
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR;
}
func = configuration_table[s->level].func;
if (func != configuration_table[level].func && strm->total_in != 0) {
/* Flush the last buffer: */
err = deflate(strm, Z_PARTIAL_FLUSH);
}
if (s->level != level) {
s->level = level;
s->max_lazy_match = configuration_table[level].max_lazy;
s->good_match = configuration_table[level].good_length;
s->nice_match = configuration_table[level].nice_length;
s->max_chain_length = configuration_table[level].max_chain;
}
s->strategy = strategy;
return err;
}
/* ========================================================================= */
int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
z_streamp strm;
int good_length;
int max_lazy;
int nice_length;
int max_chain;
{
deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
s = strm->state;
s->good_match = good_length;
s->max_lazy_match = max_lazy;
s->nice_match = nice_length;
s->max_chain_length = max_chain;
return Z_OK;
}
/* =========================================================================
* For the default windowBits of 15 and memLevel of 8, this function returns
* a close to exact, as well as small, upper bound on the compressed size.
* They are coded as constants here for a reason--if the #define's are
* changed, then this function needs to be changed as well. The return
* value for 15 and 8 only works for those exact settings.
*
* For any setting other than those defaults for windowBits and memLevel,
* the value returned is a conservative worst case for the maximum expansion
* resulting from using fixed blocks instead of stored blocks, which deflate
* can emit on compressed data for some combinations of the parameters.
*
* This function could be more sophisticated to provide closer upper bounds
* for every combination of windowBits and memLevel, as well as wrap.
* But even the conservative upper bound of about 14% expansion does not
* seem onerous for output buffer allocation.
*/
uLong ZEXPORT deflateBound(strm, sourceLen)
z_streamp strm;
uLong sourceLen;
{
deflate_state *s;
uLong destLen;
/* conservative upper bound */
destLen = sourceLen +
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
/* if can't get parameters, return conservative bound */
if (strm == Z_NULL || strm->state == Z_NULL)
return destLen;
/* if not default parameters, return conservative bound */
s = strm->state;
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
return destLen;
/* default settings: return tight bound for that case */
return compressBound(sourceLen);
}
/* =========================================================================
* Put a short in the pending buffer. The 16-bit value is put in MSB order.
* IN assertion: the stream state is correct and there is enough room in
* pending_buf.
*/
local void putShortMSB (s, b)
deflate_state *s;
uInt b;
{
put_byte(s, (Byte)(b >> 8));
put_byte(s, (Byte)(b & 0xff));
}
local void putShortMSB_ipp (s, b)
deflate_state *s;
uInt b;
{
put_byte_ipp(s, (Byte)(b >> 8));
put_byte_ipp(s, (Byte)(b & 0xff));
}
/* =========================================================================
* Flush as much pending output as possible. All deflate() output goes
* through this function so some applications may wish to modify it
* to avoid allocating a large strm->next_out buffer and copying into it.
* (See also read_buf()).
*/
local void flush_pending(strm)
z_streamp strm;
{
unsigned len = strm->state->pending;
if (len > strm->avail_out) len = strm->avail_out;
if (len == 0) return;
zmemcpy(strm->next_out, strm->state->pending_out, len);
strm->next_out += len;
strm->state->pending_out += len;
strm->total_out += len;
strm->avail_out -= len;
strm->state->pending -= len;
if (strm->state->pending == 0) {
strm->state->pending_out = strm->state->pending_buf;
}
}
local void zmemcpy_ipp(Bytef* dest, const Bytef* source, uInt len)
{
uInt i;
if( len <= 0 ) return;
for( i = 0; i < len; i++ ) dest[i] = source[i];
return;
}
local int flush_header_trailer(strm)
z_streamp strm;
{
unsigned len = strm->state->header_trailer_bytes_valid;
if(len == 0) return 0;
if (len > strm->avail_out)
{
zmemcpy_ipp(strm->next_out, strm->state->header_trailer_buff, strm->avail_out);
zmemcpy_ipp(strm->state->header_trailer_buff, &(strm->state->header_trailer_buff[strm->avail_out]), (len - strm->avail_out) );
strm->state->header_trailer_bytes_valid -= strm->avail_out;
strm->total_out += strm->avail_out;
strm->next_out += strm->avail_out;
strm->avail_out = 0;
return (-1);
}
else
{
zmemcpy_ipp(strm->next_out, strm->state->header_trailer_buff, len);
strm->state->header_trailer_bytes_valid = 0;
strm->total_out += len;
strm->next_out += len;
strm->avail_out -= len;
return 0;
} /* if else */
} /* flush_header_trailer() */
/* ========================================================================= */
int ZEXPORT deflate (strm, flush)
z_streamp strm;
int flush;
{
deflate_state *s;
IppLZ77State_8u* pLZ77State;
IppLZ77DeflateStatus deflateStatus;
IppLZ77Flush ippflush;
IppLZ77Pair* pPairs;
IppLZ77Pair* cpPairs;
IppStatus status;
int pairsInd;
int pairsLen;
int psrcLen;
int pdstLen;
int srcLen;
Ipp8u* pSrc;
int dstLen;
Ipp8u* pDst;
int chslen;
unsigned int header;
unsigned int level_flags;
switch( flush ) {
case Z_NO_FLUSH: ippflush = IppLZ77NoFlush; break;
case Z_PARTIAL_FLUSH:
case Z_SYNC_FLUSH: ippflush = IppLZ77SyncFlush; break;
case Z_FULL_FLUSH: ippflush = IppLZ77FullFlush; break;
case Z_FINISH: ippflush = IppLZ77FinishFlush; break;
default: return Z_STREAM_ERROR;
} /* switch */
if( strm == Z_NULL ) return Z_STREAM_ERROR;
if( strm->state == Z_NULL ) return Z_STREAM_ERROR;
if( strm->state->ipp_state == Z_NULL ) return Z_STREAM_ERROR;
s = strm->state;
pLZ77State = strm->state->ipp_state;
if( strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0) ) return Z_STREAM_ERROR;
ippsEncodeLZ77GetStatus_8u( &deflateStatus, pLZ77State );
for( ; ; ) {
if( flush_header_trailer(strm) < 0 ) return Z_OK;
switch( deflateStatus ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -