Ejemplo n.º 1
0
  /**
   * Generate the fixed huffman trees as described in the rfc
   *
   * @param huffmanCode - pointer to where the code shall be inserted
   * @param huffmanCodeLength
   * @param distHuffCode
   * @param distHuffCodeLength
   */
  public static void genFixedTree(
      int[] huffmanCode, byte[] huffmanCodeLength, int[] distHuffCode, byte[] distHuffCodeLength) {

    int i;
    // huffmanCodes
    for (i = 0; i <= 143; i++) {
      huffmanCode[i] = 48 + i; // 48==00110000
      huffmanCodeLength[i] = 8;
    }
    for (i = 144; i <= 255; i++) {
      huffmanCode[i] = 400 + i - 144; // 400==110010000
      huffmanCodeLength[i] = 9;
    }
    for (i = 256; i <= 279; i++) {
      huffmanCode[i] = i - 256; // 0==0
      huffmanCodeLength[i] = 7;
    }
    for (i = 280; i < 286; i++) {
      huffmanCode[i] = 192 + i - 280; // 192==11000000
      huffmanCodeLength[i] = 8;
    }
    // reverse all:
    ZipHelper.revHuffTree(huffmanCode, huffmanCodeLength);

    // distHuffCode for non fixed DISTANCE tree
    for (int j = 0; j < distHuffCode.length; j++) {
      distHuffCode[j] = j;
      distHuffCodeLength[j] = 5;
    }
    // reverse all:
    ZipHelper.revHuffTree(distHuffCode, distHuffCodeLength);
  }
Ejemplo n.º 2
0
  private void processHeader() throws IOException {
    // #debug
    System.out.println("processHeader()");
    int val;

    int HLIT; // number of miniHuff fragments
    int HDIST; // number of distance codes (should somehow lead to the same)
    int HCLEN; // number of length codes

    int[] distHuffCode = new int[30];
    int[] distHuffData = new int[30];
    byte[] distHuffCodeLength = new byte[30];

    int[] huffmanCode =
        new int[286]; // this contains the codes according to the huffman tree/mapping
    int[] huffmanData = new int[286]; // this contains the data referring to the code.
    byte[] huffmanCodeLength = new byte[286];

    this.BFINAL = (popSmallBuffer(1) == 1);

    this.BTYPE = popSmallBuffer(2);

    if (this.BTYPE == 3) {
      throw new IllegalArgumentException();
    } else if (this.BTYPE == 1) {
      // System.out.println(this.allPocessed +  ": fixed tree");

      ZipHelper.genFixedTree(huffmanCode, huffmanCodeLength, distHuffCode, distHuffCodeLength);
      for (int i = 0; i < 286; i++) {
        huffmanData[i] = i;
      }
      for (int i = 0; i < 30; i++) {
        distHuffData[i] = i;
      }

      // convert literal table to tree
      ZipHelper.convertTable2Tree(huffmanCode, huffmanCodeLength, huffmanData, this.huffmanTree);

      // convert distance table to tree
      ZipHelper.convertTable2Tree(
          distHuffCode, distHuffCodeLength, distHuffData, this.distHuffTree);

    } else if (this.BTYPE == 2) {
      // System.out.println(this.allPocessed + ": dynamic tree");

      // read/parse the length codes

      HLIT = popSmallBuffer(5);
      HDIST = popSmallBuffer(5);
      HCLEN = popSmallBuffer(4);

      // miniTree
      int[] miniHuffData = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
      int[] seq = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};

      byte[] miniHuffCodeLength = new byte[19];
      int[] miniHuffCode = new int[19];

      // read the miniHuffCodeLength
      for (int i = 0; i < HCLEN + 4; i++) {
        miniHuffCodeLength[miniHuffData[i]] = (byte) popSmallBuffer(3);
      }

      ZipHelper.genHuffTree(miniHuffCode, miniHuffCodeLength);
      ZipHelper.revHuffTree(miniHuffCode, miniHuffCodeLength);

      short[] miniTree = new short[19 * 4];
      ZipHelper.convertTable2Tree(miniHuffCode, miniHuffCodeLength, seq, miniTree);

      // parse the length code for the normal Tree and the distance Tree using the miniTree
      for (int i = 0; i < huffmanCodeLength.length; i++) {
        huffmanCodeLength[i] = 0;
      }
      for (int i = 0; i < distHuffCodeLength.length; i++) {
        distHuffCodeLength[i] = 0;
      }
      byte lastVal = 0;
      for (int j = 0; j < HLIT + 257 + HDIST + 1; ) {

        if (this.smallCodeBuffer[1] < 15) {
          refillSmallCodeBuffer();
        }
        val = ZipHelper.deHuffNext(this.smallCodeBuffer, miniTree);

        // data
        if (val < 16) {
          lastVal = (byte) val;
          val = 1;
        } else {
          // repeat code
          if (val == 16) {
            val = popSmallBuffer(2) + 3;
          } else if (val == 17) {
            lastVal = 0;
            val = popSmallBuffer(3) + 3;
          } else if (val == 18) {
            lastVal = 0;
            val = popSmallBuffer(7) + 11;
          }
        }
        // fill the value in
        for (int k = 0; k < val; k++, j++) {
          if (j < HLIT + 257) {
            huffmanCodeLength[j] = lastVal;
          } else {
            distHuffCodeLength[j - (HLIT + 257)] = lastVal;
          }
        }
      }

      // final tree:		 fill this.huffmanCode this.huffmanData
      ZipHelper.genHuffTree(huffmanCode, huffmanCodeLength);
      for (int i = 0; i < huffmanData.length; i++) {
        huffmanData[i] = i;
      }
      // converting literal table to tree
      ZipHelper.revHuffTree(huffmanCode, huffmanCodeLength);
      ZipHelper.convertTable2Tree(huffmanCode, huffmanCodeLength, huffmanData, this.huffmanTree);

      // Distance Tree
      // distHuffData for non fixed distance tree
      // this.distHuffCodeLength is read together with this.huffmanCodeLength
      for (int j = 0; j < distHuffCode.length; j++) {
        distHuffData[j] = j;
      }
      ZipHelper.genHuffTree(distHuffCode, distHuffCodeLength);
      ZipHelper.revHuffTree(distHuffCode, distHuffCodeLength);
      ZipHelper.convertTable2Tree(
          distHuffCode, distHuffCodeLength, distHuffData, this.distHuffTree);

    } else {
      // just skip bits up to the next boundary
      popSmallBuffer(this.smallCodeBuffer[1] & 7); // &7 == %8

      // read and check the header
      this.B0len = popSmallBuffer(8) | popSmallBuffer(8) << 8;
      if (this.smallCodeBuffer[1] < 15) {
        refillSmallCodeBuffer();
      }
      if (this.B0len + (popSmallBuffer(8) | popSmallBuffer(8) << 8) != 0xffff) {
        // Error:  the header for the uncompressed is wrong;
        throw new IOException("3");
      }

      // clear the buffer
      while (this.smallCodeBuffer[1] != 0 && this.B0len > 0) {
        val = popSmallBuffer(8);
        this.window[this.pProcessed] = (byte) val;
        this.pProcessed = (this.pProcessed + 1) & 32767; // == % (1<<15);

        this.outBuff[this.outEnd] = (byte) val;
        this.outEnd++;

        this.B0len--;
      }
    }

    this.status = GZipInputStream.EXPECTING_DATA;

    distHuffCode = null;
    distHuffData = null;
    distHuffCodeLength = null;

    huffmanCodeLength = null;
    huffmanCode = null;
    huffmanData = null;
  }