📄 chap09.htm
字号:
style='font-family:宋体;"Times New Roman"'>将文件指针指向图象数据的开始处</span></p>
<p style='line-height:18.0pt'><span> </span>fseek(PCXfp,(LONG)sizeof(PCXHEAD),SEEK_SET);</p>
<p style='line-height:18.0pt'><span> </span>//<span
style='font-family:宋体;"Times New Roman"'>缓冲区大小</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>//BufSize</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>为缓冲区大小</span></p>
<p style='line-height:18.0pt'><span> </span>BufSize=OffBits+bi.biHeight*LineBytes;</p>
<p style='line-height:18.0pt'><span> </span>for(y=0;y<bi.biHeight;y++){</p>
<p style='line-height:18.0pt'><span>
</span>//<span
style='font-family:宋体;"Times New Roman"'>指向新图中相应的位置</span></p>
<p style='line-height:18.0pt'><span>
</span>lpPtr=(char *)lpImgData+BufSize-LineBytes-y*LineBytes;</p>
<p style='line-height:18.0pt'><span>
</span>//<span
style='font-family:宋体;"Times New Roman"'>解码该行,放在数组</span><span lang=EN-US>LineBuffer</span><span
style='font-family:宋体;"Times New Roman"'>中</span></p>
<p style='line-height:18.0pt'><span>
</span>ReadPcxLine(LineBuffer,PCXfp);</p>
<p style='line-height:18.0pt'><span>
</span>for(x=0;x<bi.biWidth;x++)</p>
<p style='line-height:18.0pt'><span>
</span>*(lpPtr++)=LineBuffer[x]; //<span style='font-family:宋体;
"Times New Roman"'>将该行存储到位图数据中</span></p>
<p style='line-height:18.0pt'><span> </span>}</p>
<p style='line-height:18.0pt'><span> </span>//<span
style='font-family:宋体;"Times New Roman"'>创建新的位图</span></p>
<p style='line-height:18.0pt'><span> </span>hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpImgData,</p>
<p style='line-height:
18.0pt'><span lang=EN-US>(LONG)CBM_INIT,</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>(LPSTR)lpImgData+</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>sizeof(BITMAPINFOHEADER)+</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>NumColors*sizeof(RGBQUAD),</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>(LPBITMAPINFO)lpImgData,</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>DIB_RGB_COLORS);</span></p>
<p style='line-height:18.0pt'><span> </span>if(hPalette
&& hPrevPalette){</p>
<p style='line-height:18.0pt'><span>
</span>SelectPalette(hDc,hPrevPalette,FALSE);</p>
<p style='line-height:18.0pt'><span>
</span>RealizePalette(hDc);</p>
<p style='line-height:18.0pt'><span> </span>}</p>
<p style='line-height:18.0pt'><span> </span>hfbmp=_lcreat("c:\\pcx2bmp.bmp",0);</p>
<p style='line-height:18.0pt'><span> </span>_lwrite(hfbmp,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));
</p>
<p style='line-height:18.0pt'><span> </span>_lwrite(hfbmp,(LPSTR)lpImgData,BufSize);</p>
<p style='line-height:18.0pt'><span> </span>_lclose(hfbmp);</p>
<p style='line-height:18.0pt'><span> </span>fclose(PCXfp);
</p>
<p style='line-height:18.0pt'><span> </span>//<span
style='font-family:宋体;"Times New Roman"'>释放内存和资源</span></p>
<p style='line-height:18.0pt'><span> </span>ReleaseDC(hWnd,hDc);</p>
<p style='line-height:18.0pt'><span> </span>GlobalUnlock(hImgData);</p>
<p style='line-height:18.0pt'><span> </span>return
TRUE; </p>
<p style='line-height:18.0pt'><span lang=EN-US>}</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>//</span><span
style='font-family:宋体;"Times New Roman"'>对每一行进行解码,结果存储到指针</span><span lang=EN-US>p</span><span
style='font-family:宋体;"Times New Roman"'>指向的内存中</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>void ReadPcxLine(unsigned char
*p,FILE *fp)</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>{</span></p>
<p style='line-height:18.0pt'><span> </span>unsigned
int n=0,i;</p>
<p style='line-height:18.0pt'><span> </span>char
c;</p>
<p style='line-height:18.0pt'><span> </span>memset(p,0,PcxBytesPerLine);</p>
<p style='line-height:18.0pt'><span> </span>do{</p>
<p style='line-height:18.0pt'><span>
</span>//<span
style='font-family:宋体;"Times New Roman"'>读出一个字节</span></p>
<p style='line-height:18.0pt'><span>
</span>c=fgetc(fp)&0xff;</p>
<p style='line-height:
18.0pt'><span lang=EN-US>if((c&0xc0)==0xc0){ //</span><span
style='font-family:宋体;"Times New Roman"'>是个形成字节</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>//i</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></p>
<p style='line-height:
18.0pt'><span lang=EN-US>i=c&0x3f;</span></p>
<p style='line-height:18.0pt'><span>
</span>//<span
style='font-family:宋体;"Times New Roman"'>下一个字节为实际的图象数据</span></p>
<p style='line-height:18.0pt'><span>
</span>c=fgetc(fp);</p>
<p style='line-height:18.0pt'><span>
</span>while(i--) p[n++]=c; //<span style='font-family:宋体;
"Times New Roman"'>填充连续的</span><span lang=EN-US>i</span><span
style='font-family:宋体;"Times New Roman"'>个字节到</span><span lang=EN-US>p</span><span style='font-family:
宋体;"Times New Roman"'>中</span></p>
<p style='line-height:18.0pt'><span>
</span>}</p>
<p style='line-height:18.0pt'><span>
</span>else p[n++]=c; //<span style='font-family:宋体;
"Times New Roman"'>否则是实际的图象数据,直接填入到</span><span
lang=EN-US>p</span><span style='font-family:宋体;
"Times New Roman"'>中</span></p>
<p style='line-height:18.0pt'><span> </span>}while
(n<PcxBytesPerLine); //<span style='font-family:宋体;"Times New Roman";"Times New Roman"'>共读取</span><span
lang=EN-US>PcxBytesPerLine</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>个字节</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>}</span></p>
<p style='line-height:18.0pt'><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>9.2</span><span style='font-family:宋体;
"Times New Roman"'>所示。显示的是我最喜欢的法国影星阿佳妮·伊莎贝拉。</span></p>
<p align=center style='text-align:center;line-height:18.0pt'><span
lang=EN-US> <img width=263 height=337
src="chap09.files/image002.gif" v:shapes="_x0000_i1026"> </span></p>
<p align=center style='text-align:center;line-height:18.0pt'><b><span
style='font-family:宋体;"Times New Roman"'>图</span>9.2 </b><b><span
style='font-family:宋体;"Times New Roman"'>一幅</span><span lang=EN-US>PCX</span></b><b><span
style='font-family:宋体;"Times New Roman"'>文件格式的图象</span><span lang=EN-US></span></b></p>
<h2> <span
lang=EN-US>9.3</span> <a name="_Toc486331910"></a><a
name="_Toc486332910"></a><a name="_Toc486339019"></a><a name="_Toc454810884"></a><a
name="_Toc454856658"><span><span>LZW</span></span></a><span><span><span style='font-family:黑体;'>算法的大体思想</span></span></span></h2>
<p style='line-height:18.0pt'><span lang=EN-US>LZW</span><span
style='font-family:宋体;"Times New Roman"'>是一种比较复杂的压缩算法,其压缩效率也比较高。我们在这里只介绍一下它的基本原理:</span><span
lang=EN-US>LZW</span><span style='font-family:宋体;
"Times New Roman"'>把每一个第一次出现的字符串用一个数值来编码,在还原程序中再将这个数值还成原来的字符串。例如:用数值</span><span
lang=EN-US>0x100</span><span style='font-family:宋体;
"Times New Roman"'>代替字符串“</span><span lang=EN-US>abccddeee</span><span
style='font-family:宋体;"Times New Roman"'>”,每当出现该字符串时,都用</span><span lang=EN-US>0x100</span><span
style='font-family:宋体;"Times New Roman"'>代替,这样就起到了压缩的作用。至于</span><span lang=EN-US>0x100</span><span
style='font-family:宋体;"Times New Roman"'>与字符串的对应关系则是在压缩过程中动态生成的,而且这种对应关系隐含在压缩数据中,随着解压缩的进行这张编码表会从压缩数据中逐步得到恢复,后面的压缩数据再根据前面数据产生的对应关系产生更多的对应关系,直到压缩文件结束为止。</span><span
lang=EN-US>LZW</span><span style='font-family:宋体;
"Times New Roman"'>是无损的。</span><span lang=EN-US>GIF</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>LZW</span><span style='font-family:宋体;
"Times New Roman"'>算法由</span><span lang=EN-US>Unisys</span><span
style='font-family:宋体;"Times New Roman"'>公司在美国申请了专利,要使用它首先要获得该公司的认可。</span></p>
<h2> <span
lang=EN-US>9.4</span> <a name="_Toc486331911"></a><a
name="_Toc486332911"></a><a name="_Toc486339020"></a><a name="_Toc454810885"></a><a
name="_Toc454856659"><span><span>JPEG</span></span></a><span><span><span style='font-family:黑体;'>压缩编码标准</span></span></span></h2>
<p style='line-height:18.0pt'><span lang=EN-US>JPEG</span><span
style='font-family:宋体;"Times New Roman"'>是联合图象专家组</span><span lang=EN-US>(Joint
Picture Expert Group)</span><span
style='font-family:宋体;"Times New Roman"'>的英文缩写,是国际标准化组织</span><span lang=EN-US>(ISO)</span><sp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -