예제 #1
0
        static public void HandleLzRle(byte[] Input, int StartPosition, int MinLzLength, int MaxLzLength, int MaxLzDistance, int MinRleLength, int MaxRleLength, bool AllowOverlapping, Action <int, byte> ByteCallback, Action <int, int, int> LzCallback, Action <int, byte, int> RleCallback)
        {
            bool UseRle = (RleCallback != null) && (MaxRleLength > 0);

            var LzMatcher  = new LzMatcher(Input, StartPosition, MaxLzDistance, MinLzLength, MaxLzLength, AllowOverlapping);
            var RleMatcher = UseRle ? new RleMatcher(Input, StartPosition) : null;

            for (int n = StartPosition; n < Input.Length;)
            {
                //Console.WriteLine("{0}", n);
                var Result = LzMatcher.FindMaxSequence();

                int RleLength = -1;

                if (UseRle)
                {
                    RleLength = RleMatcher.Length;
                    if (RleLength < MinRleLength)
                    {
                        RleLength = 0;
                    }
                    if (RleLength > MaxRleLength)
                    {
                        RleLength = MaxRleLength;
                    }
                }

                if (Result.Found && (!UseRle || (Result.Size > RleLength)))
                {
                    //Console.WriteLine("RLE: {0}", RleLength);
                    LzCallback(n, Result.Offset - n, Result.Size);
                    n += Result.Size;
                    LzMatcher.Skip(Result.Size);
                    //Console.WriteLine(Result.Size);
                    if (UseRle)
                    {
                        RleMatcher.Skip(Result.Size);
                    }
                    continue;
                }

                if (UseRle && (RleLength >= MinRleLength))
                {
                    RleCallback(n, Input[n], RleLength);
                    n += RleLength;
                    //Console.WriteLine(RleLength);
                    LzMatcher.Skip(RleLength);
                    RleMatcher.Skip(RleLength);
                    continue;
                }

                ByteCallback(n, Input[n]);
                n += 1;
                LzMatcher.Skip(1);
                if (UseRle)
                {
                    RleMatcher.Skip(1);
                }
            }
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="input"></param>
        /// <param name="startPosition"></param>
        /// <param name="minLzLength"></param>
        /// <param name="maxLzLength"></param>
        /// <param name="maxLzDistance"></param>
        /// <param name="minRleLength"></param>
        /// <param name="maxRleLength"></param>
        /// <param name="allowOverlapping"></param>
        /// <param name="byteCallback"></param>
        /// <param name="lzCallback"></param>
        /// <param name="rleCallback"></param>
        public static void HandleLzRle(byte[] input, int startPosition, int minLzLength, int maxLzLength,
                                       int maxLzDistance, int minRleLength, int maxRleLength, bool allowOverlapping,
                                       Action <int, byte> byteCallback, Action <int, int, int> lzCallback, Action <int, byte, int> rleCallback)
        {
            var useRle = (rleCallback != null) && (maxRleLength > 0);

            var lzMatcher = new LzMatcher(input, startPosition, maxLzDistance, minLzLength, maxLzLength,
                                          allowOverlapping);
            var rleMatcher = useRle ? new RleMatcher(input, startPosition) : null;

            for (var n = startPosition; n < input.Length;)
            {
                //Console.WriteLine("{0}", n);
                var result = lzMatcher.FindMaxSequence();

                var rleLength = -1;

                if (useRle)
                {
                    rleLength = rleMatcher.Length;
                    if (rleLength < minRleLength)
                    {
                        rleLength = 0;
                    }
                    if (rleLength > maxRleLength)
                    {
                        rleLength = maxRleLength;
                    }
                }

                if (result.Found && (!useRle || (result.Size > rleLength)))
                {
                    //Console.WriteLine("RLE: {0}", RleLength);
                    lzCallback(n, result.Offset - n, result.Size);
                    n += result.Size;
                    lzMatcher.Skip(result.Size);
                    //Console.WriteLine(Result.Size);
                    if (useRle)
                    {
                        rleMatcher.Skip(result.Size);
                    }
                    continue;
                }

                if (useRle && (rleLength >= minRleLength))
                {
                    rleCallback(n, input[n], rleLength);
                    n += rleLength;
                    //Console.WriteLine(RleLength);
                    lzMatcher.Skip(rleLength);
                    rleMatcher.Skip(rleLength);
                    continue;
                }

                byteCallback(n, input[n]);
                n += 1;
                lzMatcher.Skip();
                if (useRle)
                {
                    rleMatcher.Skip();
                }
            }
        }