Source

lrc / src / strategies / zLibCompression.cxx

Full commit
//      zLibCompression.cxx
//
//      Copyright 2011 Andreas Tscharner <andy@vis.ethz.ch>
//
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU Lesser General Public License as
//      published by the Free Software Foundation; either version 3 of the
//      License, or (at your option) any later version.
//
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//
//      You should have received a copy of the GNU Lesser General Public
//      License along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.


#include <zlib.h>
#include "../StatusCodes.hxx"
#include "zLibCompression.hxx"


int zLibCompression::compress(const unsigned char *p_decompData, size_t p_decompSize,
                              unsigned char **p_compData, size_t &p_compSize)
{
	size_t maxCompressSize;
	int retVal;


	maxCompressSize = compressBound(p_decompSize);
	*p_compData = new unsigned char[maxCompressSize];

	retVal = compress2(*p_compData, (uLongf *)&maxCompressSize, p_decompData, p_decompSize, Z_BEST_COMPRESSION);
	switch (retVal) {
		case Z_STREAM_ERROR:
		case Z_BUF_ERROR:
			delete[] *p_compData;
			*p_compData = nullptr;
			return ERROR_COMPRESSION_COMPRESS;
			break;

		case Z_MEM_ERROR:
			delete[] *p_compData;
			*p_compData = nullptr;
			return ERROR_NOT_ENOUGH_MEMORY;
			break;

		case Z_OK:
			p_compSize = maxCompressSize;
			return NO_ERROR;
			break;
	};

	delete[] *p_compData;
	*p_compData = nullptr;
	return ERROR_COMPRESSION_COMPRESS;
}

int zLibCompression::decompress(const unsigned char *p_compData, size_t p_compSize,
                                unsigned char **p_decompData, size_t &p_decompSize)
{
	const int ENLARGE_FACTOR = 10;
	int retVal = Z_BUF_ERROR;


	p_decompSize = p_compSize;
	while (retVal == Z_BUF_ERROR) {
		p_decompSize = ENLARGE_FACTOR * p_decompSize;
		*p_decompData = new unsigned char[p_decompSize];

		retVal = uncompress(*p_decompData, (uLongf *)&p_decompSize, p_compData, p_compSize);
		switch (retVal) {
			case Z_DATA_ERROR:
				delete[] *p_decompData;
				*p_decompData = nullptr;
				return ERROR_COMPRESSION_DECOMPRESS;
				break;

			case Z_MEM_ERROR:
				delete[] *p_decompData;
				*p_decompData = nullptr;
				return ERROR_NOT_ENOUGH_MEMORY;
				break;

			case Z_BUF_ERROR:
				delete[] *p_decompData;
				*p_decompData = nullptr;
				break;

			case Z_OK:
				return NO_ERROR;
				break;
		};
	};

	delete[] *p_decompData;
	*p_decompData = nullptr;
	return ERROR_COMPRESSION_DECOMPRESS;
}