Esempio n. 1
0
void FreeHuffmanTree(huffman_node_t *huffmanTree){
    if(huffmanTree == NULL)
        return;
    FreeHuffmanTree(huffmanTree->left);
    FreeHuffmanTree(huffmanTree->right);
    free(huffmanTree);
}
Esempio n. 2
0
/****************************************************************************
*   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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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]);
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
/****************************************************************************
*   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 */
}
Esempio n. 7
0
/****************************************************************************
*   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);
}
Esempio n. 8
0
/****************************************************************************
*   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);
    }
}
Esempio n. 9
0
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 */
  }
Esempio n. 10
0
/****************************************************************************
*   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;
}
Esempio n. 11
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;
}
Esempio n. 12
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;
}