⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch7.prg

📁 C 常用算法程序集 徐士良 编 清华大学出版社 1994.1
💻 PRG
📖 第 1 页 / 共 4 页
字号:
    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 + -