int lz_fx_compress(void *src, uint64_t srclen, void *dst, uint64_t *dstlen, int level, uchar_t chdr, int btype, void *data) { int rv; struct lzfx_params *lzdat = (struct lzfx_params *)data; unsigned int _srclen = srclen; unsigned int _dstlen = *dstlen; /* * Ignore compressed data in fast modes. */ if (level < 7 && PC_TYPE(btype) == TYPE_COMPRESSED) return (-1); rv = lzfx_compress(src, _srclen, dst, &_dstlen, lzdat->htab_bits); if (rv != 0) { if (rv != LZFX_ESIZE) lz_fx_err(rv); return (-1); } *dstlen = _dstlen; return (0); }
int ppmd_compress(void *src, uint64_t srclen, void *dst, uint64_t *dstlen, int level, uchar_t chdr, int btype, void *data) { CPpmd8 *_ppmd = (CPpmd8 *)data; uchar_t *_src = (uchar_t *)src; if (PC_TYPE(btype) == TYPE_COMPRESSED) return (-1); Ppmd8_RangeEnc_Init(_ppmd); Ppmd8_Init(_ppmd, _ppmd->Order, PPMD8_RESTORE_METHOD_RESTART); _ppmd->buf = (Byte *)dst; _ppmd->bufLen = *dstlen; _ppmd->bufUsed = 0; _ppmd->overflow = 0; Ppmd8_EncodeBuffer(_ppmd, _src, srclen); Ppmd8_EncodeSymbol(_ppmd, -1); Ppmd8_RangeEnc_FlushData(_ppmd); if (_ppmd->overflow) return (-1); *dstlen = _ppmd->bufUsed; return (0); }
int zlib_compress(void *src, uint64_t srclen, void *dst, uint64_t *dstlen, int level, uchar_t chdr, int btype, void *data) { int ret, ending; unsigned int slen, dlen; uint64_t _srclen = srclen; uint64_t _dstlen = *dstlen; uchar_t *dst1 = (uchar_t *)dst; uchar_t *src1 = (uchar_t *)src; z_stream *zs = (z_stream *)data; /* * If the data is known to be compressed then certain types less compressed data * can be attempted to be compressed again for a possible gain. For others it is * a waste of time. */ if (PC_TYPE(btype) == TYPE_COMPRESSED && level < 7) { int subtype = PC_SUBTYPE(btype); if (subtype != TYPE_COMPRESSED_LZW && subtype != TYPE_COMPRESSED_LZ && subtype != TYPE_COMPRESSED_LZO) { return (-1); } } ending = 0; while (_srclen > 0) { if (_srclen > SINGLE_CALL_MAX) { slen = SINGLE_CALL_MAX; } else { slen = _srclen; ending = 1; } if (_dstlen > SINGLE_CALL_MAX) { dlen = SINGLE_CALL_MAX; } else { dlen = _dstlen; } zs->next_in = src1; zs->avail_in = slen; zs->next_out = dst1; zs->avail_out = dlen; if (!ending) { ret = deflate(zs, Z_NO_FLUSH); if (ret != Z_OK) { deflateReset(zs); zerr(ret, 1); return (-1); } } else { ret = deflate(zs, Z_FINISH); if (ret != Z_STREAM_END) { deflateReset(zs); if (ret == Z_OK) zerr(Z_BUF_ERROR, 1); else zerr(ret, 1); return (-1); } } dst1 += (dlen - zs->avail_out); _dstlen -= (dlen - zs->avail_out); src1 += slen; _srclen -= slen; } *dstlen = *dstlen - _dstlen; ret = deflateReset(zs); if (ret != Z_OK) { zerr(ret, 1); return (-1); } return (0); }
int adapt_compress(void *src, uint64_t srclen, void *dst, uint64_t *dstlen, int level, uchar_t chdr, int btype, void *data) { struct adapt_data *adat = (struct adapt_data *)(data); uchar_t *src1 = (uchar_t *)src; int rv = 0, bsc_type = 0; if (btype == TYPE_UNKNOWN) { uint64_t i, tot8b, tag1, tag2, tag3; double tagcnt, pct_tag; uchar_t cur_byte, prev_byte; /* * Count number of 8-bit binary bytes and XML tags in source. */ tot8b = 0; tag1 = 0; tag2 = 0; tag3 = 0; prev_byte = cur_byte = 0; for (i = 0; i < srclen; i++) { cur_byte = src1[i]; tot8b += (cur_byte & 0x80); // This way for possible auto-vectorization tag1 += (cur_byte == '<'); tag2 += (cur_byte == '>'); tag3 += ((prev_byte == '<') & (cur_byte == '/')); tag3 += ((prev_byte == '/') & (cur_byte == '>')); if (cur_byte != ' ') prev_byte = cur_byte; } tot8b /= 0x80; tagcnt = tag1 + tag2 + tag3; pct_tag = tagcnt / (double)srclen; if (adat->adapt_mode == 2 && tot8b > FORTY_PCT(srclen)) { btype = TYPE_BINARY; } else if (adat->adapt_mode == 1 && tot8b > FIFTY_PCT(srclen)) { btype = TYPE_BINARY; } else { btype = TYPE_TEXT; if (tag1 > tag2 - 4 && tag1 < tag2 + 4 && tag3 > (double)tag1 * 0.40 && tagcnt > (double)srclen * 0.001) btype |= TYPE_MARKUP; } } /* * Use PPMd if some percentage of source is 7-bit textual bytes, otherwise * use Bzip2 or LZMA. For totally incompressible data we always use LZ4. There * is no point trying to compress such data, like Jpegs. However some archive headers * and zero paddings can exist which LZ4 can easily take care of very fast. */ #ifdef ENABLE_PC_LIBBSC bsc_type = is_bsc_type(btype); #endif if (is_incompressible(btype)) { rv = lz4_compress(src, srclen, dst, dstlen, level, chdr, btype, adat->lz4_data); if (rv < 0) return (rv); rv = ADAPT_COMPRESS_LZ4; lz4_count++; } else if (adat->adapt_mode == 2 && PC_TYPE(btype) == TYPE_BINARY && !bsc_type) { rv = lzma_compress(src, srclen, dst, dstlen, level, chdr, btype, adat->lzma_data); if (rv < 0) return (rv); rv = ADAPT_COMPRESS_LZMA; lzma_count++; } else if (adat->adapt_mode == 1 && PC_TYPE(btype) == TYPE_BINARY && !bsc_type) { rv = bzip2_compress(src, srclen, dst, dstlen, level, chdr, btype, NULL); if (rv < 0) return (rv); rv = ADAPT_COMPRESS_BZIP2; bzip2_count++; } else { #ifdef ENABLE_PC_LIBBSC if (adat->bsc_data && bsc_type) { rv = libbsc_compress(src, srclen, dst, dstlen, level, chdr, btype, adat->bsc_data); if (rv < 0) return (rv); rv = ADAPT_COMPRESS_BSC; bsc_count++; } else { #endif rv = ppmd_alloc(adat->ppmd_data); if (rv < 0) return (rv); rv = ppmd_compress(src, srclen, dst, dstlen, level, chdr, btype, adat->ppmd_data); ppmd_free(adat->ppmd_data); if (rv < 0) return (rv); rv = ADAPT_COMPRESS_PPMD; ppmd_count++; #ifdef ENABLE_PC_LIBBSC } #endif } return (rv); }