📄 ch7.prg
字号:
fclose(pic);
remove(dest);
return;
}
fread(&compress,sizeof(long int),1,bmp);
/* 读入压缩标志 */
if (compress)
{
/* 若为压缩格式 */
printf("Source file is in compress format!\n");
fclose(bmp);
fclose(pic);
remove(dest);
return;
}
if (allocate(&hp,length)) return;
for(i=0;i<4;i++)
if ((tempfile[i]=fopen(tmpnam(tempfilename[i]),"wb"))==NULL)
{
printf("Can't create temperory file on disk!\n");
fclose(bmp);
exit(1);
}
bytewidth=((width+1)/2+3)/4*4;
/* 计算一行象素在bmp文件中所占字节数 */
prcdisp(-1); /* 产生百分数提示 */
fseek(bmp,0x76,SEEK_SET);
load(hp,bmp,length); /* 若分配的远程堆有效, 则将bmp源文件装入远程堆 */
for(i=0;i<bytewidth/4;i++)
{
prcdisp((float)i*60/(bytewidth/4));
/* 显示百分数提示 */
farseek(&hp,(height-1)*bytewidth+i*sizeof(long int));
/* 定位于图象第一行的第i组象素点 */
for(j=0;j<height;j++)
{
farread(&hp,(char far *)(&buf),sizeof(long));
/* 读入图象第j行的第i组象素点 */
farseek(&hp,(height-2-j)*bytewidth+i*sizeof(long int));
/* 定位于图象第j+1行的第i组象素点 */
for(m=0;m<4;m++)
{
/* 把象素的彩色值转换为pic格式的彩色值, 放在 */
/* buffer数组中 */
temp=(buf[m]&0xf0)>>4;
buffer[m*2]=piccolor[temp];
temp=buf[m]&0x0f;
buffer[m*2+1]=piccolor[temp];
}
for(m=0;m<4;m++)
{
for(n=0,result=0;n<8;n++)
{
/* 取出buffer数组中各元素的第n位, 组成一字节数据 */
result=(result<<1)|(buffer[n]&0x01);
buffer[n]=buffer[n]>>1;
}
fwrite(&result,sizeof(char),1,tempfile[m]);
/* 把该字节写入临时文件中 */
}}}
farfree(hp.start); /* 释放远程堆 */
memcpy(&pichead[0x5],&width,sizeof(int));
/* 把图像宽度拷贝到pic文件头中 */
memcpy(&pichead[0x7],&height,sizeof(int));
/* 把图像高度拷贝到pic文件头中 */
fwrite(pichead,0x800,1,pic);
/* 向pic目标文件写入文件头 */
for(i=0,count=0x800;i<4;i++)
{
prcdisp(60+i*10); /* 显示百分数提示 */
fclose(tempfile[i]);
tempfile[i]=fopen(tempfilename[i],"rb");
/* 重新打开临时文件 */
count+=compres(pic,tempfile[i]);
/* 压缩临时文件 */
fclose(tempfile[i]);
remove(tempfilename[i]);
/* 擦除临时文件 */
}
fseek(pic,0x7c,SEEK_SET);
fwrite(&count,sizeof(long int),1,pic);
/* 填写pic文件长度 */
prcdisp(100);
fclose(bmp);
fclose(pic);
return;
}
long int compres(FILE *dest,FILE * fs)
{
long int cbbytes=0; /* 写入目标文件的字节计数 */
int current, /* 指向缓充区中数据区尾部 */
i;
unsigned char ch, /* 读入字节 */
cbequal, /* 相同字节的计数 */
cbnoequal,/* 不同字节的计数 */
buffer[128];
/* 输入缓充区 */
start :
current=0;
cbequal=cbnoequal=1;
fread(&buffer[current++],sizeof(char),1,fs);
/* 从临时文件中读入一字节 */
while (1)
{
fread(&ch,sizeof(char),1,fs);
/* 从临时文件中读入一字节 */
if (feof(fs)) break; /* 若临时文件, 则退出循环 */
if (ch==buffer[current-1])
/* 若读入字节等于比较字节 */
{
cbequal++; /* 相等字节计数加一 */
if (cbnoequal==1) /* 数据区中是否有不等的字节 */
{
if (cbequal>=125)/* 相等字节的计数是否大于125 */
{
cbequal=cbequal|0x80;
/* 字节计数作相等标志 */
fwrite(&cbequal,sizeof(char),1,dest);
/* 向目标文件写入字节计数 */
fwrite(&buffer,sizeof(char),1,dest);
/* 写入字节内容 */
cbbytes+=2; /* 字节长度计数增加 */
goto start;
}}
else
{
cbnoequal--; /* 最后两字节相等, 因此不等字节计数要减一 */
fwrite(&cbnoequal,sizeof(char),1,dest);
/* 向目标文件写入字节计数 */
fwrite(&buffer,cbnoequal,1,dest);
/* 写入字节内容 */
cbbytes+=cbnoequal+1;
/* 字节长度计数增加 */
buffer[0]=ch ; /* 相等的字节移到数据区首 */
current=1; /* 调整数据区尾指针 */
cbnoequal=1; /* 调整字节计数 */
cbequal=2;
} }
else
{
if (cbequal==1) /* 数据区中是否有相等的字节 */
{
buffer[current++]=ch;
cbnoequal++; /* 不等字节计数加一 */
if (cbnoequal>=125)
/* 不等字节计数是否大于14 */
{
fwrite(&cbnoequal,sizeof(char),1,dest);
/* 写入字节计数 */
fwrite(&buffer,cbnoequal,1,dest);
/* 写入字节内容 */
cbbytes+=1+cbnoequal;
/* 字节长度计数增加 */
goto start;
}}
else
{
cbequal=cbequal|0x80;
/* 字节计数作相等标志 */
fwrite(&cbequal,sizeof(char),1,dest);
/* 向目标文件写入字节计数 */
fwrite(&buffer,sizeof(char),1,dest);
/* 写入字节内容 */
cbbytes+=2; /* 字节长度计数增加 */
cbequal=1; /* 调整字节计数 */
buffer[0]=ch; /* 把不相等的字节移到数据区首 */
current=1; /* 调整数据区尾指针 */
}}}
if (cbequal!=1) /* 数据区中是否有相等的字节 */
{
cbequal=cbequal|0x80; /* 字节计数作相等标志 */
fwrite(&cbequal,sizeof(char),1,dest);
/* 写入字节计数 */
fwrite(&buffer,sizeof(char),1,dest);
/* 写入字节内容 */
cbbytes+=2; /* 字节长度计数增加 */
}
else
{
fwrite(&cbnoequal,sizeof(char),1,dest);
/* 写入字节计数 */
fwrite(&buffer,cbnoequal,1,dest);
/* 写入字节内容 */
cbbytes+=1+cbnoequal; /* 字节长度计数增加 */
}
return(cbbytes); /* 返回字节长度计数 */
}
void pictobmp(char *dest,char *source)
{
char far *plane[4],far *pointer[4];
farmem hp;
printf("%s=>%s ",source,dest);
if (openfile(dest,source,&bmp,&pic)) return;
fseek(pic,5,SEEK_SET);
fread(&width,sizeof(int),1,pic);
/* 读入pic源文件的长度 */
fread(&height,sizeof(int),1,pic);
/* 读入位图数据在bmp文件中的偏移量 */
bmplinebyte=((width+1)/2+3)/4*4;
length=0x76+bmplinebyte*height;
/* bmp 文件长度 */
memcpy(&bmphead[2],&length,4);
/* bmp 文件长度复制到 bmp 文件头 */
memcpy(&bmphead[18],&width,2);
/* 图象宽度复制到 bmp 文件头 */
memcpy(&bmphead[22],&height,2);
/* 图象高度复制到 bmp 文件头 */
fwrite(bmphead,0x76,1,bmp);
/* 写 bmp 文件头 */
if (allocate(&hp,length))
{
fclose(bmp);
fclose(pic);
remove(dest);
return;
}
fseek(pic,0x800,SEEK_SET);
prcdisp(-1); /* 显示百分数提示 */
prcdisp(0);
expand(&hp,pic); /* 把压缩的PIC文件恢复 */
prcdisp(15);
for(i=0;i<4;i++)
/* plane数组中元素指向四组彩色位数据的起始处 */
plane[i]=(width*height+7)/8*i+hp.start;
bytewidth=(width+7)/8; /* 计算一行数据的长度 */
for(i=0;i<height;i++)
{
prcdisp(85*i/height+15);
for(j=0;j<4;j++)
/* pointer数组中元素指向四组彩色位数据的倒数 */
/* 第i行处。因为BMP文件从图像的最后一行开始 */
/* 储存 */
pointer[j]=plane[j]+height-i-1;
for(j=0;j<bytewidth;j++)
{
for(m=0;m<4;m++)
{
buf[m]=*pointer[m];
/* 取出图像数据 */
pointer[m]+=height;
/* 指针指向上一行数据 */
}
for(m=0;m<4;m++)
{
tempch1=tempch2=0;
for(n=0;n<4;n++)
/* 提取四字节数据的某一位组成一字节(低四位有 */
/* 效)的彩色值 */
{
tempch1=tempch1<<1;
tempch1=tempch1|((buf[n]&0x80)?1:0);
buf[n]=buf[n]<<1;
}
tempch1=bmpcolor[tempch1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -