繁体   English   中英

在可以包含所有字节值的 RLE 算法中指示原始数据块的结尾

[英]Indicating the end of a raw data chunk in an RLE algorithm that can contain all byte values

我正在 C# 中编写一个 RLE 算法,它可以处理任何文件作为输入。 我采用的编码方法如下:

RLE 数据包包含 1 个字节的长度和 1 个字节的值。 例如,如果字节0xFF连续出现 3 次,则将0x03 0xFF写入文件。

如果将数据表示为原始数据会更有效,我使用0x00作为终止符。 这是有效的,因为数据包的长度永远不会为零。 如果我想将字节0x53 0x2C 0x01添加到我的压缩文件中,它将如下所示:

0x03 0xFF 0x00 0x53 0x2C 0x01

但是,当尝试切换回 RLE 数据包时会出现问题。 我不能像切换到原始数据那样使用字节作为终止符,因为从0x00 to 0xFF的任何字节值都可以在输入数据中,并且在解码字节时,解码器会将字节误解为终止符并破坏所有内容.

当它不能作为文件中的数据写入时,我该怎么做才能表明我必须切换回 RLE 数据包?

如果有帮助,这是我的代码:

private static void RunLengthEncode(ref byte[] bytes)
{
    // Create a list to store the bytes
    List<byte> output = new List<byte>();
    
    byte runLengthByte;
    int runLengthCounter = 0;

    // Set the RLE byte to the first byte in the array and increment the RLE counter
    runLengthByte = bytes[0];

    // For each byte in the input array...
    for (int i = 0; i < bytes.Length; i++)
    {
        if (runLengthByte == bytes[i] || runLengthCounter == 255)
        {
            runLengthCounter++;
        }
        else 
        {
            // RLE packets under 3 should be written as raw data to avoid increasing the file size
            if (runLengthCounter < 3)
            {
                // Add a 0x00 to indicate raw data
                output.Add(0x00);

                // Add the bytes that were skipped while counting the run length
                for (int j = i - runLengthCounter; j < i; j++)
                {
                    output.Add(bytes[j]);
                }
            }
            else
            {
                // Add 2 bytes, one for the number of bytes and one for the value
                output.Add((byte)runLengthCounter);
                output.Add(runLengthByte);
            }

            runLengthCounter = 1;
            runLengthByte = bytes[i];
        }
            
        // Add the last bytes to the list when finishing
        if (i == bytes.Length - 1)
        {
            // Add 2 bytes, one for the number of bytes and one for the value
            output.Add((byte)runLengthCounter);
            output.Add(runLengthByte);
        }
    }

    // Set the bytes to the RLE encoded data
    bytes = output.ToArray();
}

此外,如果您想发表评论并说 RLE 对二进制数据不是很有效,我知道事实并非如此。 这是我正在做的一个项目,目的是实施多种压缩以了解它们,而不是针对实际产品。

任何帮助,将不胜感激! 谢谢!

有许多方法可以明确编码游程长度。 一种简单的方法是,在解码时:如果您在一行中看到两个相等的字节,那么下一个字节是前两个字节之后该字节的重复计数。 即 0..255 次额外重复,因此编码运行 2..257。 (对 0 或 1 的运行进行编码没有意义。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM