Beispiel #1
0
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);
}
Beispiel #2
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);
}
Beispiel #3
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);
}
Beispiel #4
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);
}