/// <summary> /// Write the tree to output file /// </summary> /// <param name="blTree">The bl tree.</param> public void WriteTree(DeflateTree blTree) { for (int code = 0; code < MaxUsedCodes;) { // current code length int codeLen = _codeLength[code]; // scan the code array for equal code lengths int count = 1; for (code++; code < MaxUsedCodes && codeLen == _codeLength[code]; code++) { count++; } // less than three equal code length if (count < 3) { // write the first code length to output file blTree.WriteSymbol(codeLen); // write the second code length to output file if (count > 1) { blTree.WriteSymbol(codeLen); } continue; } // Used code. Code length is other than zero. if (codeLen != 0) { // write the code length to output file blTree.WriteSymbol(codeLen); // reduce the count by one count--; // for every full block of 6 repeats add one REP_3_6 code and two bits of 1 (11) for (int index = count / 6; index > 0; index--) { blTree.WriteSymbol(RepeatSymbol_3_6); _writeBits(6 - 3, 2); } // get the remainder if ((count = count % 6) == 0) { continue; } // remainder is less than 3 if (count < 3) { // write the code length to output file blTree.WriteSymbol(codeLen); if (count > 1) { blTree.WriteSymbol(codeLen); } continue; } // remainder is beween 3 to 5 blTree.WriteSymbol(RepeatSymbol_3_6); _writeBits(count - 3, 2); continue; } // code length is zero and count is 3 or more // for every full block of 138 repeats add one REP_11_138 code plus 7 bits of 1 for (int index = count / 138; index > 0; index--) { blTree.WriteSymbol(RepeatSymbol_11_138); _writeBits(138 - 11, 7); } // get the remainder if ((count = count % 138) == 0) { continue; } // remainder is less than 3 if (count < 3) { // write the code length to output file blTree.WriteSymbol(codeLen); if (count > 1) { blTree.WriteSymbol(codeLen); } continue; } // remainder is beween 3 to 10 if (count <= 10) { blTree.WriteSymbol(RepeatSymbol_3_10); _writeBits(count - 3, 3); continue; } // remainder is beween 11 to 137 blTree.WriteSymbol(RepeatSymbol_11_138); _writeBits(count - 11, 7); } }
//////////////////////////////////////////////////////////////////// // calculate Bit Length frequency /// 0 - 15: Represent code lengths of 0 - 15 // 16: Copy the previous code length 3 - 6 times. // The next 2 bits indicate repeat length // (0 = 3, ... , 3 = 6) // Example: Codes 8, 16 (+2 bits 11), 16 (+2 bits 10) will expand to // 12 code lengths of 8 (1 + 6 + 5) // 17: Repeat a code length of 0 for 3 - 10 times. (3 bits of length) // 18: Repeat a code length of 0 for 11 - 138 times. (7 bits of length) //////////////////////////////////////////////////////////////////// public Int32 CalcBLFreq(DeflateTree blTree) { int extraBits = 0; for (int code = 0; code < MaxUsedCodes;) { // current code length int codeLen = _codeLength[code]; // scan the code array for equal code lengths int count = 1; for (code++; code < MaxUsedCodes && codeLen == _codeLength[code]; code++) { count++; } // less than three equal code length if (count < 3) { blTree.CodeFreq[codeLen] += (short)count; continue; } // code length is other than zero if (codeLen != 0) { // add one to the frequency of the code itself blTree.CodeFreq[codeLen]++; // reduce the count by one count--; // for every full block of 6 repeats add one REP_3_6 code blTree.CodeFreq[RepeatSymbol_3_6] += count / 6; extraBits += 2 * (count / 6); // get the remainder if ((count = count % 6) == 0) { continue; } // remainder is less than 3 if (count < 3) { blTree.CodeFreq[codeLen] += count; continue; } // remainder is beween 3 to 5 blTree.CodeFreq[RepeatSymbol_3_6]++; extraBits += 2; continue; } // code length is zero and count is 3 or more // for every full block of 138 repeats add one REP_11_138 code blTree.CodeFreq[RepeatSymbol_11_138] += count / 138; extraBits += 7 * (count / 138); // get the remainder if ((count = count % 138) == 0) { continue; } // remainder is less than 3 if (count < 3) { blTree.CodeFreq[codeLen] += count; continue; } // remainder is beween 3 to 10 if (count <= 10) { blTree.CodeFreq[RepeatSymbol_3_10]++; extraBits += 3; continue; } // remainder is beween 11 to 137 blTree.CodeFreq[RepeatSymbol_11_138]++; extraBits += 7; } return(extraBits); }