void FreeHuffmanTree(huffman_node_t *huffmanTree){ if(huffmanTree == NULL) return; FreeHuffmanTree(huffmanTree->left); FreeHuffmanTree(huffmanTree->right); free(huffmanTree); }
/**************************************************************************** * Function : FreeHuffmanTree * Description: This is a recursive routine for freeing the memory * allocated for a node and all of its descendants. * Parameters : ht - structure to delete along with its children. * Effects : Memory for a huffman_node_t and its children is returned to * the heap. * Returned : None ****************************************************************************/ void FreeHuffmanTree(huffman_node_t *ht) { if (ht->left != NULL) { FreeHuffmanTree(ht->left); } if (ht->right != NULL) { FreeHuffmanTree(ht->right); } free(ht); }
void DecodeFile(FILE *infile,FILE *outfile){ int ch; huffman_node_t *huffmanLeaves[CHARCOUNT], *htree, *currentnode; huffman_code_t *huffmanCodes[CHARCOUNT]; buffered_bit_file_t *bufferedInFile; buffered_bit_file_t *bufferedOutFile=CreateBitOutFile(outfile); for(ch=0;ch<CHARCOUNT;ch++){ huffmanLeaves[ch]=CreateNode(ch); } huffmanLeaves[EOF_CHAR]->value=EOF_CHAR; huffmanLeaves[EOF_CHAR]->count=1; ReadFrequencyArray(infile, huffmanLeaves); htree=BuildTree(huffmanLeaves, CHARCOUNT); bufferedInFile=CreateBitInFile(infile); if(htree != huffmanLeaves[EOF_CHAR]){ for(int i=0;i<CHARCOUNT;i++){ huffmanCodes[i]=CreateCode(); } GenerateCodeList(huffmanCodes, htree); currentnode=htree; for(;;){ int bit=BitFileGetBit(bufferedInFile); if(bit != 0) currentnode=currentnode->left; else currentnode=currentnode->right; if(currentnode->value != COMBINE_NODE){ if(currentnode->value == EOF_CHAR){ BitFileFlush(bufferedOutFile); break; } BitFilePutChar(bufferedOutFile, currentnode->value); currentnode=htree; } } for(int i=0;i<CHARCOUNT;i++) free(huffmanCodes[i]); } FreeHuffmanTree(htree); free(bufferedInFile); free(bufferedOutFile); }
void EncodeFile(FILE *infile,FILE *outfile){ int ch; huffman_node_t *huffmanLeaves[CHARCOUNT], *htree; buffered_bit_file_t *bufferedOutFile=CreateBitOutFile(outfile); huffman_code_t *huffmanCodes[CHARCOUNT]; unsigned char *buffer; size_t buffersize=1000000, readcount; buffer=(unsigned char*)malloc(buffersize*sizeof(unsigned char)); for(ch=0;ch<CHARCOUNT;ch++){ huffmanLeaves[ch]=CreateNode(ch); } while ((readcount=fread(buffer, sizeof(unsigned char), buffersize, infile)) == buffersize) { for(int i=0;i<buffersize;i++) ++huffmanLeaves[buffer[i]]->count; } for(int i=0;i<readcount;i++) ++huffmanLeaves[buffer[i]]->count; huffmanLeaves[EOF_CHAR]->value=EOF_CHAR; huffmanLeaves[EOF_CHAR]->count=1; WriteFrequencyArray(bufferedOutFile, huffmanLeaves, CHARCOUNT); htree=BuildTree(huffmanLeaves, CHARCOUNT); for(int i=0;i<CHARCOUNT;i++){ huffmanCodes[i]=CreateCode(); } GenerateCodeList(huffmanCodes, htree); rewind(infile); while ((readcount=fread(buffer, sizeof(unsigned char), buffersize, infile)) == buffersize) { for(int i=0;i<buffersize;i++) BitFileWriteCode(bufferedOutFile, huffmanCodes[buffer[i]]); } for(int i=0;i<readcount;i++) BitFileWriteCode(bufferedOutFile, huffmanCodes[buffer[i]]); BitFileWriteCode(bufferedOutFile, huffmanCodes[EOF_CHAR]); BitFileFlush(bufferedOutFile); FreeHuffmanTree(htree); free(bufferedOutFile); free(buffer); for(int i=0;i<CHARCOUNT;i++) free(huffmanCodes[i]); }
int main(int argc, char *argv[]) { FILE *fpIn; bit_file_t bfpOut; huffman_node_t *huffmanTree; /* root of huffman tree */ char outBuf[1024]; /* open binary input file and bitfile output file */ if ((fpIn = fopen(filename, "rb")) == NULL) { perror(filename); return FALSE; } bfpOut.mode = BF_WRITE; bfpOut.buf = outBuf; bfpOut.bufLen = sizeof(outBuf); BitFileInit(&bfpOut); /* build tree */ if ((huffmanTree = GenerateTreeFromFile(fpIn)) == NULL) { fclose(fpIn); BitFileClose(&bfpOut); return FALSE; } /* use tree to generate a canonical code */ if (!BuildCanonicalCode(huffmanTree, canonicalList)) { fclose(fpIn); BitFileClose(&bfpOut); FreeHuffmanTree(huffmanTree); /* free allocated memory */ return FALSE; } WriteHeader(canonicalList, &bfpOut); return TRUE; }
/**************************************************************************** * Function : DecodeFile * Description: This function decodes a huffman encode file, writing the * results to the specified output file. * Parameters : ht - pointer to array of tree node pointers * inFile - file to decode * outFile - where to output results (NULL -> stdout) * Effects : inFile is decode and the results are written to outFile. * Returned : None ****************************************************************************/ void DecodeFile(huffman_node_t **ht, char *inFile, char *outFile) { huffman_node_t *huffmanTree, *currentNode; int i, c; FILE *fpIn, *fpOut; if ((fpIn = fopen(inFile, "rb")) == NULL) { perror(inFile); exit(EXIT_FAILURE); return; } if (outFile == NULL) { fpOut = stdout; } else { if ((fpOut = fopen(outFile, "wb")) == NULL) { perror(outFile); exit(EXIT_FAILURE); } } /* allocate array of leaves for all possible characters */ for (i = 0; i < NUM_CHARS; i++) { ht[i] = AllocHuffmanNode(i); } /* populate leaves with frequency information from file header */ ReadHeader(ht, fpIn); /* put array of leaves into a huffman tree */ huffmanTree = BuildHuffmanTree(ht, NUM_CHARS); /* now we should have a tree that matches the tree used on the encode */ currentNode = huffmanTree; /* handle one symbol codes */ if (currentNode->value != COMPOSITE_NODE) { while ((c = fgetc(fpIn)) != EOF); /* read to force EOF below */ /* now just write out number of required symbols */ while(totalCount) { fputc(currentNode->value, fpOut); totalCount--; } } while ((c = fgetc(fpIn)) != EOF) { /* traverse the tree finding matches for our characters */ for(i = 0; i < 8; i++) { if (c & 0x80) { currentNode = currentNode->right; } else { currentNode = currentNode->left; } if (currentNode->value != COMPOSITE_NODE) { /* we've found a character */ fputc(currentNode->value, fpOut); currentNode = huffmanTree; totalCount--; if (totalCount == 0) { /* we've just written the last character */ break; } } c <<= 1; } } /* close all files */ fclose(fpIn); fclose(fpOut); FreeHuffmanTree(huffmanTree); /* free allocated memory */ }
/**************************************************************************** * Function : EncodeFile * Description: This function uses the provide Huffman tree to encode * the file passed as a parameter. * Parameters : ht - pointer to root of tree * inFile - file to encode * outFile - where to output results (NULL -> stdout) * Effects : inFile is encoded and the code plus the results are * written to outFile. * Returned : None ****************************************************************************/ void EncodeFile(huffman_node_t *ht, char *inFile, char *outFile) { code_list_t codeList[NUM_CHARS]; /* table for quick encode */ FILE *fpIn, *fpOut; int c, i, bitCount; char bitBuffer; /* open binary input and output files */ if ((fpIn = fopen(inFile, "rb")) == NULL) { perror(inFile); exit(EXIT_FAILURE); } if (outFile == NULL) { fpOut = stdout; } else { if ((fpOut = fopen(outFile, "wb")) == NULL) { perror(outFile); FreeHuffmanTree(ht); exit(EXIT_FAILURE); } } WriteHeader(ht, fpOut); /* write header for rebuilding of tree */ MakeCodeList(ht, codeList); /* convert code to easy to use list */ /* write encoded file 1 byte at a time */ bitBuffer = 0; bitCount = 0; while((c = fgetc(fpIn)) != EOF) { /* shift in bits */ for(i = 0; i < codeList[c].codeLen; i++) { bitCount++; bitBuffer = (bitBuffer << 1) | (TestBit256(codeList[c].code, i) == 1); if (bitCount == 8) { /* we have a byte in the buffer */ fputc(bitBuffer, fpOut); bitCount = 0; } } } /* now handle spare bits */ if (bitCount != 0) { bitBuffer <<= 8 - bitCount; fputc(bitBuffer, fpOut); } fclose(fpIn); fclose(fpOut); }
/**************************************************************************** * Function : PrintCode * Description: This function does a depth first traversal of huffman tree * printing out the code for each character node it reaches. * Parameters : ht - pointer to root of tree * outFile - where to output results (NULL -> stdout) * Effects : The code for the characters contained in the tree is * printed to outFile. * Returned : None ****************************************************************************/ void PrintCode(huffman_node_t *ht, char *outFile) { char code[256]; int depth = 0; FILE *fp; if (outFile == NULL) { fp = stdout; } else { if ((fp = fopen(outFile, "w")) == NULL) { perror(outFile); FreeHuffmanTree(ht); exit(EXIT_FAILURE); } } /* print heading to make things look pretty (int is 10 char max) */ fprintf(fp, "Char Count Encoding\n"); fprintf(fp, "----- ---------- ----------------\n"); for(;;) { /* follow this branch all the way left */ while (ht->left != NULL) { code[depth] = '0'; ht = ht->left; depth++; } if (ht->value != COMPOSITE_NODE) { /* handle the case of a single symbol code */ if (depth == 0) { code[depth] = '0'; depth++; } /* we hit a character node, print its code */ code[depth] = '\0'; fprintf(fp, "0x%02X %10d %s\n", ht->value, ht->count, code); } while (ht->parent != NULL) { if (ht != ht->parent->right) { /* try the parent's right */ code[depth - 1] = '1'; ht = ht->parent->right; break; } else { /* parent's right tried, go up one level yet */ depth--; ht = ht->parent; code[depth] = '\0'; } } if (ht->parent == NULL) { /* we're at the top with nowhere to go */ break; } } if (outFile != NULL) { fclose(fp); } }
main(){ struct sockaddr_in server; struct sockaddr_in client; pid_t pid; int sock; int sock_client; int sin_size; int byte_recv; char send_data[1024]; char recv_data[1024]; struct hostent *host; int stat_val; pid_t child_pid; int checkuser, checkpass; huffman_node_t *huffmanTree; /* root of huffman tree */ int opt; char *inFile, *outFile; MODES mode; long numbyte; // number of byte receive // Tao kiem soat tin hieu signal(SIGCHLD, handle_child); if((sock = socket(AF_INET,SOCK_STREAM,0)) == -1) { perror("Socket"); exit(0); } server.sin_family = AF_INET; server.sin_port = htons(PORT); server.sin_addr.s_addr = INADDR_ANY; /* Cach Khac Lay LocalHost server.sin_addr = *((struct in_addr *)host->h_addr); server.sin_addr.s_addr=inet_ntoa(); */ bzero(&(server.sin_zero),8); if(bind(sock,(struct sockaddr*)&server,sizeof(struct sockaddr)) == -1){ perror("bind() error!!"); exit(0); } if(listen(sock,BACKLOG) == -1){ perror("Listen() error!!"); exit(0); } while(1){ sin_size = sizeof(struct sockaddr_in); sock_client = accept(sock,(struct sockaddr*)&client,&sin_size); if( sock_client == -1){ perror("Accept() error!!\n"); exit(0); } // Forking Server pid = fork(); switch(pid){ case -1: //khong the tao them chuong trinh con printf("can't fork()\n");break; case 0: close(sock); /* Child Socket Listening ; */ printf("Have a connection from:%s\n\n",inet_ntoa(client.sin_addr)); send(sock_client,"\t\tDang nhap he thong!\n\t\tUsername:"******"Username: %s \n" , recv_data); //kiem tra username recv_data[byte_recv-1] = '\0'; if(strcmp(recv_data,"conghoan")!=0) { send(sock_client,"sai",50,0);//neu sai ten checkuser =-1; }else { send(sock_client,"dung",50,0);//neu dung user checkuser =0; } if(checkuser == -1) { //send(sock_client,"0",1,0); send(sock_client,"\tTai khoan nay chua ton tai, nhap Username => Dang ki\n\t\tUsername:"******"New Username: %s \n" , recv_data); send(sock_client,"\tNhap Password => Dang ki\n\t\tPassword:"******"New Password: %s \n" , recv_data); send(sock_client,"Dang ki thanh cong",50,0); close(sock_client); /* Close With terminal of Child Socket */ break; } else{ send(sock_client,"\n\t\tPassword:"******"Password: %s \n" , recv_data); //kiem tra password recv_data[byte_recv-1] = '\0'; if(strcmp(recv_data,"conghoan")!=0) { send(sock_client,"sai2",50,0);//sai pass checkpass =-1; }else { send(sock_client,"dung2",50,0);//dung pass checkpass = 0; } if(checkpass == -1)//neu sai { //send(sock_client,"Dang nhap khong thanh cong",50,0); close(sock_client); /* Close With terminal of Child Socket */ break; } else { //menu chuong trinh //send(sock_client,"\t\tWelcome to my server!\n\t\tMenu:\n\t\t1: Ma hoa.\n\t\t2: Giai ma.\n\t\t3: Thoat.",100,0); send(sock_client,"\t\tWelcome to my server!\n\t\tMenu:\n\t\t1: Ma hoa.\n\t\t2: Giai ma.\n\t\t3: Thoat.",200,0); //while(1) //{ byte_recv = recv(sock_client,recv_data,1024,0); recv_data[byte_recv] = '\0'; if(strcmp(recv_data,"3")==0) { close(sock_client); /* Close With terminal of Child Socket */ break; } //=================================giai ma mot file gui toi if(recv_data[0]=='2') { //else{ printf("\nClient da chon: %s -- Giai ma\n" , recv_data); //nhan file va luu file FILE *pFileluu; pFileluu = fopen ("giaima.txt", "wb"); if ((numbyte = recv(sock_client,recv_data,MAXSIZE,0)) == -1){ /* calls recv() */ printf("recv() error\n"); exit(-1); } printf ("Da nhan -%ld-ki tu", numbyte); fwrite(recv_data,1,numbyte,pFileluu);//luu lai file da nhan //fclose(pFileluu); printf("File tu Client da Upload: \n%s\n",recv_data); /* it prints server's welcome message =) */ fclose(pFileluu); //ma hoa DecodeFile(huffmanArray,"giaima.txt","da_giaima.txt"); { FILE * pFile; FILE *pFile1; long lSize; char * buffer; size_t result; int fd, numbytes; /* files descriptors */ char buf[MAXDATASIZE]; /* buf will store received text */ char buf1[MAXDATASIZE]; pFile = fopen ("da_giaima.txt", "rb" ); // pFile1 = fopen ("myfile1.txt", "wb"); if (pFile==NULL) {fputs ("File error",stderr); exit (1);} // obtain file size: fseek (pFile , 0 , SEEK_END); lSize = ftell (pFile); rewind (pFile); // allocate memory to contain the whole file: buffer = (char*) malloc (sizeof(char)*lSize); if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);} // copy the file into the buffer: result = fread (buffer,1,lSize,pFile); if (result != lSize) {fputs ("Reading error",stderr); exit (3);} if ((numbytes = send (sock_client, buffer, lSize, 0)) == -1){ printf ("send()error\n"); exit(-1); } printf("--%ld ki tu da duoc gui di--\n", lSize); printf ("Ket thuc gui\n"); exit(-1); // if ((numbytes=recv(fd,buf,MAXDATASIZE,0)) == -1){ /* calls recv() */ // printf("recv() error\n"); // exit(-1); // } } close(sock_client); /* Close With terminal of Child Socket */ break; } // ----------------------==-=-===================== ma hoa file gui toi if(recv_data[0]=='1'){ printf("\nClient da chon: %s -- Ma hoa\n" , recv_data); //nhan file va luu file FILE *pFileluu; pFileluu = fopen ("mahoa.txt", "wb"); if ((numbyte = recv(sock_client,recv_data,MAXSIZE,0)) == -1){ /* calls recv() */ printf("recv() error\n"); exit(-1); } printf ("Da nhan -%ld-ki tu", numbyte); fwrite(recv_data,1,numbyte,pFileluu);//luu lai file da nhan //fclose(pFileluu); printf("File tu Client da Upload: \n%s\n",recv_data); /* it prints server's welcome message =) */ fclose(pFileluu); //ma hoa huffmanTree = GenerateTreeFromFile("mahoa.txt"); EncodeFile(huffmanTree,"mahoa.txt","da_mahoa.txt"); PrintCode(huffmanTree,"bangma.txt"); FreeHuffmanTree(huffmanTree); /* free allocated memory */ { FILE * pFile; FILE *pFile1; long lSize; char * buffer; size_t result; int fd, numbytes; /* files descriptors */ char buf[MAXDATASIZE]; /* buf will store received text */ char buf1[MAXDATASIZE]; pFile = fopen ("da_mahoa.txt", "rb" ); // pFile1 = fopen ("myfile1.txt", "wb"); if (pFile==NULL) {fputs ("File error",stderr); exit (1);} // obtain file size: fseek (pFile , 0 , SEEK_END); lSize = ftell (pFile); rewind (pFile); // allocate memory to contain the whole file: buffer = (char*) malloc (sizeof(char)*lSize); if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);} // copy the file into the buffer: result = fread (buffer,1,lSize,pFile); if (result != lSize) {fputs ("Reading error",stderr); exit (3);} if ((numbytes = send (sock_client, buffer, lSize, 0)) == -1){ printf ("send()error\n"); exit(-1); } printf("--%ld-- ki tu da ma hoa gui ve cho Client--\n", lSize); printf ("Ket thuc gui\n"); exit(-1); // if ((numbytes=recv(fd,buf,MAXDATASIZE,0)) == -1){ /* calls recv() */ // printf("recv() error\n"); // exit(-1); // } } close(sock_client); /* Close With terminal of Child Socket */ break; } } } case 1: if(strcmp(recv_data,"3")==0){ close(sock); /* Close Listening */ break; } break; } } close(sock_client); /* Parent Close Connect Socket */ }
/**************************************************************************** * Function : HuffmanEncodeFile * Description: This routine genrates a huffman tree optimized for a file * and writes out an encoded version of that file. * Parameters : inFile - Open file pointer for file to encode (must be * rewindable). * outFile - Open file pointer for file receiving encoded data * Effects : File is Huffman encoded * Returned : 0 for success, -1 for failure. errno will be set in the * event of a failure. Either way, inFile and outFile will * be left open. ****************************************************************************/ int HuffmanEncodeFile(FILE *inFile, FILE *outFile) { huffman_node_t *huffmanTree; /* root of huffman tree */ code_list_t codeList[NUM_CHARS]; /* table for quick encode */ bit_file_t *bOutFile; int c; /* validate input and output files */ if ((NULL == inFile) || (NULL == outFile)) { errno = ENOENT; return -1; } bOutFile = MakeBitFile(outFile, BF_WRITE); if (NULL == bOutFile) { perror("Making Output File a BitFile"); return -1; } /* build tree */ if ((huffmanTree = GenerateTreeFromFile(inFile)) == NULL) { outFile = BitFileToFILE(bOutFile); return -1; } /* build a list of codes for each symbol */ /* initialize code list */ for (c = 0; c < NUM_CHARS; c++) { codeList[c].code = NULL; codeList[c].codeLen = 0; } if (0 != MakeCodeList(huffmanTree, codeList)) { outFile = BitFileToFILE(bOutFile); return -1; } /* write out encoded file */ /* write header for rebuilding of tree */ WriteHeader(huffmanTree, bOutFile); /* read characters from file and write them to encoded file */ rewind(inFile); /* start another pass on the input file */ while((c = fgetc(inFile)) != EOF) { BitFilePutBits(bOutFile, BitArrayGetBits(codeList[c].code), codeList[c].codeLen); } /* now write EOF */ BitFilePutBits(bOutFile, BitArrayGetBits(codeList[EOF_CHAR].code), codeList[EOF_CHAR].codeLen); /* free the code list */ for (c = 0; c < NUM_CHARS; c++) { if (codeList[c].code != NULL) { BitArrayDestroy(codeList[c].code); } } /* clean up */ outFile = BitFileToFILE(bOutFile); /* make file normal again */ FreeHuffmanTree(huffmanTree); /* free allocated memory */ return 0; }
/**************************************************************************** * Function : HuffmanShowTree * Description: This routine genrates a huffman tree optimized for a file * and writes out an ASCII representation of the code * represented by the tree. * Parameters : inFile - Open file pointer for file to create the tree for * outFile - Open file pointer for file to write the tree to * Effects : Huffman tree is written out to a file * Returned : 0 for success, -1 for failure. errno will be set in the * event of a failure. Either way, inFile and outFile will * be left open. ****************************************************************************/ int HuffmanShowTree(FILE *inFile, FILE *outFile) { huffman_node_t *huffmanTree; /* root of huffman tree */ huffman_node_t *htp; /* pointer into tree */ char code[NUM_CHARS - 1]; /* 1s and 0s in character's code */ int depth = 0; /* depth of tree */ /* validate input and output files */ if ((NULL == inFile) || (NULL == outFile)) { errno = ENOENT; return -1; } /* build tree */ if ((huffmanTree = GenerateTreeFromFile(inFile)) == NULL) { return -1; } /* write out tree */ /* print heading to make things look pretty (int is 10 char max) */ fprintf(outFile, "Char Count Encoding\n"); fprintf(outFile, "----- ---------- ----------------\n"); htp = huffmanTree; for(;;) { /* follow this branch all the way left */ while (htp->left != NULL) { code[depth] = '0'; htp = htp->left; depth++; } if (htp->value != COMPOSITE_NODE) { /* handle the case of a single symbol code */ if (depth == 0) { code[depth] = '0'; depth++; } /* we hit a character node, print its code */ code[depth] = '\0'; if (htp->value != EOF_CHAR) { fprintf(outFile, "0x%02X %10d %s\n", htp->value, htp->count, code); } else { fprintf(outFile, "EOF %10d %s\n", htp->count, code); } } while (htp->parent != NULL) { if (htp != htp->parent->right) { /* try the parent's right */ code[depth - 1] = '1'; htp = htp->parent->right; break; } else { /* parent's right tried, go up one level yet */ depth--; htp = htp->parent; code[depth] = '\0'; } } if (htp->parent == NULL) { /* we're at the top with nowhere to go */ break; } } /* clean up */ FreeHuffmanTree(huffmanTree); /* free allocated memory */ return 0; }
/**************************************************************************** * Function : HuffmanDecodeFile * Description: This routine reads a Huffman coded file and writes out a * decoded version of that file. * Parameters : inFile - Open file pointer for file to decode * outFile - Open file pointer for file receiving decoded data * Effects : Huffman encoded file is decoded * Returned : 0 for success, -1 for failure. errno will be set in the * event of a failure. Either way, inFile and outFile will * be left open. ****************************************************************************/ int HuffmanDecodeFile(FILE *inFile, FILE *outFile) { huffman_node_t *huffmanArray[NUM_CHARS]; /* array of all leaves */ huffman_node_t *huffmanTree; huffman_node_t *currentNode; int i, c; bit_file_t *bInFile; /* validate input and output files */ if ((NULL == inFile) || (NULL == outFile)) { errno = ENOENT; return -1; } bInFile = MakeBitFile(inFile, BF_READ); if (NULL == bInFile) { perror("Making Input File a BitFile"); return -1; } /* allocate array of leaves for all possible characters */ for (i = 0; i < NUM_CHARS; i++) { if ((huffmanArray[i] = AllocHuffmanNode(i)) == NULL) { /* allocation failed clear existing allocations */ for (i--; i >= 0; i--) { free(huffmanArray[i]); } inFile = BitFileToFILE(bInFile); return -1; } } /* populate leaves with frequency information from file header */ if (0 != ReadHeader(huffmanArray, bInFile)) { for (i = 0; i < NUM_CHARS; i++) { free(huffmanArray[i]); } inFile = BitFileToFILE(bInFile); return -1; } /* put array of leaves into a huffman tree */ if ((huffmanTree = BuildHuffmanTree(huffmanArray, NUM_CHARS)) == NULL) { FreeHuffmanTree(huffmanTree); inFile = BitFileToFILE(bInFile); return -1; } /* now we should have a tree that matches the tree used on the encode */ currentNode = huffmanTree; while ((c = BitFileGetBit(bInFile)) != EOF) { /* traverse the tree finding matches for our characters */ if (c != 0) { currentNode = currentNode->right; } else { currentNode = currentNode->left; } if (currentNode->value != COMPOSITE_NODE) { /* we've found a character */ if (currentNode->value == EOF_CHAR) { /* we've just read the EOF */ break; } fputc(currentNode->value, outFile); /* write out character */ currentNode = huffmanTree; /* back to top of tree */ } } /* clean up */ inFile = BitFileToFILE(bInFile); /* make file normal again */ FreeHuffmanTree(huffmanTree); /* free allocated memory */ return 0; }