C# 创建用于解压缩面向字节的RLE映像的代码

C# 创建用于解压缩面向字节的RLE映像的代码,c#,postscript,image-compression,run-length-encoding,C#,Postscript,Image Compression,Run Length Encoding,我试图创建一个代码,从PostScript文件中解压一个面向RLE字节的图像,我已经尝试了在web上找到的解决方案,也尝试了构建自己的解决方案;但是没有一个能产生我需要的结果 解压rle图像后,我应该有一个原始图像,可以在photoshop上打开,告知宽度、高度和通道数。但是,当我试图打开提取的图像时,它不起作用;仅显示黑色输出 我的输入是一个二进制ASCII编码文件,编码为十六进制字符串和一个二进制文件;在十六进制文件的情况下,这两种RLE都是面向字节的压缩,只是在尝试RLE解压缩之前将其转换

我试图创建一个代码,从PostScript文件中解压一个面向RLE字节的图像,我已经尝试了在web上找到的解决方案,也尝试了构建自己的解决方案;但是没有一个能产生我需要的结果

解压rle图像后,我应该有一个原始图像,可以在photoshop上打开,告知宽度、高度和通道数。但是,当我试图打开提取的图像时,它不起作用;仅显示黑色输出

我的输入是一个二进制ASCII编码文件,编码为十六进制字符串和一个二进制文件;在十六进制文件的情况下,这两种RLE都是面向字节的压缩,只是在尝试RLE解压缩之前将其转换为字节的问题

我已经把样品寄到这里了

WorkingSample.raw->我用另一个软件得到的图像样本,以及它的尺寸

MySample.raw->我使用代码构建的图像示例,以及它的维度

OriginalFile.ppf->包含原始图像数据和其他所有内容的文件

ExtractedBinary.bin->仅来自OriginalFile.ppf的二进制部分-更易于读取和处理数据

此代码由用户nyerguds提供,他是SO社区的一部分。 原始资料来源: 这是我尝试使用的,但结果不正确。老实说,我很难理解他的代码,他让我改变一些事情,以便使它在我的情况下工作,但我不能

下面是我在附言红皮书之后尝试做的事情: 书: 该部分: RunLengthCode筛选器根据运行长度以简单的面向字节的格式对数据进行编码。 压缩数据格式是一个运行序列,其中每个运行由一个长度字节和1到128字节的数据组成。如果长度字节在0到127的范围内,则在解压缩时将按字面复制以下长度+1字节1到128字节。如果长度在129到255之间,则以下单个字节将在解压缩时复制257-长度乘以2到128次。 第142页,运行代码过滤器

List<byte> final = new List<byte>();
                var split01 = ArraySplit(bytefile, 2);
                foreach (var binPart in split01)
                {                    
                    try
                    {
                        if (binPart.ElementAt(0) <= 127)
                        {
                            int currLen = binPart[0] + 1;
                            for (int i = 0; i <= binPart[0]; i++)
                            {
                                final.Add(binPart[1]);
                                //Console.WriteLine(binPart[1]);
                            }
                        }
                        else if (binPart[0] >= 128)
                        {
                            int currLen = 257 - binPart[0];
                            for (int i = 0; i < currLen; i++)
                            {
                                final.Add(binPart[1]);
                                // Console.WriteLine(binPart[1]);
                            }
                        }
                    }
                    catch(Exception)
                    {
                        break;
                    }


                }

                File.WriteAllBytes(@"C:\test\again.raw", final.ToArray());

 private static IEnumerable<byte[]> ArraySplit(byte[] bArray, int intBufforLengt)
        {
            int bArrayLenght = bArray.Length;
            byte[] bReturn = null;

            int i = 0;
            for (; bArrayLenght > (i + 1) * intBufforLengt; i++)
            {
                bReturn = new byte[intBufforLengt];
                Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLengt);
                yield return bReturn;
            }

            int intBufforLeft = bArrayLenght - i * intBufforLengt;
            if (intBufforLeft > 0)
            {
                bReturn = new byte[intBufforLeft];
                Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLeft);
                yield return bReturn;
            }
        }

  private static byte[] StringToByteArray(String hex)
        {
            int iValue = 0;
            int NumberChars = hex.Length;
            if (NumberChars % 2 != 0)
            {
                string m = string.Empty;
            }
            byte[] bytes = new byte[NumberChars / 2];
            try
            {

                for (int i = 0; i < NumberChars; i += 2)
                {
                    bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
                    iValue = i;
                }

            }
            catch (Exception e)
            {
                var value = iValue;
                Console.WriteLine(e.Message);
            }


            return bytes;
        }
