Advertisement
Guest User

Untitled

a guest
Dec 15th, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.60 KB | None | 0 0
  1. /*Author: Rui Pedro Paiva
  2. Teoria da Informação, LEI, 2007/2008*/
  3.  
  4. #include <cstdlib>
  5. #include "gzip.h"
  6.  
  7.  
  8. //função principal, a qual gere todo o processo de descompactação
  9. int main()
  10. {
  11. //--- Gzip file management variables
  12. FILE *gzFile; //ponteiro para o ficheiro a abrir
  13. long fileSize;
  14. long origFileSize;
  15. int numBlocks = 0;
  16. gzipHeader gzh;
  17. unsigned char byte; //variável temporária para armazenar um byte lido directamente do ficheiro
  18. unsigned int rb = 0; //último byte lido (poderá ter mais que 8 bits, se tiverem sobrado alguns de leituras anteriores)
  19. char needBits = 0, availBits = 0;
  20. char *vetor_ficheiro;
  21. HuffmanTree *hft, *hft_hlit, *hft_hdist;
  22.  
  23.  
  24. //--- obter ficheiro a descompactar
  25. char fileName[] = "FAQ.txt.gz";
  26.  
  27.  
  28. //--- processar ficheiro
  29. gzFile = fopen(fileName, "rb");
  30. fseek(gzFile, 0L, SEEK_END);
  31. fileSize = ftell(gzFile);
  32. fseek(gzFile, 0L, SEEK_SET);
  33.  
  34. //ler tamanho do ficheiro original (acrescentar: e definir Vector com símbolos
  35. origFileSize = getOrigFileSize(gzFile);
  36.  
  37.  
  38. //--- ler cabeçalho
  39. int erro = getHeader(gzFile, &gzh);
  40. if (erro != 0)
  41. {
  42. printf ("Formato inválido!!!");
  43. return -1;
  44. }
  45.  
  46. //--- Para todos os blocos encontrados
  47. char BFINAL;
  48.  
  49. do
  50. {
  51. //--- ler o block header: primeiro byte depois do cabeçalho do ficheiro
  52. needBits = 3;
  53. if (availBits < needBits)
  54. {
  55. fread(&byte, 1, 1, gzFile);
  56. rb = (byte << availBits) | rb;
  57. availBits += 8;
  58. }
  59.  
  60. //obter BFINAL
  61. //ver se é o último bloco
  62. BFINAL = rb & 0x01; //primeiro bit é o menos significativo
  63. rb = rb >> 1; //descartar o bit correspondente ao BFINAL
  64. availBits -=1;
  65.  
  66. //analisar block header e ver se é huffman dinâmico
  67. if(!isDynamicHuffman(rb)) //ignorar bloco se não for Huffman dinâmico
  68. continue;
  69. rb = rb >> 2; //descartar os 2 bits correspondentes ao BTYPE
  70. availBits -= 2;
  71.  
  72. int HLIT, HDIST, HCLEN;
  73.  
  74. HLIT = read_data(5,&availBits,&rb,gzFile);
  75. printf("HLIT = %d\n", HLIT);
  76.  
  77. HDIST = read_data(5,&availBits,&rb,gzFile);
  78. printf("HDIST = %d\n", HDIST);
  79.  
  80. HCLEN = read_data(4,&availBits,&rb,gzFile);
  81. printf("HCLEN = %d\n", HCLEN);
  82.  
  83. unsigned int comps[19] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  84. int posi[19] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
  85. int auxiliar[19] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  86. int comp=0;
  87.  
  88. for(int i = 0; i<(HCLEN + 4) ; i++){
  89. auxiliar[i]+=read_data(3,&availBits,&rb,gzFile);
  90. }
  91. for(int i = 0; i<19; i++){
  92. comps[posi[i]]+=auxiliar[i];
  93. }
  94. for(int i = 0; i<19; i++){
  95. printf("%d ", comps[i]);
  96. }
  97.  
  98. hft = compcode_to_huffman(comps,19);
  99.  
  100. //Semana 3 - pergunta 4
  101. unsigned int *length_codes1;
  102. int read_size =HLIT+257;
  103. length_codes1= (unsigned int*)malloc(read_size*sizeof(unsigned int));
  104. length_codes1 = get_length_codes(hft, &rb, &availBits, read_size, gzFile);
  105.  
  106. //Semana 4 - pergunta 5
  107. printf("\n\n");
  108. unsigned int *length_codes2;
  109. read_size= HDIST+1;
  110. length_codes2= (unsigned int*)malloc(read_size*sizeof(unsigned int));
  111. length_codes2 = get_length_codes(hft, &rb, &availBits, read_size, gzFile);
  112.  
  113. //Semana 5- pergunta 6
  114.  
  115. hft_hlit = compcode_to_huffman(length_codes1,HLIT+257);
  116. hft_hdist= compcode_to_huffman(length_codes2,HDIST+1);
  117.  
  118. int pos_vetor=0, read_bits, copy_length, dist_node, back_dist, pos_aux;
  119. bool end_block=false;
  120. //pode haver mais blocos
  121. int array_bits_hlit[29]= {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
  122. int array_length_hlit[29]= {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258};
  123.  
  124. int array_bits_hdist[30]= {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
  125. int array_distance_hdist[30]= {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
  126.  
  127. unsigned int bit;
  128. int i_node;
  129. int n=0;
  130. bit=0;
  131. char bits[10];
  132. vetor_ficheiro= (char*)malloc(sizeof(char)*origFileSize);
  133. while(!end_block){
  134. while(1){
  135. bit= read_data(1, &availBits, &rb, gzFile);
  136. i_node= nextNode(hft_hlit, '0'+bit);
  137. if(i_node>=-1){
  138. if(i_node==256){
  139. end_block=true;
  140. break;
  141. }
  142. else if(i_node<256){
  143. printf("%d\n", i_node);
  144. printf("%d\n", pos_vetor);
  145. vetor_ficheiro[0]='0';
  146. printf("%s\n", "sou um teste");
  147. vetor_ficheiro[pos_vetor]=i_node;
  148.  
  149. printf("teste2\n");
  150. pos_vetor++;
  151.  
  152. printf("teste2\n");
  153. }
  154. else{
  155. printf("teste1\n");
  156. pos_aux= i_node -257;
  157. if(i_node<=264 ||i_node== 285)
  158. copy_length= array_length_hlit[pos_aux];
  159. else{
  160. read_bits= array_bits_hlit[pos_aux];
  161. bit= read_data(read_bits, &availBits, &rb, gzFile);
  162.  
  163. copy_length= array_length_hlit[pos_aux]+bit;
  164. }
  165.  
  166. do{
  167. bit= read_data(1, &availBits, &rb, gzFile);
  168. dist_node= nextNode(hft_hdist, '0' + bit);
  169. }while(dist_node==-2);
  170.  
  171. read_bits= array_bits_hdist[dist_node];
  172.  
  173. bit=0;
  174. if(dist_node>=4)
  175. bit= read_data(read_bits, &availBits, &rb, gzFile);
  176.  
  177. back_dist= bit+array_distance_hdist[dist_node];
  178.  
  179. for(int i=0; i<copy_length; i++)
  180. vetor_ficheiro[pos_vetor+i]= vetor_ficheiro[pos_vetor-back_dist+i];
  181. pos_vetor+=copy_length;
  182. printf("n-> %d\n",n);
  183. n++;
  184. }
  185.  
  186. resetCurNode(hft_hlit);
  187. resetCurNode(hft_hdist);
  188. break;
  189. }
  190. }
  191. }
  192.  
  193. //actualizar número de blocos analisados
  194. numBlocks++;
  195.  
  196. }while(BFINAL == 0);
  197.  
  198.  
  199. //terminações
  200. FILE *fp;
  201. fp= fopen("final.txt","w+");
  202.  
  203. fprintf(fp,"%s",vetor_ficheiro);
  204. fclose(fp);
  205.  
  206.  
  207. fclose(gzFile);
  208.  
  209. printf("End: %d bloco(s) analisado(s).\n", numBlocks);
  210.  
  211.  
  212.  
  213. //RETIRAR antes de criar o executável final
  214. system("PAUSE");
  215. return EXIT_SUCCESS;
  216. }
  217.  
  218.  
  219. //---------------------------------------------------------------
  220. //Lê o cabeçalho do ficheiro gzip: devolve erro (-1) se o formato for inválidodevolve, ou 0 se ok
  221. int getHeader(FILE *gzFile, gzipHeader *gzh) //obtém cabeçalho
  222. {
  223. unsigned char byte;
  224.  
  225. //Identicação 1 e 2: valores fixos
  226. fread(&byte, 1, 1, gzFile);
  227. (*gzh).ID1 = byte;
  228. if ((*gzh).ID1 != 0x1f) return -1; //erro no cabeçalho
  229.  
  230. fread(&byte, 1, 1, gzFile);
  231. (*gzh).ID2 = byte;
  232. if ((*gzh).ID2 != 0x8b) return -1; //erro no cabeçalho
  233.  
  234. //Método de compressão (deve ser 8 para denotar o deflate)
  235. fread(&byte, 1, 1, gzFile);
  236. (*gzh).CM = byte;
  237. if ((*gzh).CM != 0x08) return -1; //erro no cabeçalho
  238.  
  239. //Flags
  240. fread(&byte, 1, 1, gzFile);
  241. unsigned char FLG = byte;
  242.  
  243. //MTIME
  244. char lenMTIME = 4;
  245. fread(&byte, 1, 1, gzFile);
  246. (*gzh).MTIME = byte;
  247. for (int i = 1; i <= lenMTIME - 1; i++)
  248. {
  249. fread(&byte, 1, 1, gzFile);
  250. (*gzh).MTIME = (byte << 8) + (*gzh).MTIME;
  251. }
  252.  
  253. //XFL (not processed...)
  254. fread(&byte, 1, 1, gzFile);
  255. (*gzh).XFL = byte;
  256.  
  257. //OS (not processed...)
  258. fread(&byte, 1, 1, gzFile);
  259. (*gzh).OS = byte;
  260.  
  261. //--- Check Flags
  262. (*gzh).FLG_FTEXT = (char)(FLG & 0x01);
  263. (*gzh).FLG_FHCRC = (char)((FLG & 0x02) >> 1);
  264. (*gzh).FLG_FEXTRA = (char)((FLG & 0x04) >> 2);
  265. (*gzh).FLG_FNAME = (char)((FLG & 0x08) >> 3);
  266. (*gzh).FLG_FCOMMENT = (char)((FLG & 0x10) >> 4);
  267.  
  268. //FLG_EXTRA
  269. if ((*gzh).FLG_FEXTRA == 1)
  270. {
  271. //ler 2 bytes XLEN + XLEN bytes de extra field
  272. //1º byte: LSB, 2º: MSB
  273. char lenXLEN = 2;
  274.  
  275. fread(&byte, 1, 1, gzFile);
  276. (*gzh).xlen = byte;
  277. fread(&byte, 1, 1, gzFile);
  278. (*gzh).xlen = (byte << 8) + (*gzh).xlen;
  279.  
  280. (*gzh).extraField = new unsigned char[(*gzh).xlen];
  281.  
  282. //ler extra field (deixado como está, i.e., não processado...)
  283. for (int i = 0; i <= (*gzh).xlen - 1; i++)
  284. {
  285. fread(&byte, 1, 1, gzFile);
  286. (*gzh).extraField[i] = byte;
  287. }
  288. }
  289. else
  290. {
  291. (*gzh).xlen = 0;
  292. (*gzh).extraField = 0;
  293. }
  294.  
  295. //FLG_FNAME: ler nome original
  296. if ((*gzh).FLG_FNAME == 1)
  297. {
  298. (*gzh).fName = new char[1024];
  299. unsigned int i = 0;
  300. do
  301. {
  302. fread(&byte, 1, 1, gzFile);
  303. if (i <= 1023) //guarda no máximo 1024 caracteres no array
  304. (*gzh).fName[i] = byte;
  305. i++;
  306. }while(byte != 0);
  307. if (i > 1023)
  308. (*gzh).fName[1023] = 0; //apesar de nome incompleto, garantir que o array termina em 0
  309. }
  310. else
  311. (*gzh).fName = 0;
  312.  
  313. //FLG_FCOMMENT: ler comentário
  314. if ((*gzh).FLG_FCOMMENT == 1)
  315. {
  316. (*gzh).fComment = new char[1024];
  317. unsigned int i = 0;
  318. do
  319. {
  320. fread(&byte, 1, 1, gzFile);
  321. if (i <= 1023) //guarda no máximo 1024 caracteres no array
  322. (*gzh).fComment[i] = byte;
  323. i++;
  324. }while(byte != 0);
  325. if (i > 1023)
  326. (*gzh).fComment[1023] = 0; //apesar de comentário incompleto, garantir que o array termina em 0
  327. }
  328. else
  329. (*gzh).fComment = 0;
  330.  
  331.  
  332. //FLG_FHCRC (not processed...)
  333. if ((*gzh).FLG_FHCRC == 1)
  334. {
  335. (*gzh).HCRC = new unsigned char[2];
  336. fread(&byte, 1, 1, gzFile);
  337. (*gzh).HCRC[0] = byte;
  338. fread(&byte, 1, 1, gzFile);
  339. (*gzh).HCRC[1] = byte;
  340. }
  341. else
  342. (*gzh).HCRC = 0;
  343.  
  344. return 0;
  345. }
  346.  
  347.  
  348. //---------------------------------------------------------------
  349. //Analisa block header e vê se é huffman dinâmico
  350. int isDynamicHuffman(unsigned char rb)
  351. {
  352. unsigned char BTYPE = rb & 0x03;
  353.  
  354. if (BTYPE == 0) //--> sem compressão
  355. {
  356. printf("Ignorando bloco: sem compactação!!!\n");
  357. return 0;
  358. }
  359. else if (BTYPE == 1)
  360. {
  361. printf("Ignorando bloco: compactado com Huffman fixo!!!\n");
  362. return 0;
  363. }
  364. else if (BTYPE == 3)
  365. {
  366. printf("Ignorando bloco: BTYPE = reservado!!!\n");
  367. return 0;
  368. }
  369. else
  370. return 1;
  371. }
  372.  
  373.  
  374. //---------------------------------------------------------------
  375. //Obtém tamanho do ficheiro original
  376. long getOrigFileSize(FILE * gzFile)
  377. {
  378. //salvaguarda posição actual do ficheiro
  379. long fp = ftell(gzFile);
  380.  
  381. //últimos 4 bytes = ISIZE;
  382. fseek(gzFile, -4, SEEK_END);
  383.  
  384. //determina ISIZE (só correcto se cabe em 32 bits)
  385. unsigned long sz = 0;
  386. unsigned char byte;
  387. fread(&byte, 1, 1, gzFile);
  388. sz = byte;
  389. for (int i = 0; i <= 2; i++)
  390. {
  391. fread(&byte, 1, 1, gzFile);
  392. sz = (byte << 8*(i+1)) + sz;
  393. }
  394.  
  395.  
  396. //restaura file pointer
  397. fseek(gzFile, fp, SEEK_SET);
  398.  
  399. return sz;
  400. }
  401.  
  402.  
  403. //---------------------------------------------------------------
  404. void bits2String(char *strBits, char byte, char len)
  405. {
  406. char mask = 0x01; //get LSbit
  407.  
  408. strBits[len] = 0;
  409. for (char bit, i = len-1; i >= 0; i--)
  410. {
  411. bit = byte & mask;
  412. strBits[i] = bit +48; //converter valor numérico para o caracter alfanumérico correspondente
  413. byte = byte >> 1;
  414. }
  415. }
  416.  
  417. int read_data(char needBits, char *availBits, unsigned int *rb, FILE *gzFile){
  418. int resultado;
  419. int mask;
  420. unsigned char byte;
  421.  
  422. mask = (1<<needBits)-1;
  423. while (*availBits < needBits){
  424. fread(&byte, 1, 1, gzFile);
  425. *rb = (byte << *availBits) | *rb;
  426. *availBits += 8;
  427. }
  428. resultado = *rb & mask;
  429. *rb = *rb >> needBits;
  430. *availBits -= needBits;
  431. return resultado;
  432. }
  433. //--------------------------------------------------------------
  434. HuffmanTree * compcode_to_huffman(unsigned int *comps, int tam){
  435. int mini=0, maxi=0;
  436. for(int i=0; i<tam; i++){
  437. if(mini == 0 || (comps[i]!=0 && comps[i]<mini))
  438. mini= comps[i];
  439. if(comps[i]>maxi)
  440. maxi= comps[i];
  441. }
  442. char * dec_codes;
  443. dec_codes= (char*)malloc(tam*sizeof(char));
  444. int entrou;
  445. int comprimento =0;
  446. for(int k=mini; k<=maxi; k++){
  447. entrou=0;
  448. for(int i=0; i<(tam); i++){
  449. if(comps[i]==k){
  450. entrou=1;
  451. dec_codes[i]=comprimento;
  452. for(int j=i+1; j<(tam); j++){
  453. if(comps[j]==k){
  454. comprimento= comprimento+1;
  455. dec_codes[j]=comprimento;
  456. }
  457. }
  458. comprimento= (1+comprimento)*2;
  459. break;
  460. }
  461. }
  462. if(entrou==0){
  463. printf("entrou 0 com k= %d\n",k);
  464. comprimento= comprimento*2;
  465. }
  466. }
  467.  
  468. for(int i=0; i<tam; i++){
  469. if(comps[i]==0)
  470. dec_codes[i]=0;
  471. }
  472.  
  473. char codigos[tam][256];
  474. // codigos = (char *)malloc(sizeof(char));
  475. for(int i = 0; i<tam; i++){
  476. bits2String(codigos[i], dec_codes[i],comps[i]);
  477. printf("%s ", codigos[i]);
  478. }
  479.  
  480. printf("\n");
  481. HuffmanTree * hft;
  482. hft = createHFTree();
  483.  
  484. for(int i = 0; i<tam; i++){
  485. if(strlen(codigos[i])>0){
  486. addNode(hft, codigos[i], i, 1);
  487. }
  488. }
  489. printf("\n\n");
  490. /*for(int i = 0; i<tam; i++){
  491. if(strlen(codigos[i])>0){
  492. findNode(hft, codigos[i], 1);
  493. }
  494. }*/
  495. return hft;
  496.  
  497. }
  498.  
  499.  
  500.  
  501. unsigned int * get_length_codes(HuffmanTree *hft, unsigned int *rb, char *availBits, int read_size, FILE *gzfile){
  502. unsigned int bit;
  503. int i_node;
  504. int extra_bits;
  505. unsigned int * length_codes;
  506. length_codes= (unsigned int*)malloc(read_size*sizeof(unsigned int));
  507. int i=0;
  508. while(i<read_size){
  509. while(1){
  510. bit= read_data(1, availBits, rb, gzfile);
  511. i_node= nextNode(hft, '0' + bit);
  512. if(i_node>=-1){
  513. if(i_node==-1)
  514. length_codes[i++]=0;
  515.  
  516. else{
  517. if(i_node <16)
  518. length_codes[i++]= i_node;
  519. else if(i_node==16){
  520. bit= read_data(2, availBits, rb, gzfile);
  521. extra_bits= bit+3;
  522. for(int j=i; j<extra_bits+i;j++)
  523. length_codes[j]= length_codes[i-1];
  524. i+=extra_bits;
  525. }
  526. else if(i_node==17){
  527. bit= read_data(3, availBits, rb, gzfile);
  528. extra_bits= bit+3;
  529. for(int j=i; j<extra_bits+i; j++)
  530. length_codes[j]=0;
  531. i+=extra_bits;
  532.  
  533. }
  534. else if(i_node==18){
  535. bit= read_data(7, availBits, rb, gzfile);
  536. extra_bits= bit+11;
  537. for(int j=i; j<extra_bits+i;j++)
  538. length_codes[j]= 0;
  539. i+=extra_bits;
  540. }
  541. }
  542. resetCurNode(hft);
  543. break;
  544. }
  545. }
  546. }
  547. for(i=0; i<read_size;i++){
  548. printf("%d ",length_codes[i]);
  549. }
  550.  
  551. return length_codes;
  552. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement