/*
 * Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.57
 *
 * Copyright (C) 2007-2008 Industrie Dial Face S.p.A.
 * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com)
 *
 * Copyright (C) 1999-2005 Igor Pavlov
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * LZMA_Alone stream format:
 *
 * uchar   Properties[5]
 * uint64  Uncompressed size
 * uchar   data[*]
 *
 */
#include <config.h>
#include <common.h>

#ifdef CONFIG_LZMA

#define LZMA_PROPERTIES_OFFSET 0
#define LZMA_SIZE_OFFSET       LZMA_PROPERTIES_SIZE
#define LZMA_DATA_OFFSET       LZMA_SIZE_OFFSET+sizeof(uint64_t)

#include "LzmaTools.h"
#include "LzmaDecode.h"

#include <linux/string.h>
#include <malloc.h>

#define LZMA_DECOMPRESS_NOALLOC

int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize,
			      unsigned char *inStream,  SizeT  length)
{
	int res = LZMA_RESULT_DATA_ERROR;
	int i;

	SizeT outSizeFull = 0xFFFFFFFF; /* 4GBytes limit */
	SizeT outAvail;
	SizeT inProcessed;
	SizeT outProcessed;
	SizeT outSize;
	SizeT outSizeHigh;
	CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
	unsigned char properties[LZMA_PROPERTIES_SIZE];
	SizeT compressedSize = (SizeT)(length - LZMA_DATA_OFFSET);

	debug ("LZMA: Image address............... 0x%lx\n", (unsigned long) inStream);
	debug ("LZMA: Properties address.......... 0x%lx\n", (unsigned long) inStream + LZMA_PROPERTIES_OFFSET);
	debug ("LZMA: Uncompressed size address... 0x%lx\n", (unsigned long) inStream + LZMA_SIZE_OFFSET);
	debug ("LZMA: Compressed data address..... 0x%lx\n", (unsigned long) inStream + LZMA_DATA_OFFSET);
	debug ("LZMA: Destination address......... 0x%lx\n", (unsigned long) outStream);

	memcpy(properties, inStream + LZMA_PROPERTIES_OFFSET, LZMA_PROPERTIES_SIZE);

	memset(&state, 0, sizeof(state));
	res = LzmaDecodeProperties(&state.Properties,
				 properties,
				 LZMA_PROPERTIES_SIZE);
	if (res != LZMA_RESULT_OK) {
		return res;
	}

	outSize = 0;
	outSizeHigh = 0;
	/* Read the uncompressed size */
	for (i = 0; i < 8; i++) {
		unsigned char b = inStream[LZMA_SIZE_OFFSET + i];
	        if (i < 4) {
		        outSize     += (UInt32)(b) << (i * 8);
		} else {
	                outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
		}
	}

	outSizeFull = (SizeT)outSize;
	if (sizeof(SizeT) >= 8) {
		/*
	         * SizeT is a 64 bit uint => We can manage files larger than 4GB!
		 *
		 */
	        outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
	} else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) {
		/*
		 * SizeT is a 32 bit uint => We cannot manage files larger than
		 * 4GB!  Assume however that all 0xf values is "unknown size" and
		 * not actually a file of 2^64 bits.
		 *
		 */
		if (outSizeHigh != (SizeT)-1 || outSize != (SizeT)-1) {
			debug ("LZMA: 64bit support not enabled.\n");
			return LZMA_RESULT_DATA_ERROR;
		}
	}

	/* Short-circuit early if we know the buffer can't hold the results. */
	if (outSizeFull != (SizeT)-1 && *uncompressedSize < outSizeFull)
		return LZMA_RESULT_DATA_ERROR;

	outAvail = min(outSizeFull, *uncompressedSize);

	debug ("LZMA: Available output buffer..... 0x%lx\n", (unsigned long) outAvail);
	debug ("LZMA: Uncompresed size............ 0x%lx\n", (unsigned long) outSizeFull);
	debug ("LZMA: Compresed size.............. 0x%lx\n", (unsigned long) compressedSize);

#ifdef LZMA_DECOMPRESS_NOALLOC
	debug ("LZMA: Decompress buffer needed.... 0x%lx\n",
			(unsigned long) LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
	/* decompression buffer lives at the end of the decompressed image area */
	state.Probs = (void*)(((unsigned long) outStream + outAvail + 0x80) & ~(0x80 - 1));
#else
	debug ("LZMA: Dynamic memory needed....... 0x%lx, allocating...\n",
			(unsigned long) LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
	state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
#endif

	if (state.Probs == 0
	    || (outStream == 0 && outSizeFull != 0)
	    || (inStream == 0 && compressedSize != 0)) {
#ifndef LZMA_DECOMPRESS_NOALLOC
		free(state.Probs);
#endif
		debug ("\n");
		return LZMA_RESULT_DATA_ERROR;
	}

	debug ("LZMA: Decompress buffer at........ 0x%lx\n", (unsigned long) state.Probs);

	/* Decompress */

	res = LzmaDecode(&state,
		inStream + LZMA_DATA_OFFSET, compressedSize, &inProcessed,
		outStream, outAvail,  &outProcessed);
	if (res != LZMA_RESULT_OK)  {
		return res;
	}

	debug ("LZMA: Uncompressed bytes out...... 0x%lx\n", (unsigned long) outProcessed);
	debug ("LZMA: Compressed bytes in......... 0x%lx\n", (unsigned long) inProcessed);

	if (outProcessed != outSizeFull && outProcessed == outAvail) {
		/*
		 * If the size of the uncompressed image matches exactly the
		 * size of the output buffer, then we do not know whether that
		 * is a just coincident or whether LzmaDecode stopped
		 * prematurely due to insufficient output buffer space. Err on
		 * the side of caution and return an error.
		 * */
		return LZMA_RESULT_DATA_ERROR;
	}

	*uncompressedSize = outProcessed;
#ifndef LZMA_DECOMPRESS_NOALLOC
	free(state.Probs);
#endif
	return res;
}

#endif
