ArithmeticCoding
0.0.0a
Arithmetic coding in C
|
00001 #pragma once 00002 #ifdef __cplusplus 00003 extern "C" { 00004 #endif 00005 00006 #include <stdint.h> 00007 #include <stdlib.h> // for size_t 00008 00009 // 00010 // Bit Stream 00011 // - will realloc to resize if necessary 00012 // - push appends to end 00013 // - pop removes from front 00014 // - models a FIFO stream 00015 // - push/pop are not meant to work together. That is, can't simultaneously 00016 // encode and decode on the same stream; Can't interleave push/pop. 00017 // 00018 // - carry is somewhat specific to arithmetic coding, but seems like a stream 00019 // op, so it's included here. Alternatively, I could add an operation to 00020 // rewind the stream a bit so that the carry op could be implemented 00021 // elsewhere. 00022 // 00023 00024 typedef struct _stream_t 00025 { size_t nbytes; //capacity 00026 size_t ibyte; //current byte 00027 size_t ibit; //current bit (for u8 stream this is always 0) 00028 uint8_t mask; //bit is set in the position of the last write 00029 uint8_t *d; //data 00030 int own; //ownship flag: should this object be responsible for freeing d [??:used] 00031 } stream_t; 00032 00033 // Attach 00034 // ------ 00035 // if <d> is NULL, will allocate some space. 00036 // otherwise, free's the internal buffer (if there is one), 00037 // and uses <d> instead. 00038 // <n> is the byte size of <d> 00039 // 00040 // Detach 00041 // ------ 00042 // returns the pointer to the streams buffer and it's size via <d> and <n>. 00043 // The stream, disowns (but does not free) the buffer, returning the stream 00044 // to an empty state. 00045 // 00046 void attach (stream_t *s, void *d, size_t n); 00047 void detach (stream_t *s, void **d, size_t *n); 00048 00049 void push_u1 (stream_t *s, uint8_t v); 00050 void push_u4 (stream_t *s, uint8_t v); 00051 void push_u8 (stream_t *s, uint8_t v); 00052 void push_u16(stream_t *s, uint16_t v); 00053 void push_u32(stream_t *s, uint32_t v); 00054 void push_u64(stream_t *s, uint64_t v); 00055 void push_i8 (stream_t *s, int8_t v); 00056 void push_i16(stream_t *s, int16_t v); 00057 void push_i32(stream_t *s, int32_t v); 00058 void push_i64(stream_t *s, int64_t v); 00059 00060 uint8_t pop_u1 (stream_t *s); 00061 uint8_t pop_u4 (stream_t *s); 00062 uint8_t pop_u8 (stream_t *s); 00063 uint16_t pop_u16 (stream_t *s); 00064 uint32_t pop_u32 (stream_t *s); 00065 uint64_t pop_u64 (stream_t *s); 00066 int8_t pop_i8 (stream_t *s); 00067 int16_t pop_i16 (stream_t *s); 00068 int32_t pop_i32 (stream_t *s); 00069 int64_t pop_i64 (stream_t *s); 00070 00071 void carry_u1 (stream_t* s); 00072 void carry_u4 (stream_t* s); 00073 void carry_u8 (stream_t* s); 00074 void carry_u16(stream_t* s); 00075 void carry_u32(stream_t* s); 00076 00077 #ifdef __cplusplus 00078 } 00079 #endif 00080 void carry_u64(stream_t* s);