void makeavi(FILE *fp)
{
unsigned char byte;
int x,y;
memcpy(block.type,"00db",4);
block.size=(unsigned long)linebytes*bmpheight;
fwrite(&block,sizeof(block),1,fp);
for(y=0;y<bmpheight;y++)
for(x=0;x<linebytes;x++)
if(x<bmpwidth) {
byte=getpixel(left+x,bottom-y)>0?
color:bkcolor;
fputc(byte,fp);
}
else
fputc(0,fp);
}
void makeidxchunk(FILE *fp)
{
int i;
memcpy(block.type,"idx1",4);
block.size=(unsigned long)16*frames;
fwrite(&block,sizeof(block),1,fp);
memcpy(idx.type,"00db",4);
idx.flags=0x10;idx.offset=4;
idx.length=(unsigned long)linebytes*bmpheight;
for(i=1;i<=frames;i++) {
fwrite(&idx,sizeof(idx),1,fp);
idx.offset+=8+idx.length;
}
}
void putRLE8code(FILE *fp,unsigned char
*buffer,unsigned int bytes)
{
unsigned int count;
if(bytes>2) {
fputc(0,fp);
fputc(bytes,fp);
imagebytes+=2;
for(count=0;count<bytes;count++) {
fputc(buffer[count],fp);
imagebytes++;
}
if(bytes&1) {
fputc(0,fp);
imagebytes++;
}
}
else {
for(count=0;count<bytes;count++) {
fputc(1,fp);
fputc(buffer[count],fp);
imagebytes+=2;
}
}
}
void encodeRLE8(FILE *fp)
{
unsigned char linebuf[320],buffer[640];
unsigned int x,y,linebytes,bytes,
bytecount,nonbytes;
linebytes=bmpwidth;y=bmpheight;
while(y--) {
bytecount=nonbytes=bytes=0;
for(x=0;x<linebytes;x++) {
linebuf[x]=getpixel(left+x,top+y+1)>0?
color:bkcolor;
}
while(bytecount<linebytes) {
while(linebuf[bytecount+bytes]==
linebuf[bytecount+bytes+1] &&
(bytecount+bytes+1)<linebytes&&bytes<254)
bytes++;
if(bytes>1) {
if(nonbytes) {
putRLE8code(fp,buffer,nonbytes);
nonbytes=0;
}
bytes++;
fputc(bytes,fp);
fputc(linebuf[bytecount],fp);
bytecount+=bytes;
bytes=0;
imagebytes += 2;
}
else {
if(bytes)
bytes--;
buffer[nonbytes++]=linebuf[bytecount++];
if(nonbytes==255) {
putRLE8code(fp,buffer,nonbytes);
nonbytes=0;
}
}
}
if(nonbytes)
putRLE8code(fp,buffer,nonbytes);
fputc(0,fp);fputc(0,fp);
imagebytes+=2;
}
fputc(0,fp);fputc(1,fp);
imagebytes += 2;
}
unsigned long formavi(FILE *fp)
{
imagebytes=0;
fwrite(&block,sizeof(block),1,fp);
encodeRLE8(fp);
fseek(fp,-8-imagebytes,1);
memcpy(block.type,"00dc",4);
block.size=imagebytes;
fwrite(&block,sizeof(block),1,fp);
list.size+=8+imagebytes;
fseek(fp,imagebytes,1);
return(imagebytes);
}
void formidxchunk(FILE *fp)
{
int i;
memcpy(block.type,"idx1",4);
block.size=(unsigned long)16*frames;
fwrite(&block,sizeof(block),1,fp);
memcpy(idx.type,"00dc",4);
idx.flags=0x00;idx.offset=4;
for(i=0;i<frames;i++) {
idx.length=bmpsize[i];
fwrite(&idx,sizeof(idx),1,fp);
idx.offset+=8+idx.length;
}
}
void showimage( )
{
int i,charsize=4;
char text[]="AVI Animator!";
FILE *fp;
settextstyle(TRIPLEX_FONT,HORIZ_DIR,
charsize);
left=220;top=200;right=420;bottom=280,
compression=1;frames=21;
bmpwidth=right-left;bmpheight=bottom-top;
color=GREEN;bkcolor=BLACK,colors=16;
if((fp=fopen("Animator.avi","wb"))==NULL) {
printf("Can not create avi File!\n");
exit(1);
}
createchunkhead(fp);
list.size=4;
bmpsize=malloc(frames*sizeof
(unsigned long));
setbkcolor(bkcolor);
for(i=0;i<frames;i++) {
setcolor(color);
outtextxy(right-20*i-20,top+20,text);
if(compression)
bmpsize[i]=formavi(fp);
else
makeavi(fp);
delay(200);
setcolor(bkcolor);
outtextxy(right-20*i-20,top+20,text);
cleardevice( );
}
if(compression) {
formidxchunk(fp);
riff.size=220L+4*colors+16*frames+list.size;
fseek(fp,0L,0);
fwrite(&riff,sizeof(riff),1,fp);
offset=212L+4*colors;
fseek(fp,offset,0);
memcpy(list.type,"LIST",4);
fwrite(&list,sizeof(list),1,fp);
}
else
makeidxchunk(fp);
free(bmpsize);
fclose(fp);
}
main( )
{
int g_driver,g_mode,g_error;
detectgraph(&g_driver,&g_mode);
if(g_driver<0) {
printf("no graphics hardware detected !\n");
exit(1);
}
if(registerbgidriver(EGAVGA_driver)<0)
exit(1);
if(registerbgifont(triplex_font)!=TRIPLEX_FONT)
exit(1);
initgraph(&g_driver,&g_mode," ");
g_error=graphresult( );
if(g_error<0) {
printf("initgraph error: %s.\n",
grapherrormsg(g_error));
exit(1);
}
cleardevice( );
showimage( );
closegraph( );
}
参考文献
1.李振辉,李仁和编著。 探索图像文件的奥妙。清华大学出版社。
2.刘瑞祥等,AVI文件格式探秘。电子与电脑。1997年4月。
|