Skip to content

Commit b56c86f

Browse files
committed
move common huffman code in adhuff_common.c
fix byte to bit transformation
1 parent ae9b8c5 commit b56c86f

16 files changed

+136
-112
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ Mkfile.old
5252
dkms.conf
5353
cmake-build-debug/*
5454
.idea/workspace.xml
55+
.DS_Store

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ project(algo C)
33

44
set(CMAKE_C_STANDARD 99)
55

6-
add_executable(algo main.c node.c node.h test.c test.h bin_io.c bin_io.h adhuff_compress.c adhuff_compress.h adhuff_decompress.c adhuff_decompress.h constants.h adhuff_common.h)
6+
add_executable(algo main.c test.c test.h bin_io.c bin_io.h adhuff_compress.c adhuff_compress.h adhuff_decompress.c adhuff_decompress.h constants.h adhuff_common.h adhuff_common.c)

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@ xxd -b ../test-res/ff_ff_ff
1919
```
2020

2121
### ASCII table
22-
https://en.wikipedia.org/wiki/ASCII
22+
https://en.wikipedia.org/wiki/ASCII
23+
24+
```
25+
'A' = 01000001
26+
idx = 01234567
27+
```

node.c renamed to adhuff_common.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
#include <stdio.h>
22
#include <stdlib.h>
33

4-
#include "node.h"
4+
#include "adhuff_common.h"
55
#include "bin_io.h"
66

7-
8-
/*
9-
* module variables
10-
*/
7+
//
8+
// module variables
9+
//
1110

1211
static unsigned short _nextOrder = MAX_ORDER;
1312
static Node * adh_root_node = NULL;
1413
static Node * adh_nyt_node = NULL;
1514

15+
//
16+
// private methods
17+
//
18+
Node * createNYT();
19+
Node * createNode(unsigned short value);
20+
void destroyNode(Node * node);
21+
Node * searchCharFromNode(Node * node, unsigned short ch);
22+
23+
1624
/*
1725
* Initialize the tree with a single NYT node
1826
*/

adhuff_common.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#ifndef ALGO_ADHUFF_COMMON_H
22
#define ALGO_ADHUFF_COMMON_H
33

4-
#define HEADER_BITS 3
5-
#define HEADER_DATA_BITS 5
4+
#include "constants.h"
65

6+
/*
7+
* Header of compressed file
8+
*/
79
#pragma pack(1)
810
typedef struct
911
{
@@ -18,5 +20,33 @@ typedef union
1820
} first_byte_union;
1921
#pragma pack()
2022

23+
/*
24+
* Node struct
25+
*/
26+
struct Node {
27+
unsigned short value;
28+
unsigned int weight;
29+
unsigned short order;
30+
struct Node *left;
31+
struct Node *right;
32+
struct Node *parent;
33+
};
34+
typedef struct Node Node;
35+
36+
//
37+
// public methods
38+
//
39+
int initializeTree();
40+
void destroyTree();
41+
42+
void updateTree(Node * node, bool isNewNode);
43+
44+
Node * searchCharInTree(unsigned short ch);
45+
46+
Node * createNodeAndAppend(unsigned short ch);
47+
48+
int getNYTCode(unsigned char bit_array[]);
49+
int getSymbolCode(unsigned short ch, unsigned char bit_array[]);
50+
2151

2252
#endif //ALGO_ADHUFF_COMMON_H

adhuff_compress.c

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@
22
#include "adhuff_common.h"
33
#include "constants.h"
44
#include "bin_io.h"
5-
#include "node.h"
6-
#include "node.h"
75

8-
/*
9-
* modules variables
10-
*/
11-
static unsigned char output_buffer[BLOCK_SIZE];
6+
//
7+
// modules variables
8+
//
9+
static unsigned char output_buffer[BUFFER_SIZE];
1210
static unsigned short buffer_bit_idx;
1311

1412
static FILE * outputFilePtr;
1513

