/*-------------------------------------------------------------------------
 * Filename:      mini_inflate.c
 * Version:       $Id: mini_inflate.c,v 1.3 2002/01/24 22:58:42 rfeany Exp $
 * Copyright:     Copyright (C) 2001, Russ Dill
 * Author:        Russ Dill <Russ.Dill@asu.edu>
 * Description:   Mini inflate implementation (RFC 1951)
 *-----------------------------------------------------------------------*/
/*
 *
 * 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
 *
 */

#include <config.h>

#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)

#include <jffs2/mini_inflate.h>

/* The order that the code lengths in section 3.2.7 are in */
static unsigned char huffman_order[] = {16, 17, 18,  0,  8,  7,  9,  6, 10,  5,
					11,  4, 12,  3, 13,  2, 14,  1, 15};

inline void cramfs_memset(int *s, const int c, size n)
{
	n--;
	for (;n > 0; n--) s[n] = c;
	s[0] = c;
}

/* associate a stream with a block of data and reset the stream */
static void init_stream(struct bitstream *stream, unsigned char *data,
			void *(*inflate_memcpy)(void *, const void *, size))
{
	stream->error = NO_ERROR;
	stream->memcpy = inflate_memcpy;
	stream->decoded = 0;
	stream->data = data;
	stream->bit = 0;	/* The first bit of the stream is the lsb of the
				 * first byte */

	/* really sorry about all this initialization, think of a better way,
	 * let me know and it will get cleaned up */
	stream->codes.bits = 8;
	stream->codes.num_symbols = 19;
	stream->codes.lengths = stream->code_lengths;
	stream->codes.symbols = stream->code_symbols;
	stream->codes.count = stream->code_count;
	stream->codes.first = stream->code_first;
	stream->codes.pos = stream->code_pos;

	stream->lengths.bits = 16;
	stream->lengths.num_symbols = 288;
	stream->lengths.lengths = stream->length_lengths;
	stream->lengths.symbols = stream->length_symbols;
	stream->lengths.count = stream->length_count;
	stream->lengths.first = stream->length_first;
	stream->lengths.pos = stream->length_pos;

	stream->distance.bits = 16;
	stream->distance.num_symbols = 32;
	stream->distance.lengths = stream->distance_lengths;
	stream->distance.symbols = stream->distance_symbols;
	stream->distance.count = stream->distance_count;
	stream->distance.first = stream->distance_first;
	stream->distance.pos = stream->distance_pos;

}

/* pull 'bits' bits out of the stream. The last bit pulled it returned as the
 * msb. (section 3.1.1)
 */
inline unsigned long pull_bits(struct bitstream *stream,
			       const unsigned int bits)
{
	unsigned long ret;
	int i;

	ret = 0;
	for (i = 0; i < bits; i++) {
		ret += ((*(stream->data) >> stream->bit) & 1) << i;

		/* if, before incrementing, we are on bit 7,
		 * go to the lsb of the next byte */
		if (stream->bit++ == 7) {
			stream->bit = 0;
			stream->data++;
		}
	}
	return ret;
}

inline int pull_bit(struct bitstream *stream)
{
	int ret = ((*(stream->data) >> stream->bit) & 1);
	if (stream->bit++ == 7) {
		stream->bit = 0;
		stream->data++;
	}
	return ret;
}

/* discard bits up to the next whole byte */
static void discard_bits(struct bitstream *stream)
{
	if (stream->bit != 0) {
		stream->bit = 0;
		stream->data++;
	}
}

/* No decompression, the data is all literals (section 3.2.4) */
static void decompress_none(struct bitstream *stream, unsigned char *dest)
{
	unsigned int length;

	discard_bits(stream);
	length = *(stream->data++);
	length += *(stream->data++) << 8;
	pull_bits(stream, 16);	/* throw away the inverse of the size */

	stream->decoded += length;
	stream->memcpy(dest, stream->data, length);
	stream->data += length;
}

/* Read in a symbol from the stream (section 3.2.2) */
static int read_symbol(struct bitstream *stream, struct huffman_set *set)
{
	int bits = 0;
	int code = 0;
	while (!(set->count[bits] && code < set->first[bits] +
					     set->count[bits])) {
		code = (code << 1) + pull_bit(stream);
		if (++bits > set->bits) {
			/* error decoding (corrupted data?) */
			stream->error = CODE_NOT_FOUND;
			return -1;
		}
	}
	return set->symbols[set->pos[bits] + code - set->first[bits]];
}

