public static IList <byte> MTF(IList <byte> bytes) { var mtf = new MoveToFront(bytes); var mtfResult = mtf.InverseTransform(); return(mtfResult); }
// Performs the Move To Front transform and Run Length Encoding[1] stages public void Encode() { var huffmanSymbolMap = new byte[256]; var symbolMTF = new MoveToFront(); int totalUniqueValues = 0; for (var i = 0; i < 256; i++) { if (bwtValuesInUse[i]) huffmanSymbolMap[i] = (byte) totalUniqueValues++; } int endOfBlockSymbol = totalUniqueValues + 1; int mtfIndex = 0; int repeatCount = 0; int totalRunAs = 0; int totalRunBs = 0; for (var i = 0; i < bwtLength; i++) { // Move To Front int mtfPosition = symbolMTF.ValueToFront(huffmanSymbolMap[bwtBlock[i] & 0xff]); // Run Length Encode if (mtfPosition == 0) { repeatCount++; } else { if (repeatCount > 0) { repeatCount--; while (true) { if ((repeatCount & 1) == 0) { mtfBlock[mtfIndex++] = RLE_SYMBOL_RUNA; totalRunAs++; } else { mtfBlock[mtfIndex++] = RLE_SYMBOL_RUNB; totalRunBs++; } if (repeatCount <= 1) break; repeatCount = (repeatCount - 2) >> 1; } repeatCount = 0; } mtfBlock[mtfIndex++] = (char) (mtfPosition + 1); mtfSymbolFrequencies[mtfPosition + 1]++; } } if (repeatCount > 0) { repeatCount--; while (true) { if ((repeatCount & 1) == 0) { mtfBlock[mtfIndex++] = RLE_SYMBOL_RUNA; totalRunAs++; } else { mtfBlock[mtfIndex++] = RLE_SYMBOL_RUNB; totalRunBs++; } if (repeatCount <= 1) break; repeatCount = (repeatCount - 2) >> 1; } } mtfBlock[mtfIndex] = (ushort)endOfBlockSymbol; mtfSymbolFrequencies[endOfBlockSymbol]++; mtfSymbolFrequencies[RLE_SYMBOL_RUNA] += totalRunAs; mtfSymbolFrequencies[RLE_SYMBOL_RUNB] += totalRunBs; this.MtfLength = mtfIndex + 1; this.MtfAlphabetSize = endOfBlockSymbol + 1; }