16-
/*
17-
* Private methods
18-
*/
19-
void processChar(unsigned char ch);
14+
//
15+
// private methods
16+
//
17+
void encodeChar(unsigned char ch);
2018
void outputBitArray(const unsigned char bit_array[], int num_bit);
2119
void outputChar(unsigned char ch);
2220
void flushData();
@@ -31,15 +29,15 @@ int compressFile(const char * input_file, const char * output_file) {
3129

3230
FILE * inputFilePtr = openReadBinary(input_file);
3331
if (inputFilePtr == NULL) {
34-
return 1;
32+
return RC_FAIL;
3533
}
3634

3735
outputFilePtr = openWriteBinary(output_file);
3836
if (outputFilePtr == NULL) {
39-
return 1;
37+
return RC_FAIL;
4038
}
4139

42-
unsigned char buffer[BLOCK_SIZE];
40+
unsigned char buffer[BUFFER_SIZE];
4341

4442
int rc = initializeTree();
4543
if (rc == 0) {
@@ -49,7 +47,7 @@ int compressFile(const char * input_file, const char * output_file) {
4947
while ((bytesRead = fread(buffer, 1, sizeof(buffer), inputFilePtr)) > 0)
5048
{
5149
for(int i=0;i<bytesRead;i++)
52-
processChar(buffer[i]);
50+
encodeChar(buffer[i]);
5351
}
5452

5553

@@ -69,26 +67,10 @@ int compressFile(const char * input_file, const char * output_file) {
6967
return rc;
7068
}
7169

72-
73-
void flushHeader() {
74-
rewind(outputFilePtr);
75-
76-
unsigned char buffer[1];
77-
fread(buffer, 1, 1, outputFilePtr);
78-
79-
first_byte_union first_byte;
80-
first_byte.raw = buffer[0];
81-
first_byte.split.header = buffer_bit_idx % CHAR_BIT;
82-
83-
traceCharBinMsg("flushHeader: ", first_byte.raw);
84-
85-
fwrite(&first_byte.raw, 1, 1, outputFilePtr);
86-
}
87-
8870
/*
89-
* Process char
71+
* encode char
9072
*/
91-
void processChar(unsigned char ch) {
73+
void encodeChar(unsigned char ch) {
9274
traceCharBinMsg("processChar: ", ch);
9375
unsigned char bit_array[MAX_CODE_SIZE];
9476

@@ -125,7 +107,7 @@ void processChar(unsigned char ch) {
125107
void outputChar(unsigned char ch) {
126108
traceCharBinMsg("outputChar: ", ch);
127109

128-
unsigned char bit_array[CHAR_BIT];
110+
unsigned char bit_array[CHAR_BIT+1];
129111
for (int bitPos = CHAR_BIT-1; bitPos >= 0; --bitPos) {
130112
char val = bit_check(ch, bitPos);
131113
bit_array[bitPos] = val;
@@ -140,13 +122,13 @@ void outputChar(unsigned char ch) {
140122
void outputBitArray(const unsigned char bit_array[], int num_bit) {
141123
trace("outputBitArray: %d\n", num_bit);
142124

143-
for(int i = num_bit; i>0; i--) {
125+
for(int i = num_bit-1; i>=0; i--) {
144126

145127
// calculate the current position (in byte) of the output_buffer
146128
unsigned int buffer_byte_idx = buffer_bit_idx / CHAR_BIT;
147129

148130
// calculate which bit to change in the byte
149-
int bit_to_change = buffer_bit_idx % CHAR_BIT;
131+
unsigned int bit_to_change = CHAR_BIT - 1 - (buffer_bit_idx % CHAR_BIT);
150132

151133
if(bit_array[i] == BIT_1)
152134
bit_set_one(&output_buffer[buffer_byte_idx], bit_to_change);
@@ -156,7 +138,7 @@ void outputBitArray(const unsigned char bit_array[], int num_bit) {
156138
buffer_bit_idx++;
157139

158140
// buffer full, flush data to file
159-
if(buffer_bit_idx == BLOCK_SIZE * CHAR_BIT) {
141+
if(buffer_bit_idx == BUFFER_SIZE * CHAR_BIT) {
160142
flushData();
161143

162144
// reset buffer index
@@ -183,4 +165,22 @@ void flushData() {
183165

184166
// TODO check error code
185167
size_t bytesWritten = fwrite(output_buffer, buffer_byte_idx, 1, outputFilePtr);
186-
}
168+
}
169+
170+
/*
171+
* flush header to file
172+
*/
173+
void flushHeader() {
174+
rewind(outputFilePtr);
175+
176+
unsigned char buffer[1];
177+
fread(buffer, 1, 1, outputFilePtr);
178+
179+
first_byte_union first_byte;
180+
first_byte.raw = buffer[0];
181+
first_byte.split.header = buffer_bit_idx % CHAR_BIT;
182+
183+
traceCharBinMsg("flushHeader: ", first_byte.raw);
184+
185+
fwrite(&first_byte.raw, 1, 1, outputFilePtr);
186+
}

adhuff_compress.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#ifndef ALGO_ADHUFF_COMPRESS_H
22
#define ALGO_ADHUFF_COMPRESS_H
33

4+
//
5+
// public methods
6+
//
47
int compressFile(const char *input_file, const char *output_file);
58

69
#endif //ALGO_ADHUFF_COMPRESS_H

adhuff_decompress.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
#include "adhuff_common.h"
55
#include "constants.h"
66
#include "bin_io.h"
7-
#include "node.h"
8-
#include "node.h"
97

108
/*
119
* modules variables
1210
*/
1311
static FILE * outputFilePtr;
14-
static unsigned char output_buffer[BLOCK_SIZE];
12+
static unsigned char output_buffer[BUFFER_SIZE];
1513
static unsigned short buffer_bit_idx;
1614
static unsigned int oddBits;
1715

@@ -30,12 +28,12 @@ int decompressFile(const char *input_file, const char *output_file) {
3028

3129
FILE * inputFilePtr = openReadBinary(input_file);
3230
if (inputFilePtr == NULL) {
33-
return 1;
31+
return RC_FAIL;
3432
}
3533

3634
outputFilePtr = openWriteBinary(output_file);
3735
if (outputFilePtr == NULL) {
38-
return 1;
36+
return RC_FAIL;
3937
}
4038

4139
int rc = initializeTree();
@@ -47,7 +45,7 @@ int decompressFile(const char *input_file, const char *output_file) {
4745
bool firstChar = true;
4846
int byteToRead = 1;
4947

50-
unsigned char buffer[BLOCK_SIZE];
48+
unsigned char buffer[BUFFER_SIZE];
5149

5250
// read up to sizeof(buffer) bytes
5351
while ((bytesRead = fread(buffer, byteToRead, 1, inputFilePtr)) > 0)

adhuff_decompress.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#ifndef ALGO_ADHUFF_DECOMPRESS_H
22
#define ALGO_ADHUFF_DECOMPRESS_H
33

4+
//
5+
// public methods
6+
//
47
int decompressFile(const char *input_file, const char *output_file);
58

69
#endif //ALGO_ADHUFF_DECOMPRESS_H

bin_io.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ FILE* openWriteBinary(const char * filename) {
3232
*/
3333
int readBinaryFile(const char *filename, void (*processChar)(unsigned char)) {
3434
FILE * filePtr = openReadBinary(filename);
35+
if(filePtr == NULL)
36+
return RC_FAIL;
3537

36-
unsigned char buffer[BLOCK_SIZE];
38+
unsigned char buffer[BUFFER_SIZE];
3739
size_t bytesRead = 0;
3840
// read up to sizeof(buffer) bytes
3941
while ((bytesRead = fread(buffer, 1, sizeof(buffer), filePtr)) > 0)
@@ -42,14 +44,14 @@ int readBinaryFile(const char *filename, void (*processChar)(unsigned char)) {
4244
processChar(buffer[i]);
4345
}
4446
fclose(filePtr);
45-
return 0;
47+
return RC_OK;
4648
}
4749

4850
/*
4951
* Diagnostic functions
5052
*/
5153
void traceCharBin(unsigned char ch) {
52-
for (int bitPos = 7; bitPos >= 0; --bitPos) {
54+
for (int bitPos = CHAR_BIT-1; bitPos >= 0; --bitPos) {
5355
char val = bit_check(ch, bitPos);
5456
putchar(val);
5557
}
@@ -73,20 +75,20 @@ void trace(const char *msg, ...) {
7375
/*
7476
* return '1' if the bit at bit_pos is 1, otherwise '0'
7577
*/
76-
char bit_check(unsigned char ch, unsigned int bit_pos) {
78+
char bit_check(unsigned char ch, int bit_pos) {
7779
unsigned int val = (ch & (1u << bit_pos));
7880
return val ? BIT_1 : BIT_0;
7981
}
8082

81-
void bit_set_one(unsigned char * ch, unsigned int bit_pos) {
83+
void bit_set_one(unsigned char * ch, int bit_pos) {
8284
*ch |= (1u << bit_pos);
8385
}
8486

85-
void bit_set_zero(unsigned char * ch, unsigned int bit_pos) {
87+
void bit_set_zero(unsigned char * ch, int bit_pos) {
8688
*ch &= ~(1u << bit_pos);
8789
}
8890

89-
void bit_copy(unsigned char * byte_to, unsigned char byte_from, unsigned int read_pos, unsigned int write_pos, unsigned int size) {
91+
void bit_copy(unsigned char * byte_to, unsigned char byte_from, int read_pos, int write_pos, int size) {
9092
for(unsigned int offset=0; offset < size; offset++) {
9193

9294
unsigned int from = read_pos + offset;

0 commit comments

Comments
 (0)