📄 cbzip2outputstream.java
字号:
bsPutUChar('h'); bsPutUChar('0' + blockSize100k); combinedCRC = 0; } private int allowableBlockSize; private void initBlock() { // blockNo++; mCrc.initialiseCRC(); last = -1; // ch = 0; for (int i = 0; i < 256; i++) { inUse[i] = false; } /* 20 is just a paranoia constant */ allowableBlockSize = baseBlockSize * blockSize100k - 20; } private void endBlock() throws IOException { blockCRC = mCrc.getFinalCRC(); combinedCRC = (combinedCRC << 1) | (combinedCRC >>> 31); combinedCRC ^= blockCRC; /* sort the block and establish posn of original string */ doReversibleTransformation(); /* A 6-byte block header, the value chosen arbitrarily as 0x314159265359 :-). A 32 bit value does not really give a strong enough guarantee that the value will not appear by chance in the compressed datastream. Worst-case probability of this event, for a 900k block, is about 2.0e-3 for 32 bits, 1.0e-5 for 40 bits and 4.0e-8 for 48 bits. For a compressed file of size 100Gb -- about 100000 blocks -- only a 48-bit marker will do. NB: normal compression/ decompression do *not* rely on these statistical properties. They are only important when trying to recover blocks from damaged files. */ bsPutUChar(0x31); bsPutUChar(0x41); bsPutUChar(0x59); bsPutUChar(0x26); bsPutUChar(0x53); bsPutUChar(0x59); /* Now the block's CRC, so it is in a known place. */ bsPutint(blockCRC); /* Now a single bit indicating randomisation. */ if (blockRandomised) { bsW(1, 1); nBlocksRandomised++; } else { bsW(1, 0); } /* Finally, block's contents proper. */ moveToFrontCodeAndSend(); } private void endCompression() throws IOException { /* Now another magic 48-bit number, 0x177245385090, to indicate the end of the last block. (sqrt(pi), if you want to know. I did want to use e, but it contains too much repetition -- 27 18 28 18 28 46 -- for me to feel statistically comfortable. Call me paranoid.) */ bsPutUChar(0x17); bsPutUChar(0x72); bsPutUChar(0x45); bsPutUChar(0x38); bsPutUChar(0x50); bsPutUChar(0x90); bsPutint(combinedCRC); bsFinishedWithStream(); } private void hbAssignCodes (int[] code, char[] length, int minLen, int maxLen, int alphaSize) { int n, vec, i; vec = 0; for (n = minLen; n <= maxLen; n++) { for (i = 0; i < alphaSize; i++) { if (length[i] == n) { code[i] = vec; vec++; } }; vec <<= 1; } } private void bsSetStream(OutputStream f) { bsStream = f; bsLive = 0; bsBuff = 0; bytesOut = 0; } private void bsFinishedWithStream() throws IOException { while (bsLive > 0) { int ch = (bsBuff >> 24); try { bsStream.write(ch); // write 8-bit } catch (IOException e) { throw e; } bsBuff <<= 8; bsLive -= 8; bytesOut++; } } private void bsW(int n, int v) throws IOException { while (bsLive >= 8) { int ch = (bsBuff >> 24); try { bsStream.write(ch); // write 8-bit } catch (IOException e) { throw e; } bsBuff <<= 8; bsLive -= 8; bytesOut++; } bsBuff |= (v << (32 - bsLive - n)); bsLive += n; } private void bsPutUChar(int c) throws IOException { bsW(8, c); } private void bsPutint(int u) throws IOException { bsW(8, (u >> 24) & 0xff); bsW(8, (u >> 16) & 0xff); bsW(8, (u >> 8) & 0xff); bsW(8, u & 0xff); } private void bsPutIntVS(int numBits, int c) throws IOException { bsW(numBits, c); } private void sendMTFValues() throws IOException { char len[][] = new char[N_GROUPS][MAX_ALPHA_SIZE]; int v, t, i, j, gs, ge, totc, bt, bc, iter; int nSelectors = 0, alphaSize, minLen, maxLen, selCtr; int nGroups, nBytes; alphaSize = nInUse + 2; for (t = 0; t < N_GROUPS; t++) { for (v = 0; v < alphaSize; v++) { len[t][v] = (char) GREATER_ICOST; } } /* Decide how many coding tables to use */ if (nMTF <= 0) { panic(); } if (nMTF < 200) { nGroups = 2; } else if (nMTF < 600) { nGroups = 3; } else if (nMTF < 1200) { nGroups = 4; } else if (nMTF < 2400) { nGroups = 5; } else { nGroups = 6; } /* Generate an initial set of coding tables */ { int nPart, remF, tFreq, aFreq; nPart = nGroups; remF = nMTF; gs = 0; while (nPart > 0) { tFreq = remF / nPart; ge = gs - 1; aFreq = 0; while (aFreq < tFreq && ge < alphaSize - 1) { ge++; aFreq += mtfFreq[ge]; } if (ge > gs && nPart != nGroups && nPart != 1 && ((nGroups - nPart) % 2 == 1)) { aFreq -= mtfFreq[ge]; ge--; } for (v = 0; v < alphaSize; v++) { if (v >= gs && v <= ge) { len[nPart - 1][v] = (char) LESSER_ICOST; } else { len[nPart - 1][v] = (char) GREATER_ICOST; } } nPart--; gs = ge + 1; remF -= aFreq; } } int[][] rfreq = new int[N_GROUPS][MAX_ALPHA_SIZE]; int[] fave = new int[N_GROUPS]; short[] cost = new short[N_GROUPS]; /* Iterate up to N_ITERS times to improve the tables. */ for (iter = 0; iter < N_ITERS; iter++) { for (t = 0; t < nGroups; t++) { fave[t] = 0; } for (t = 0; t < nGroups; t++) { for (v = 0; v < alphaSize; v++) { rfreq[t][v] = 0; } } nSelectors = 0; totc = 0; gs = 0; while (true) { /* Set group start & end marks. */ if (gs >= nMTF) { break; } ge = gs + G_SIZE - 1; if (ge >= nMTF) { ge = nMTF - 1; } /* Calculate the cost of this group as coded by each of the coding tables. */ for (t = 0; t < nGroups; t++) { cost[t] = 0; } if (nGroups == 6) { short cost0, cost1, cost2, cost3, cost4, cost5; cost0 = cost1 = cost2 = cost3 = cost4 = cost5 = 0; for (i = gs; i <= ge; i++) { short icv = szptr[i]; cost0 += len[0][icv]; cost1 += len[1][icv]; cost2 += len[2][icv]; cost3 += len[3][icv]; cost4 += len[4][icv]; cost5 += len[5][icv]; } cost[0] = cost0; cost[1] = cost1; cost[2] = cost2; cost[3] = cost3; cost[4] = cost4; cost[5] = cost5; } else { for (i = gs; i <= ge; i++) { short icv = szptr[i]; for (t = 0; t < nGroups; t++) { cost[t] += len[t][icv]; } } } /* Find the coding table which is best for this group, and record its identity in the selector table. */ bc = 999999999; bt = -1; for (t = 0; t < nGroups; t++) { if (cost[t] < bc) { bc = cost[t]; bt = t; } }; totc += bc; fave[bt]++; selector[nSelectors] = (char) bt; nSelectors++; /* Increment the symbol frequencies for the selected table. */ for (i = gs; i <= ge; i++) { rfreq[bt][szptr[i]]++; } gs = ge + 1; } /* Recompute the tables based on the accumulated frequencies. */ for (t = 0; t < nGroups; t++) { hbMakeCodeLengths(len[t], rfreq[t], alphaSize, 20); } } rfreq = null; fave = null; cost = null; if (!(nGroups < 8)) { panic(); } if (!(nSelectors < 32768 && nSelectors <= (2 + (900000 / G_SIZE)))) { panic(); } /* Compute MTF values for the selectors. */ { char[] pos = new char[N_GROUPS]; char ll_i, tmp2, tmp; for (i = 0; i < nGroups; i++) { pos[i] = (char) i; } for (i = 0; i < nSelectors; i++) { ll_i = selector[i]; j = 0; tmp = pos[j]; while (ll_i != tmp) { j++; tmp2 = tmp; tmp = pos[j]; pos[j] = tmp2; } pos[0] = tmp; selectorMtf[i] = (char) j; } } int[][] code = new int[N_GROUPS][MAX_ALPHA_SIZE]; /* Assign actual codes for the tables. */ for (t = 0; t < nGroups; t++) { minLen = 32; maxLen = 0; for (i = 0; i < alphaSize; i++) { if (len[t][i] > maxLen) { maxLen = len[t][i]; } if (len[t][i] < minLen) { minLen = len[t][i]; } } if (maxLen > 20) { panic(); } if (minLen < 1) { panic(); } hbAssignCodes(code[t], len[t], minLen, maxLen, alphaSize); } /* Transmit the mapping table. */ { boolean[] inUse16 = new boolean[16]; for (i = 0; i < 16; i++) { inUse16[i] = false; for (j = 0; j < 16; j++) { if (inUse[i * 16 + j]) { inUse16[i] = true; } } } nBytes = bytesOut; for (i = 0; i < 16; i++) { if (inUse16[i]) { bsW(1, 1); } else { bsW(1, 0); } } for (i = 0; i < 16; i++) { if (inUse16[i]) { for (j = 0; j < 16; j++) { if (inUse[i * 16 + j]) { bsW(1, 1); } else { bsW(1, 0); } } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -