SPT和PaintBrush文件的双向转换程序
SPT是Super-CCDOS提供的一个黑白两色的图文编辑程序,PaintBrush是WINDOWS提供的一个彩色图形
编辑程序,它们各有优点,SPT提供的逐点编辑对图形的精细加工特别好用,而PaintBrush对图形的放大缩小
是SPT所没有的。如果能够使两个程序直接交换数据,则是一件令人赏心的事情。
一、图形文件的格式
通过对SPT和PaintBrush的图形文件的格式进行分析发现,SPT的未压缩Super Star图形文件(*.SPT)和
PaintBrush的BMP格式文件(*.BMP)均是按点阵(位映象)存放图形的,只是存放次序和组织方法不同,所以完
全可以利用这两种文件进行数据交换。PaintBrush中的BMP格式有单色位映象、16色位映象、256色位映象以
及24b位映象4种,这里只考虑单色位映象一种格式,在此格式中,1bit(位)代表一个象素点,1B(字节)代
表8个象素点。
SPT文件和BMP文件都有一个文件头,其中记录了图形的宽度、高度、文件长度和标志信息。SPT文件头有64B,
如图1所示。前16B为SPT的文件头的标志,第34字节开始为两字节的图形宽度,紧接其后的是图形的高度,单
位均是象素点。BMP的文件头如图2所示,前2B为标志,后面的4B是文件长度(LongInt),第11,12两字节是
指向点阵信息的指针,即从第3EH+1个字节开始存放点阵数据,第19,20字节表示图形宽度,23,24字节表示
高度,单位也是象素点,第29字节(01)表示该BMP文件为单色位映象格式。BMP文件头共用了62字节。
SPT文件标志
3910:0100 53 75 70 65 72 2D 53 74-61 72 20 46 69 6C 65 1A Super-Star File.
3910:0110 00 01 00 00 00 00 00 00-00 00 00 00 C0 EE C3 F7 ................
3910:0120 40 00 F0 03 F4 01 01 00-00 00 00 00 00 00 00 00 @...............
3910:0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
图形宽度 图形高度
(1000点) (500点)
图1.SPT图形文件头
BMP文件标志 文件长度 指向点阵信息的指针
3910:0100 42 4D 76 28 00 00 00 00-00 00 3E 00 00 00 28 00 BMv(......v...(.
3910:0110 00 00 7B 00 00 00 A0 00-00 00 01 00 01 00 00 00 ..{.............
3910:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
3910:0130 00 00 00 00 00 00 00 00-00 00 00 00 80 00 ..............
图形宽度 图形高度 单色位映象格式标志
(123点) (160点)
图2.BMP图形文件头
紧接文件头之后,SPT和BMP文件都是图形的点阵信息,SPT文件从图形的第一行开始,依次为第二、第三、
...、第n行,BMP文件恰恰相反,为第n行、第n-1行、...、第一行,其中n为图形的高度。设图形的宽度为
width个象素点,高度为height个象素点,因SPT只取width为8的倍数,故每行占的字节数LineByte为
(width div 8);BMP文件中的width任意,但每行所占字节数比为4的倍数,所以实际每行所需字节数
LineByte=(width+7) div 8。
二、程序设计和使用方法
据上述分析,用TURBO C 2.0编写了一个SPT2BMP.C程序,以实现SPT和BMP文件的双向转换。进行数据转换时
应注意两点:(1)在SPT系统中存图形时,要选SuperStar文件类别,非压缩存储格式;(2)在
PaintBrush在存图时,在存文件对话框中打开Option文件格式选项,选Monochromoe bitmap项,然后存盘。
程序的使用方法是:
SPT2BMP <SPT文件名> <BMP文件名> </开关>
开关有两个选项:
/BS --- BMP文件转换为SPT文件
/SB --- SPT文件转换为BMP文件
三、源程序清单
/*************************************************************/
/* 程序名称: SPT2BMP.C 1.1 */
/* 作 者: 董占山 */
/* 完成日期: 1995-11-07 */
/* 用 途: SPT文件与BMP文件的相互转换程序 */
/* 编译方法: 用下列命令编译连接可以得到SPT2BMP.COM: */
/* tcc -mt spt2bmp */
/* tlink c:\tc\lib\c0t+spt2bmp,spt2bmp,,c:\tc\lib\cs\lib /t */
/*************************************************************/
#include <stdio.h>
#include <string.h>
unsigned char SPT_Head[64] = { /* SUPER STAR图形文件头 */
0x53,0x75,0x70,0x65,0x72,0x2D,0x53,0x74,0x61,0x72,
0x20,0x46,0x69,0x6C,0x65,0x1A,0x00,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x62,
0x63,0x64,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00 };
unsigned char BMP_Head[62] = { /* Bitmap文件头 */
0x42,0x4D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3E,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,
0xFF,0x00 };
char BMP_file[80],SPT_file[80];
char ch,oneline[1000]/* 一个扫描行的缓冲区 */;
unsigned int width,height,bytes; /* 位图象的宽度、高度和每行点阵实际所占字节数 */
unsigned long linebyte,ofs,flength; /* linebyte为每扫描行所占字节数 */
char Switch[3]; /* 程序启动开关 */
/* 显示错误信息 */
void DispError()
{
printf("Error : File not found !\n");
exit(0);
}
/* 执行SPT文件向BMP文件的转换功能 */
void SPT_to_BMP()
{
FILE *BMP,*SPT;
int i;
if (strchr(SPT_file,'.') == NULL) strcat(SPT_file,".SPT");
if (strchr(BMP_file,'.') == NULL) strcat(BMP_file,".BMP");
if ((SPT = fopen(SPT_file,"rb"))==NULL) DispError();
BMP = fopen(BMP_file,"wb+");
fseek(SPT,34,SEEK_SET);
fread(&width,sizeof(width),1,SPT); /* 读出位图象宽度 */
fread(&height,sizeof(height),1,SPT); /* 读出位图象高度 */
bytes = width / 8;
linebyte = ((bytes + 3) / 4) * 4;
flength = 62 + linebyte * height; /* 计算文件长度 */
memcpy(&BMP_Head[2],&flength,4); /* 填写BMP文件头 */
memcpy(&BMP_Head[18],&width,2);
memcpy(&BMP_Head[22],&height,2);
fwrite(BMP_Head,sizeof(BMP_Head),1,BMP); /* 写BMP文件头 */
for (i=bytes;i<linebyte;i++) oneline[i] = '\0';
for (i=0;i<height;i++) {
ofs = bytes * (i+1); /* 计算扫描行的偏移量 */
fseek(SPT,-ofs,SEEK_END); /* 置文件指针到扫描行头 */
fread(oneline,bytes,1,SPT); /* 读扫描行位图象信息 */
fwrite(oneline,linebyte,1,BMP); /* 写扫描行位图象信息 */
}
fclose(SPT);
fclose(BMP);
}
/* 执行BMP文件向SPT文件的转换功能 */
void BMP_to_SPT()
{
int i;
FILE *BMP,*SPT;
if (strchr(SPT_file,'.') == NULL) strcat(SPT_file,".SPT");
if (strchr(BMP_file,'.') == NULL) strcat(BMP_file,".BMP");
if ((BMP = fopen(BMP_file,"rb"))==NULL) DispError();
SPT = fopen(SPT_file,"wb+");
fseek(BMP,18,SEEK_SET);
fread(&width,2,1,BMP); /* 读出位图象宽度 */
fseek(BMP,22,SEEK_SET);
fread(&height,2,1,BMP); /* 读出位图象高度 */
bytes = (width + 7) / 8;
linebyte = ((width + 31) / 32) * 4;
width = bytes * 8;
memcpy(&SPT_Head[34],&width,2); /* 填写BMP文件头 */
memcpy(&SPT_Head[36],&height,2);
fwrite(SPT_Head,sizeof(SPT_Head),1,SPT);
for (i=0;i<height;i++) {
ofs = linebyte * (i+1); /* 计算扫描行的偏移量 */
fseek(BMP,-ofs,SEEK_END); /* 置文件指针到扫描行头 */
fread(oneline,bytes,1,BMP); /* 读扫描行位图象信息 */
fwrite(oneline,bytes,1,SPT); /* 写扫描行位图象信息 */
}
fclose(BMP);
fclose(SPT);
}
/* 显示程序的使用信息 */
void help()
{
printf("Syntex : SPT2BMP <SPT file> <BMP file> <Switch>\n");
printf("Switch :\n /SB --- SPT file to BMP file\n%s",
" /BS --- BMP file to SPT file\n");
exit(0);
}
/* 主程序 */
main(argc,argv)
int argc;
char *argv[];
{
printf("SPT2BMP Version 1.1 Copyright (c) 1994,95 Dong Zhanshan\n");
switch (argc) {
case 0 :
case 1 :
case 2 :
case 3 : help();
break;
case 4 : strcpy(SPT_file,argv[1]);
strcpy(BMP_file,argv[2]);
strupr(strcpy(Switch,argv[3]));
}
if (strcmp(Switch,"/SB")==0) SPT_to_BMP();
if (strcmp(Switch,"/BS")==0) BMP_to_SPT();
}
|