Mercurial > audlegacy
comparison src/librcd/librcd.c @ 2313:3149d4b1a9a9 trunk
[svn] - objective-make autodepend fixes
- move all sourcecode into src/ and adjust Makefiles accordingly
author | nenolod |
---|---|
date | Fri, 12 Jan 2007 11:43:40 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2312:e1a5a66fb9cc | 2313:3149d4b1a9a9 |
---|---|
1 #include <stdio.h> | |
2 #include <string.h> | |
3 | |
4 #define _LIBRCD_C | |
5 #include "librcd.h" | |
6 | |
7 #define NF_VALUE -2 | |
8 #define max(a,b) ((a>b)?a:b) | |
9 #define min(a,b) ((a<b)?a:b) | |
10 #define bit(i) (1<<i) | |
11 | |
12 typedef struct lng_stat2 { | |
13 unsigned char a; | |
14 unsigned char b; | |
15 double rate; | |
16 double srate; | |
17 double erate; | |
18 } lng_stat2; | |
19 | |
20 #include "russian_table.h" | |
21 | |
22 | |
23 static int end_symbol(char ch) { | |
24 if (ch=='\r'||ch=='\n'||ch==0||ch==' '||ch=='\t'||ch==','||ch=='.'||ch=='!'||ch=='?'||ch==';'||ch=='-'||ch==':'||ch=='"'||ch=='\''||ch==')') return 1; | |
25 return 0; | |
26 } | |
27 | |
28 static int start_symbol(char ch) { | |
29 if ((ch=='\t')||ch=='\r'||ch=='\n'||(ch==' ')||(ch=='(')||(ch=='"')||(ch=='\'')) return 1; | |
30 return 0; | |
31 } | |
32 | |
33 typedef const struct lng_stat2 *lng_stat2_ptr; | |
34 | |
35 static void bfind(const unsigned char *a, lng_stat2_ptr *w, lng_stat2_ptr *k, lng_stat2_ptr *al) { | |
36 const struct lng_stat2 *winptr, *koiptr,*altptr; | |
37 int ki,wi,ai,d,ws=0,ks=0,as=0; | |
38 d=npow2>>1; | |
39 wi=d; | |
40 ki=d; | |
41 ai=d; | |
42 winptr=0; | |
43 koiptr=0; | |
44 altptr=0; | |
45 do{ | |
46 d>>=1; | |
47 | |
48 if(!ws){ | |
49 if (wi>indexes2) wi-=d; | |
50 else { | |
51 winptr=enc_win+wi-1; | |
52 if(a[0]==winptr->a){ | |
53 if(a[1]==winptr->b){ | |
54 ws=1; | |
55 }else if(a[1]<winptr->b){ | |
56 wi-=d; | |
57 }else{ //b>win[wi].b | |
58 wi+=d; | |
59 } | |
60 }else if(a[0]<winptr->a){ | |
61 wi-=d; | |
62 }else{ //a>win[wi].a | |
63 wi+=d; | |
64 } | |
65 } | |
66 } | |
67 if(!ks){ | |
68 if (ki>indexes2) ki-=d; | |
69 else { | |
70 koiptr=enc_koi+ki-1; | |
71 if(a[0]==koiptr->a){ | |
72 if(a[1]==koiptr->b){ | |
73 ks=1; | |
74 }else if(a[1]<koiptr->b){ | |
75 ki-=d; | |
76 }else{ //b>win[wi].b | |
77 ki+=d; | |
78 } | |
79 }else if(a[0]<koiptr->a){ | |
80 ki-=d; | |
81 }else{ //a>win[wi].a | |
82 ki+=d; | |
83 } | |
84 } | |
85 } | |
86 if(!as){ | |
87 if (ai>indexes2) ai-=d; | |
88 else { | |
89 altptr=enc_alt+ai-1; | |
90 if(a[0]==altptr->a){ | |
91 if(a[1]==altptr->b){ | |
92 as=1; | |
93 }else if(a[1]<altptr->b){ | |
94 ai-=d; | |
95 }else{ //b>win[wi].b | |
96 ai+=d; | |
97 } | |
98 }else if(a[0]<altptr->a){ | |
99 ai-=d; | |
100 }else{ //a>win[wi].a | |
101 ai+=d; | |
102 } | |
103 } | |
104 } | |
105 }while(d); | |
106 if (ws) *w=winptr; | |
107 else *w=NULL; | |
108 if (ks) *k=koiptr; | |
109 else *k=NULL; | |
110 if (as) *al=altptr; | |
111 else *al=NULL; | |
112 } | |
113 | |
114 static double calculate(double s, double m, double e) { | |
115 return s+m+e; | |
116 } | |
117 | |
118 static int is_win_charset2(const unsigned char *txt, int len){ | |
119 const struct lng_stat2 *winptr, *koiptr,*altptr; | |
120 double winstep,koistep,altstep,winestep,koiestep,altestep,winsstep,koisstep,altsstep; | |
121 double winstat=0,koistat=0,altstat=0,winestat=0,koiestat=0,altestat=0,winsstat=0,koisstat=0,altsstat=0; | |
122 long j; | |
123 | |
124 #ifdef _AUTO_DEBUG | |
125 fprintf(stderr,"Word: %s\n",txt); | |
126 #endif | |
127 for(j=0;j<len-1;j++){ | |
128 //skip bottom half of table | |
129 if(txt[j]<128 || txt[j+1]<128) continue; | |
130 #ifdef _AUTO_DEBUG | |
131 fprintf(stderr,"Pair: %c%c",txt[j],txt[j+1]); | |
132 #endif | |
133 bfind(txt+j,&winptr,&koiptr,&altptr); | |
134 | |
135 if ((j==0)||(start_symbol(txt[j-1]))) { | |
136 if (winptr) winsstep=winptr->srate; | |
137 else winsstep=NF_VALUE; | |
138 if (koiptr) koisstep=koiptr->srate; | |
139 else koisstep=NF_VALUE; | |
140 if (altptr) altsstep=altptr->srate; | |
141 else altsstep=NF_VALUE; | |
142 winestep=0; | |
143 koiestep=0; | |
144 altestep=0; | |
145 winstep=0; | |
146 koistep=0; | |
147 altstep=0; | |
148 #ifdef _AUTO_DEBUG | |
149 fprintf(stderr,", Win %lf, Koi %lf, Alt: %lf\n",winsstep,koisstep,altsstep); | |
150 #endif | |
151 } else if ((j==len-2)||(end_symbol(txt[j+2]))) { | |
152 if (winptr) winestep=winptr->erate; | |
153 else winestep=NF_VALUE; | |
154 if (koiptr) koiestep=koiptr->erate; | |
155 else koiestep=NF_VALUE; | |
156 if (altptr) altestep=altptr->erate; | |
157 else altestep=NF_VALUE; | |
158 winsstep=0; | |
159 koisstep=0; | |
160 altsstep=0; | |
161 winstep=0; | |
162 koistep=0; | |
163 altstep=0; | |
164 #ifdef _AUTO_DEBUG | |
165 fprintf(stderr,", Win %lf, Koi %lf, Alt %lf\n",winestep,koiestep,altestep); | |
166 #endif | |
167 } else { | |
168 if (winptr) winstep=winptr->rate; | |
169 else winstep=NF_VALUE; | |
170 if (koiptr) koistep=koiptr->rate; | |
171 else koistep=NF_VALUE; | |
172 if (altptr) altstep=altptr->rate; | |
173 else altstep=NF_VALUE; | |
174 winsstep=0; | |
175 winestep=0; | |
176 koisstep=0; | |
177 koiestep=0; | |
178 altsstep=0; | |
179 altestep=0; | |
180 #ifdef _AUTO_DEBUG | |
181 fprintf(stderr,", Win %lf, Koi %lf, Alt %lf\n",winstep,koistep,altstep); | |
182 #endif | |
183 } | |
184 | |
185 winstat+=winstep; | |
186 koistat+=koistep; | |
187 altstat+=altstep; | |
188 winsstat+=winsstep; | |
189 koisstat+=koisstep; | |
190 altsstat+=altsstep; | |
191 winestat+=winestep; | |
192 koiestat+=koiestep; | |
193 altestat+=altestep; | |
194 } | |
195 | |
196 #ifdef _AUTO_DEBUG | |
197 fprintf(stderr,"Start. Win: %lf, Koi: %lf, Alt: %lf\n",winsstat,koisstat,altsstat); | |
198 fprintf(stderr,"Middle. Win: %lf, Koi: %lf, Alt: %lf\n",winstat,koistat,altstat); | |
199 fprintf(stderr,"End. Win: %lf, Koi: %lf, Alt: %lf\n",winestat,koiestat,altestat); | |
200 fprintf(stderr,"Final. Win: %lf, Koi: %lf, Alt: %lf\n",calculate(winsstat,winstat,winestat),calculate(koisstat,koistat,koiestat),calculate(altsstat,altstat,altestat)); | |
201 #endif | |
202 if ((calculate(altsstat,altstat,altestat)>calculate(koisstat,koistat,koiestat))&&(calculate(altsstat,altstat,altestat)>calculate(winsstat,winstat,winestat))) return 3; | |
203 if (calculate(koisstat,koistat,koiestat)>calculate(winsstat,winstat,winestat)) return 1; | |
204 return 0; | |
205 } | |
206 | |
207 | |
208 static int check_utf8(const unsigned char *buf, int len) { | |
209 long i,j; | |
210 int bytes=0,rflag=0; | |
211 unsigned char tmp; | |
212 int res=0; | |
213 | |
214 for (i=0;i<len;i++) { | |
215 if (buf[i]<128) continue; | |
216 | |
217 if (bytes>0) { | |
218 if ((buf[i]&0xC0)==0x80) { | |
219 if (rflag) { | |
220 tmp=buf[i]&0x3F; | |
221 // Russian is 0x410-0x44F | |
222 if ((rflag==1)&&(tmp>=0x10)) res++; | |
223 else if ((rflag==2)&&(tmp<=0x0F)) res++; | |
224 } | |
225 bytes--; | |
226 } else { | |
227 res--; | |
228 bytes=1-bytes; | |
229 rflag=0; | |
230 } | |
231 } else { | |
232 for (j=6;j>=0;j--) | |
233 if ((buf[i]&bit(j))==0) break; | |
234 | |
235 if ((j==0)||(j==6)) { | |
236 if ((j==6)&&(bytes<0)) bytes++; | |
237 else res--; | |
238 continue; | |
239 } | |
240 bytes=6-j; | |
241 if (bytes==1) { | |
242 // Cyrrilic D0-D3, Russian - D0-D1 | |
243 if (buf[i]==0xD0) rflag=1; | |
244 else if (buf[i]==0xD1) rflag=2; | |
245 } | |
246 } | |
247 | |
248 if ((buf[i]==0xD0)||(buf[i]==0xD1)) { | |
249 if (i+1==len) break; | |
250 | |
251 } | |
252 } | |
253 return res; | |
254 } | |
255 | |
256 | |
257 | |
258 rcd_russian_charset rcdGetRussianCharset(const char *buf,int len) { | |
259 long l; | |
260 | |
261 l = len?len:strlen(buf); | |
262 if (check_utf8((const unsigned char *)buf,l)>1) return RUSSIAN_CHARSET_UTF8; | |
263 return is_win_charset2((const unsigned char *)buf,l); | |
264 } | |
265 | |
266 /* Compatibility */ | |
267 rcd_russian_charset get_russian_charset(const char *buf,int len) { | |
268 return rcdGetRussianCharset(buf, len); | |
269 } |