typedef short bit16;
typedef unsigned int bit32 ;
typedef int bit16 ;
typedef unsigned long bit32 ;
char *formatstring;
int
file
;
int bitget(char *bit,int i,int j)
{
bit32 num;
bit32 num2=0xffffffff;
*(&num)=*(bit32 *)bit;/*不使用指针来赋值的话,*/
/*vc使用movzx来把字节扩展到32位,那么在24位真彩模式下会有问题*/
num>>=i%8;/*把数组当做一个bitset对象*/
num2>>=(32-j);/*只对比这么多位*/
num&=num2;
return
num==num2?0:1;/*白色为0*/
}
void bmptochars(char *chars,char *dots,int count,int bitofdot)
{
int i,j,k=(8
/bitofdot
)?(8
/bitofdot-1
):0;/*区分位图是1,4,8,24模式*/
int l,num=(count-1)
/8
+1;/*num是需要多少字节来存放转换后的数据*/
char Buffer[100];/*字符串缓冲区*/
memset(dots,0,num+1);/*清零*/
for
(i=0,j=k;i<count;++i,--j)
{
if
(j<0)j=k;
if
(bitget(chars+i*bitofdot
/8
,j*bitofdot,bitofdot))
dots[i
/8
]|=(unsigned char)1<<i%8;
}/*一次性把这一行都转换掉*/
for
(l=0;l<num;++l)
{
if
(dots[l]==0)write(
file
,
"0,"
,2);
else
write(
file
,Buffer,sprintf(Buffer,formatstring,dots[l]&255));
}/*写入文件*/
return
;
}
int main(int argc,char *argv[])
{
bit32 Width,Height,bitoff;/*宽,高,位图文件的位图数据偏移*/
bit16 fp,i,j,m,bitofdot,cflag=0;
/*fp 位图文件句柄,bitofdot 位图中多少个位表示一个点,cflag 是否翻译成c格式*/
char Buffer[200];/*文件名等缓冲区*/
char *bit,*dots;/*用于保存从位图文件中读取的数据和转换后的数据,后面会为其分配内存*/
printf
(
"\t\t\t http://www.asmedu.net\n\t\t\tCopyright (C) 2012-2012.\n"
);
switch(argc)
{
case
1:
printf
(
"Input the file name:\n"
);
scanf(
"%s"
,Buffer);
break
;
case
2:
if
(!memicmp(argv[1],
"/?"
,2))
{
printf
(
"bmptodot [/c] filename.bmp\n[/c] use the c language format\n%s%s"
,
"use the default assembly langusge format\n"
,
"the bitmap must height=width,background must white\n"
);
return
0;
}
else
strcpy(Buffer,argv[1]);
break
;
case
3:
{
if
(!memicmp(argv[1],
"/c"
,2))cflag=i=2;
else
if
(!memicmp(argv[2],
"/c"
,2))cflag=i=1;
else
{
printf
(
"error cmdline!\n"
);
return
-1;}
strcpy(Buffer,argv[i]);
break
;
}
default:
return
-1;
}/*处理命令行参数*/
if
(cflag)formatstring=
"%#x,"
;
else
formatstring=
"0%xh,"
;/*指定翻译格式*/
if
((fp =
open
(Buffer, O_RDONLY|O_BINARY)) == -1) /* 打开文件 */
{
printf
(
"Can't open the file!\n"
);
return
-1;
}/*文件打开失败的处理*/
lseek(fp,10L,SEEK_SET);
read
(fp,&bitoff,4);/*得到数据区相对与BMP文件的开始位置偏移*/
lseek(fp,18L,SEEK_SET); /* 读取文件宽高 */
read
(fp,&Width,4);/*宽(X)*/
read
(fp,&Height,4);/*高(Y)*/
lseek(fp,0x1CL,SEEK_SET);
read
(fp,&bitofdot,2);/*每个像素需要多少位来存储*/
Width*=bitofdot;/*得到图像每行需要的位数*/
m=j=(Width-1)
/8
+1;/*得到字节数*/
j=j%4?(j+4-j%4):j;/*补充为4字节倍数*/
m=j-m;/*得到填补字节数*/
bit=(char *)malloc(j+4);
dots=(char*)malloc((Height-1)
/8
+2);/*分配内存*/
if
(!bit||!dots)
exit
(-1);
memset(bit,0,j+4);
strcpy(strrchr(Buffer,
'.'
),
".txt"
);
file
=creat(Buffer,S_IWRITE);/*生成转换后的文件和位图文件同名*/
if
(
file
== -1)
{
printf
(
"Can't create file!\n"
);
return
-1;
}
bitoff+=Height*j;/*得到文件的位图数据区最后偏移*/
*strrchr(Buffer,
'.'
)=
'\0'
;
Buffer[7]=
'\0'
;/*如果文件名超出7个字符就截断,主要是想把一个缓冲区当两个用*/
if
(cflag)
write(
file
,Buffer+8,sprintf(Buffer+8,
"char bmp%s%d[]={ \n"
,Buffer,Height));
else
write(
file
,Buffer+8,sprintf(Buffer+8,
"bmp%s%d \n"
,Buffer,Height));
for
(i = 1; i <=Height; ++i)
{
lseek(fp,bitoff-(bit32)i*j, SEEK_SET); /*需要倒着读 */
read
(fp, bit,j); /* 一次读取一行*/
if
(cflag)/*判断翻译格式*/
bmptochars(bit,dots,Height,bitofdot);
else
{
write(
file
,
"db "
,3);
bmptochars(bit,dots,Height,bitofdot);
lseek(
file
,-1,SEEK_CUR);
}
write(
file
,
"\n"
,1);/*换行*/
}
if
(cflag)write(
file
,
"};\n"
,4);
close(fp);
close(
file
);/*关闭文件*/
return
0;
}