目 录
1 文件头信息
2 解压缩算法
PCX文件最早应用于ZSOFT公司的软件PC PAINBRUSH中,当时它是最早支持彩色图像的一种格式。由于该绘图软件功能强大并成功移植到Windows操作系统,加上PCX是最早支持彩色的图象格式之一,PCX成为目前比较流行的图象格式。PCX文件是采用行程编码( run-length encoded)对数据进行压缩。这种压缩不是很有效,但很容易实现。对于游戏设计而言,256色是最基本的要求了,因此我们只讨论256色的文件(更高的色彩在PCX中将不被支持)。
1、文件头信息typedef struct {
BYTE manufacturer;
BYTE version;
BYTE encoding;
BYTE bita_per_pixel:
WORD xmin,ymin;
WORD hres;
WORD vres;
BYTE palette[48];
BYTE reserved;
BYTE color_planes;
WORD bytes_per_line;
WORD palette_type;
BYTE filler[58];
}
manufacturer :总是0x0a,这是识别条件之一。
version :描述该文件的版本号。
·为0:早期的2.5版本。
·为2:2.8版本,包括一个有效的调色版信息。
·为3:2.8版本,使用一个缺省的调色版。
·为5:3.0或更高版本,图形是256色文件。
encoding :只有一种值,说明采用行程编码方式。
bit_per_pixel :与色彩有关。
xmin,ymin,xmax,ymax:定义了图像的尺寸大小。
palette :用来描述16色以下的图像的。
byte_per_line :每一行图像数据需要多少字节。
palette_type :·1为灰度图像、·2为彩色图像。
2、图像解压缩算法图1 |
显示256色图像程序( DOS Mode13 300x200x256),要求:被显示的PCX图像必须在320x200大小内。
#include <string.h>
#include <conio.h>
#include <stdio.h>
#include <alloc.h>
#include <dos.h>
#include <graphics.h>
#include <stdlib.h>
typedef struct
{
char manufacture;
char version;
char encoding;
char bit_per_pixel;
int xmin,ymin;
int xmax,ymax;
int hres;
int vres;
char palette[48];
char reserved;
char color_planes;
int bytes_per_line;
int palette_type;
char filler[58];
} PCXHEAD; PCXHEAD header;
unsigned int width,height;
unsigned int bytes;
char palette[768];
void init()
{
union REGS r;
r.x.ax=0x0013;
int86(0x10,&r,&r);
}
void deinit()
{
union REGS r;
r.x.ax=0x0003;
int86(0x10,&r,&r);
}
void setVGApalette(char *p)
{
union REGS r;
struct SREGS sr;
int i;
for(i=0;i<768;i++)
p[i]=p[i]>>2;
r.x.ax=0x1012;
r.x.bx=0;
r.x.cx=256;
r.x.dx=FP_OFF(p);
sr.es=FP_SEG(p);
int86x(0x10,&r,&r,&sr);
}
int ReadPcxLine(unsigned char far *p,FILE * fp)
{
int n=0,c,i;
_fmemset(p,0,bytes);
do
{
c=fgetc(fp)&0xff;
if((c&0xc0)==0xc0)
{
i=c&0x3f;
c=fgetc(fp);
while(i--)
p[n++]=c;
}
else
p[n++]=c;
} while(n<bytes);
return n;
}
void Unpack(FILE *fp)
{
int i;
init();
setVGApalette(palette);
for(i=0;i>height;i++)
{
ReadPcxLine((unsigned char far *)MK_FP(0xa000,i*320),fp);
}
getch();
deinit();
}
void main(int argc,char *argv[])
{
FILE *fp;
if(argc>1)
{
if((fp=fopen(argv[1],"rb"))!=NULL)
fread(&header,1,sizeof(PCXHEAD),fp);
fseek(fp,-768l,SEEK_END);
fread(palette,1,768,fp);
fseek(fp,128l,SEEK_SET);
width = header.xmax - header.xmin +1;
height= header.ymax - header.ymin +1;
bytes=header.bytes_per_line;
Unpack(fp);
fclose(fp);
}
}