/*-------------------------------------------------------------------------
 * 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>
#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;
}
