00001
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #include "reader.h"
00062
00063
00064
00065
00067 #define NO_SAMPLE NUL
00068
00069 #define NO_CODE 0
00070
00071 #define OK_CODE 1
00072
00073 #define NO_DECODE 0
00074
00075 #define OK_DECODE 1
00076
00078 #define MAX_DECODE 32
00079
00081 #define QUIET_MULTIPLIER 10
00082
00083
00084
00085
00086 enum{STANDARD, SPECIAL};
00087
00088
00089
00090 unsigned short DecodeI25(struct BC_STRUCT *p, unsigned char length);
00091 static unsigned short FindStart(struct BC_STRUCT *p, unsigned char length);
00092 static unsigned short FindStop(struct BC_STRUCT *p, unsigned char length);
00093 static unsigned short Decode(struct BC_STRUCT *p, unsigned char length, unsigned short reference);
00094 static unsigned short DecodeChar(struct BC_STRUCT *p, unsigned char decode_pair[2], unsigned short reference);
00095
00096
00104 unsigned short
00105 DecodeI25(struct BC_STRUCT *p, unsigned char length)
00106 {
00107
00108 if(length == 0 || length > MAX_DECODE){
00109 return 0;
00110 }
00111
00112
00113 if(p->sample_ctr < ((length * 5) + 7)){
00114 return 0;
00115 }
00116
00117
00118 p->sample_ptr = &p->sample_buffer[0];
00119 if(FindStart(p, length) != NO_CODE){
00120 if(Decode(p, length, STANDARD) != NO_DECODE){
00121 return p->decode_count;
00122 }
00123 }
00124
00125
00126 p->sample_ptr = &p->sample_buffer[0];
00127 if(FindStart(p, length) != NO_CODE){
00128 if(Decode(p, length, SPECIAL) != NO_DECODE){
00129 return p->decode_count;
00130 }
00131 }
00132
00133
00134 return NO_DECODE;
00135 }
00136
00137
00138
00139
00140
00141 static
00142 unsigned short
00143 Decode(struct BC_STRUCT *p, unsigned char length, unsigned short reference)
00144 {
00145 unsigned char DecodePair[2];
00146
00147
00148 p->decode_count = 0;
00149
00150
00151 while((DecodeChar(p, &DecodePair[0], reference) != NO_CODE)){
00152
00153
00154 if(p->decode_count >= MAX_DECODE){
00155 return NO_DECODE;
00156 }
00157
00158 p->decode_buffer[p->decode_count++] = DecodePair[0];
00159 p->decode_buffer[p->decode_count++] = DecodePair[1];
00160
00161
00162 if(p->decode_count == length){
00163 if(FindStop(p, length)){
00164
00165
00166 p->decode_buffer[p->decode_count] = NUL;
00167
00168
00169 if(*p->sample_ptr == NO_SAMPLE){
00170 return OK_DECODE;
00171 }
00172
00173
00174 else if(*(p->sample_ptr) > *(p->sample_ptr - 1) * QUIET_MULTIPLIER){
00175 return OK_DECODE;
00176 }
00177
00178
00179 else{
00180 return NO_DECODE;
00181 }
00182 }
00183 }
00184 }
00185
00186
00187 return NO_DECODE;
00188 }
00189
00190
00191
00192
00193
00194 static
00195 unsigned short
00196 DecodeChar(struct BC_STRUCT *p, unsigned char decode_pair[2], unsigned short reference)
00197 {
00198 static const unsigned char DecodeTable[32] = {
00199 0,0,0,'3',0,'5','6',0,0,'8','9',0,'0',0,0,0,0,'1','2',0,'4',0,0,0,'7',0,0,0,0,0,0,0
00200 };
00201
00202 unsigned short *TempPtr;
00203 unsigned int BarThreshold;
00204 unsigned int SpaceThreshold;
00205 unsigned char Bars;
00206 unsigned char Spaces;
00207 unsigned short c;
00208
00209 TempPtr = p->sample_ptr;
00210 BarThreshold = SpaceThreshold = 0;
00211
00212
00213 if(reference == STANDARD){
00214 for(c = 0; c < 10; c++){
00215 if((*TempPtr) == NO_SAMPLE){
00216 return NO_CODE;
00217 }
00218 BarThreshold += *TempPtr++;
00219 }
00220 BarThreshold *= .1;
00221 SpaceThreshold = BarThreshold;
00222 }
00223
00224
00225 if(reference == SPECIAL){
00226 for(c = 0; c < 5; c++){
00227 if((*TempPtr) == NO_SAMPLE){
00228 return NO_CODE;
00229 }
00230
00231 BarThreshold += *TempPtr++;
00232 if((*TempPtr) == NO_SAMPLE){
00233 return NO_CODE;
00234 }
00235 SpaceThreshold += *TempPtr++;
00236 }
00237 BarThreshold *= .2;
00238 SpaceThreshold *= .2;
00239 }
00240
00241
00242 else{
00243 return NO_CODE;
00244 }
00245
00246
00247 Bars = 0;
00248 Spaces = 0;
00249
00250
00251 for(c = 0; c < 5; c++){
00252
00253
00254 if(*p->sample_ptr++ > BarThreshold){
00255 Bars |= 0x20;
00256 }
00257 Bars >>= 1;
00258
00259
00260 if(*p->sample_ptr++ > SpaceThreshold){
00261 Spaces |= 0x20;
00262 }
00263 Spaces >>= 1;
00264 }
00265
00266
00267 if(Bars > 31 || Spaces > 31){
00268 return NO_CODE;
00269 }
00270
00271
00272 if((decode_pair[0] = DecodeTable[Bars]) == NO_CODE){
00273 return NO_CODE;
00274 }
00275
00276
00277 if((decode_pair[1] = DecodeTable[Spaces]) == NO_CODE){
00278 return NO_CODE;
00279 }
00280
00281
00282 else{
00283 return OK_CODE;
00284 }
00285 }
00286
00287
00288
00289
00290
00291 static
00292 unsigned short
00293 FindStart(struct BC_STRUCT *p, unsigned char length)
00294 {
00295 unsigned short Found;
00296 unsigned short AttemptCount, c;
00297 unsigned short TempCount;
00298 unsigned short *TempPtr;
00299
00300
00301 AttemptCount = 5;
00302 TempCount = p->sample_ctr;
00303 TempPtr = p->sample_ptr;
00304
00305
00306 while(AttemptCount != 0 && TempCount >= ((length * 5) + 7)){
00307
00308
00309 for(c = 0; c < 4; c++){
00310 if((TempPtr[c]) == NO_SAMPLE){
00311 return NO_CODE;
00312 }
00313 }
00314 Found = 1;
00315
00316
00317 for(c = 1; c < 4; c++){
00318 if(TempPtr[c] < (TempPtr[c + 1] * .25) ||
00319 TempPtr[c] > (TempPtr[c + 1] * 1.75)){
00320 Found = 0;
00321 }
00322 }
00323
00324
00325 if(Found){
00326
00327
00328 if(TempPtr == &p->sample_buffer[0]){
00329 p->sample_ptr += 4;
00330 return OK_CODE;
00331 }
00332
00333
00334 else if(*(TempPtr - 1) > *(TempPtr) * QUIET_MULTIPLIER){
00335 p->sample_ptr += 4;
00336 return OK_CODE;
00337 }
00338
00339
00340 else{
00341 Found = NO_CODE;
00342 }
00343 }
00344
00345
00346 if(!Found){
00347 AttemptCount--;
00348 TempCount--;
00349 TempPtr++;
00350 p->sample_ptr = TempPtr;
00351 }
00352 }
00353
00354
00355 return NO_CODE;
00356 }
00357
00358
00359
00360
00361
00362 static
00363 unsigned short
00364 FindStop(struct BC_STRUCT *p, unsigned char length)
00365 {
00366 unsigned char c;
00367 unsigned short TempCount;
00368 unsigned short *TempPtr;
00369
00370 TempCount = p->sample_ctr;
00371 TempPtr = p->sample_ptr;
00372
00373 while(TempCount >= ((length * 5) + 7)){
00374
00375
00376 for(c = 0; c < 3; c++){
00377 if((TempPtr[c]) == NO_SAMPLE){
00378 return NO_CODE;
00379 }
00380 }
00381
00382
00383 if(TempPtr[0] < TempPtr[1] * 1.75){
00384 return NO_CODE;
00385 }
00386
00387
00388 if(TempPtr[1] < TempPtr[2] *.25 || TempPtr[1] > TempPtr[2] * 1.75){
00389 return NO_CODE;
00390 }
00391
00392
00393 else{
00394 p->sample_ptr += 3;
00395 return OK_CODE;
00396 }
00397 }
00398
00399
00400 return NO_CODE;
00401 }