![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
|
|
#1 |
|
Newbie
Join Date: Oct 2004
Posts: 2
Rep Power: 0
![]() |
I need to know how to write a huffman code in a java/c++ program
its for a friend of mine...please ![]() |
|
|
|
|
|
#2 |
|
I eat cake for breakfast.
![]() ![]() ![]() ![]() Join Date: Jul 2004
Location: In my box.
Posts: 4,434
Rep Power: 9
![]() |
|
|
|
|
|
|
#3 |
|
Newbie
Join Date: Oct 2004
Posts: 2
Rep Power: 0
![]() |
man, I dont want an explaination to what a huffman code is. I only want to know how to put it in a java/c++ program...I know how to use google but I'm clueless with the subject
![]() |
|
|
|
|
|
#4 |
|
Programming Guru
![]() |
Google is still your god, just search for the right things. I searched for "Huffman code in C++" and found a C implementation of it. Im sure though if you kept looking you could find C++ implementation.
/* File: codhuff.c
Author: David Bourgin (David.Bourgin@ufrima.imag.fr)
Creation date: 7/2/94
Last update: 24/7/95
Purpose: Example of Huffman encoding with a file source to compress.
Attention: The compiler must have been configured for a stack of at least
20 kb.
*/
#include <stdio.h>
/* For routines fgetc,fputc,fwrite and rewind */
#include <memory.h>
/* For routines memset,memcpy */
#include <malloc.h>
/* For routines malloc and free */
#include <stdlib.h>
/* For routines qsort et exit */
/* Error codes returned to the caller */
#define NO_ERROR 0
#define BAD_FILE_NAME 1
#define BAD_ARGUMENT 2
#define BAD_MEM_ALLOC 3
/* Useful constants */
#define FALSE 0
#define TRUE 1
/* Global variables */
FILE *source_file,*dest_file;
typedef struct s_tree { unsigned int byte;
/* A byte has to be coded as an unsigned integer to allow a node to have a value over 255 */
unsigned long int weight;
struct s_tree *left_ptr,
*right_ptr;
} t_tree,*p_tree;
#define BYTE_OF_TREE(ptr_tree) ((*(ptr_tree)).byte)
#define WEIGHT_OF_TREE(ptr_tree) ((*(ptr_tree)).weight)
#define LEFTPTR_OF_TREE(ptr_tree) ((*(ptr_tree)).left_ptr)
#define RIGHTPTR_OF_TREE(ptr_tree) ((*(ptr_tree)).right_ptr)
typedef struct { unsigned char bits[32];
unsigned int bits_nb;
} t_bin_val;
#define BITS_BIN_VAL(bin_val) ((bin_val).bits)
#define BITS_NB_BIN_VAL(bin_val) ((bin_val).bits_nb)
/* Being that fgetc=EOF only after any access
then 'stored_byte_status' is 'TRUE' if a byte has been stored with 'fgetc'
or 'FALSE' if there's no valid byte not already read and not handled in 'stored_byte_val' */
int stored_byte_status=FALSE;
int stored_byte_val;
/* Pseudo procedures */
#define beginning_of_data() { (void)rewind(source_file); stored_byte_status=FALSE; }
#define end_of_data() (stored_byte_status?FALSE:!(stored_byte_status=((stored_byte_val=fgetc(source_file))!=EOF)))
#define read_byte() (stored_byte_status?stored_byte_status=FALSE,(unsigned char)stored_byte_val:(unsigned char)fgetc(source_file))
#define write_byte(byte) ((void)fputc((byte),dest_file))
unsigned char bit_counter_to_write=0;
unsigned int val_to_write=0;
void write_bin_val(bin_val)
/* Returned parameters: None
Action: Writes in the output stream the value binary-coded into 'bin_val'
Errors: An input/output error could disturb the running of the program
*/
t_bin_val bin_val;
{ unsigned char bin_pos,
byte_pos;
byte_pos=(BITS_NB_BIN_VAL(bin_val)+7) >> 3;
bin_pos=BITS_NB_BIN_VAL(bin_val) & 7;
if (bin_pos)
{ byte_pos--;
val_to_write=(val_to_write<<bin_pos)|BITS_BIN_VAL(bin_val)[byte_pos];
bit_counter_to_write += bin_pos;
if (bit_counter_to_write>=8)
{ bit_counter_to_write -= 8;
write_byte((unsigned char)(val_to_write>>bit_counter_to_write));
val_to_write &= ((1<<bit_counter_to_write)-1);
}
}
while (byte_pos)
{ byte_pos--;
val_to_write=(val_to_write<<8)|BITS_BIN_VAL(bin_val)[byte_pos];
write_byte((unsigned char)(val_to_write>>bit_counter_to_write));
val_to_write &= ((1<<bit_counter_to_write)-1);
}
}
void fill_encoding()
/* Returned parameters: None
Action: Fills the last byte to write in the output stream with zero values
Errors: An input/output error could disturb the running of the program
*/
{ if (bit_counter_to_write)
write_byte(val_to_write << (8-bit_counter_to_write));
}
void write_header(codes_table)
/* Returned parameters: None
Action: Writes the header in the stream of codes
Errors: An input/output error could disturb the running of the program
*/
t_bin_val codes_table[257];
{ register unsigned int i,j;
t_bin_val bin_val_to_0,
bin_val_to_1,
bin_val; /* Is used to send in binary mode via write_bin_val */
*BITS_BIN_VAL(bin_val_to_0)=0;
BITS_NB_BIN_VAL(bin_val_to_0)=1;
*BITS_BIN_VAL(bin_val_to_1)=1;
BITS_NB_BIN_VAL(bin_val_to_1)=1;
for (i=0,j=0;j<=255;j++)
if BITS_NB_BIN_VAL(codes_table[j])
i++;
/* From there, i contains the number of bytes of the several non null occurrences to encode */
/* First part of the header: Specifies the bytes that appear in the source of encoding */
if (i<32)
{ /* Encoding of the appeared bytes with a block of bytes */
write_bin_val(bin_val_to_0);
BITS_NB_BIN_VAL(bin_val)=5;
*BITS_BIN_VAL(bin_val)=(unsigned char)(i-1);
write_bin_val(bin_val);
BITS_NB_BIN_VAL(bin_val)=8;
for (j=0;j<=255;j++)
if BITS_NB_BIN_VAL(codes_table[j])
{ *BITS_BIN_VAL(bin_val)=(unsigned char)j;
write_bin_val(bin_val);
}
}
else { /* Encoding of the appeared bytes with a block of bits */
write_bin_val(bin_val_to_1);
for (j=0;j<=255;j++)
if BITS_NB_BIN_VAL(codes_table[j])
write_bin_val(bin_val_to_1);
else write_bin_val(bin_val_to_0);
};
/* Second part of the header: Specifies the encoding of the bytes (fictive or not) that appear in the source of encoding */
for (i=0;i<=256;i++)
if (j=BITS_NB_BIN_VAL(codes_table[i]))
{ if (j<33)
{ write_bin_val(bin_val_to_0);
BITS_NB_BIN_VAL(bin_val)=5;
}
else { write_bin_val(bin_val_to_1);
BITS_NB_BIN_VAL(bin_val)=8;
}
*BITS_BIN_VAL(bin_val)=(unsigned char)(j-1);
write_bin_val(bin_val);
write_bin_val(codes_table[i]);
}
}
int weight_tree_comp(tree1,tree2)
/* Returned parameters: Returns a comparison status
Action: Returns a negative, zero or positive integer depending on the weight
of 'tree2' is less than, equal to, or greater than the weight of 'tree1'
Errors: None
*/
p_tree *tree1,*tree2;
{ return (WEIGHT_OF_TREE(*tree2) ^ WEIGHT_OF_TREE(*tree1))?((WEIGHT_OF_TREE(*tree2)<WEIGHT_OF_TREE(*tree1))?-1:1):0;
}
void suppress_tree(tree)
/* Returned parameters: None
Action: Suppresses the allocated memory for the 'tree'
Errors: None if the tree has been build with dynamical allocations!
*/
p_tree tree;
{ if (tree!=NULL)
{ suppress_tree(LEFTPTR_OF_TREE(tree));
suppress_tree(RIGHTPTR_OF_TREE(tree));
free(tree);
}
}
p_tree build_tree_encoding()
/* Returned parameters: Returns a tree of encoding
Action: Generates an Huffman encoding tree based on the data from the stream to compress
Errors: If no memory is available for the allocations then a 'BAD_MEM_ALLOC' exception is raised
*/
{ register unsigned int i;
p_tree occurrences_table[257],
ptr_fictive_tree;
/* Sets up the occurrences number of all bytes to 0 */
for (i=0;i<=256;i++)
{ if ((occurrences_table[i]=(p_tree)malloc(sizeof(t_tree)))==NULL)
{ for (;i;i--)
free(occurrences_table[i-1]);
exit(BAD_MEM_ALLOC);
}
BYTE_OF_TREE(occurrences_table[i])=i;
WEIGHT_OF_TREE(occurrences_table[i])=0;
LEFTPTR_OF_TREE(occurrences_table[i])=NULL;
RIGHTPTR_OF_TREE(occurrences_table[i])=NULL;
}
/* Valids the occurrences of 'occurrences_table' with regard to the data to compressr */
if (!end_of_data())
{ while (!end_of_data())
{ i=read_byte();
WEIGHT_OF_TREE(occurrences_table[i])++;
}
WEIGHT_OF_TREE(occurrences_table[256])=1;
/* Sorts the occurrences table depending on the weight of each character */
(void)qsort(occurrences_table,257,sizeof(p_tree),weight_tree_comp);
for (i=256;(i!=0)&&(!WEIGHT_OF_TREE(occurrences_table[i]));i--)
free(occurrences_table[i]);
i++;
/* From there, 'i' gives the number of different bytes with a null occurrence in the stream to compress */
while (i>0) /* Looks up (i+1)/2 times the occurrence table to link the nodes in an uniq tree */
{ if ((ptr_fictive_tree=(p_tree)malloc(sizeof(t_tree)))==NULL)
{ for (i=0;i<=256;i++)
suppress_tree(occurrences_table[i]);
exit(BAD_MEM_ALLOC);
}
BYTE_OF_TREE(ptr_fictive_tree)=257;
WEIGHT_OF_TREE(ptr_fictive_tree)=WEIGHT_OF_TREE(occurrences_table[--i]);
LEFTPTR_OF_TREE(ptr_fictive_tree)=occurrences_table[i];
if (i)
{ i--;
WEIGHT_OF_TREE(ptr_fictive_tree) += WEIGHT_OF_TREE(occurrences_table[i]);
RIGHTPTR_OF_TREE(ptr_fictive_tree)=occurrences_table[i];
}
else RIGHTPTR_OF_TREE(ptr_fictive_tree)=NULL;
occurrences_table[i]=ptr_fictive_tree;
(void)qsort((char *)occurrences_table,i+1,sizeof(p_tree),weight_tree_comp);
if (i) /* Is there an other node in the occurrence tables? */
i++; /* Yes, then takes care to the fictive node */
}
}
return (*occurrences_table);
}
void encode_codes_table(tree,codes_table,code_val)
/* Returned parameters: The data of 'codes_table' can have been modified
Action: Stores the encoding tree as a binary encoding table to speed up the access.
'val_code' gives the encoding for the current node of the tree
Errors: None
*/
p_tree tree;
t_bin_val codes_table[257],
*code_val;
{ register unsigned int i;
t_bin_val tmp_code_val;
if (BYTE_OF_TREE(tree)==257)
{ if (LEFTPTR_OF_TREE(tree)!=NULL)
/* The sub-trees on left begin with an bit set to 1 */
{ tmp_code_val = *code_val;
for (i=31;i>0;i--)
BITS_BIN_VAL(*code_val)[i]=(BITS_BIN_VAL(*code_val)[i] << 1)|(BITS_BIN_VAL(*code_val)[i-1] >> 7);
*BITS_BIN_VAL(*code_val)=(*BITS_BIN_VAL(*code_val) << 1) | 1;
BITS_NB_BIN_VAL(*code_val)++;
encode_codes_table(LEFTPTR_OF_TREE(tree),codes_table,code_val);
*code_val = tmp_code_val;
};
if (RIGHTPTR_OF_TREE(tree)!=NULL)
/* The sub-trees on right begin with an bit set to 0 */
{ tmp_code_val = *code_val;
for (i=31;i>0;i--)
BITS_BIN_VAL(*code_val)[i]=(BITS_BIN_VAL(*code_val)[i] << 1)|(BITS_BIN_VAL(*code_val)[i-1] >> 7);
*BITS_BIN_VAL(*code_val) <<= 1;
BITS_NB_BIN_VAL(*code_val)++;
encode_codes_table(RIGHTPTR_OF_TREE(tree),codes_table,code_val);
*code_val = tmp_code_val;
};
}
else codes_table[BYTE_OF_TREE(tree)] = *code_val;
}
void create_codes_table(tree,codes_table)
/* Returned parameters: The data in 'codes_table' will be modified
Action: Stores the encoding tree as a binary encoding table to speed up the access by calling encode_codes_table
Errors: None
*/
p_tree tree;
t_bin_val codes_table[257];
{ register unsigned int i;
t_bin_val code_val;
(void)memset((char *)&code_val,0,sizeof(code_val));
(void)memset((char *)codes_table,0,257*sizeof(*codes_table));
encode_codes_table(tree,codes_table,&code_val);
}
void huffmanencoding()
/* Returned parameters: None
Action: Compresses with Huffman method all bytes read by the function 'read_byte'
Errors: An input/output error could disturb the running of the program
*/
{ p_tree tree;
t_bin_val encoding_table[257];
unsigned char byte_read;
if (!end_of_data())
/* Generates only whether there are data */
{ tree=build_tree_encoding();
/* Creation of the best adapted tree */
create_codes_table(tree,encoding_table);
suppress_tree(tree);
/* Obtains the binary encoding in an array to speed up the accesses */
write_header(encoding_table);
/* Writes the defintion of the encoding */
beginning_of_data(); /* Real compression of the data */
while (!end_of_data())
{ byte_read=read_byte();
write_bin_val(encoding_table[byte_read]);
}
write_bin_val(encoding_table[256]);
/* Code of the end of encoding */
fill_encoding();
/* Fills the last byte before closing file, if any */
}
}
void help()
/* Returned parameters: None
Action: Displays the help of the program and then stops its running
Errors: None
*/
{ printf("This utility enables you to compress a file by using Huffman method\n");
printf("as given in 'La Video et Les Imprimantes sur PC'\n");
printf("\nUse: codhuff source target\n");
printf("source: Name of the file to compress\n");
printf("target: Name of the compressed file\n");
}
int main(argc,argv)
/* Returned parameters: Returns an error code (0=None)
Action: Main procedure
Errors: Detected, handled and an error code is returned, if any
*/
int argc;
char *argv[];
{ if (argc!=3)
{ help();
exit(BAD_ARGUMENT);
}
else if ((source_file=fopen(argv[1],"rb"))==NULL)
{ help();
exit(BAD_FILE_NAME);
}
else if ((dest_file=fopen(argv[2],"wb"))==NULL)
{ help();
exit(BAD_FILE_NAME);
}
else { huffmanencoding();
fclose(source_file);
fclose(dest_file);
}
printf("Execution of codhuff completed.\n");
return (NO_ERROR);
}
__________________
|
|
|
|
|
|
#5 |
|
Expert Programmer
|
I imagine this is for some kind of school assignment? You won't learn anything if you bear such a defeatist code, and you will usually find that scouring forums for simple answers like that will usually not yeild close to what you have managed this time around.
There are MANY excellent tutorials describing huffman trees, I should know... I studied them when I was 10 years old and did not have a problem finding materials in which to do so. All you had to do was take a look.
__________________
Clifford Matthew Roche <geek@cliffordroche.com> Web Hosting: http://www.crd-hosting.com Consulting: http://www.crdev-consulting.com |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|