ArithmeticCoding
0.0.0a
Arithmetic coding in C
|
00001 00002 00003 #include "ac.h" 00004 #include <stdio.h> 00005 00006 #define countof(e) (sizeof(e)/sizeof(*(e))) 00007 #define ROW 80 00008 #define ENDL "\n" 00009 typedef unsigned long long u64; 00010 00012 void pcode(u8 *out, size_t nout) 00013 { size_t i,j; 00014 printf("Code:\n"); 00015 for(i=0;i<nout;++i) 00016 { for(j=0;j<ROW/3 && i<nout;j++,i++) 00017 printf(" %02x",out[i]); 00018 --i; 00019 printf("\n"); 00020 } 00021 printf("--\n"); 00022 } 00023 00025 void pascii(u8 *out, size_t nout) 00026 { size_t i,j; 00027 printf("Code:\n"); 00028 for(i=0;i<nout;++i) 00029 { for(j=0;j<ROW/2 && i<nout;j++,i++) 00030 printf(" %c",out[i]+33); 00031 --i; 00032 printf("\n"); 00033 } 00034 printf("--\n"); 00035 } 00036 00038 void pmsg(u32 *v,size_t n) 00039 { size_t i,j; 00040 printf("Message: %p\n",v); 00041 for(i=0;i<n;++i) 00042 { for(j=0;j<ROW/2 && i<n;j++,i++) 00043 printf(" %d",v[i]); 00044 --i; 00045 printf("\n"); 00046 } 00047 printf("--\n"); 00048 } 00049 00051 int main(int argc, char* argv[]) 00052 { u32 s[] = {2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00053 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00054 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00055 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00056 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00057 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00058 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00059 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00060 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00061 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00062 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00063 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00064 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00065 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00066 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00067 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00068 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00069 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00070 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00071 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00072 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00073 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00074 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00075 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00076 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00077 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00078 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00079 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00080 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00081 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00082 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00083 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00084 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00085 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00086 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00087 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00088 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00089 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00090 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00091 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00092 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0, 00093 2,1,0,0,0,0,0,0,0,0,0,0,3,3,2,3,2,1,0}, 00094 //0 x x x x x x x x x x x 11 /19 00095 //1 x x 2 00096 //2 x x x 3 00097 //3 x x x 3 00098 // 19 00099 *t=0; 00100 real c[] = {0.0,11/19.0, 13/19.0, 16/19.0, 1.0}; 00101 //real c[] = {0.0, 0.2, 0.7, 0.9, 1.0}; 00102 u8 *out = NULL; 00103 size_t nout = 0,nt=countof(t); 00104 00105 pmsg(s,countof(s)); 00106 #if 0 00107 encode_u8_u32((void**)&out,&nout,s,countof(s),c,countof(c)-1); 00108 pcode(out,nout); 00109 printf("Compression: %3.2f%% (%llu bytes -> %llu bytes)"ENDL,100.0*nout/(double)sizeof(s),(u64)sizeof(s),(u64)nout); 00110 decode_u32_u8(&t,&nt,out,nout,c,countof(c)-1); 00111 #else 00112 { // ASCII normalish is from 33 to 126 inclusive, 94 things 00113 int D = 94; //2; 00114 vencode_u32(&out,&nout,D,s,countof(s),countof(c)-1,c); 00115 pascii(out,nout); 00116 printf("Compression: %3.2f%% (%llu bytes -> %llu bytes)"ENDL, 00117 100.0*nout/(double)sizeof(s), 00118 (u64)sizeof(s), 00119 (u64)nout); 00120 vdecode_u32(&t,&nt,countof(c)-1,out,nout,D ,c); 00121 } 00122 #endif 00123 if(nt != countof(s)) 00124 printf("*** Wrong symbol count. Got: %zu Expected: %zu"ENDL,nt,(size_t)countof(s)); 00125 pmsg(t,countof(s)); 00126 00127 free(out); 00128 free(t); 00129 return 0; 00130 } 00131