9 changed files with 1056 additions and 1393 deletions
File diff suppressed because it is too large
Load Diff
@ -1,119 +0,0 @@
|
||||
/**
|
||||
libsmacker - A C library for decoding .smk Smacker Video files |
||||
Copyright (C) 2012-2017 Greg Kennedy |
||||
|
||||
See smacker.h for more information. |
||||
|
||||
smk_bitstream.c |
||||
Implements a bitstream structure, which can extract and |
||||
return a bit at a time from a raw block of bytes. |
||||
*/ |
||||
|
||||
#include "smk_bitstream.h" |
||||
|
||||
/* malloc and friends */ |
||||
#include "smk_malloc.h" |
||||
|
||||
/*
|
||||
Bitstream structure |
||||
Pointer to raw block of data and a size limit. |
||||
Maintains internal pointers to byte_num and bit_number. |
||||
*/ |
||||
struct smk_bit_t |
||||
{ |
||||
const unsigned char* buffer; |
||||
unsigned long size; |
||||
|
||||
unsigned long byte_num; |
||||
char bit_num; |
||||
}; |
||||
|
||||
/* BITSTREAM Functions */ |
||||
struct smk_bit_t* smk_bs_init(const unsigned char* b, const unsigned long size) |
||||
{ |
||||
struct smk_bit_t* ret = NULL; |
||||
|
||||
/* sanity check */ |
||||
smk_assert(b); |
||||
|
||||
/* allocate a bitstream struct */ |
||||
smk_malloc(ret, sizeof(struct smk_bit_t)); |
||||
|
||||
/* set up the pointer to bitstream, and the size counter */ |
||||
ret->buffer = b; |
||||
ret->size = size; |
||||
|
||||
/* point to initial byte: note, smk_malloc already sets these to 0 */ |
||||
/* ret->byte_num = 0;
|
||||
ret->bit_num = 0; */ |
||||
|
||||
/* return ret or NULL if error : ) */ |
||||
error: |
||||
return ret; |
||||
} |
||||
|
||||
/* Reads a bit
|
||||
Returns -1 if error encountered */ |
||||
char _smk_bs_read_1(struct smk_bit_t* bs) |
||||
{ |
||||
unsigned char ret = -1; |
||||
|
||||
/* sanity check */ |
||||
smk_assert(bs); |
||||
|
||||
/* don't die when running out of bits, but signal */ |
||||
if (bs->byte_num >= bs->size) |
||||
{ |
||||
fprintf(stderr, "libsmacker::_smk_bs_read_1(bs): ERROR: bitstream (length=%lu) exhausted.\n", bs->size); |
||||
goto error; |
||||
} |
||||
|
||||
/* get next bit and return */ |
||||
ret = (((bs->buffer[bs->byte_num]) & (1 << bs->bit_num)) != 0); |
||||
|
||||
/* advance to next bit */ |
||||
bs->bit_num ++; |
||||
|
||||
/* Out of bits in this byte: next! */ |
||||
if (bs->bit_num > 7) |
||||
{ |
||||
bs->byte_num ++; |
||||
bs->bit_num = 0; |
||||
} |
||||
|
||||
/* return ret, or (default) -1 if error */ |
||||
error: |
||||
return ret; |
||||
} |
||||
|
||||
/* Reads a byte
|
||||
Returns -1 if error. */ |
||||
short _smk_bs_read_8(struct smk_bit_t* bs) |
||||
{ |
||||
unsigned char ret = -1; |
||||
|
||||
/* sanity check */ |
||||
smk_assert(bs); |
||||
|
||||
/* don't die when running out of bits, but signal */ |
||||
if (bs->byte_num + (bs->bit_num > 0) >= bs->size) |
||||
{ |
||||
fprintf(stderr, "libsmacker::_smk_bs_read_8(bs): ERROR: bitstream (length=%lu) exhausted.\n", bs->size); |
||||
goto error; |
||||
} |
||||
|
||||
if (bs->bit_num) |
||||
{ |
||||
/* unaligned read */ |
||||
ret = bs->buffer[bs->byte_num] >> bs->bit_num; |
||||
bs->byte_num ++; |
||||
ret |= (bs->buffer[bs->byte_num] << (8 - bs->bit_num)); |
||||
} else { |
||||
/* aligned read */ |
||||
ret = bs->buffer[bs->byte_num ++]; |
||||
} |
||||
|
||||
/* return ret, or (default) -1 if error */ |
||||
error: |
||||
return ret; |
||||
} |
||||
@ -1,50 +0,0 @@
|
||||
/**
|
||||
libsmacker - A C library for decoding .smk Smacker Video files |
||||
Copyright (C) 2012-2017 Greg Kennedy |
||||
|
||||
See smacker.h for more information. |
||||
|
||||
smk_bitstream.h |
||||
SMK bitstream structure. Presents a block of raw bytes one |
||||
bit at a time, and protects against over-read. |
||||
*/ |
||||
|
||||
#ifndef SMK_BITSTREAM_H |
||||
#define SMK_BITSTREAM_H |
||||
|
||||
/** Bitstream structure, Forward declaration */ |
||||
struct smk_bit_t; |
||||
|
||||
/* BITSTREAM Functions */ |
||||
/** Initialize a bitstream */ |
||||
struct smk_bit_t* smk_bs_init(const unsigned char* b, unsigned long size); |
||||
|
||||
/** This macro checks return code from _smk_bs_read_1 and
|
||||
jumps to error label if problems occur. */ |
||||
#define smk_bs_read_1(t,uc) \ |
||||
{ \
|
||||
if ((char)(uc = _smk_bs_read_1(t)) < 0) \
|
||||
{ \
|
||||
fprintf(stderr, "libsmacker::smk_bs_read_1(" #t ", " #uc ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \
|
||||
goto error; \
|
||||
} \
|
||||
} |
||||
/** Read a single bit from the bitstream, and advance.
|
||||
Returns -1 on error. */ |
||||
char _smk_bs_read_1(struct smk_bit_t* bs); |
||||
|
||||
/** This macro checks return code from _smk_bs_read_8 and
|
||||
jumps to error label if problems occur. */ |
||||
#define smk_bs_read_8(t,s) \ |
||||
{ \
|
||||
if ((short)(s = _smk_bs_read_8(t)) < 0) \
|
||||
{ \
|
||||
fprintf(stderr, "libsmacker::smk_bs_read_8(" #t ", " #s ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \
|
||||
goto error; \
|
||||
} \
|
||||
} |
||||
/** Read eight bits from the bitstream (one byte), and advance.
|
||||
Returns -1 on error. */ |
||||
short _smk_bs_read_8(struct smk_bit_t* bs); |
||||
|
||||
#endif |
||||
@ -1,425 +0,0 @@
|
||||
/**
|
||||
libsmacker - A C library for decoding .smk Smacker Video files |
||||
Copyright (C) 2012-2017 Greg Kennedy |
||||
|
||||
See smacker.h for more information. |
||||
|
||||
smk_hufftree.c |
||||
Implementation of Smacker Huffman coding trees. |
||||
*/ |
||||
|
||||
#include "smk_hufftree.h" |
||||
|
||||
/* malloc and friends */ |
||||
#include "smk_malloc.h" |
||||
|
||||
/**
|
||||
8-bit Tree node structure. |
||||
If b0 is non-null, this is a branch, and b1 from the union should be used. |
||||
If b0 is null, this is a leaf, and val / escape code from union should be used. |
||||
*/ |
||||
struct smk_huff8_t |
||||
{ |
||||
struct smk_huff8_t* b0; |
||||
union |
||||
{ |
||||
struct smk_huff8_t* b1; |
||||
struct |
||||
{ |
||||
unsigned short value; |
||||
unsigned char escapecode; |
||||
} leaf; |
||||
} u; |
||||
}; |
||||
|
||||
/**
|
||||
16-bit Tree root struct: holds a huff8_t structure, |
||||
as well as a cache of three 16-bit values. |
||||
*/ |
||||
struct smk_huff16_t |
||||
{ |
||||
struct smk_huff8_t* t; |
||||
unsigned short cache[3]; |
||||
}; |
||||
|
||||
/*********************** 8-BIT HUFF-TREE FUNCTIONS ***********************/ |
||||
/** safe build with built-in error jump */ |
||||
#define smk_huff8_build_rec(bs,p) \ |
||||
{ \
|
||||
if (!(p = _smk_huff8_build_rec(bs))) \
|
||||
{ \
|
||||
fprintf(stderr, "libsmacker::smk_huff8_build_rec(" #bs ", " #p ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \
|
||||
goto error; \
|
||||
} \
|
||||
} |
||||
/** Recursive tree-building function. */ |
||||
static struct smk_huff8_t* _smk_huff8_build_rec(struct smk_bit_t* bs) |
||||
{ |
||||
struct smk_huff8_t* ret = NULL; |
||||
char bit; |
||||
|
||||
/* sanity check - removed: bs cannot be null, because it was checked at smk_huff8_build below */ |
||||
/* smk_assert(bs); */ |
||||
|
||||
/* Read the bit */ |
||||
smk_bs_read_1(bs, bit); |
||||
|
||||
/* Malloc a structure. */ |
||||
smk_malloc(ret, sizeof(struct smk_huff8_t)); |
||||
|
||||
if (bit) |
||||
{ |
||||
/* Bit set: this forms a Branch node. */ |
||||
/* Recursively attempt to build the Left branch. */ |
||||
smk_huff8_build_rec(bs, ret->b0); |
||||
|
||||
/* Everything is still OK: attempt to build the Right branch. */ |
||||
smk_huff8_build_rec(bs, ret->u.b1); |
||||
|
||||
/* return branch pointer here */ |
||||
return ret; |
||||
} |
||||
|
||||
/* Bit unset signifies a Leaf node. */ |
||||
/* Attempt to read value */ |
||||
smk_bs_read_8(bs, ret->u.leaf.value); |
||||
|
||||
/* smk_malloc sets entries to 0 by default */ |
||||
/* ret->b0 = NULL; */ |
||||
ret->u.leaf.escapecode = 0xFF; |
||||
|
||||
return ret; |
||||
|
||||
error: |
||||
/* In case of error, undo the subtree we were building, and return NULL. */ |
||||
smk_huff8_free(ret); |
||||
return NULL; |
||||
} |
||||
|
||||
/* Look up an 8-bit value from a basic huff tree.
|
||||
Return -1 on error. */ |
||||
short _smk_huff8_lookup(struct smk_bit_t* bs, const struct smk_huff8_t* t) |
||||
{ |
||||
char bit; |
||||
|
||||
/* sanity check */ |
||||
smk_assert(bs); |
||||
smk_assert(t); |
||||
|
||||
if (!t->b0) |
||||
{ |
||||
/* Reached a Leaf node. Return its value. */ |
||||
return t->u.leaf.value; |
||||
} |
||||
|
||||
/* Read the next bit from bitstream to determine path */ |
||||
smk_bs_read_1(bs, bit); |
||||
|
||||
if (bit) |
||||
{ |
||||
/* get_bit returned Set, follow Right branch. */ |
||||
return _smk_huff8_lookup(bs, t->u.b1); |
||||
} |
||||
|
||||
/* follow Left branch */ |
||||
return _smk_huff8_lookup(bs, t->b0); |
||||
|
||||
error: |
||||
return -1; |
||||
} |
||||
|
||||
/**
|
||||
Entry point for huff8 build. Basically just checks the start/end tags |
||||
and calls smk_huff8_build_rec recursive function. |
||||
*/ |
||||
struct smk_huff8_t* _smk_huff8_build(struct smk_bit_t* bs) |
||||
{ |
||||
struct smk_huff8_t* ret = NULL; |
||||
char bit; |
||||
|
||||
/* sanity check */ |
||||
smk_assert(bs); |
||||
|
||||
/* Smacker huff trees begin with a set-bit. */ |
||||
smk_bs_read_1(bs, bit); |
||||
|
||||
if (!bit) |
||||
{ |
||||
/* Got a bit, but it was not 1. In theory, there could be a smk file
|
||||
without this particular tree. */ |
||||
fputs("libsmacker::_smk_huff8_build(bs) - Warning: initial get_bit returned 0\n", stderr); |
||||
goto error; |
||||
} |
||||
|
||||
/* Begin parsing the tree data. */ |
||||
smk_huff8_build_rec(bs, ret); |
||||
|
||||
/* huff trees end with an unset-bit */ |
||||
smk_bs_read_1(bs, bit); |
||||
|
||||
if (bit) |
||||
{ |
||||
fputs("libsmacker::_smk_huff8_build(bs) - ERROR: final get_bit returned 1\n", stderr); |
||||
goto error; |
||||
} |
||||
|
||||
return ret; |
||||
|
||||
error: |
||||
smk_huff8_free(ret); |
||||
return NULL; |
||||
} |
||||
|
||||
/* function to recursively delete a huffman tree */ |
||||
void smk_huff8_free(struct smk_huff8_t* t) |
||||
{ |
||||
/* Sanity check: do not double-free */ |
||||
smk_assert(t); |
||||
|
||||
/* If this is not a leaf node, free child trees first */ |
||||
if (t->b0) |
||||
{ |
||||
smk_huff8_free(t->b0); |
||||
smk_huff8_free(t->u.b1); |
||||
} |
||||
|
||||
/* Safe-delete tree node. */ |
||||
smk_free(t); |
||||
|
||||
error: ; |
||||
} |
||||
|
||||
/*********************** 16-BIT HUFF-TREE FUNCTIONS ***********************/ |
||||
/* safe bigtree build with built-in error jump */ |
||||
#define smk_huff16_build_rec(bs,cache,low8,hi8,p) \ |
||||
{ \
|
||||
if (!(p = _smk_huff16_build_rec(bs, cache, low8, hi8))) \
|
||||
{ \
|
||||
fprintf(stderr, "libsmacker::smk_huff16_build_rec(" #bs ", " #cache ", " #low8 ", " #hi8 ", " #p ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \
|
||||
goto error; \
|
||||
} \
|
||||
} |
||||
/* Recursively builds a Big tree. */ |
||||
static struct smk_huff8_t* _smk_huff16_build_rec(struct smk_bit_t* bs, const unsigned short cache[3], const struct smk_huff8_t* low8, const struct smk_huff8_t* hi8) |
||||
{ |
||||
struct smk_huff8_t* ret = NULL; |
||||
|
||||
char bit; |
||||
short lowval; |
||||
|
||||
/* sanity check - removed: these cannot be null, because they were checked at smk_huff16_build below */ |
||||
/* smk_assert(bs);
|
||||
smk_assert(cache); |
||||
smk_assert(low8); |
||||
smk_assert(hi8); */ |
||||
|
||||
/* Get the first bit */ |
||||
smk_bs_read_1(bs, bit); |
||||
|
||||
/* Malloc a structure. */ |
||||
smk_malloc(ret, sizeof(struct smk_huff8_t)); |
||||
|
||||
if (bit) |
||||
{ |
||||
/* Recursively attempt to build the Left branch. */ |
||||
smk_huff16_build_rec(bs, cache, low8, hi8, ret->b0); |
||||
|
||||
/* Recursively attempt to build the Left branch. */ |
||||
smk_huff16_build_rec(bs, cache, low8, hi8, ret->u.b1); |
||||
|
||||
/* return branch pointer here */ |
||||
return ret; |
||||
} |
||||
|
||||
/* Bit unset signifies a Leaf node. */ |
||||
smk_huff8_lookup(bs, low8, lowval); |
||||
smk_huff8_lookup(bs, hi8, ret->u.leaf.value); |
||||
|
||||
/* Looks OK: we got low and hi values. Return a new LEAF */ |
||||
/* ret->b0 = NULL; */ |
||||
ret->u.leaf.value = lowval | (ret->u.leaf.value << 8); |
||||
|
||||
/* Last: when building the tree, some Values may correspond to cache positions.
|
||||
Identify these values and set the Escape code byte accordingly. */ |
||||
if (ret->u.leaf.value == cache[0]) |
||||
{ |
||||
ret->u.leaf.escapecode = 0; |
||||
} |
||||
else if (ret->u.leaf.value == cache[1]) |
||||
{ |
||||
ret->u.leaf.escapecode = 1; |
||||
} |
||||
else if (ret->u.leaf.value == cache[2]) |
||||
{ |
||||
ret->u.leaf.escapecode = 2; |
||||
} |
||||
else |
||||
{ |
||||
ret->u.leaf.escapecode = 0xFF; |
||||
} |
||||
|
||||
return ret; |
||||
|
||||
error: |
||||
smk_huff8_free(ret); |
||||
return NULL; |
||||
} |
||||
|
||||
/* Entry point for building a big 16-bit tree. */ |
||||
struct smk_huff16_t* _smk_huff16_build(struct smk_bit_t* bs) |
||||
{ |
||||
struct smk_huff16_t* big = NULL; |
||||
|
||||
struct smk_huff8_t* low8 = NULL; |
||||
struct smk_huff8_t* hi8 = NULL; |
||||
|
||||
short lowval; |
||||
|
||||
char bit; |
||||
unsigned char i; |
||||
|
||||
/* sanity check */ |
||||
smk_assert(bs); |
||||
|
||||
/* Smacker huff trees begin with a set-bit. */ |
||||
smk_bs_read_1(bs, bit); |
||||
|
||||
if (!bit) |
||||
{ |
||||
fputs("libsmacker::smk_huff16_build(bs) - ERROR: initial get_bit returned 0\n", stderr); |
||||
goto error; |
||||
} |
||||
|
||||
/* build low-8-bits tree */ |
||||
smk_huff8_build(bs, low8); |
||||
/* build hi-8-bits tree */ |
||||
smk_huff8_build(bs, hi8); |
||||
|
||||
/* Everything looks OK so far. Time to malloc structure. */ |
||||
smk_malloc(big, sizeof(struct smk_huff16_t)); |
||||
|
||||
/* Init the escape code cache. */ |
||||
for (i = 0; i < 3; i ++) |
||||
{ |
||||
smk_bs_read_8(bs, lowval); |
||||
smk_bs_read_8(bs, big->cache[i]); |
||||
big->cache[i] = lowval | (big->cache[i] << 8); |
||||
} |
||||
|
||||
/* Finally, call recursive function to retrieve the Bigtree. */ |
||||
smk_huff16_build_rec(bs, big->cache, low8, hi8, big->t); |
||||
|
||||
/* Done with 8-bit hufftrees, free them. */ |
||||
smk_huff8_free(hi8); |
||||
smk_huff8_free(low8); |
||||
|
||||
/* Check final end tag. */ |
||||
smk_bs_read_1(bs, bit); |
||||
|
||||
if (bit) |
||||
{ |
||||
fputs("libsmacker::smk_huff16_build(bs) - ERROR: final get_bit returned 1\n", stderr); |
||||
goto error; |
||||
} |
||||
|
||||
return big; |
||||
|
||||
error: |
||||
smk_huff16_free(big); |
||||
smk_huff8_free(hi8); |
||||
smk_huff8_free(low8); |
||||
return NULL; |
||||
} |
||||
|
||||
static int _smk_huff16_lookup_rec(struct smk_bit_t* bs, unsigned short cache[3], const struct smk_huff8_t* t) |
||||
{ |
||||
unsigned short val; |
||||
char bit; |
||||
|
||||
/* sanity check */ |
||||
/* smk_assert(bs);
|
||||
smk_assert(cache); |
||||
smk_assert(t); */ |
||||
|
||||
/* Reached a Leaf node */ |
||||
if (!t->b0) |
||||
{ |
||||
if (t->u.leaf.escapecode != 0xFF) |
||||
{ |
||||
/* Found escape code. Retrieve value from Cache. */ |
||||
val = cache[t->u.leaf.escapecode]; |
||||
} |
||||
else |
||||
{ |
||||
/* Use value directly. */ |
||||
val = t->u.leaf.value; |
||||
} |
||||
|
||||
if (cache[0] != val) |
||||
{ |
||||
/* Update the cache, by moving val to the front of the queue,
|
||||
if it isn't already there. */ |
||||
cache[2] = cache[1]; |
||||
cache[1] = cache[0]; |
||||
cache[0] = val; |
||||
} |
||||
|
||||
return val; |
||||
} |
||||
|
||||
/* Read the next bit from bitstream to determine path */ |
||||
smk_bs_read_1(bs, bit); |
||||
|
||||
if (bit) |
||||
{ |
||||
/* get_bit returned Set, follow Right branch. */ |
||||
return _smk_huff16_lookup_rec(bs, cache, t->u.b1); |
||||
} |
||||
|
||||
return _smk_huff16_lookup_rec(bs, cache, t->b0); |
||||
|
||||
error: |
||||
return -1; |
||||
} |
||||
|
||||
/* Convenience call-out for recursive bigtree lookup function */ |
||||
long _smk_huff16_lookup(struct smk_bit_t* bs, struct smk_huff16_t* big) |
||||
{ |
||||
/* sanity check */ |
||||
smk_assert(bs); |
||||
smk_assert(big); |
||||
|
||||
return _smk_huff16_lookup_rec(bs, big->cache, big->t); |
||||
|
||||
error: |
||||
return -1; |
||||
} |
||||
|
||||
/* Resets a Big hufftree cache */ |
||||
void smk_huff16_reset(struct smk_huff16_t* big) |
||||
{ |
||||
/* sanity check */ |
||||
smk_assert(big); |
||||
|
||||
big->cache[0] = 0; |
||||
big->cache[1] = 0; |
||||
big->cache[2] = 0; |
||||
|
||||
error: ; |
||||
} |
||||
|
||||
/* delete a (big) huffman tree */ |
||||
void smk_huff16_free(struct smk_huff16_t* big) |
||||
{ |
||||
/* Sanity check: do not double-free */ |
||||
smk_assert(big); |
||||
|
||||
/* free the subtree */ |
||||
if (big->t) |
||||
smk_huff8_free(big->t); |
||||
|
||||
/* free the bigtree */ |
||||
smk_free(big); |
||||
|
||||
error: ; |
||||
}; |
||||
@ -1,88 +0,0 @@
|
||||
/**
|
||||
libsmacker - A C library for decoding .smk Smacker Video files |
||||
Copyright (C) 2012-2017 Greg Kennedy |
||||
|
||||
See smacker.h for more information. |
||||
|
||||
smk_hufftree.h |
||||
SMK huffmann trees. There are two types: |
||||
- a basic 8-bit tree, and |
||||
- a "big" 16-bit tree which includes a cache for recently |
||||
searched values. |
||||
*/ |
||||
|
||||
#ifndef SMK_HUFFTREE_H |
||||
#define SMK_HUFFTREE_H |
||||
|
||||
#include "smk_bitstream.h" |
||||
|
||||
/** Tree node structures - Forward declaration */ |
||||
struct smk_huff8_t; |
||||
struct smk_huff16_t; |
||||
|
||||
/*********************** 8-BIT HUFF-TREE FUNCTIONS ***********************/ |
||||
/** This macro checks return code from _smk_huff8_build and
|
||||
jumps to error label if problems occur. */ |
||||
#define smk_huff8_build(bs,t) \ |
||||
{ \
|
||||
if (!(t = _smk_huff8_build(bs))) \
|
||||
{ \
|
||||
fprintf(stderr, "libsmacker::smk_huff8_build(" #bs ", " #t ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \
|
||||
goto error; \
|
||||
} \
|
||||
} |
||||
/** Build an 8-bit tree from a bitstream */ |
||||
struct smk_huff8_t* _smk_huff8_build(struct smk_bit_t* bs); |
||||
|
||||
/** This macro checks return code from _smk_huff8_lookup and
|
||||
jumps to error label if problems occur. */ |
||||
#define smk_huff8_lookup(bs,t,s) \ |
||||
{ \
|
||||
if ((short)(s = _smk_huff8_lookup(bs, t)) < 0) \
|
||||
{ \
|
||||
fprintf(stderr, "libsmacker::smk_huff8_lookup(" #bs ", " #t ", " #s ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \
|
||||
goto error; \
|
||||
} \
|
||||
} |
||||
/** Look up an 8-bit value in the referenced tree by following a bitstream
|
||||
returns -1 on error */ |
||||
short _smk_huff8_lookup(struct smk_bit_t* bs, const struct smk_huff8_t* t); |
||||
|
||||
/** function to recursively delete an 8-bit huffman tree */ |
||||
void smk_huff8_free(struct smk_huff8_t* t); |
||||
|
||||
/************************ 16-BIT HUFF-TREE FUNCTIONS ************************/ |
||||
/** This macro checks return code from _smk_huff16_build and
|
||||
jumps to error label if problems occur. */ |
||||
#define smk_huff16_build(bs,t) \ |
||||
{ \
|
||||
if (!(t = _smk_huff16_build(bs))) \
|
||||
{ \
|
||||
fprintf(stderr, "libsmacker::smk_huff16_build(" #bs ", " #t ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \
|
||||
goto error; \
|
||||
} \
|
||||
} |
||||
/** Build a 16-bit tree from a bitstream */ |
||||
struct smk_huff16_t* _smk_huff16_build(struct smk_bit_t* bs); |
||||
|
||||
/** This macro checks return code from smk_huff16_lookup and
|
||||
jumps to error label if problems occur. */ |
||||
#define smk_huff16_lookup(bs,t,s) \ |
||||
{ \
|
||||
if ((s = _smk_huff16_lookup(bs, t)) < 0) \
|
||||
{ \
|
||||
fprintf(stderr, "libsmacker::smk_huff16_lookup(" #bs ", " #t ", " #s ") - ERROR (file: %s, line: %lu)\n", __FILE__, (unsigned long)__LINE__); \
|
||||
goto error; \
|
||||
} \
|
||||
} |
||||
/** Look up a 16-bit value in the bigtree by following a bitstream
|
||||
returns -1 on error */ |
||||
long _smk_huff16_lookup(struct smk_bit_t* bs, struct smk_huff16_t* big); |
||||
|
||||
/** Reset the cache in a 16-bit tree */ |
||||
void smk_huff16_reset(struct smk_huff16_t* big); |
||||
|
||||
/** function to recursively delete a 16-bit huffman tree */ |
||||
void smk_huff16_free(struct smk_huff16_t* big); |
||||
|
||||
#endif |
||||
Loading…
Reference in new issue