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
00065 #define STORE_SS_CODES
00066
00067
00068
00069
00071 #define NO_SAMPLE NUL
00072
00073 #define NO_CODE 0
00074
00075 #define OK_CODE 1
00076
00077 #define NO_DECODE 0
00078
00079 #define OK_DECODE 1
00080
00082 #define MAX_DECODE 32
00083
00085 #define StartCode1 'A'
00086
00087 #define StartCode2 'B'
00088
00089 #define StartCode3 'C'
00090
00091 #define StartCode4 'D'
00092
00093 #define StopCode1 'A'
00094
00095 #define StopCode2 'B'
00096
00097 #define StopCode3 'C'
00098
00099 #define StopCode4 'D'
00100
00102 #define QUIET_MULTIPLIER 10
00103
00104
00105
00106 unsigned short DecodeCodabar(struct BC_STRUCT *p);
00107 static unsigned short FindStart(struct BC_STRUCT *p);
00108 static unsigned short Decode(struct BC_STRUCT *p);
00109 static unsigned short DecodeChar(struct BC_STRUCT *p, unsigned short *reference);
00110
00111
00118 unsigned short
00119 DecodeCodabar(struct BC_STRUCT *p)
00120 {
00121
00122 if(p->sample_ctr < 21){
00123 return 0;
00124 }
00125
00126
00127 p->sample_ptr = &p->sample_buffer[0];
00128 if(FindStart(p) != NO_CODE){
00129 if(Decode(p) != NO_DECODE){
00130 return p->decode_count;
00131 }
00132 }
00133
00134
00135 return 0;
00136 }
00137
00138
00139
00140
00141
00142 static
00143 unsigned short
00144 Decode(struct BC_STRUCT *p)
00145 {
00146 unsigned short reference;
00147 unsigned char DecodeByte;
00148
00149
00150
00151 while((*p->sample_ptr++ != NO_SAMPLE) && ((DecodeByte = DecodeChar(p, &reference)) != NO_CODE)){
00152
00153
00154 if(DecodeByte == StopCode1 || DecodeByte == StopCode2 ||
00155 DecodeByte == StopCode3 || DecodeByte == StopCode4){
00156
00157 #ifdef STORE_SS_CODES
00158
00159 if(p->decode_count > MAX_DECODE-1){
00160 return NO_DECODE;
00161 }
00162
00163
00164 p->decode_buffer[p->decode_count++] = DecodeByte;
00165 #endif
00166
00167
00168 p->decode_buffer[p->decode_count] = NUL;
00169
00170
00171 if(*p->sample_ptr == NO_SAMPLE){
00172 return OK_DECODE;
00173 }
00174
00175
00176 else if(*(p->sample_ptr) > (reference * QUIET_MULTIPLIER)){
00177 return OK_DECODE;
00178 }
00179
00180
00181 else{
00182 return NO_DECODE;
00183 }
00184 }
00185
00186
00187 if(p->decode_count > MAX_DECODE-1){
00188 return NO_DECODE;
00189 }
00190
00191
00192 else{
00193 p->decode_buffer[p->decode_count++] = DecodeByte;
00194 }
00195 }
00196
00197
00198 return NO_DECODE;
00199 }
00200
00201
00202
00203
00204 static
00205 unsigned short
00206 DecodeChar(struct BC_STRUCT *p, unsigned short *reference)
00207 {
00208 unsigned short BarThreshold, SpaceThreshold;
00209
00211 static const struct key{
00212 unsigned char key;
00213 unsigned char value;
00214 }
00215 search_table[20] = {
00216 3, '0',
00217 6, '1',
00218 9, '2',
00219 96, '3',
00220 18, '4',
00221 66, '5',
00222 33, '6',
00223 36, '7',
00224 48, '8',
00225 72, '9',
00226 12, '-',
00227 24, '$',
00228 69, ':',
00229 81, '/',
00230 84, '.',
00231 21, '+',
00232 26, 'A',
00233 41, 'B',
00234 11, 'C',
00235 14, 'D',
00236 };
00237
00238 unsigned short *TempPtr;
00239 unsigned char BarSpace;
00240 unsigned short WideBar, WideSpace;
00241 unsigned short wide_bars;
00242 unsigned short c;
00243
00244
00245 WideBar = 0;
00246 WideSpace = 0;
00247 TempPtr = p->sample_ptr;
00248 for(c = 0; c < 7; c++){
00249
00250
00251 if((*TempPtr) == NO_SAMPLE){
00252 return NO_CODE;
00253 }
00254
00255
00256 if(c & 1){
00257 if(*TempPtr > WideSpace){
00258 WideSpace = *TempPtr;
00259 }
00260 }
00261
00262
00263 else{
00264 if(*TempPtr > WideBar){
00265 WideBar = *TempPtr;
00266 }
00267 }
00268 ++TempPtr;
00269 }
00270
00271
00272 wide_bars = 0;
00273 TempPtr = p->sample_ptr;
00274 BarThreshold = WideBar * .625;
00275 for(c = 0; c < 4; c++){
00276 if(*TempPtr > BarThreshold){
00277 ++wide_bars;
00278 }
00279 TempPtr += 2;
00280 }
00281
00282
00283 if(wide_bars == 1){
00284
00285
00286 BarSpace = 0;
00287 SpaceThreshold = WideSpace * .625;
00288 for(c = 0; c < 3; c++){
00289
00290
00291 if(*p->sample_ptr++ > BarThreshold){
00292 BarSpace |= 1;
00293 }
00294 BarSpace <<= 1;
00295
00296
00297 if(*p->sample_ptr++ > SpaceThreshold){
00298 BarSpace |= 1;
00299 }
00300 BarSpace <<= 1;
00301 }
00302
00303
00304 if(*p->sample_ptr++ > BarThreshold){
00305 BarSpace |= 1;
00306 }
00307
00308
00309 for(c = 0; c < sizeof search_table / 2; c++){
00310 if(search_table[c].key == BarSpace){
00311 return search_table[c].value;
00312 }
00313 }
00314 }
00315
00316
00317 else if(wide_bars == 3){
00318
00319 BarSpace = 0;
00320 SpaceThreshold = WideSpace * .375;
00321 for(c = 0; c < 3; c++){
00322
00323
00324 if(*p->sample_ptr++ > BarThreshold){
00325 BarSpace |= 1;
00326 }
00327 BarSpace <<= 1;
00328
00329
00330 if(*p->sample_ptr++ < SpaceThreshold){
00331 BarSpace |= 0xfe;
00332 }
00333 BarSpace <<= 1;
00334 }
00335
00336
00337 if(*p->sample_ptr++ > BarThreshold){
00338 BarSpace |= 1;
00339 }
00340
00341
00342 for(c = 0; c < sizeof search_table / 2; c++){
00343 if(search_table[c].key == BarSpace){
00344 *reference = BarThreshold;
00345 return search_table[c].value;
00346 }
00347 }
00348 }
00349
00350
00351 return NO_CODE;
00352 }
00353
00354
00355
00356
00357
00358 static
00359 unsigned short
00360 FindStart(struct BC_STRUCT *p)
00361 {
00362 unsigned short AttemptCount;
00363 unsigned short TempCount;
00364 unsigned short *TempPtr;
00365 unsigned short reference;
00366 unsigned short c;
00367
00368
00369 TempCount = p->sample_ctr;
00370 AttemptCount = 5;
00371 TempPtr = p->sample_ptr;
00372
00373
00374 while(AttemptCount != 0 && TempCount >= 21){
00375
00376
00377 c = DecodeChar(p, &reference);
00378 if(c == StartCode1 || c == StartCode2 ||
00379 c == StartCode3 || c == StartCode4){
00380
00381
00382 p->decode_count = 0;
00383
00384
00385 #ifdef STORE_SS_CODES
00386 p->decode_buffer[p->decode_count++] = c;
00387 #endif
00388
00389
00390 if(TempPtr == &p->sample_buffer[0]){
00391 return c;
00392 }
00393
00394
00395 else if(*(TempPtr - 1) > (reference * QUIET_MULTIPLIER)){
00396 return NO_CODE;
00397 }
00398 }
00399
00400
00401 AttemptCount--;
00402 TempCount--;
00403 TempPtr++;
00404 p->sample_ptr = TempPtr;
00405 }
00406
00407
00408 return NO_CODE;
00409 }