ArithmeticCoding
0.0.0a
Arithmetic coding in C
|
00001 #include <gtest/gtest.h> 00002 #include "stream.h" 00003 00005 00006 // templated calls to the stream api 00007 // - won't work for u1 and u4 types, but these usually require 00008 // special tests anyway 00009 template<class T> void push(stream_t *s, T v); 00010 #define DEFN_PUSH(a,b) \ 00011 template<> void push<a>(stream_t *s, a v) { push_##b(s,v); } 00012 DEFN_PUSH(uint8_t ,u8); 00013 DEFN_PUSH(uint16_t,u16); 00014 DEFN_PUSH(uint32_t,u32); 00015 DEFN_PUSH(uint64_t,u64); 00016 DEFN_PUSH( int8_t ,i8); 00017 DEFN_PUSH( int16_t,i16); 00018 DEFN_PUSH( int32_t,i32); 00019 DEFN_PUSH( int64_t,i64); 00020 00021 template<class T> T pop(stream_t *s); 00022 #define DEFN_POP(a,b) \ 00023 template<> a pop(stream_t *s) { return pop_##b(s); } 00024 DEFN_POP(uint8_t ,u8); 00025 DEFN_POP(uint16_t,u16); 00026 DEFN_POP(uint32_t,u32); 00027 DEFN_POP(uint64_t,u64); 00028 DEFN_POP( int8_t ,i8); 00029 DEFN_POP( int16_t,i16); 00030 DEFN_POP( int32_t,i32); 00031 DEFN_POP( int64_t,i64); 00032 00033 template<class T> void carry(stream_t *s); 00034 #define DEFN_CARRY(a,b) \ 00035 template<> void carry<a> (stream_t *s) { carry_##b(s); } 00036 DEFN_CARRY(uint8_t ,u8); 00037 DEFN_CARRY(uint16_t,u16); 00038 DEFN_CARRY(uint32_t,u32); 00039 00041 00042 TEST(Attach,NullBuffer) 00043 { stream_t d={0}; 00044 attach(&d,NULL,0); 00045 EXPECT_TRUE(d.d!=NULL); 00046 EXPECT_GT(d.nbytes,0); 00047 EXPECT_EQ(0,d.ibyte); 00048 EXPECT_EQ(0,d.ibit); 00049 //clean up 00050 { ASSERT_TRUE(d.d!=NULL); 00051 void *buf; 00052 size_t n; 00053 detach(&d,&buf,&n); 00054 EXPECT_EQ(0,n); // nothing pushed so zero length 00055 ASSERT_TRUE(buf!=NULL); 00056 free(buf); 00057 } 00058 } 00059 00060 TEST(Attach,ExistingBuffer) 00061 { stream_t d={0}; 00062 float buf[1024]; 00063 size_t n = sizeof(buf)/sizeof(*buf); 00064 attach(&d,buf,n); 00065 EXPECT_EQ((void*)buf,(void*)d.d); 00066 EXPECT_EQ(n,d.nbytes); 00067 EXPECT_EQ(0,d.ibyte); 00068 EXPECT_EQ(0,d.ibit); 00069 } 00070 00072 00073 class StreamSanityTest : public ::testing::Test 00074 { public: 00075 inline stream_t *s() {return &stream_;} 00076 protected: 00077 virtual void SetUp() 00078 { memset(&stream_,0,sizeof(stream_)); // important to zero things out 00079 attach(&stream_,NULL,0); 00080 memset(stream_.d,0,stream_.nbytes); // attach doesn't zero (nor should it) 00081 } 00082 virtual void TearDown() 00083 { void *buf; 00084 size_t n; 00085 detach(&stream_,&buf,&n); 00086 if(buf) free(buf); 00087 } 00088 stream_t stream_; 00089 }; 00090 00092 00093 TEST_F(StreamSanityTest,PushU1) 00094 { 00095 push_u1(s(),1); 00096 push_u1(s(),0); 00097 push_u1(s(),0); 00098 push_u1(s(),1); 00099 EXPECT_EQ(0,s()->ibyte); 00100 EXPECT_EQ(4,s()->ibit); 00101 EXPECT_EQ(0x90,s()->d[0]); 00102 00103 push_u1(s(),0); 00104 push_u1(s(),1); 00105 push_u1(s(),0); 00106 push_u1(s(),1); 00107 EXPECT_EQ(1,s()->ibyte); 00108 EXPECT_EQ(0,s()->ibit); 00109 EXPECT_EQ(0x95,s()->d[0]); 00110 } 00111 TEST_F(StreamSanityTest,PushU4) 00112 { 00113 push_u4(s(),9); 00114 EXPECT_EQ(0,s()->ibyte); 00115 EXPECT_EQ(4,s()->ibit); 00116 EXPECT_EQ(0x90,s()->d[0]); 00117 00118 push_u4(s(),5); 00119 EXPECT_EQ(1,s()->ibyte); 00120 EXPECT_EQ(0,s()->ibit); 00121 EXPECT_EQ(0x95,s()->d[0]); 00122 } 00123 TEST_F(StreamSanityTest,PushU8) 00124 { 00125 push_u8(s(),0x95); 00126 EXPECT_EQ(1,s()->ibyte); 00127 EXPECT_EQ(0,s()->ibit); 00128 push_u8(s(),0x59); 00129 EXPECT_EQ(2,s()->ibyte); 00130 EXPECT_EQ(0,s()->ibit); 00131 EXPECT_EQ(0x95,s()->d[0]); 00132 EXPECT_EQ(0x59,s()->d[1]); 00133 } 00134 00136 00137 typedef testing::Types< 00138 uint8_t, 00139 uint16_t, 00140 uint32_t, 00141 uint64_t, 00142 int8_t, 00143 int16_t, 00144 int32_t, 00145 int64_t 00146 > RegularTypes; 00147 00148 template<class T> class TypedStreamSanityTest : public StreamSanityTest {}; 00149 00150 TYPED_TEST_CASE(TypedStreamSanityTest,RegularTypes); 00151 00152 TYPED_TEST(TypedStreamSanityTest,PushPop) 00153 { stream_t *t = StreamSanityTest::s(); 00154 push<TypeParam>(t,1); 00155 push<TypeParam>(t,2); 00156 push<TypeParam>(t,3); 00157 push<TypeParam>(t,4); 00158 t->ibyte = 0; 00159 EXPECT_EQ(1,pop<TypeParam>(t)); 00160 EXPECT_EQ(2,pop<TypeParam>(t)); 00161 EXPECT_EQ(3,pop<TypeParam>(t)); 00162 EXPECT_EQ(4,pop<TypeParam>(t)); 00163 EXPECT_EQ(0,pop<TypeParam>(t)); // should return 0's on overflow 00164 EXPECT_EQ(0,pop<TypeParam>(t)); 00165 } 00166 TEST_F(StreamSanityTest,PushPopU1) 00167 { stream_t *t = s(); 00168 push_u1(t,1); 00169 push_u1(t,0); 00170 push_u1(t,1); 00171 push_u1(t,1); 00172 t->ibyte = 0; 00173 t->ibit = 0; 00174 EXPECT_EQ(1,pop_u1(t)); 00175 EXPECT_EQ(0,pop_u1(t)); 00176 EXPECT_EQ(1,pop_u1(t)); 00177 EXPECT_EQ(1,pop_u1(t)); 00178 EXPECT_EQ(0,pop_u1(t)); // should return 0's on overflow 00179 EXPECT_EQ(0,pop_u1(t)); 00180 } 00181 TEST_F(StreamSanityTest,PushPopU4) 00182 { stream_t *t = s(); 00183 push_u4(t,1); 00184 push_u4(t,2); 00185 push_u4(t,3); 00186 push_u4(t,4); 00187 EXPECT_EQ(2,t->ibyte); 00188 EXPECT_EQ(0,t->ibit); 00189 t->ibyte = 0; 00190 t->ibit = 0; 00191 EXPECT_EQ(1,pop_u4(t)); 00192 EXPECT_EQ(2,pop_u4(t)); 00193 EXPECT_EQ(3,pop_u4(t)); 00194 EXPECT_EQ(4,pop_u4(t)); 00195 EXPECT_EQ(0,pop_u4(t)); // should return 0's on overflow 00196 EXPECT_EQ(0,pop_u4(t)); 00197 } 00198 00200 00201 typedef testing::Types< 00202 uint8_t, 00203 uint16_t, 00204 uint32_t 00205 > CarryTypes; 00206 00207 template<class T> class TypedStreamCarryTest : public StreamSanityTest {}; 00208 TYPED_TEST_CASE(TypedStreamCarryTest,CarryTypes); 00209 TYPED_TEST(TypedStreamCarryTest,Carry) 00210 { stream_t *t = StreamSanityTest::s(); 00211 push<TypeParam>(t,2); 00212 push<TypeParam>(t,(TypeParam)-1); 00213 push<TypeParam>(t,(TypeParam)-1); 00214 push<TypeParam>(t,(TypeParam)-1); 00215 push<TypeParam>(t,(TypeParam)-1); 00216 carry<TypeParam>(t); 00217 push<TypeParam>(t,2); 00218 t->ibyte = 0; 00219 EXPECT_EQ(3,pop<TypeParam>(t)); 00220 EXPECT_EQ(0,pop<TypeParam>(t)); 00221 EXPECT_EQ(0,pop<TypeParam>(t)); 00222 EXPECT_EQ(0,pop<TypeParam>(t)); 00223 EXPECT_EQ(0,pop<TypeParam>(t)); 00224 EXPECT_EQ(2,pop<TypeParam>(t)); 00225 EXPECT_EQ(0,pop<TypeParam>(t)); // should return 0's on overflow 00226 } 00227 00228 TEST_F(StreamSanityTest,CarryU1) 00229 { stream_t *t = s(); 00230 push_u1(t,0); 00231 push_u1(t,1); 00232 push_u1(t,1); 00233 push_u1(t,1); 00234 push_u1(t,1); 00235 carry_u1(t); 00236 push_u1(t,1); 00237 t->ibyte = 0; 00238 t->ibit = 0; 00239 EXPECT_EQ(1,pop_u1(t)); 00240 EXPECT_EQ(0,pop_u1(t)); 00241 EXPECT_EQ(0,pop_u1(t)); 00242 EXPECT_EQ(0,pop_u1(t)); 00243 EXPECT_EQ(0,pop_u1(t)); 00244 EXPECT_EQ(1,pop_u1(t)); 00245 EXPECT_EQ(0,pop_u1(t)); // should return 0's on overflow 00246 } 00247 00248 TEST_F(StreamSanityTest,CarryU4) 00249 { stream_t *t = s(); 00250 push_u4(t,2); 00251 push_u4(t,(uint8_t)-1); 00252 push_u4(t,(uint8_t)-1); 00253 push_u4(t,(uint8_t)-1); 00254 push_u4(t,(uint8_t)-1); 00255 carry_u4(t); 00256 push_u4(t,2); 00257 t->ibyte = 0; 00258 t->ibit = 0; 00259 EXPECT_EQ(3,pop_u4(t)); 00260 EXPECT_EQ(0,pop_u4(t)); 00261 EXPECT_EQ(0,pop_u4(t)); 00262 EXPECT_EQ(0,pop_u4(t)); 00263 EXPECT_EQ(0,pop_u4(t)); 00264 EXPECT_EQ(2,pop_u4(t)); 00265 EXPECT_EQ(0,pop_u4(t)); // should return 0's on overflow 00266 }