📄 chap09.htm
字号:
lang=EN-US>9.2</span> <span lang=EN-US> </span><a name="_Toc486331909"></a><a
name="_Toc486332909"></a><a name="_Toc486339018"></a><a name="_Toc454810883"></a><a
name="_Toc454856657"><span><span>行程编码</span></span></a></h2>
<p style='line-height:18.0pt'><span style='font-family:宋体;
"Times New Roman"'>行程编码</span><span
lang=EN-US>(Run Length Coding)</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>的原理也很简单:将一行中颜色值相同的相邻象素用一个计数值和该颜色值来代替。例如</span><span
lang=EN-US>aaabccccccddeee</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>可以表示为</span><span
lang=EN-US>3a1b6c2d3e</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>。如果一幅图象是由很多块颜色相同的大面积区域组成,那么采用行程编码的压缩效率是惊人的。然而,该算法也导致了一个致命弱点,如果图象中每两个相邻点的颜色都不同,用这种算法不但不能压缩,反而数据量增加一倍。所以现在单纯采用行程编码的压缩算法用得并不多,</span><span
lang=EN-US>PCX</span><span style='font-family:宋体;
"Times New Roman"'>文件算是其中的一种。</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>PCX</span><span
style='font-family:宋体;"Times New Roman"'>文件最早是</span><span lang=EN-US>PC Paintbrush</span><span
style='font-family:宋体;"Times New Roman"'>软件所采用的一种文件格式,由于压缩比不高,现在用的并不是很多了。它也是由头信息、调色板、实际的图象数据三个部分组成。其中头信息的结构为:</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>typedef struct{</span></p>
<p style='line-height:18.0pt'><span>
</span> char manufacturer;</p>
<p style='line-height:18.0pt'><span>
</span> char version;</p>
<p style='line-height:18.0pt'><span>
</span> char encoding;</p>
<p style='line-height:18.0pt'><span>
</span> char bits_per_pixel;</p>
<p style='line-height:18.0pt'><span>
</span> WORD xmin,ymin;</p>
<p style='line-height:18.0pt'><span>
</span> WORD xmax,ymax;</p>
<p style='line-height:18.0pt'><span>
</span> WORD hres;</p>
<p style='line-height:18.0pt'><span>
</span> WORD vres;</p>
<p style='line-height:18.0pt'><span>
</span> char palette[48];</p>
<p style='line-height:18.0pt'><span>
</span> char reserved;</p>
<p style='line-height:18.0pt'><span>
</span> char colour_planes;</p>
<p style='line-height:18.0pt'><span>
</span> WORD bytes_per_line;</p>
<p style='line-height:18.0pt'><span>
</span> WORD palette_type;</p>
<p style='line-height:18.0pt'><span>
</span> char filler[58];</p>
<p style='line-height:18.0pt'><span> </span>}
PCXHEAD;</p>
<p style='line-height:18.0pt'><span style='font-family:宋体;
"Times New Roman"'>其中值得注意的是以下几个数据:</span><span
lang=EN-US>manufacturer</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>为</span><span
lang=EN-US>PCX</span><span style='font-family:宋体;
"Times New Roman"'>文件的标识,必须为</span><span lang=EN-US>0x0a</span><span
style='font-family:宋体;"Times New Roman"'>;</span><span lang=EN-US>xmin</span><span style='font-family:
宋体;"Times New Roman"'>为最小的</span><span
lang=EN-US>x</span><span style='font-family:宋体;
"Times New Roman"'>坐标,</span><span lang=EN-US>xmax</span><span
style='font-family:宋体;"Times New Roman"'>最大的</span><span lang=EN-US>x</span><span style='font-family:
宋体;"Times New Roman"'>坐标,所以图象的宽度为</span><span
lang=EN-US>xmax-xmin+1</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>,同样图象的高度为</span><span
lang=EN-US>ymax-yin+1</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>;</span><span
lang=EN-US>bytes_per_line</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>为每个编码行所占的字节数,下面将详细介绍。</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>PCX</span><span
style='font-family:宋体;"Times New Roman"'>的调色板在文件的最后。以</span><span lang=EN-US>256</span><span
style='font-family:宋体;"Times New Roman"'>色</span><span lang=EN-US>PCX</span><span style='font-family:
宋体;"Times New Roman"'>文件为例,倒数第</span><span
lang=EN-US>769</span><span style='font-family:宋体;
"Times New Roman"'>个字节为颜色数的标识,</span><span lang=EN-US>256</span><span
style='font-family:宋体;"Times New Roman"'>时该字节必须为</span><span lang=EN-US>12</span><span
style='font-family:宋体;"Times New Roman"'>,剩下的</span><span lang=EN-US>768(256</span><span
style='font-family:宋体;"Times New Roman"'>×</span><span lang=EN-US>3)</span><span style='font-family:
宋体;"Times New Roman"'>为调色板的</span><span
lang=EN-US>RGB</span><span style='font-family:宋体;
"Times New Roman"'>值。</span></p>
<p style='line-height:18.0pt'><span style='font-family:宋体;
"Times New Roman"'>为了叙述方便,我们针对</span><span
lang=EN-US>256</span><span style='font-family:宋体;
"Times New Roman"'>色</span><span lang=EN-US>PCX</span><span
style='font-family:宋体;"Times New Roman"'>文件,介绍一下它的解码过程。编码是解码的逆过程,有兴趣的读者可以试着自己来完成。</span></p>
<p style='line-height:18.0pt'><span style='font-family:宋体;
"Times New Roman"'>解码是以行为单位的,该行所占的字节数由</span><span
lang=EN-US>bytes_per_line</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>给定。为此,我们开一个大小为</span><span
lang=EN-US>bytes_per_line</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>的解码缓冲区。一开始,将缓冲区的所有内容清零。从文件中读出一个字节</span><span
lang=EN-US>C</span><span style='font-family:宋体;
"Times New Roman"'>,若</span><span lang=EN-US>C>0xc0</span><span
style='font-family:宋体;"Times New Roman"'>,说明是行程</span><span lang=EN-US>(Run Length)</span><span
style='font-family:宋体;"Times New Roman"'>信息,即</span><span lang=EN-US>C</span><span style='font-family:
宋体;"Times New Roman"'>的低</span><span
lang=EN-US>6</span><span style='font-family:宋体;
"Times New Roman"'>位表示后面连续的字节个数</span><span lang=EN-US>(</span><span
style='font-family:宋体;"Times New Roman"'>所以最多</span><span lang=EN-US>63</span><span style='font-family:
宋体;"Times New Roman"'>个连续颜色相同的象素,若还有颜色相同的象素,将在下一个行程处理</span><span
lang=EN-US>)</span><span style='font-family:宋体;
"Times New Roman"'>,文件的下一个字节就是实际的图象数据</span><span
lang=EN-US>(</span><span style='font-family:宋体;
"Times New Roman"'>即该颜色在调色板中的索引值</span><span lang=EN-US>)</span><span
style='font-family:宋体;"Times New Roman"'>。若</span><span lang=EN-US>C<0xc0</span><span
style='font-family:宋体;"Times New Roman"'>,则表示</span><span lang=EN-US>C</span><span style='font-family:
宋体;"Times New Roman"'>是实际的图象数据。如此反复,直到这</span><span
lang=EN-US>bytes_per_line</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>个字节处理完,这一行的解码完成。</span><span
lang=EN-US>PCX</span><span style='font-family:宋体;
"Times New Roman"'>就是有若干个这样的解码行组成。</span></p>
<p style='line-height:18.0pt'><span style='font-family:宋体;
"Times New Roman"'>下面是实现</span><span
lang=EN-US>256</span><span style='font-family:宋体;
"Times New Roman"'>色</span><span lang=EN-US>PCX</span><span
style='font-family:宋体;"Times New Roman"'>文件解码的源程序,其中第二个函数对一行进行解码,应该把阅读的重点放在这个函数上。要注意的是,执行时文件</span><span
lang=EN-US>C:\\test.pcx</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>必须存在,而且是一个</span><span
lang=EN-US>256</span><span style='font-family:宋体;
"Times New Roman"'>色</span><span lang=EN-US>PCX</span><span
style='font-family:宋体;"Times New Roman"'>文件。</span></p>
<p style='line-height:18.0pt'>unsigned int PcxBytesPerLine;</p>
<p style='line-height:18.0pt'><span lang=EN-US>BOOL LoadPcxFile (HWND hWnd,char
*PcxFileName)</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>{</span></p>
<p style='line-height:18.0pt'><span> </span>FILE
*PCXfp;</p>
<p style='line-height:18.0pt'><span> </span>PCXHEAD
header;</p>
<p style='line-height:18.0pt'><span> </span> LOGPALETTE
*pPal;</p>
<p style='line-height:18.0pt'><span> </span> HPALETTE
hPrevPalette; </p>
<p style='line-height:18.0pt'><span> </span> HDC
hDc;</p>
<p style='line-height:18.0pt'><span> </span>HLOCAL
hPal;</p>
<p style='line-height:18.0pt'><span> </span>DWORD
ImgSize;</p>
<p style='line-height:18.0pt'><span> </span>DWORD
OffBits,BufSize;</p>
<p style='line-height:18.0pt'><span> </span>LPBITMAPINFOHEADER
lpImgData; </p>
<p style='line-height:18.0pt'><span> </span>DWORD
i;</p>
<p style='line-height:18.0pt'><span> </span>LONG
x,y;</p>
<p style='line-height:18.0pt'><span> </span>int
PcxTag;</p>
<p style='line-height:18.0pt'><span> </span>unsigned
char
LineBuffer[6400];</p>
<p style='line-height:18.0pt'><span> </span>LPSTR
lpPtr;</p>
<p style='line-height:18.0pt'><span> </span>HFILE
hfbmp;</p>
<p style='line-height:18.0pt'><span
lang=EN-US>if((PCXfp=fopen(PcxFileName,"rb"))==NULL){ //</span><span
style='font-family:宋体;"Times New Roman"'>文件没有找到</span></p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -