Beispiel #1
0
        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;
        }