/* decompress a stream of data encoded with the passed length and distance
 * huffman codes */
static void decompress_huffman(struct bitstream *stream, unsigned char *dest)
{
	struct huffman_set *lengths = &(stream->lengths);
	struct huffman_set *distance = &(stream->distance);

	int symbol, length, dist, i;

	do {
		if ((symbol = read_symbol(stream, lengths)) < 0) return;
		if (symbol < 256) {
			*(dest++) = symbol; /* symbol is a literal */
			stream->decoded++;
		} else if (symbol > 256) {
			/* Determine the length of the repitition
			 * (section 3.2.5) */
			if (symbol < 265) length = symbol - 254;
			else if (symbol == 285) length = 258;
			else {
				length = pull_bits(stream, (symbol - 261) >> 2);
				length += (4 << ((symbol - 261) >> 2)) + 3;
				length += ((symbol - 1) % 4) <<
					  ((symbol - 261) >> 2);
			}

			/* Determine how far back to go */
			if ((symbol = read_symbol(stream, distance)) < 0)
				return;
			if (symbol < 4) dist = symbol + 1;
			else {
				dist = pull_bits(stream, (symbol - 2) >> 1);
				dist += (2 << ((symbol - 2) >> 1)) + 1;
				dist += (symbol % 2) << ((symbol - 2) >> 1);
			}
			stream->decoded += length;
			for (i = 0; i < length; i++) {
				*dest = dest[-dist];
				dest++;
			}
		}
	} while (symbol != 256); /* 256 is the end of the data block */
}

/* Fill the lookup tables (section 3.2.2) */
static void fill_code_tables(struct huffman_set *set)
{
	int code = 0, i, length;

	/* fill in the first code of each bit length, and the pos pointer */
	set->pos[0] = 0;
	for (i = 1; i < set->bits; i++) {
		code = (code + set->count[i - 1]) << 1;
		set->first[i] = code;
		set->pos[i] = set->pos[i - 1] + set->count[i - 1];
	}

	/* Fill in the table of symbols in order of their huffman code */
	for (i = 0; i < set->num_symbols; i++) {
		if ((length = set->lengths[i]))
			set->symbols[set->pos[length]++] = i;
	}

	/* reset the pos pointer */
	for (i = 1; i < set->bits; i++) set->pos[i] -= set->count[i];
}

static void init_code_tables(struct huffman_set *set)
{
	cramfs_memset(set->lengths, 0, set->num_symbols);
	cramfs_memset(set->count, 0, set->bits);
	cramfs_memset(set->first, 0, set->bits);
}

