簡體   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