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> 00008 00009 typedef uint8_t u8; 00010 typedef uint32_t u32; 00011 typedef float real; 00012 00013 /* 00014 * encode 00015 * ------ 00016 * <out> <*out> may be NULL or point to a preallocated buffer with <*nout> 00017 * elements. The buffer may be reallocated if it's not big enough, 00018 * in which case the new size and adress are output via <*out> and 00019 * <*nout>. 00020 * <nsym> The number of symbols. 00021 * <cdf> The cumulative distribution of the symbols 0..<nsym>-1. 00022 * It should be specified as a sequence of <nsym>+1 real numbers. 00023 * cdf[0] shold be 0.0, and cdf[nsym] should be 1.0. The sequence 00024 * should be monotonically increasing. No symbol should have 00025 * probability less than the resolution of the coder, which depends on 00026 * the output bit depth. See the source for details. As a rule of 00027 * thumb, probabilities should be greater than 1/2^(32-bitsof(output 00028 * symbol)). 00029 * 00030 * Note that this doesn't have to be the _actual_ probability of the 00031 * symbol. Differences will result in a slightly less efficient 00032 * compression. 00033 * 00034 * decode 00035 * ------ 00036 * <out> output buffer, should be pre-allocated 00037 * <nout> must be less than or equal to the actual message size 00038 * <in> the bit string returned in encode's <out.d> 00039 * <c> the CDF over output symbols 00040 * <nsym> the number of output symbols 00041 */ 00042 00043 void cdf_build(real **cdf, size_t *nsym, u32 *s, size_t ns); 00044 00047 // encode_<Tout>_<Tin> 00048 // - Tout: u1,u4,u8,u16 00049 // - Tin : u8,u16,u32,u64 00050 void encode_u1_u8 (void **out, size_t *nout, uint8_t *in, size_t nin, real *cdf, size_t nsym); 00051 void encode_u4_u8 (void **out, size_t *nout, uint8_t *in, size_t nin, real *cdf, size_t nsym); 00052 void encode_u8_u8 (void **out, size_t *nout, uint8_t *in, size_t nin, real *cdf, size_t nsym); 00053 00054 void encode_u1_u16 (void **out, size_t *nout, uint16_t *in, size_t nin, real *cdf, size_t nsym); 00055 void encode_u4_u16 (void **out, size_t *nout, uint16_t *in, size_t nin, real *cdf, size_t nsym); 00056 void encode_u8_u16 (void **out, size_t *nout, uint16_t *in, size_t nin, real *cdf, size_t nsym); 00057 00058 void encode_u1_u32 (void **out, size_t *nout, uint32_t *in, size_t nin, real *cdf, size_t nsym); 00059 void encode_u4_u32 (void **out, size_t *nout, uint32_t *in, size_t nin, real *cdf, size_t nsym); 00060 void encode_u8_u32 (void **out, size_t *nout, uint32_t *in, size_t nin, real *cdf, size_t nsym); 00061 00062 void encode_u1_u64 (void **out, size_t *nout, uint64_t *in, size_t nin, real *cdf, size_t nsym); 00063 void encode_u4_u64 (void **out, size_t *nout, uint64_t *in, size_t nin, real *cdf, size_t nsym); 00064 void encode_u8_u64 (void **out, size_t *nout, uint64_t *in, size_t nin, real *cdf, size_t nsym); 00065 00066 // Only use u16 outputs if u64's are supported on your system. 00067 void encode_u16_u8 (void **out, size_t *nout, uint8_t *in, size_t nin, real *cdf, size_t nsym); 00068 void encode_u16_u16 (void **out, size_t *nout, uint16_t *in, size_t nin, real *cdf, size_t nsym); 00069 void encode_u16_u32 (void **out, size_t *nout, uint32_t *in, size_t nin, real *cdf, size_t nsym); 00070 void encode_u16_u64 (void **out, size_t *nout, uint64_t *in, size_t nin, real *cdf, size_t nsym); 00072 00075 // decode_<Tout>_<Tin> 00076 // - Tout: u8,u16,u32,u64 00077 // - Tin : u1,u4,u8,u16 00078 void decode_u8_u1 (uint8_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00079 void decode_u8_u4 (uint8_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00080 void decode_u8_u8 (uint8_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00081 00082 void decode_u16_u1 (uint16_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00083 void decode_u16_u4 (uint16_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00084 void decode_u16_u8 (uint16_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00085 00086 void decode_u32_u1 (uint32_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00087 void decode_u32_u4 (uint32_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00088 void decode_u32_u8 (uint32_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00089 00090 void decode_u64_u1 (uint64_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00091 void decode_u64_u4 (uint64_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00092 void decode_u64_u8 (uint64_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00093 00094 // Only use u16 inputs if u64's are supported on your system. 00095 void decode_u8_u16(uint8_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00096 void decode_u16_u16(uint16_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00097 void decode_u32_u16(uint32_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00098 void decode_u64_u16(uint64_t **out, size_t *nout, void *in, size_t nin, real *cdf, size_t nsym); 00100 00101 00104 // 00105 // Variably sized encoding alphabet 00106 // 00107 00108 void vencode_u8 (uint8_t **out, size_t *nout, size_t noutsym, uint8_t *in, size_t nin, size_t ninsym, real *cdf); 00109 void vencode_u16(uint8_t **out, size_t *nout, size_t noutsym, uint16_t *in, size_t nin, size_t ninsym, real *cdf); 00110 void vencode_u32(uint8_t **out, size_t *nout, size_t noutsym, uint32_t *in, size_t nin, size_t ninsym, real *cdf); 00111 void vencode_u64(uint8_t **out, size_t *nout, size_t noutsym, uint64_t *in, size_t nin, size_t ninsym, real *cdf); 00112 00113 void vdecode_u8 (uint8_t **out, size_t *nout, size_t noutsym, uint8_t *in, size_t nin, size_t ninsym, real *cdf); 00114 void vdecode_u16(uint16_t **out, size_t *nout, size_t noutsym, uint8_t *in, size_t nin, size_t ninsym, real *cdf); 00115 void vdecode_u32(uint32_t **out, size_t *nout, size_t noutsym, uint8_t *in, size_t nin, size_t ninsym, real *cdf); 00116 void vdecode_u64(uint64_t **out, size_t *nout, size_t noutsym, uint8_t *in, size_t nin, size_t ninsym, real *cdf); 00118 #ifdef __cplusplus 00119 } 00120 #endif