Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Rudolf
/
huffman
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
a68e36c6
authored
Nov 22, 2016
by
Rudolf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial commit of proper tree huffman
parent
0b682649
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
163 additions
and
74 deletions
header.c
print_helper.c
tree.c
header.c
View file @
a68e36c6
...
...
@@ -6,24 +6,30 @@
static
int
write_entries
(
struct
BIT_BUFFER
*
bitbuf
,
struct
tree
*
parent
)
{
int
bit
;
if
(
parent
->
left
)
{
struct
tree
*
left
=
parent
->
left
;
struct
tree
*
right
=
parent
->
right
;
if
(
left
&&
right
)
{
bit
=
1
;
bb_write
(
bitbuf
,
&
bit
,
1
);
write_entries
(
bitbuf
,
parent
->
left
);
printf
(
" 1"
);
}
if
(
!
parent
->
left
)
{
if
(
left
)
write_entries
(
bitbuf
,
left
);
if
(
right
)
write_entries
(
bitbuf
,
right
);
if
(
!
left
&&
!
right
)
{
bit
=
0
;
bb_write
(
bitbuf
,
&
bit
,
1
);
/* This means now we have 8 bits of char. */
bb_write
(
bitbuf
,
&
bit
,
1
);
bb_writebyte
(
bitbuf
,
parent
->
ch
);
printf
(
" 0"
);
printf
(
"%c"
,
parent
->
ch
);
}
if
(
parent
->
right
)
{
/* Why should we write this if we can save more bits. */
//bit = 0;
//bb_write(bitbuf, &bit, 1);
bb_writebyte
(
bitbuf
,
parent
->
right
->
ch
);
}
return
0
;
}
...
...
@@ -33,37 +39,31 @@ int encode_header(struct BIT_BUFFER *bitbuf, struct tree *parent)
return
0
;
}
static
int
read_entr
ies
(
struct
BIT_BUFFER
*
bitbuf
,
struct
tree
*
parent
)
static
int
read_entr
y
(
struct
BIT_BUFFER
*
bitbuf
,
struct
tree
*
parent
)
{
int
*
bit
=
bb_read
(
bitbuf
,
1
)
;
int
*
bit
;
if
(
bit
==
NULL
)
return
0
;
bit
=
bb_read
(
bitbuf
,
1
);
if
(
*
bit
==
1
)
{
parent
->
left
=
insert_simple_tree
(
0
,
0
);
parent
->
right
=
insert_simple_tree
(
0
,
0
);
read_entries
(
bitbuf
,
parent
->
left
);
}
/* Reads last left character (the inner left). */
if
(
*
bit
==
0
)
{
read_entry
(
bitbuf
,
parent
->
left
);
read_entry
(
bitbuf
,
parent
->
right
);
}
else
{
int
*
c
=
bb_readbyte
(
bitbuf
);
parent
->
ch
=
*
c
;
free
(
c
);
}
/* Reads right character. */
if
(
*
bit
==
1
)
{
int
*
c
=
bb_readbyte
(
bitbuf
);
parent
->
right
->
ch
=
*
c
;
free
(
c
);
printf
(
"Found from header %c
\n
"
,
*
c
);
}
free
(
bit
);
return
0
;
}
static
int
read_entries
(
struct
BIT_BUFFER
*
bitbuf
,
struct
tree
*
parent
)
{
read_entry
(
bitbuf
,
parent
);
}
int
decode_header
(
struct
BIT_BUFFER
*
bitbuf
,
struct
tree
*
parent
)
{
read_entries
(
bitbuf
,
parent
);
...
...
print_helper.c
View file @
a68e36c6
...
...
@@ -48,7 +48,7 @@ void print_char(unsigned char c)
void
print_tree
(
struct
tree
*
parent
)
{
int
level
=
1
;
/*
int level = 1;
printf("Showing tree\n");
while (parent->left != NULL ) {
if (parent->right) {
...
...
@@ -70,5 +70,5 @@ void print_tree(struct tree *parent)
level += 1;
parent = parent->left;
}
}
*/
}
tree.c
View file @
a68e36c6
#include <stdbool.h>
#include <stdlib.h>
#include "huffman.h"
...
...
@@ -27,6 +28,49 @@ struct tree *insert_proper_tree(struct tree *left, struct tree *right)
return
new
;
}
struct
tree
*
merge_smallest
(
struct
tree
**
forest
,
int
length
)
{
struct
tree
*
smallest1
=
NULL
;
struct
tree
*
smallest2
=
NULL
;
printf
(
"--
\n
"
);
int
i1
=
0
,
i2
=
0
;
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
if
(
forest
[
i
]
==
NULL
)
continue
;
if
(
smallest1
==
NULL
)
{
smallest1
=
forest
[
i
];
i1
=
i
;
printf
(
"init Smallest1 %c:%d
\n
"
,
smallest1
->
ch
,
smallest1
->
freq
);
continue
;
}
else
if
(
smallest2
==
NULL
)
{
smallest2
=
forest
[
i
];
i2
=
i
;
printf
(
"init Smallest2 %c:%d
\n
"
,
smallest2
->
ch
,
smallest2
->
freq
);
continue
;
}
printf
(
"comp %c:%d
\n
"
,
forest
[
i
]
->
ch
,
forest
[
i
]
->
freq
);
if
(
forest
[
i
]
->
freq
<
smallest1
->
freq
)
{
smallest1
=
forest
[
i
];
i1
=
i
;
}
else
if
(
forest
[
i
]
->
freq
<
smallest2
->
freq
)
{
smallest2
=
forest
[
i
];
i2
=
i
;
}
}
forest
[
i1
]
=
NULL
;
forest
[
i2
]
=
insert_proper_tree
(
smallest1
,
smallest2
);
printf
(
"Smallest1 %c:%d
\n
"
,
smallest1
->
ch
,
smallest1
->
freq
);
printf
(
"Smallest2 %c:%d
\n
"
,
smallest2
->
ch
,
smallest2
->
freq
);
printf
(
"Merged %c:%d
\n
"
,
forest
[
i2
]
->
ch
,
forest
[
i2
]
->
freq
);
return
forest
[
i2
];
}
struct
tree
*
create_tree
(
FILE
*
file
)
{
int
freq
[
MY_BUF
]
=
{
};
...
...
@@ -58,6 +102,8 @@ struct tree *create_tree(FILE *file)
}
}
printf
(
"Created initial tree with %d trees
\n
"
,
ntrees
);
/* Sort ascending */
for
(
int
i
=
0
;
i
<
ntrees
;
i
++
)
{
for
(
int
j
=
i
+
1
;
j
<
ntrees
;
j
++
)
{
...
...
@@ -69,20 +115,24 @@ struct tree *create_tree(FILE *file)
}
}
int
newforestcount
=
0
;
for
(
int
i
=
0
;
i
<
ntrees
-
1
;
i
++
)
{
struct
tree
*
small1
=
forest
[
i
];
struct
tree
*
small2
=
forest
[
i
+
1
];
for
(
int
i
=
0
;
i
<
ntrees
;
i
++
)
{
printf
(
"ch %c freq %d
\n
"
,
forest
[
i
]
->
ch
,
forest
[
i
]
->
freq
);
}
forest
[
newforestcount
]
=
insert_proper_tree
(
small1
,
small2
)
;
forest
[
i
+
1
]
=
forest
[
newforestcount
];
newforestcount
++
;
struct
tree
*
parent
=
forest
[
0
]
;
for
(
int
i
=
0
;
i
<
ntrees
-
1
;
i
++
)
{
parent
=
merge_smallest
(
forest
,
ntrees
)
;
}
/* We have our leader. */
struct
tree
*
parent
=
forest
[
newforestcount
-
1
];
/*
* At this step, we have the leader.
*/
/* This is not needed anymore */
free
(
forest
);
printf
(
"Returning tree
\n
"
);
return
parent
;
}
...
...
@@ -90,41 +140,69 @@ struct tree *create_tree(FILE *file)
* Encoding/Decodíng
*/
static
int
write_entry
(
struct
BIT_BUFFER
*
bitbuf
,
struct
tree
*
parent
,
unsigned
char
c
)
static
unsigned
int
get_max_height
(
struct
tree
*
parent
)
{
if
(
!
parent
)
return
0
;
int
left_height
=
get_max_height
(
parent
->
left
);
int
right_height
=
get_max_height
(
parent
->
right
);
return
(
left_height
>
right_height
)
?
left_height
+
1
:
right_height
+
1
;
}
static
int
get_rev_path
(
struct
tree
*
parent
,
unsigned
char
c
,
int
*
buf
,
unsigned
int
index
)
{
int
bit
=
0
;
while
(
parent
!=
NULL
)
{
struct
tree
*
left
,
*
right
;
int
ret
=
-
1
;
left
=
parent
->
left
;
r
ight
=
parent
->
right
;
if
(
parent
==
NULL
)
r
eturn
-
1
;
if
(
right
->
ch
==
c
)
{
bit
=
1
;
bb_write
(
bitbuf
,
&
bit
,
1
);
break
;
}
else
if
(
left
->
left
==
NULL
)
{
if
(
parent
->
ch
==
c
)
return
index
;
if
((
ret
=
get_rev_path
(
parent
->
left
,
c
,
buf
,
index
))
>=
0
)
bit
=
0
;
bb_write
(
bitbuf
,
&
bit
,
1
);
break
;
else
if
((
ret
=
get_rev_path
(
parent
->
right
,
c
,
buf
,
index
))
>=
0
)
bit
=
1
;
if
(
ret
>=
0
)
{
index
=
ret
;
buf
[
index
]
=
bit
;
return
index
+
1
;
}
bit
=
0
;
bb_write
(
bitbuf
,
&
bit
,
1
);
return
-
1
;
}
static
int
write_entry
(
struct
BIT_BUFFER
*
bitbuf
,
struct
tree
*
parent
,
unsigned
char
c
,
int
*
pathbuf
)
{
int
length
=
get_rev_path
(
parent
,
c
,
pathbuf
,
0
);
printf
(
"Length %d
\n
"
,
length
);
parent
=
left
;
/* The path is in reverse. Now write it out in correct order. */
for
(
int
i
=
length
-
1
;
i
>=
0
;
i
--
)
{
bb_write
(
bitbuf
,
&
pathbuf
[
i
],
1
);
printf
(
"i %d Bit %d
\n
"
,
i
,
pathbuf
[
i
]);
}
return
0
;
}
int
encode_tree
(
struct
BIT_BUFFER
*
bitbuf
,
struct
tree
*
parent
,
char
*
buf
,
size_t
length
)
{
printf
(
"Bit pos at %d %d
\n
"
,
ftell
(
bitbuf
->
fp
),
bitbuf
->
pos
);
int
maxheight
=
get_max_height
(
parent
)
-
1
;
int
*
pathbuf
=
calloc
(
maxheight
,
sizeof
(
int
));
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
write_entry
(
bitbuf
,
parent
,
buf
[
i
]);
write_entry
(
bitbuf
,
parent
,
buf
[
i
]
,
pathbuf
);
}
free
(
pathbuf
);
insert_throwaways
(
bitbuf
->
fp
,
8
-
bitbuf
->
pos
);
return
0
;
...
...
@@ -134,34 +212,45 @@ static int read_entries(struct BIT_BUFFER *bitbuf, FILE *out,
struct
tree
*
parent
)
{
int
*
bit
;
int
bitsread
=
0
;
int
totalbits
=
get_file_size
(
bitbuf
->
fp
)
*
8
;
int
huffmanbits
=
totalbits
-
read_throwaways
(
bitbuf
->
fp
);
printf
(
"Total bits to parse %d
\n
"
,
huffmanbits
);
int
lastbyte
=
get_file_size
(
bitbuf
->
fp
);
int
throwaways
=
read_throwaways
(
bitbuf
->
fp
);
struct
tree
*
leaf
=
parent
;
/* If we compress only one letter, the root node is the node containing
* character. So this needs special care. */
#if 0
if (!parent->left && !parent->right) {
while (ftell(bitbuf->fp) != lastbyte && bitbuf->pos + throwaways < 8) {
bit = bb_read(bitbuf, 1);
free(bit);
fwrite(&parent->ch, 1, 1, out);
}
return 0;
}
#endif
while
((
bit
=
bb_read
(
bitbuf
,
1
))
!=
NULL
)
{
printf
(
"Reading bit %d
\n
"
,
*
bit
);
if
(
*
bit
==
1
)
{
fwrite
(
&
leaf
->
right
->
ch
,
1
,
1
,
out
);
leaf
->
right
->
freq
++
;
leaf
=
parent
;
/* Reset */
}
else
{
if
(
*
bit
==
0
)
leaf
=
leaf
->
left
;
if
(
!
leaf
->
left
)
{
else
leaf
=
leaf
->
right
;
if
(
!
leaf
->
left
&&
!
leaf
->
right
)
{
printf
(
"Found from encoded %c
\n
"
,
leaf
->
ch
);
fwrite
(
&
leaf
->
ch
,
1
,
1
,
out
);
leaf
->
freq
++
;
leaf
=
parent
;
/* Reset */
}
leaf
=
parent
;
}
free
(
bit
);
if
(
bitsread
==
huffmanbits
)
if
(
ftell
(
bitbuf
->
fp
)
==
lastbyte
&&
bitbuf
->
pos
+
throwaways
>=
8
)
{
printf
(
"Stopping
\n
"
);
break
;
bitsread
++
;
}
}
return
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment