Skip to content

Commit

Permalink
Refactor: Converted Huffman codec API to C++ only
Browse files Browse the repository at this point in the history
A proper wrapper should be added to de/c_wrapper.h if access
is needed for C (currently no one needs it).

Namespace de::codec is intended for codec algorithms.
  • Loading branch information
skyjake committed Mar 25, 2012
1 parent f261259 commit d9c9d61
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 33 deletions.
31 changes: 11 additions & 20 deletions doomsday/libdeng2/include/de/data/huffman.h
Expand Up @@ -26,37 +26,28 @@
#define LIBDENG2_HUFFMAN_H

#include "../libdeng2.h"
#include "../Block"

#ifdef __cplusplus
extern "C" {
#endif
namespace de {
namespace codec {

/**
* Encodes the data using Huffman codes.
* @param data Block of data to encode.
*
* @param data Block of data to encode.
* @param size Size of data to encode.
* @param encodedSize The number of bytes in the encoded data is written here.
*
* @return Pointer to the encoded block of bits. Caller gets ownership and must
* delete the data with M_Free().
* @return Encoded block of bits.
*/
void* DENG2_PUBLIC Huffman_Encode(const dbyte* data, dsize size, dsize *encodedSize);
Block huffmanEncode(const Block& data);

/**
* Decodes the coded message using the Huffman tree.
* @param data Block of Huffman-coded data.
*
* @param data Block of Huffman-coded data.
* @param size Size of the data to decode.
* @param decodedSize The number of bytes in the decoded data is written here.
*
* @return Pointer to the decoded data. Caller gets ownership and must delete
* the data with M_Free().
* @return Decoded block of data.
*/
dbyte* DENG2_PUBLIC Huffman_Decode(const void *data, dsize size, dsize *decodedSize);
Block huffmanDecode(const Block& codedData);

#ifdef __cplusplus
} // extern "C"
#endif
} // namespace codec
} // namespace de

#endif // LIBDENG2_HUFFMAN_H
8 changes: 4 additions & 4 deletions doomsday/libdeng2/include/de/libdeng2.h
Expand Up @@ -142,13 +142,13 @@ typedef duint32 dintptr;
/*
* Data types for C APIs.
*/
typedef unsigned char dbyte;
typedef unsigned int duint; // 32-bit
typedef unsigned char dbyte;
typedef unsigned int duint; // 32-bit

#ifdef DENG2_64BIT
typedef unsigned int64_t dsize; // 64-bit size
typedef uint64_t dsize; // 64-bit size
#else
typedef unsigned int dsize; // 32-bit size
typedef unsigned int dsize; // 32-bit size
#endif

#endif
Expand Down
42 changes: 33 additions & 9 deletions doomsday/libdeng2/src/data/huffman.cpp
Expand Up @@ -26,6 +26,14 @@
#include "de/data/huffman.h"
#include "de/App"
#include "de/Log"
#include "de/ByteRefArray"

// Heap relations.
#define HEAP_PARENT(i) (((i) + 1)/2 - 1)
#define HEAP_LEFT(i) (2*(i) + 1)
#define HEAP_RIGHT(i) (2*(i) + 2)

using namespace de;

typedef struct huffnode_s {
struct huffnode_s *left, *right;
Expand Down Expand Up @@ -143,7 +151,7 @@ struct Huffman
for(i = 0; i < 256; ++i)
{
// These are the leaves of the tree.
node = calloc(1, sizeof(huffnode_t));
node = (huffnode_t*) calloc(1, sizeof(huffnode_t));
node->freq = freqs[i];
node->value = i;
Huff_QueueInsert(&queue, node);
Expand All @@ -152,7 +160,7 @@ struct Huffman
// Build the tree.
for(i = 0; i < 255; ++i)
{
node = calloc(1, sizeof(huffnode_t));
node = (huffnode_t*) calloc(1, sizeof(huffnode_t));
node->left = Huff_QueueExtract(&queue);
node->right = Huff_QueueExtract(&queue);
node->freq = node->left->freq + node->right->freq;
Expand Down Expand Up @@ -326,7 +334,7 @@ struct Huffman
while(neededSize > buffer->size)
{
if(!buffer->size)
buffer->size = MAX_OF(1024, neededSize);
buffer->size = qMax(dsize(1024), neededSize);
else
buffer->size *= 2;
}
Expand Down Expand Up @@ -355,7 +363,7 @@ struct Huffman
memset(buffer, 0, sizeof(*buffer));
}

void* encode(const dbyte *data, dsize size, dsize *encodedSize)
dbyte* encode(const dbyte *data, dsize size, dsize *encodedSize)
{
huffbuffer_t huffEnc;
dsize i;
Expand Down Expand Up @@ -420,7 +428,7 @@ struct Huffman
return huffEnc.data;
}

dbyte* decode(const void *data, dsize size, dsize *decodedSize)
dbyte* decode(const dbyte *data, dsize size, dsize *decodedSize)
{
huffbuffer_t huffDec;
huffnode_t* node;
Expand Down Expand Up @@ -488,12 +496,28 @@ struct Huffman

static Huffman huff;

void* Huffman_Encode(const dbyte *data, dsize size, dsize *encodedSize)
Block codec::huffmanEncode(const Block& data)
{
huff.encode(data, size, encodedSize);
Block result;
dsize size = 0;
dbyte* coded = huff.encode(data.data(), data.size(), &size);
if(coded)
{
result.copyFrom(ByteRefArray(coded, size), 0, size);
free(coded);
}
return result;
}

dbyte* Huffman_Decode(const void *data, dsize size, dsize *decodedSize)
Block codec::huffmanDecode(const Block& codedData)
{
return huff.decode(data, size, decodedSize);
Block result;
dsize size = 0;
dbyte* decoded = huff.decode(codedData.data(), codedData.size(), &size);
if(decoded)
{
result.copyFrom(ByteRefArray(decoded, size), 0, size);
free(decoded);
}
return result;
}

0 comments on commit d9c9d61

Please sign in to comment.