所需的输出将是TIFF灰度。不过,我也可以处理PNG。 我已经设法从这种文件中提取了未压缩的数据;使用EMV包装器,我能够创建一个可视的图像,并在上面执行我的逻辑

我的RLE压缩的实际结果只是无效的原始文件,即使在photoshop或IrfanViewer上也无法查看

欢迎您的任何意见。谢谢

EDIT1:卡在这个零件上

for(int i=0; i < bytefile.Length; i+=2)
            {
                try
                {
                    var lengthByte = bytefile[i];
                    if (lengthByte <= 127)
                    {
                        int currLen = lengthByte + 1;
                        for (int j = 0; j < currLen; j++)
                        {
                            final.Add(bytefile[i]);
                            i++;
                        }

                    }
                    if (bytefile[i] >= 128)
                    {
                        int currLen = 257 - bytefile[i];
                        for (int k = 0; k < currLen; k++)
                        {
                            final.Add(bytefile[i + 1]);
                        }
                    }
                }
                catch(Exception)
                {
                    break;
                }          
            }

这就是我遵循的逻辑。在它引发异常之前,我发现这是因为我忘记添加结束字节;最终结果没有差别。

虽然没有明确说明,但我相信您正在尝试从Postscript文件中提取运行长度编码的图像,并将其保存为灰度TIFF

作为这样的起点,您是否尝试过简单地将Postscript文件中未压缩的图像保存为灰度TIFF,以确保负责构建TIFF图像数据的应用程序逻辑确实按照预期工作?我要提醒大家,在开始支持解压RLE数据并将其转化为TIFF之前,这将是一个很好的第一步


我认为这一点很重要的原因是,您的问题可能与如何解压缩RLE数据无关,而与如何根据假定正确解码的数据创建输出TIFF无关。

尝试以下基本要点:

int i = 0;
while (i < bytefile.length)    
{
    var lengthByte = bytefile[i++];
    if (lengthByte <= 127)
    {
        int currLen = lengthByte + 1;
        for (int j = 0; j < currLen; j++)
            final.Add(bytefile[i++]);
    }
    else
    {
        int currLen = 257 - lengthByte;
        byte byteToCopy = bytefile[i++];
        for (int j = 0; j < currLen; j++)
            final.Add(byteToCopy);
    }
}

无论如何,这就是我如何理解上面指定的内容。

您好。是的。它起作用了,我能够使用EMV包装器创建TIFF。我现在编辑问题并添加当前进度。我编辑了问题并添加了信息。就像我说的,从未压缩的数据创建图像的逻辑很好;没有问题。我的问题是RLE压缩。我只提取了原始图像的一部分,但其中的一部分只有黑色模糊,就像丢失了数据一样。在十六进制编辑器上分析文件时,我可以看到很多零,我应该在这里有一些数据。你没有在那里复制未压缩的字节,只有binPart[1]-不应该是binPart[i+1]或类似的东西吗?这是我对解释的理解。。。也许我的英语理解能力不好?不知道我的英语很好,但我真的很困惑。。。如果长度字节>=128,我必须复制以下字节257-length次。这部分我做得很好。也许我对第一部分有点困惑。让我在这里试试。从上面复制:如果长度字节在0到127的范围内,那么在解压时将从字面上复制以下长度+1字节1到128字节-注意我的重点。考虑到长度字节是5。我必须复制下六个5+1字节,然后继续下一个循环迭代?差不多。复制接下来的5个字节[1]到[6]
,然后为下一个循环迭代将下一个读取索引设置为7。我认为你的第二个curren是错误的。它只有257个字节,仅此而已。我改变了这一行,使图像正常工作。我会尝试更多的安瓿,但嘿-谢谢!5天后,我取得了一些进展。似乎我已经接近这个了…只是一个问题:我没有看到你在任何地方更新i的值。代码停止是因为我添加了一个exception子句,当它超出范围时将其中断。我在bytefile中获取它的增量?I++在它被递增之前递增I并返回它的值。