/*****************************************************************************/
/* Copyright (c) 2008 NXP B.V.                                               */
/*                                                                           */
/* 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, using version 2 of the License.             */
/*                                                                           */
/* 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.                                                                      */
/*                                                                           */
/*****************************************************************************/
/**
    @file   phStbBootDsp_Decompress.c
    @brief  Decompression for phStbBootDsp component.

@b  Component:  phStbBootDsp.

*//*

Rev Date       Author      Comments
--------------------------------------------------------------------------------
  1 20061121   batelaan    Initial
  2 20061201   batelaan    Solve QMORE issues.
  3 20070112   steel       Update for 2.6.19 kernel
  4 20071207   hutchinson  Merge in EB's 20071128 WinCe rel.
  5 20080118   hutchinson  Merge in EB's 20080117 release.
  6 20080422   batelaan    Update file header
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/

#include "tmNxTypes.h"

#if TMFL_OS_IS_LINUX
#include <linux/module.h>
#endif
#include <phStbBootDsp_Internal.h>
#include "zlib.h"

static void *zalloc(void *, unsigned, unsigned);
static void zfree(void *, void *, unsigned);

#define	ZALLOC_ALIGNMENT	16

static void *zalloc(void *x, unsigned items, unsigned size)
{
	void *p;

	size *= items;
	size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
#if TMFL_OS_IS_CE
    p = malloc (size);
#else
	p = kmalloc (size, GFP_KERNEL);
#endif
	return (p);
}

static void zfree(void *x, void *addr, unsigned nb)
{
#if TMFL_OS_IS_CE
    free(addr);
#else
	kfree (addr);
#endif
}

#define HEAD_CRC	2
#define EXTRA_FIELD	4
#define ORIG_NAME	8
#define COMMENT		0x10
#define RESERVED	0xe0

#define DEFLATED	8

int phStbBootDsp_Gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
{
	z_stream s;
	int r, i, flags;

	/* skip header */
	i = 10;
	flags = src[3];
	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
            printk(KERN_ERR "Bad gzipped data\n");
            return (-1);
	}
	if ((flags & EXTRA_FIELD) != 0)
		i = 12 + src[10] + (src[11] << 8);
	if ((flags & ORIG_NAME) != 0)
		while (src[i++] != 0)
			;
	if ((flags & COMMENT) != 0)
		while (src[i++] != 0)
			;
	if ((flags & HEAD_CRC) != 0)
		i += 2;
	if ( (unsigned long)i >= *lenp) {
	    
		printk(KERN_ERR "gunzip out of data in header\n");
		return (-1);
	}

	s.zalloc = zalloc;
	s.zfree = zfree;
	s.outcb = Z_NULL;

	r = inflateInit2(&s, -MAX_WBITS);
	if (r != Z_OK) {
		printk(KERN_ERR "inflateInit2() returned %d\n", r);
		return (-1);
	}
	s.next_in = src + i;
	s.avail_in = *lenp - i;
	s.next_out = dst;
	s.avail_out = dstlen;
	r = inflate(&s, Z_FINISH);
	if (r != Z_OK && r != Z_STREAM_END) {
		printk(KERN_ERR "inflate() returned %d\n", r);
		return (-1);
	}
	*lenp = s.next_out - (unsigned char *) dst;
	inflateEnd(&s);

	return (0);
}
