/* DeflaterHuffman.java --
   Copyright (C) 2001, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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, or (at your option)
any later version.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.util.zip;

/**
 * This is the DeflaterHuffman class.
 *
 * This class is <i>not</i> thread safe.  This is inherent in the API, due
 * to the split of deflate and setInput.
 *
 * @author Jochen Hoenicke
 * @date Jan 6, 2000 
 */
class DeflaterHuffman
{
  private static final int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6);
  private static final int LITERAL_NUM = 286;
  private static final int DIST_NUM = 30;
  private static final int BITLEN_NUM = 19;
  private static final int REP_3_6    = 16;
  private static final int REP_3_10   = 17;
  private static final int REP_11_138 = 18;
  private static final int EOF_SYMBOL = 256;
  private static final int[] BL_ORDER =
  { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };

  private static final String bit4Reverse =
    "\000\010\004\014\002\012\006\016\001\011\005\015\003\013\007\017";

  class Tree {
    short[] freqs;
    short[] codes;
    byte[]  length;
    int[]   bl_counts;
    int     minNumCodes, numCodes;
    int     maxLength;

    Tree(int elems, int minCodes, int maxLength) {
      this.minNumCodes = minCodes;
      this.maxLength  = maxLength;
      freqs  = new short[elems];
      bl_counts = new int[maxLength];
    }

    void reset() {
      for (int i = 0; i < freqs.length; i++)
	freqs[i] = 0;
      codes = null;
      length = null;
    }

    final void writeSymbol(int code)
    {
      if (DeflaterConstants.DEBUGGING)
 	{
 	  freqs[code]--;
//  	  System.err.print("writeSymbol("+freqs.length+","+code+"): ");
 	}
      pending.writeBits(codes[code] & 0xffff, length[code]);
    }

    final void checkEmpty()
    {
      boolean empty = true;
      for (int i = 0; i < freqs.length; i++)
	if (freqs[i] != 0)
	  {
	    System.err.println("freqs["+i+"] == "+freqs[i]);
	    empty = false;
	  }
      if (!empty)
	throw new InternalError();
      System.err.println("checkEmpty suceeded!");
    }

    void setStaticCodes(short[] stCodes, byte[] stLength)
    {
      codes = stCodes;
      length = stLength;
    }

    public void buildCodes() {
      int[] nextCode = new int[maxLength];
      int code = 0;
      codes = new short[freqs.length];

      if (DeflaterConstants.DEBUGGING)
	System.err.println("buildCodes: "+freqs.length);
      for (int bits = 0; bits < maxLength; bits++) 
	{
	  nextCode[bits] = code;
	  code += bl_counts[bits] << (15 - bits);
	  if (DeflaterConstants.DEBUGGING)
	    System.err.println("bits: "+(bits+1)+" count: "+bl_counts[bits]
			       +" nextCode: "+Integer.toHexString(code));
	}
      if (DeflaterConstants.DEBUGGING && code != 65536)
	throw new RuntimeException("Inconsistent bl_counts!");
      
      for (int i=0; i < numCodes; i++)
	{
	  int bits = length[i];
	  if (bits > 0)
	    {
	      if (DeflaterConstants.DEBUGGING)
		System.err.println("codes["+i+"] = rev("
				   +Integer.toHexString(nextCode[bits-1])+"),"
				   +bits);
	      codes[i] = bitReverse(nextCode[bits-1]);
	      nextCode[bits-1] += 1 << (16 - bits);
	    }
	}
    }

    private void buildLength(int childs[])
    {
      this.length = new byte [freqs.length];
      int numNodes = childs.length / 2;
      int numLeafs = (numNodes + 1) / 2;
      int overflow = 0;
      
      for (int i = 0; i < maxLength; i++)
	bl_counts[i] = 0;

      /* First calculate optimal bit lengths */
      int lengths[] = new int[numNodes];
      lengths[numNodes-1] = 0;
      for (int i = numNodes - 1; i >= 0; i--)
	{
	  if (childs[2*i+1] != -1)
	    {
	      int bitLength = lengths[i] + 1;
	      if (bitLength > maxLength)
		{
		  bitLength = maxLength;
		  overflow++;
		}
	      lengths[childs[2*i]] = lengths[childs[2*i+1]] = bitLength;
	    }
	  else
	    {
	      /* A leaf node */
	      int bitLength = lengths[i];
	      bl_counts[bitLength - 1]++;
	      this.length[childs[2*i]] = (byte) lengths[i];
	    }
	}
      
      if (DeflaterConstants.DEBUGGING)
	{
	  System.err.println("Tree "+freqs.length+" lengths:");
	  for (int i=0; i < numLeafs; i++)
	    System.err.println("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
			       + " len: "+length[childs[2*i]]);
	}
      
      if (overflow == 0)
	return;
      
      int incrBitLen = maxLength - 1;
      do
	{
	  /* Find the first bit length which could increase: */
	  while (bl_counts[--incrBitLen] == 0)
	    ;
	  
	  /* Move this node one down and remove a corresponding
	   * amount of overflow nodes.
	   */
	  do
	    {
	      bl_counts[incrBitLen]--;
	      bl_counts[++incrBitLen]++;
	      overflow -= 1 << (maxLength - 1 - incrBitLen);
	    }
	  while (overflow > 0 && incrBitLen < maxLength - 1);
	}
      while (overflow > 0);

      /* We may have overshot above.  Move some nodes from maxLength to
       * maxLength-1 in that case.
       */
      bl_counts[maxLength-1] += overflow;
      bl_counts[maxLength-2] -= overflow;
      
      /* Now recompute all bit lengths, scanning in increasing
       * frequency.  It is simpler to reconstruct all lengths instead of
       * fixing only the wrong ones. This idea is taken from 'ar'
       * written by Haruhiko Okumura.
       *
       * The nodes were inserted with decreasing frequency into the childs
       * array.
       */
      int nodePtr = 2 * numLeafs;
      for (int bits = maxLength; bits != 0; bits--) 
	{
	  int n = bl_counts[bits-1];
	  while (n > 0) 
	    {
	      int childPtr = 2*childs[nodePtr++];
	      if (childs[childPtr + 1] == -1)
		{
		  /* We found another leaf */
		  length[childs[childPtr]] = (byte) bits;
		  n--;
		}
	    }
	}
      if (DeflaterConstants.DEBUGGING)
	{
	  System.err.println("*** After overflow elimination. ***");
	  for (int i=0; i < numLeafs; i++)
	    System.err.println("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
			       + " len: "+length[childs[2*i]]);
	}
    }
    
    void buildTree() 
    {
      int numSymbols = freqs.length;

      /* heap is a priority queue, sorted by frequency, least frequent
       * nodes first.  The heap is a binary tree, with the property, that
       * the parent node is smaller than both child nodes.  This assures
       * that the smallest node is the first parent.
       *
       * The binary tree is encoded in an array:  0 is root node and
       * the nodes 2*n+1, 2*n+2 are the child nodes of node n.
       */
      int[] heap = new int[numSymbols];
      int heapLen = 0;
      int maxCode = 0;
      for (int n = 0; n < numSymbols; n++)
	{
	  int freq = freqs[n];
	  if (freq != 0)
	    {
	      /* Insert n into heap */
	      int pos = heapLen++;
	      int ppos;
	      while (pos > 0 &&
		     freqs[heap[ppos = (pos - 1) / 2]] > freq) {
		heap[pos] = heap[ppos];
		pos = ppos;
	      }
	      heap[pos] = n;
	      maxCode = n;
	    }
	}
      
      /* We could encode a single literal with 0 bits but then we
       * don't see the literals.  Therefore we force at least two
       * literals to avoid this case.  We don't care about order in
       * this case, both literals get a 1 bit code.  
       */
      while (heapLen < 2)
	{
	  int node = maxCode < 2 ? ++maxCode : 0;
	  heap[heapLen++] = node;
	}

      numCodes = Math.max(maxCode + 1, minNumCodes);
      
      int numLeafs = heapLen;
      int[] childs = new int[4*heapLen - 2];
      int[] values = new int[2*heapLen - 1];
      int numNodes = numLeafs;
      for (int i = 0; i < heapLen; i++)
	{
	  int node = heap[i];
	  childs[2*i]   = node;
	  childs[2*i+1] = -1;
	  values[i] = freqs[node] << 8;
	  heap[i] = i;
	}
      
      /* Construct the Huffman tree by repeatedly combining the least two
       * frequent nodes.
       */
      do
	{
	  int first = heap[0];
	  int last  = heap[--heapLen];
	  
	  /* Propagate the hole to the leafs of the heap */
	  int ppos = 0;
	  int path = 1;
	  while (path < heapLen)
	    {
	      if (path + 1 < heapLen 
		  && values[heap[path]] > values[heap[path+1]])
		path++;
	      
	      heap[ppos] = heap[path];
	      ppos = path;
	      path = path * 2 + 1;
	    }
	  
	  /* Now propagate the last element down along path.  Normally
	   * it shouldn't go too deep.
	   */
	  int lastVal = values[last];
	  while ((path = ppos) > 0
		 && values[heap[ppos = (path - 1)/2]] > lastVal)
	    heap[path] = heap[ppos];
	  heap[path] = last;
	  
	  
	  int second = heap[0];
	  
	  /* Create a new node father of first and second */
	  last = numNodes++;
	  childs[2*last] = first;
	  childs[2*last+1] = second;
	  int mindepth = Math.min(values[first] & 0xff, values[second] & 0xff);
	  values[last] = lastVal = values[first] + values[second] - mindepth + 1;
	  
	  /* Again, propagate the hole to the leafs */
	  ppos = 0;
	  path = 1;
	  while (path < heapLen)
	    {
	      if (path + 1 < heapLen 
		  && values[heap[path]] > values[heap[path+1]])
		path++;
	      
	      heap[ppos] = heap[path];
	      ppos = path;
	      path = ppos * 2 + 1;
	    }
	  
	  /* Now propagate the new element down along path */
	  while ((path = ppos) > 0
		 && values[heap[ppos = (path - 1)/2]] > lastVal)
	    heap[path] = heap[ppos];
	  heap[path] = last;
	}
      while (heapLen > 1);
      
      if (heap[0] != childs.length / 2 - 1)
	throw new RuntimeException("Weird!");
      
      buildLength(childs);
    }

    int getEncodedLength() 
    {
      int len = 0;
      for (int i = 0; i < freqs.length; i++)
	len += freqs[i] * length[i];
      return len;
    }

    void calcBLFreq(Tree blTree) {
      int max_count;               /* max repeat count */
      int min_count;               /* min repeat count */
      int count;                   /* repeat count of the current code */
      int curlen = -1;             /* length of current code */
      
      int i = 0;
      while (i < numCodes)
	{
	  count = 1;
	  int nextlen = length[i];
	  if (nextlen == 0) 
	    {
	      max_count = 138;
	      min_count = 3;
	    }
	  else
	    {
	      max_count = 6;
	      min_count = 3;
	      if (curlen != nextlen)
		{
		  blTree.freqs[nextlen]++;
		  count = 0;
		}
	    }
	  curlen = nextlen;
	  i++;

	  while (i < numCodes && curlen == length[i])
	    {
	      i++;
	      if (++count >= max_count)
		break;
	    }

	  if (count < min_count)
	    blTree.freqs[curlen] += count;
	  else if (curlen != 0)
	    blTree.freqs[REP_3_6]++;
	  else if (count <= 10)
	    blTree.freqs[REP_3_10]++;
	  else
	    blTree.freqs[REP_11_138]++;
	}
    }

    void writeTree(Tree blTree)
    {
      int max_count;               /* max repeat count */
      int min_count;               /* min repeat count */
      int count;                   /* repeat count of the current code */
      int curlen = -1;             /* length of current code */
      
      int i = 0;
      while (i < numCodes)
	{
	  count = 1;
	  int nextlen = length[i];
	  if (nextlen == 0) 
	    {
	      max_count = 138;
	      min_count = 3;
	    }
	  else
	    {
	      max_count = 6;
	      min_count = 3;
	      if (curlen != nextlen)
		{
		  blTree.writeSymbol(nextlen);
		  count = 0;
		}
	    }
	  curlen = nextlen;
	  i++;

	  while (i < numCodes && curlen == length[i])
	    {
	      i++;
	      if (++count >= max_count)
		break;
	    }

	  if (count < min_count)
	    {
	      while (count-- > 0)
		blTree.writeSymbol(curlen);
	    }
	  else if (curlen != 0)
	    {
	      blTree.writeSymbol(REP_3_6);
	      pending.writeBits(count - 3, 2);
	    }
	  else if (count <= 10)
	    {
	      blTree.writeSymbol(REP_3_10);
	      pending.writeBits(count - 3, 3);
	    }
	  else
	    {
	      blTree.writeSymbol(REP_11_138);
	      pending.writeBits(count - 11, 7);
	    }
	}
    }
  }



  DeflaterPending pending;
  private Tree literalTree, distTree, blTree;

  private short d_buf[];
  private byte l_buf[];
  private int last_lit;
  private int extra_bits;

  private static short staticLCodes[];
  private static byte  staticLLength[];
  private static short staticDCodes[];
  private static byte  staticDLength[];

  /**
   * Reverse the bits of a 16 bit value.
   */
  static short bitReverse(int value) {
    return (short) (bit4Reverse.charAt(value & 0xf) << 12
		    | bit4Reverse.charAt((value >> 4) & 0xf) << 8
		    | bit4Reverse.charAt((value >> 8) & 0xf) << 4
		    | bit4Reverse.charAt(value >> 12));
  }

  static {
    /* See RFC 1951 3.2.6 */
    /* Literal codes */
    staticLCodes = new short[LITERAL_NUM];
    staticLLength = new byte[LITERAL_NUM];
    int i = 0;
    while (i < 144) {
      staticLCodes[i] = bitReverse((0x030 + i) << 8);
      staticLLength[i++] = 8;
    }
    while (i < 256) {
      staticLCodes[i] = bitReverse((0x190 - 144 + i) << 7);
      staticLLength[i++] = 9;
    }
    while (i < 280) {
      staticLCodes[i] = bitReverse((0x000 - 256 + i) << 9);
      staticLLength[i++] = 7;
    }
    while (i < LITERAL_NUM) {
      staticLCodes[i] = bitReverse((0x0c0 - 280 + i)  << 8);
      staticLLength[i++] = 8;
    }

    /* Distant codes */
    staticDCodes = new short[DIST_NUM];
    staticDLength = new byte[DIST_NUM];
    for (i = 0; i < DIST_NUM; i++) {
      staticDCodes[i] = bitReverse(i << 11);
      staticDLength[i] = 5;
    }
  }
    
  public DeflaterHuffman(DeflaterPending pending) 
  {
    this.pending = pending;

    literalTree = new Tree(LITERAL_NUM, 257, 15);
    distTree    = new Tree(DIST_NUM, 1, 15);
    blTree      = new Tree(BITLEN_NUM, 4, 7);

    d_buf = new short[BUFSIZE];
    l_buf = new byte [BUFSIZE];
  }

  public final void reset() {
    last_lit = 0;
    extra_bits = 0;
    literalTree.reset();
    distTree.reset();
    blTree.reset();
  }

  private int l_code(int len) {
    if (len == 255)
      return 285;

    int code = 257;
    while (len >= 8)
      {
	code += 4;
	len >>= 1;
      }
    return code + len;
  }

  private int d_code(int distance) {
    int code = 0;
    while (distance >= 4)
      {
	code += 2;
	distance >>= 1;
      }
    return code + distance;
  }

  public void sendAllTrees(int blTreeCodes) {
    blTree.buildCodes();
    literalTree.buildCodes();
    distTree.buildCodes();
    pending.writeBits(literalTree.numCodes - 257, 5);
    pending.writeBits(distTree.numCodes - 1, 5);
    pending.writeBits(blTreeCodes - 4, 4);
    for (int rank = 0; rank < blTreeCodes; rank++)
      pending.writeBits(blTree.length[BL_ORDER[rank]], 3);
    literalTree.writeTree(blTree);
    distTree.writeTree(blTree);
    if (DeflaterConstants.DEBUGGING)
      blTree.checkEmpty();
  }

  public void compressBlock() {
    for (int i = 0; i < last_lit; i++) 
      {
	int litlen = l_buf[i] & 0xff;
	int dist = d_buf[i];
	if (dist-- != 0)
	  {
	    if (DeflaterConstants.DEBUGGING)
	      System.err.print("["+(dist+1)+","+(litlen+3)+"]: ");

	    int lc = l_code(litlen);
	    literalTree.writeSymbol(lc);

	    int bits = (lc - 261) / 4;
	    if (bits > 0 && bits <= 5)
	      pending.writeBits(litlen & ((1 << bits) - 1), bits);

	    int dc = d_code(dist);
	    distTree.writeSymbol(dc);

	    bits = dc / 2 - 1;
	    if (bits > 0)
	      pending.writeBits(dist & ((1 << bits) - 1), bits);
	  }
	else
	  {
	    if (DeflaterConstants.DEBUGGING)
	      {
		if (litlen > 32 && litlen < 127)
		  System.err.print("("+(char)litlen+"): ");
		else
		  System.err.print("{"+litlen+"}: ");
	      }
	    literalTree.writeSymbol(litlen);
	  }
      }
    if (DeflaterConstants.DEBUGGING)
      System.err.print("EOF: ");
    literalTree.writeSymbol(EOF_SYMBOL);
    if (DeflaterConstants.DEBUGGING)
      {
	literalTree.checkEmpty();
	distTree.checkEmpty();
      }
  }

  public void flushStoredBlock(byte[] stored, 
			       int stored_offset, int stored_len,
			       boolean lastBlock) {
    if (DeflaterConstants.DEBUGGING)
      System.err.println("Flushing stored block "+ stored_len);
    pending.writeBits((DeflaterConstants.STORED_BLOCK << 1)
		      + (lastBlock ? 1 : 0), 3);
    pending.alignToByte();
    pending.writeShort(stored_len);
    pending.writeShort(~stored_len);
    pending.writeBlock(stored, stored_offset, stored_len);
    reset();
  }

  public void flushBlock(byte[] stored, int stored_offset, int stored_len,
			 boolean lastBlock) {
    literalTree.freqs[EOF_SYMBOL]++;

    /* Build trees */
    literalTree.buildTree();
    distTree.buildTree();

    /* Calculate bitlen frequency */
    literalTree.calcBLFreq(blTree);
    distTree.calcBLFreq(blTree);

    /* Build bitlen tree */
    blTree.buildTree();

    int blTreeCodes = 4;
    for (int i = 18; i > blTreeCodes; i--)
      {
	if (blTree.length[BL_ORDER[i]] > 0)
	  blTreeCodes = i+1;
      }
    int opt_len = 14 + blTreeCodes * 3 + blTree.getEncodedLength()
      + literalTree.getEncodedLength() + distTree.getEncodedLength()
      + extra_bits;

    int static_len = extra_bits;
    for (int i = 0; i < LITERAL_NUM; i++)
      static_len += literalTree.freqs[i] * staticLLength[i];
    for (int i = 0; i < DIST_NUM; i++)
      static_len += distTree.freqs[i] * staticDLength[i];
    if (opt_len >= static_len)
      {
	/* Force static trees */
	opt_len = static_len;
      }

    if (stored_offset >= 0 && stored_len+4 < opt_len >> 3)
      {
	/* Store Block */
	if (DeflaterConstants.DEBUGGING)
	  System.err.println("Storing, since " + stored_len + " < " + opt_len
			     + " <= " + static_len);
	flushStoredBlock(stored, stored_offset, stored_len, lastBlock);
      }
    else if (opt_len == static_len)
      {
	/* Encode with static tree */
	pending.writeBits((DeflaterConstants.STATIC_TREES << 1)
			  + (lastBlock ? 1 : 0), 3);
	literalTree.setStaticCodes(staticLCodes, staticLLength);
	distTree.setStaticCodes(staticDCodes, staticDLength);
	compressBlock();
	reset();
      }
    else
      {
	/* Encode with dynamic tree */
	pending.writeBits((DeflaterConstants.DYN_TREES << 1)
			  + (lastBlock ? 1 : 0), 3);
	sendAllTrees(blTreeCodes);
	compressBlock();
	reset();
      }
  }

  public final boolean isFull()
  {
    return last_lit == BUFSIZE;
  }

  public final boolean tallyLit(int lit) 
  {
    if (DeflaterConstants.DEBUGGING)
      {
	if (lit > 32 && lit < 127)
	  System.err.println("("+(char)lit+")");
	else
	  System.err.println("{"+lit+"}");
      }
    d_buf[last_lit] = 0;
    l_buf[last_lit++] = (byte) lit;
    literalTree.freqs[lit]++;
    return last_lit == BUFSIZE;
  }

  public final boolean tallyDist(int dist, int len) 
  {
    if (DeflaterConstants.DEBUGGING)
      System.err.println("["+dist+","+len+"]");

    d_buf[last_lit] = (short) dist;
    l_buf[last_lit++] = (byte) (len - 3);

    int lc = l_code(len-3);
    literalTree.freqs[lc]++;
    if (lc >= 265 && lc < 285)
      extra_bits += (lc - 261) / 4;

    int dc = d_code(dist-1);
    distTree.freqs[dc]++;
    if (dc >= 4)
      extra_bits += dc / 2 - 1;
    return last_lit == BUFSIZE;
  }
}
