CSDN博客

img flydeveloper

处理PCX文件

发表于2004/10/27 15:06:00  2501人阅读

目 录
  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);
    }
  }
阅读全文
0 0

相关文章推荐

img
取 消
img