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