📄 cbzip2outputstream.java
字号:
int nHeap = 0; heap[0] = 0; weight[0] = 0; parent[0] = -2; for (int i = 1; i <= alphaSize; i++) { parent[i] = -1; nHeap++; heap[nHeap] = i; int zz = nHeap; int tmp = heap[zz]; while (weight[tmp] < weight[heap[zz >> 1]]) { heap[zz] = heap[zz >> 1]; zz >>= 1; } heap[zz] = tmp; } while (nHeap > 1) { int n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; int yy = 0; int zz = 1; int tmp = heap[1]; while (true) { yy = zz << 1; if (yy > nHeap) { break; } if ((yy < nHeap) && (weight[heap[yy + 1]] < weight[heap[yy]])) { yy++; } if (weight[tmp] < weight[heap[yy]]) { break; } heap[zz] = heap[yy]; zz = yy; } heap[zz] = tmp; int n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; yy = 0; zz = 1; tmp = heap[1]; while (true) { yy = zz << 1; if (yy > nHeap) { break; } if ((yy < nHeap) && (weight[heap[yy + 1]] < weight[heap[yy]])) { yy++; } if (weight[tmp] < weight[heap[yy]]) { break; } heap[zz] = heap[yy]; zz = yy; } heap[zz] = tmp; nNodes++; parent[n1] = parent[n2] = nNodes; final int weight_n1 = weight[n1]; final int weight_n2 = weight[n2]; weight[nNodes] = ((weight_n1 & 0xffffff00) + (weight_n2 & 0xffffff00)) | (1 + (((weight_n1 & 0x000000ff) > (weight_n2 & 0x000000ff)) ? (weight_n1 & 0x000000ff) : (weight_n2 & 0x000000ff))); parent[nNodes] = -1; nHeap++; heap[nHeap] = nNodes; tmp = 0; zz = nHeap; tmp = heap[zz]; final int weight_tmp = weight[tmp]; while (weight_tmp < weight[heap[zz >> 1]]) { heap[zz] = heap[zz >> 1]; zz >>= 1; } heap[zz] = tmp; } for (int i = 1; i <= alphaSize; i++) { int j = 0; int k = i; for (int parent_k; (parent_k = parent[k]) >= 0;) { k = parent_k; j++; } len[i - 1] = (byte) j; if (j > maxLen) { tooLong = true; } } if (tooLong) { for (int i = 1; i < alphaSize; i++) { int j = weight[i] >> 8; j = 1 + (j >> 1); weight[i] = j << 8; } } } } /** Index of the last char in the block, so the block size == last + 1. */ private int last; /** * Index in fmap[] of original string after sorting. */ private int origPtr; /** Always: in the range 0 .. 9. The current block size is 100000 * this number. */ private final int blockSize100k; private boolean blockRandomised; private int bsBuff; private int bsLive; private final CRC crc = new CRC(); private int nInUse; private int nMTF; /* * Used when sorting. If too many long comparisons * happen, we stop sorting, randomise the block * slightly, and try again. */ private int workDone; private int workLimit; private boolean firstAttempt; private int currentChar = -1; private int runLength = 0; private int blockCRC; private int combinedCRC; private int allowableBlockSize; /** * All memory intensive stuff. */ private CBZip2OutputStream.Data data; private OutputStream out; /** * Chooses a blocksize based on the given length of the data to compress. * * @return * The blocksize, between {@link #MIN_BLOCKSIZE} and {@link #MAX_BLOCKSIZE} * both inclusive. For a negative <tt>inputLength</tt> this method returns * <tt>MAX_BLOCKSIZE</tt> always. * * @param inputLength * The length of the data which will be compressed by * <tt>CBZip2OutputStream</tt>. */ public static int chooseBlockSize(long inputLength) { return (inputLength > 0) ? (int) Math.min((inputLength / 132000) + 1, 9) : MAX_BLOCKSIZE; } /** * Constructs a new <tt>CBZip2OutputStream</tt> with a blocksize of 900k. * * <p><b>Attention: </b>The caller is resonsible to write the two * BZip2 magic bytes <tt>"BZ"</tt> to the specified stream prior * to calling this constructor.</p> * * @param out * the destination stream. * * @throws IOException * if an I/O error occurs in the specified stream. * @throws NullPointerException * if <code>out == null</code>. */ public CBZip2OutputStream(final OutputStream out) throws IOException { this(out, MAX_BLOCKSIZE); } /** * Constructs a new <tt>CBZip2OutputStream</tt> with specified blocksize. * * <p><b>Attention: </b>The caller is resonsible to write the two * BZip2 magic bytes <tt>"BZ"</tt> to the specified stream prior * to calling this constructor.</p> * * * @param out * the destination stream. * @param blockSize * the blockSize as 100k units. * * @throws IOException * if an I/O error occurs in the specified stream. * @throws IllegalArgumentException * if <code>(blockSize < 1) || (blockSize > 9)</code>. * @throws NullPointerException * if <code>out == null</code>. * * @see #MIN_BLOCKSIZE * @see #MAX_BLOCKSIZE */ public CBZip2OutputStream(final OutputStream out, final int blockSize) throws IOException { super(); if (blockSize < 1) { throw new IllegalArgumentException("blockSize(" + blockSize + ") < 1"); } if (blockSize > 9) { throw new IllegalArgumentException("blockSize(" + blockSize + ") > 9"); } this.blockSize100k = blockSize; this.out = out; init(); } public void write(final int b) throws IOException { if (this.out != null) { write0(b); } else { throw new IOException("closed"); } } private void writeRun() throws IOException { final int lastShadow = this.last; if (lastShadow < this.allowableBlockSize) { final int currentCharShadow = this.currentChar; final Data dataShadow = this.data; dataShadow.inUse[currentCharShadow] = true; final byte ch = (byte) currentCharShadow; int runLengthShadow = this.runLength; this.crc.updateCRC(currentCharShadow, runLengthShadow); switch (runLengthShadow) { case 1: dataShadow.block[lastShadow + 2] = ch; this.last = lastShadow + 1; break; case 2: dataShadow.block[lastShadow + 2] = ch; dataShadow.block[lastShadow + 3] = ch; this.last = lastShadow + 2; break; case 3: { final byte[] block = dataShadow.block; block[lastShadow + 2] = ch; block[lastShadow + 3] = ch; block[lastShadow + 4] = ch; this.last = lastShadow + 3; } break; default: { runLengthShadow -= 4; dataShadow.inUse[runLengthShadow] = true; final byte[] block = dataShadow.block; block[lastShadow + 2] = ch; block[lastShadow + 3] = ch; block[lastShadow + 4] = ch; block[lastShadow + 5] = ch; block[lastShadow + 6] = (byte) runLengthShadow; this.last = lastShadow + 5; } break; } } else { endBlock(); initBlock(); writeRun(); } } /** * Overriden to close the stream. */ protected void finalize() throws Throwable { close(); super.finalize(); } public void close() throws IOException { OutputStream outShadow = this.out; if (outShadow != null) { try { if (this.runLength > 0) { writeRun(); } this.currentChar = -1; endBlock(); endCompression(); outShadow.close(); } finally { this.out = null; this.data = null; } } } public void flush() throws IOException { OutputStream outShadow = this.out; if (outShadow != null) { outShadow.flush(); } } private void init() throws IOException { // write magic: done by caller who created this stream //this.out.write('B'); //this.out.write('Z'); this.data = new Data(this.blockSize100k); /* Write `magic' bytes h indicating file-format == huffmanised, followed by a digit indicating blockSize100k. */ bsPutUByte('h'); bsPutUByte('0' + this.blockSize100k); this.combinedCRC = 0; initBlock(); } private void initBlock() { // blockNo++; this.crc.initialiseCRC(); this.last = -1; // ch = 0; boolean[] inUse = this.data.inUse; for (int i = 256; --i >= 0;) { inUse[i] = false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -