我编写了一个执行行程编码的程序。 在典型情况下,如果文本是
AAAAAABBCDEEEEGGHJ
运行长度编码将使它
A6B2C1D1E4G2H1J1
但它为每个非重复字符添加了额外的1。由于我用它压缩BMP文件,我想到放置一个标记“$”来表示重复字符的出现,(假设图像文件有大量的重复文本)。
所以它看起来像
$A6$B2CD$E4$G2HJ
对于当前示例,它的长度是相同的,但BMP文件有明显的区别。现在我的问题在于解码。因此,一些BMP文件在原始文件中具有模式$<char><num>
,即$I9
,因此在压缩文件中我也包含相同的文本。 $I9
但是,在解码时,它会将其视为重复的I,重复9次!所以它会产生错误的输出。我想知道的是我可以使用哪个符号来标记重复字符(运行)的开头,以便它不会与原始源冲突。
答案 0 :(得分:6)
为什么不将原始文件中的每个$
编码为压缩文件中的$$
?
和/或使用其他字符而不是$
- 一个在bmp文件中使用不多的字符。
另请注意,BMP格式在“图像数据和压缩”下有“内置”RLE压缩 - 在页面底部附近看here。
我不知道你正在使用你的程序,或者它只是用于学习,但如果你使用“官方”bmp方法,你的压缩图像在查看之前不需要解压缩。
答案 1 :(得分:2)
AAAAAABBCDEEEEGGHJ $ IIIIIIIII ==&gt; $ $ A6 $ B2CD E4 $ $$ G2HJ I9
如果数据中出现重复字符,请尝试在编码数据中插入额外的重复字符。然后,如果解码器看到双重复字符,它可以插入实际的重复字符
$ A6 $ B2CD $ E4 $ G2HJ $$ I9 ==&gt; AAAAAABBCDEEEEGGHJ $ IIIIIIIII
答案 2 :(得分:1)
大多数程序所做的是表示某些字符需要按字面意思对待它们是否具有已定义的转义序列。
例如,在regular expressions中,以下是特别定义的字符,通常具有含义:
^[].*+{}()$
是的,你有趣的美元符号字符在那里,通常意味着行尾。
因此,使用正则表达式的程序员必须做的是让字面上解释这些字符是他们需要将这些字符表示为转义序列。例如,要将 $ 解释为 $ ,而不是行尾,程序员将使用 \ $ ,其中是转义序列。(1)
在您的情况下,您可以将文字美元符号存储到压缩文件中 \ $ 。(2)
注意:grep颠倒了这个逻辑。
当您在BMP文件中运行 $ 时,将 $ 存储为 $$ 的上述解决方案会变得混乱。< / p>
答案 3 :(得分:1)
如果您能够在开始压缩之前能够扫描整个输入,那么您可以选择输入中最不频繁的值作为转义值。 例如,给定此输入:
AAAABBCCCCDDEEEEEEEFFG
您可以选择“G”作为转义值(如果它是符号集的一部分,则选择“H”)并采用约定,其中编码流的第一个字符是转义值。所以上面的字符串可能编码为:
GGA4BBGC4DDGE7FFGG
甚至更好:
HHA4BBHC4DDHE7FFG
请注意,编码两个相同值的“运行”是没有意义的,因为“压缩”版本(例如HD2)比未压缩版本(DD)更长。
希望有所帮助!
答案 4 :(得分:0)
如果我理解正确,问题是$既是标记重复的符号,也可以是'BMP'值?
如果是这样,你可以做的是标记一个双$('$$')字符来表示'$'字符不应该被视为重复,而应该被视为单个'$'。这当然意味着'$'编码成本很高(需要两个符号而不是1),但可以解决您的问题。
如果您想要运行'$'字符,则需要将其编码为: $$$ 5 - 意为'$'运行'$$'= $,'5' - 5次。
答案 5 :(得分:0)
老实说,如果他们想用它来压缩二进制数据,我不确定会有人使用基于文本的RLE。 BMP不是文本。
现在,因为在$
之后只读取一个字节,并且它被解释为从0到9的ascii数,所以此过程的运行长度范围为0到9,这意味着您只能压缩在需要写入新的游程长度标志之前,最多重复9次。毕竟,对于34的游程长度,$I34
和对于重复3的文字$I3
,4
+ 4
之间的差异无法区分。
如果相同的字节被解释为二进制值,它可以包含从0到 255 的值,从而在效率上产生大量差异
至于$
符号本身的转义,我建议要么总是将其视为重复至少1($$1
),或者更好的是,对整个事物进行不同的编码,运行长度值的顺序和交换的数据,因此代码变为$<length><data>
;然后,您可以使用$0
作为特殊符号来表示“只$
”。解压缩并在$
之后遇到0时,只需不要读取第三个字节。无论如何,运行长度0永远不会出现在压缩数据中,因此它可以被赋予特殊含义,但如果首先放置数据字节则这是无用的,因为它仍然与正常重复的长度相同。