行程編碼(run length coding)的原理也很簡單:將一行中顏色值相同的相鄰象素用乙個計數值和該顏色值來代替。例如aaabccccccddeee可以表示為3a1b6c2d3e。如果一幅圖象是由很多塊顏色相同的大面積區域組成,那麼採用行程編碼的壓縮效率是驚人的。然而,該演算法也導致了乙個致命弱點,如果圖象中每兩個相鄰點的顏色都不同,用這種演算法不但不能壓縮,反而資料量增加一倍。所以現在單純採用行程編碼的壓縮演算法用得並不多,pcx檔案算是其中的一種。
pcx檔案最早是pc paintbrush軟體所採用的一種檔案格式,由於壓縮比不高,現在用的並不是很多了。它也是由頭資訊、調色盤、實際的圖象資料三個部分組成。其中頭資訊的結構為:
typedef struct pcxhead;
其中值得注意的是以下幾個資料:manufacturer為pcx檔案的標識,必須為0x0a;xmin為最小的x座標,xmax最大的x座標,所以圖象的寬度為xmax-xmin+1,同樣圖象的高度為ymax-yin+1;bytes_per_line為每個編碼行所佔的位元組數,下面將詳細介紹。
pcx的調色盤在檔案的最後。以256色pcx檔案為例,倒數第769個位元組為顏色數的標識,256時該位元組必須為12,剩下的768(256×3)為調色盤的rgb值。
為了敘述方便,我們針對256色pcx檔案,介紹一下它的解碼過程。編碼是解碼的逆過程,有興趣的讀者可以試著自己來完成。
解碼是以行為單位的,該行所佔的位元組數由bytes_per_line給定。為此,我們開乙個大小為bytes_per_line的解碼緩衝區。一開始,將緩衝區的所有內容清零。從檔案中讀出乙個位元組c,若c>0xc0,說明是行程(run length)資訊,即c的低6位表示後面連續的位元組個數(所以最多63個連續顏色相同的象素,若還有顏色相同的象素,將在下乙個行程處理),檔案的下乙個位元組就是實際的圖象資料(即該顏色在調色盤中的索引值)。若c<0xc0,則表示c是實際的圖象資料。如此反覆,直到這bytes_per_line個位元組處理完,這一行的解碼完成。pcx就是有若干個這樣的解碼行組成。
下面是實現256色pcx檔案解碼的源程式,其中第二個函式對一行進行解碼,應該把閱讀的重點放在這個函式上。要注意的是,執行時檔案c://test.pcx必須存在,而且是乙個256色pcx檔案。
unsigned int pcxbytesperline;
bool loadpcxfile (hwnd hwnd,char *pcxfilename)
//讀出頭資訊
fread((char*)&header,1,sizeof(pcxhead),pcxfp);
if(header.manufacturer!=0x0a)
//將檔案指標指向調色盤開始處
fseek(pcxfp,-769l,seek_end);
//獲取顏色數資訊
pcxtag=fgetc(pcxfp)&0xff;
if(pcxtag!=12)
//建立新的bitmapfileheader和bitmapinfoheader
memset((char *)&bf,0,sizeof(bitmapfileheader));
memset((char *)&bi,0,sizeof(bitmapinfoheader));
//填寫bitmapinfoheader頭資訊
bi.bisize=sizeof(bitmapinfoheader);
//得到圖象的寬和高
bi.biwidth=header.xmax-header.xmin+1;
bi.biheight=header.ymax-header.ymin+1;
bi.biplanes=1;
bi.bibitcount=8;
bi.bicompression=bi_rgb;
imgwidth=bi.biwidth;
imgheight=bi.biheight;
numcolors=256;
linebytes=(dword)widthbytes(bi.biwidth*bi.bibitcount);
imgsize=(dword)linebytes*bi.biheight;
//填寫bitmapfileheader頭資訊
bf.bftype=0x4d42;
bf.bfsize=sizeof(bitmapfileheader)+sizeof(bitmapinfoheader)+
numcolors*sizeof(rgbquad)+imgsize;
bf.bfoffbits=(dword)(numcolors*sizeof(rgbquad)+
sizeof(bitmapfileheader)+sizeof(bitmapinfoheader));
//為新圖分配緩衝區
if((himgdata=globalalloc(ghnd,(dword)
(sizeof(bitmapinfoheader)+
numcolors*sizeof(rgbquad)+imgsize)))==null)
lpimgdata=(lpbitmapinfoheader)globallock(himgdata);
//拷貝頭資訊
memcpy(lpimgdata,(char *)&bi,sizeof(bitmapinfoheader));
lpptr=(char *)lpimgdata+sizeof(bitmapinfoheader);
//為256色調色盤分配記憶體
hpal=localalloc(lhnd,sizeof(logpalette)+
numcolors* sizeof(paletteentry));
ppal =(logpalette *)locallock(hpal);
ppal->palnumentries =256;
ppal->palversion = 0x300;
for (i = 0; i < 256; i++)
//產生新的邏輯調色盤
hpalette=createpalette(ppal);
localunlock(hpal);
localfree(hpal);
hdc=getdc(hwnd);
if(hpalette)
//解碼行所佔的位元組數
pcxbytesperline=(unsigned int)header.bytes_per_line;
//將檔案指標指向圖象資料的開始處
fseek(pcxfp,(long)sizeof(pcxhead),seek_set);
//緩衝區大小
offbits=bf.bfoffbits-sizeof(bitmapfileheader);
//bufsize為緩衝區大小
bufsize=offbits+bi.biheight*linebytes;
for(y=0;y//指向新圖中相應的位置
lpptr=(char *)lpimgdata+bufsize-linebytes-y*linebytes;
//解碼該行,放在陣列linebuffer中
readpcxline(linebuffer,pcxfp);
for(x=0;x*(lpptr++)=linebuffer[x]; //將該行儲存到位圖資料中
}//建立新的點陣圖
hbitmap=createdibitmap(hdc,(lpbitmapinfoheader)lpimgdata,
(long)cbm_init,
(lpstr)lpimgdata+
sizeof(bitmapinfoheader)+
numcolors*sizeof(rgbquad),
(lpbitmapinfo)lpimgdata,
dib_rgb_colors);
if(hpalette && hprevpalette)
hfbmp=_lcreat("c://pcx2bmp.bmp",0);
_lwrite(hfbmp,(lpstr)&bf,sizeof(bitmapfileheader));
_lwrite(hfbmp,(lpstr)lpimgdata,bufsize);
_lclose(hfbmp);
fclose(pcxfp);
//釋放記憶體和資源
releasedc(hwnd,hdc);
globalunlock(himgdata);
return true;
}//對每一行進行解碼,結果儲存到指標p指向的記憶體中
void readpcxline(unsigned char *p,file *fp)
else p[n++]=c; //否則是實際的圖象資料,直接填入到p中
}while (n}
對一幅的pcx檔案格式的圖象解碼後,結果如圖9.2所示。顯示的是我最喜歡的法國影星阿佳妮·伊莎貝拉。
圖9.2一幅pcx檔案格式的圖象
PackBits解壓縮演算法
packbits壓縮方式是每段資料都有乙個頭 有符號的8bit型別資料 和資料。具體形式如下圖所示。當頭部的值為 1 127表示頭部後面的1乙個位元組的資料進行過資料壓縮,解壓縮時需要將頭部後面的乙個位元組的資料重複頭部值的絕對值 1次。當頭部的值為0 127表示頭部後面頭部值 1個位元組的資料沒有...
壓縮解壓縮
壓縮 壓縮後的檔名 包含物理路徑 待壓縮的資料夾 包含物理路徑 public static void packfiles string filename,string directory catch exception 解壓縮 待解壓檔名 包含物理路徑 解壓到哪個目錄中 包含物理路徑 public ...
壓縮 解壓縮
linux使用最廣泛的壓縮格式位gz,使用gzip命令進行壓縮和解壓縮 1 gzip,gunzip,壓縮 解壓縮檔案,compress or expand files gzip acdfhkllnnrtvv19 s suffix name gunzip acfhkllnnrtvv s suffix ...