天天看点

处理PCX文件

目 录

  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、图像解压缩算法
处理PCX文件
图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);

    }

  }