/* read in the huffman codes for dynamic decoding (section 3.2.7) */
static void decompress_dynamic(struct bitstream *stream, unsigned char *dest)
{
	/* I tried my best to minimize the memory footprint here, while still
	 * keeping up performance. I really dislike the _lengths[] tables, but
	 * I see no way of eliminating them without a sizable performance
	 * impact. The first struct table keeps track of stats on each bit
	 * length. The _length table keeps a record of the bit length of each
	 * symbol. The _symbols table is for looking up symbols by the huffman
	 * code (the pos element points to the first place in the symbol table
	 * where that bit length occurs). I also hate the initization of these
	 * structs, if someone knows how to compact these, lemme know. */

	struct huffman_set *codes = &(stream->codes);
	struct huffman_set *lengths = &(stream->lengths);
	struct huffman_set *distance = &(stream->distance);

	int hlit = pull_bits(stream, 5) + 257;
	int hdist = pull_bits(stream, 5) + 1;
	int hclen = pull_bits(stream, 4) + 4;
	int length, curr_code, symbol, i, last_code;

	last_code = 0;

	init_code_tables(codes);
	init_code_tables(lengths);
	init_code_tables(distance);

	/* fill in the count of each bit length' as well as the lengths
	 * table */
	for (i = 0; i < hclen; i++) {
		length = pull_bits(stream, 3);
		codes->lengths[huffman_order[i]] = length;
		if (length) codes->count[length]++;

	}
	fill_code_tables(codes);

	/* Do the same for the length codes, being carefull of wrap through
	 * to the distance table */
	curr_code = 0;
	while (curr_code < hlit) {
		if ((symbol = read_symbol(stream, codes)) < 0) return;
		if (symbol == 0) {
			curr_code++;
			last_code = 0;
		} else if (symbol < 16) { /* Literal length */
			lengths->lengths[curr_code] =  last_code = symbol;
			lengths->count[symbol]++;
			curr_code++;
		} else if (symbol == 16) { /* repeat the last symbol 3 - 6
					    * times */
			length = 3 + pull_bits(stream, 2);
			for (;length; length--, curr_code++)
				if (curr_code < hlit) {
					lengths->lengths[curr_code] =
						last_code;
					lengths->count[last_code]++;
				} else { /* wrap to the distance table */
					distance->lengths[curr_code - hlit] =
						last_code;
					distance->count[last_code]++;
				}
		} else if (symbol == 17) { /* repeat a bit length 0 */
			curr_code += 3 + pull_bits(stream, 3);
			last_code = 0;
		} else { /* same, but more times */
			curr_code += 11 + pull_bits(stream, 7);
			last_code = 0;
		}
	}
	fill_code_tables(lengths);

	/* Fill the distance table, don't need to worry about wrapthrough
	 * here */
	curr_code -= hlit;
	while (curr_code < hdist) {
		if ((symbol = read_symbol(stream, codes)) < 0) return;
		if (symbol == 0) {
			curr_code++;
			last_code = 0;
		} else if (symbol < 16) {
			distance->lengths[curr_code] = last_code = symbol;
			distance->count[symbol]++;
			curr_code++;
		} else if (symbol == 16) {
			length = 3 + pull_bits(stream, 2);
			for (;length; length--, curr_code++) {
				distance->lengths[curr_code] =
					last_code;
				distance->count[last_code]++;
			}
		} else if (symbol == 17) {
			curr_code += 3 + pull_bits(stream, 3);
			last_code = 0;
		} else {
			curr_code += 11 + pull_bits(stream, 7);
			last_code = 0;
		}
	}
	fill_code_tables(distance);

	decompress_huffman(stream, dest);
}

/* fill in the length and distance huffman codes for fixed encoding
 * (section 3.2.6) */
static void decompress_fixed(struct bitstream *stream, unsigned char *dest)
{
	/* let gcc fill in the initial values */
	struct huffman_set *lengths = &(stream->lengths);
	struct huffman_set *distance = &(stream->distance);

	cramfs_memset(lengths->count, 0, 16);
	cramfs_memset(lengths->first, 0, 16);
	cramfs_memset(lengths->lengths, 8, 144);
	cramfs_memset(lengths->lengths + 144, 9, 112);
	cramfs_memset(lengths->lengths + 256, 7, 24);
	cramfs_memset(lengths->lengths + 280, 8, 8);
	lengths->count[7] = 24;
	lengths->count[8] = 152;
	lengths->count[9] = 112;

	cramfs_memset(distance->count, 0, 16);
	cramfs_memset(distance->first, 0, 16);
	cramfs_memset(distance->lengths, 5, 32);
	distance->count[5] = 32;


	fill_code_tables(lengths);
	fill_code_tables(distance);


	decompress_huffman(stream, dest);
}

/* returns the number of bytes decoded, < 0 if there was an error. Note that
 * this function assumes that the block starts on a byte boundry
 * (non-compliant, but I don't see where this would happen). section 3.2.3 */
long decompress_block(unsigned char *dest, unsigned char *source,
		      void *(*inflate_memcpy)(void *, const void *, size))
{
	int bfinal, btype;
	struct bitstream stream;

	init_stream(&stream, source, inflate_memcpy);
	do {
		bfinal = pull_bit(&stream);
		btype = pull_bits(&stream, 2);
		if (btype == NO_COMP) decompress_none(&stream, dest + stream.decoded);
		else if (btype == DYNAMIC_COMP)
			decompress_dynamic(&stream, dest + stream.decoded);
		else if (btype == FIXED_COMP) decompress_fixed(&stream, dest + stream.decoded);
		else stream.error = COMP_UNKNOWN;
	} while (!bfinal && !stream.error);

#if 0
	putstr("decompress_block start\r\n");
	putLabeledWord("stream.error = ",stream.error);
	putLabeledWord("stream.decoded = ",stream.decoded);
	putLabeledWord("dest = ",dest);
	putstr("decompress_block end\r\n");
#endif
	return stream.error ? -stream.error : stream.decoded;
}

#endif /* CFG_CMD_JFFS2 */
