HUFFMAN.CPP
上传用户:lzq06628
上传日期:2021-04-24
资源大小:3k
文件大小:9k
源码类别:

压缩解压

开发平台:

C/C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dir.h>
  4. #include <io.h>
  5. #include <conio.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include <dos.h>
  9. struct node
  10. {
  11. unsigned char c;
  12. unsigned long int freq;
  13. struct node *up,*left,*right;
  14. };
  15. struct ftable
  16. {
  17. unsigned long int freq;
  18. };
  19. struct ftable ft;
  20. struct node leaf[256];
  21. struct node *t[256];
  22. struct node *a,*b;
  23. int i,j,k;
  24. int buf[50],bc;
  25. int buft[20],bct;
  26. int buftv[20];
  27. unsigned char q;
  28. long int y=0;/*For debugging*/
  29. int init(char *);
  30. int sortt(int);//
  31. int maketree();//
  32. void add2buffCom(int);
  33. void add2buffDec(int);
  34. void refreshbufferCom(FILE *);
  35. void refreshbufferDec(FILE *);
  36. int nodecmp(struct node *,struct node *);
  37. int nodecpy(struct node *,struct node *);
  38. int getzero();//
  39. unsigned char oddchar();
  40. char *getname(char *);
  41. void init();
  42. int retrieveft(char *);
  43. int getzero()
  44. {
  45. int h=0;
  46. for(i=0;i<256;i++)
  47. {
  48. if(leaf[i].freq==0)
  49. h++;
  50. }
  51. return (255-h);
  52. }
  53. char *getname(char *filepath)
  54. {
  55. char drive[4],dir[67],file[15],ext[5];
  56. fnsplit(filepath,drive,dir,file,ext);
  57. strcat(file,ext);
  58. return file;
  59. }
  60. unsigned char oddchar()
  61. {
  62. for(i=bc;i<8;i++)
  63. {
  64. buf[i]=0;
  65. }
  66. return ((1*buf[7])+(2*buf[6])+(4*buf[5])+(8*buf[4])+(16*buf[3])+(32*buf[2])+(64*buf[1])+(128*buf[0]));
  67. }
  68. int nodecmp(struct node *a,struct node *b)
  69. {
  70. if(a->c==b->c && a->freq==b->freq && a->up==b->up &&a->left==b->left && a->right==b->right)
  71. return 0;
  72. return -1;
  73. }
  74. int nodecpy(struct node *a,struct node *b)
  75. {
  76. a->c=b->c;
  77. a->freq=b->freq;
  78. a->up=b->up;
  79. a->left=b->left;
  80. a->right=b->right;
  81. return 0;
  82. }
  83. int init(char *filename)        //Membuka file//
  84. {
  85. FILE *p;
  86. for(i=0;i<256;i++)          //deklarasi awal tree//
  87. {
  88. leaf[i].c=i;
  89. leaf[i].freq=0;
  90. leaf[i].up=NULL;
  91. leaf[i].left=NULL;
  92. leaf[i].right=NULL;
  93. }
  94. p=fopen(filename,"rb");
  95. if(p==NULL)
  96. {
  97. return -1; /*Could not open file */
  98. }
  99. while(j=fgetc(p),j!=EOF)
  100. {
  101. leaf[j].freq++;
  102. if(j<0 || j>255)
  103. {
  104. printf("nError...");
  105.             getch();
  106. }
  107. }
  108. fclose(p);
  109. for(i=0;i<256;i++)
  110. {
  111. t[i]=&leaf[i];
  112. if((t[i]->up)!=NULL)
  113. {
  114. printf("nError..");
  115. getch();
  116. }
  117. }
  118. bc=0;  /*Setting the global buffer counter to 0*/
  119. return 0;
  120. }
  121. int sortt(int z)/*sorts upto t[z] and not t[z-1]*/
  122. {
  123. for(k=0;k<=z;k++)
  124. for(j=(k+1);j<=z;j++)
  125. {
  126. if((t[k]->freq)<(t[j]->freq))
  127. {
  128. //b=NULL;
  129. b=t[k];
  130. t[k]=t[j];
  131. t[j]=b;
  132. }
  133. }
  134. return 0;
  135. }
  136. int maketree()
  137. {
  138. sortt(255);
  139. for(i=getzero();i>0;i--)
  140. {
  141. sortt(i);
  142. a=NULL;
  143. a=(struct node *)malloc(sizeof(struct node));
  144. if(a==NULL)
  145. {
  146. printf("nMemory allocation error...");
  147. getch();
  148. return -1;  /*Memory allocation error*/
  149. }
  150. /*Assingning values*/
  151. a->freq=(t[i]->freq)+(t[i-1]->freq);
  152. a->right=t[i];
  153. a->left=t[i-1];
  154. a->up=NULL;
  155. a->c='';
  156. t[i]->up=a;
  157. t[i-1]->up=a;
  158. /*Changing the pointer*/
  159. t[i-1]=a;
  160. }
  161. return 0;
  162. }
  163. void add2buffCom(int r)
  164. {
  165. bct=-1;
  166. if(r>255 || r<0)
  167. {
  168. printf("nValue error...");
  169. getch();
  170. }
  171. a=&leaf[r];
  172. while((a->up)!=NULL)
  173. {
  174. if(nodecmp((a->up->left),a)==0)
  175. {
  176. buft[++bct]=0;
  177. }
  178. else if(nodecmp((a->up->right),a)==0)
  179. {
  180. buft[++bct]=1;
  181. }
  182. else
  183. {
  184. printf("nParent Error");  /*For debugging*/
  185. }
  186. a=a->up;
  187. }
  188. for(i=0;i<=bct;i++)
  189. {
  190. buftv[bct-i]=buft[i];
  191. }
  192. for(i=0;i<=bct;i++)
  193. {
  194. buf[bc+i]=buftv[i];
  195. }
  196. bc=bc+bct+1;
  197. return;  /*Successful completetion of function*/
  198. }
  199. void refreshbufferCom(FILE *p)
  200. {
  201. while(bc>=8)
  202. {
  203. q=(1*buf[7])+(2*buf[6])+(4*buf[5])+(8*buf[4])+(16*buf[3])+(32*buf[2])+(64*buf[1])+(128*buf[0]);
  204. if(fputc(q,p)!=(unsigned)q || q<0 || q>255) printf("nError");
  205. for(i=8;i<bc;i++)
  206. {
  207. buf[i-8]=buf[i];
  208. }
  209. bc-=8;
  210. }
  211. }
  212. void refreshbufferDec(FILE *p)
  213. {
  214. int count=0,j,i;
  215. a=t[0];i=0;
  216. for(i=0;i<=bc;i++)
  217. {
  218. if(a->left==NULL && a->right==NULL)
  219. {
  220. fputc(a->c,p);
  221. /*For debugging*/
  222. y++;
  223. /*debugging over*/
  224. for(j=count;j<bc;j++)
  225. {
  226. buf[j-count]=buf[j];
  227. }
  228. bc-=count;
  229. //i=0;
  230. count=0;
  231. a=t[0];
  232. }
  233. else if(buf[count]==0)
  234. {
  235. a=a->left;
  236. count++;
  237. //i++;
  238. }
  239. else if(buf[count]==1)
  240. {
  241. a=a->right;
  242. count++;
  243. //i++;
  244. }
  245. else
  246. {
  247. printf("nError");
  248. }
  249. }
  250. return;
  251. }
  252. void add2buffDec(int c)
  253. {
  254. bct=-1;
  255. while(c!=0)
  256. {
  257. buft[++bct]=(c%2);
  258. c/=2;
  259. }
  260. for(i=(bct+1);i<8;i++)
  261. {
  262. buft[i]=0;
  263. }
  264. for(i=(0);i<8;i++)
  265. {
  266. buftv[7-i]=buft[i];
  267. }
  268. for(i=0;i<8;i++)
  269. {
  270. buf[bc+i]=buftv[i];
  271. }
  272. bc+=8;
  273. }
  274. int retrieveft(char *filename)
  275. {
  276. FILE *p;
  277. p=fopen(filename,"rb");
  278. if(p==NULL)
  279. {
  280. return -1;/*Could not open file */
  281. }
  282. for(i=0;i<256;i++)
  283. {
  284. fread(&ft,sizeof(struct ftable),1,p);
  285. leaf[i].c=(unsigned char)i;
  286. leaf[i].freq=ft.freq;
  287. leaf[i].up=NULL;
  288. leaf[i].right=NULL;
  289. leaf[i].left=NULL;
  290. }
  291. fclose(p);
  292. return 0;
  293. }
  294. void init()
  295. {
  296. int i;
  297. for(i=0;i<256;i++)
  298. {
  299. leaf[i].c=(unsigned char)i;
  300. leaf[i].freq=0;
  301. leaf[i].up=NULL;
  302. leaf[i].left=NULL;
  303. leaf[i].right=NULL;
  304. t[i]=&leaf[i];
  305. }
  306. for(i=0;i<256;i++)
  307. {
  308. t[i]=&leaf[i];
  309. }
  310. return;
  311. }
  312. main()
  313. {
  314. FILE *p,*q;
  315. int ch,ct;
  316. char filename[100],encfile[100],outfile[100];
  317. long int filesize,encfilesize;
  318.     long int filelen,count=1024;
  319. float ratio;
  320.     char pil;
  321.     while(pil!=27)
  322.     {
  323.     clrscr();
  324.         printf("nHUFFMANn-------------------n");
  325.         printf("[1]Compressionn[2]Decompressionn[ESC]exitn");
  326.         pil=getch();
  327.         if(pil=='C'||pil=='c')
  328.         {
  329.             clrscr();
  330.         printf("nMasukkan Nama File yang akan dikompresi:");
  331.         scanf("%s",filename);
  332.         printf("nMasukkan Nama File hasil kompresi:");
  333.         scanf("%s",encfile);
  334.         if(init(filename)==-1)
  335.         {
  336.         printf("nError...Tidak bisa membuka file");
  337.         fcloseall();
  338.         return -1;
  339.         }
  340.         if(maketree()==-1)
  341.         {
  342.         printf("nAllokasi error");
  343.         fcloseall();
  344.         return -1;
  345.         }
  346.         q=fopen(encfile,"wb");
  347.         if(q==NULL)
  348.         {
  349.         printf("nError...Tidak bisa membuka file");
  350.         fcloseall();
  351.         return -1;
  352.         }
  353.         p=fopen(filename,"rb");
  354.         if(p==NULL)
  355.         {
  356.         printf("nError...Tidak bisa membuka file");
  357.         fcloseall();
  358.         return -1;
  359.         }
  360.         filesize=filelength(fileno(p));
  361.         /****To write the decoding table */
  362.         for(i=0;i<256;i++)
  363.         {
  364.         ft.freq=leaf[i].freq;
  365.         fwrite(&ft.freq,sizeof(struct ftable),1,q);
  366.         }
  367.         /*To write the character that denotes the size of filenamelength*/
  368.         fputc(strlen(getname(filename))+1,q);
  369.         /*To write the filename*/
  370.         fwrite(getname(filename),strlen(getname(filename))+1,1,q);
  371.         /***Completed writing of decoding table*****/
  372.         while(ch=fgetc(p),ch!=EOF)
  373.         {
  374.         add2buffCom(ch);
  375.         refreshbufferCom(q);
  376.         }
  377.         fputc(oddchar(),q);
  378.         fputc(bc,q);
  379.         fcloseall();
  380.         printf("Kompresi Sukses");
  381.         /*****For display of compression summary****/
  382.         p=fopen(encfile,"rb");
  383.         if(p==NULL)
  384.         {
  385.         printf("nHasil Kompresi tidak bisa ditampilkan");
  386.         return -1;
  387.         }
  388.         encfilesize=filelength(fileno(p));fcloseall();
  389.         printf("nnInformasi Kompresin");
  390.         printf("nInput filesize :%ld bytes",filesize);
  391.         printf("nOutput filesize:%ld",encfilesize);
  392.         ratio=(float)(encfilesize*100/filesize);
  393.         printf("nHasil Kompresi %.3f%% dari hasil asli",ratio);
  394.             getch();
  395.         }else if(pil=='D'||pil=='d')
  396.         {
  397.         printf("nMasukkan file yang ingin didekompres:");scanf("%s",filename);
  398.         init();
  399.         if(retrieveft(filename)==-1)
  400.         {
  401.         printf("nTidak bisa membuka file");
  402.         return -1;
  403.         }
  404.         maketree();
  405.         /*To retrieve the filename from the compressed file*/
  406.         p=fopen(filename,"rb");
  407.         fseek(p,1024,SEEK_SET);
  408.         ct=fgetc(p);
  409.         fread(outfile,ct,1,p);
  410.         /***Filename retrieval finished*/
  411.         p=fopen(filename,"rb");
  412.         /***check for user renaming of output file*/
  413.             printf("nFile yang akan didekompres mengandung file asli: %s",outfile);
  414.         {
  415.         printf("nnMasukkan nama file hasil dekompresi:");scanf("%s",outfile);
  416.         }
  417.         /******check for renaming complete*****/
  418.         q=fopen(outfile,"wb");
  419.         if(q==NULL || p==NULL)
  420.         {
  421.         printf("nTidak bisa membuka file");
  422.         fcloseall();
  423.         return -1;
  424.         }
  425.         fseek(p,256*sizeof(struct ftable)+1+ct,SEEK_SET);
  426.         filelen=filelength(fileno(p));
  427.         count=1024+1+ct;
  428.         while(ch=fgetc(p),count++,ch!=EOF)
  429.         {
  430.         if(count==(filelen-1))
  431.         {
  432.         add2buffDec(ch);
  433.         bc-=8;
  434.         bc+=fgetc(p);
  435.         refreshbufferDec(q);
  436.         while(bc!=0)
  437.         {
  438. refreshbufferDec(q);
  439.         }
  440.         }
  441.         else
  442.         {
  443.         add2buffDec(ch);
  444.         refreshbufferDec(q);
  445.         }
  446.         }
  447.         printf("nDecompression complete.n");
  448.         printf("nOutput file tercipta %s ",outfile);
  449.             getch();
  450.         }
  451.     }
  452. return -1;
  453. }