Leptonica 1.82.0
Image processing and image analysis suite
bardecode.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
62#ifdef HAVE_CONFIG_H
63#include <config_auto.h>
64#endif /* HAVE_CONFIG_H */
65
66#include <string.h>
67#include "allheaders.h"
68#include "readbarcode.h"
69
70static l_int32 barcodeFindFormat(char *barstr);
71static l_int32 barcodeVerifyFormat(char *barstr, l_int32 format,
72 l_int32 *pvalid, l_int32 *preverse);
73static char *barcodeDecode2of5(char *barstr, l_int32 debugflag);
74static char *barcodeDecodeI2of5(char *barstr, l_int32 debugflag);
75static char *barcodeDecode93(char *barstr, l_int32 debugflag);
76static char *barcodeDecode39(char *barstr, l_int32 debugflag);
77static char *barcodeDecodeCodabar(char *barstr, l_int32 debugflag);
78static char *barcodeDecodeUpca(char *barstr, l_int32 debugflag);
79static char *barcodeDecodeEan13(char *barstr, l_int32 first, l_int32 debugflag);
80
81#ifndef NO_CONSOLE_IO
82#define DEBUG_CODES 0
83#endif /* ~NO_CONSOLE_IO */
84
85/*------------------------------------------------------------------------*
86 * Decoding dispatcher *
87 *------------------------------------------------------------------------*/
96char *
98 l_int32 format,
99 l_int32 debugflag)
100{
101char *data = NULL;
102
103 PROCNAME("barcodeDispatchDecoder");
104
105 if (!barstr)
106 return (char *)ERROR_PTR("barstr not defined", procName, NULL);
107
108 debugflag = FALSE; /* not used yet */
109
110 if (format == L_BF_ANY)
111 format = barcodeFindFormat(barstr);
112
113 if (format == L_BF_CODE2OF5)
114 data = barcodeDecode2of5(barstr, debugflag);
115 else if (format == L_BF_CODEI2OF5)
116 data = barcodeDecodeI2of5(barstr, debugflag);
117 else if (format == L_BF_CODE93)
118 data = barcodeDecode93(barstr, debugflag);
119 else if (format == L_BF_CODE39)
120 data = barcodeDecode39(barstr, debugflag);
121 else if (format == L_BF_CODABAR)
122 data = barcodeDecodeCodabar(barstr, debugflag);
123 else if (format == L_BF_UPCA)
124 data = barcodeDecodeUpca(barstr, debugflag);
125 else if (format == L_BF_EAN13)
126 data = barcodeDecodeEan13(barstr, 0, debugflag);
127 else
128 return (char *)ERROR_PTR("format not implemented", procName, NULL);
129
130 return data;
131}
132
133
134/*------------------------------------------------------------------------*
135 * Barcode format determination *
136 *------------------------------------------------------------------------*/
143static l_int32
144barcodeFindFormat(char *barstr)
145{
146l_int32 i, format, valid;
147
148 PROCNAME("barcodeFindFormat");
149
150 if (!barstr)
151 return ERROR_INT("barstr not defined", procName, L_BF_UNKNOWN);
152
153 for (i = 0; i < NumSupportedBarcodeFormats; i++) {
154 format = SupportedBarcodeFormat[i];
155 barcodeVerifyFormat(barstr, format, &valid, NULL);
156 if (valid) {
157 L_INFO("Barcode format: %s\n", procName,
158 SupportedBarcodeFormatName[i]);
159 return format;
160 }
161 }
162 return L_BF_UNKNOWN;
163}
164
165
173l_int32
175{
176l_int32 i;
177
178 for (i = 0; i < NumSupportedBarcodeFormats; i++) {
179 if (format == SupportedBarcodeFormat[i])
180 return 1;
181 }
182 return 0;
183}
184
185
207static l_int32
209 l_int32 format,
210 l_int32 *pvalid,
211 l_int32 *preverse)
212{
213char *revbarstr;
214l_int32 i, start, len, stop, mid;
215
216 PROCNAME("barcodeVerifyFormat");
217
218 if (!pvalid)
219 return ERROR_INT("barstr not defined", procName, 1);
220 *pvalid = 0;
221 if (preverse) *preverse = 0;
222 if (!barstr)
223 return ERROR_INT("barstr not defined", procName, 1);
224
225 switch (format)
226 {
227 case L_BF_CODE2OF5:
228 start = !strncmp(barstr, Code2of5[C25_START], 3);
229 len = strlen(barstr);
230 if (len < 20)
231 return ERROR_INT("barstr too short for CODE2OF5", procName, 1);
232 stop = !strncmp(&barstr[len - 5], Code2of5[C25_STOP], 5);
233 if (start && stop) {
234 *pvalid = 1;
235 } else {
236 revbarstr = stringReverse(barstr);
237 start = !strncmp(revbarstr, Code2of5[C25_START], 3);
238 stop = !strncmp(&revbarstr[len - 5], Code2of5[C25_STOP], 5);
239 LEPT_FREE(revbarstr);
240 if (start && stop) {
241 *pvalid = 1;
242 if (preverse) *preverse = 1;
243 }
244 }
245 break;
246 case L_BF_CODEI2OF5:
247 start = !strncmp(barstr, CodeI2of5[CI25_START], 4);
248 len = strlen(barstr);
249 if (len < 20)
250 return ERROR_INT("barstr too short for CODEI2OF5", procName, 1);
251 stop = !strncmp(&barstr[len - 3], CodeI2of5[CI25_STOP], 3);
252 if (start && stop) {
253 *pvalid = 1;
254 } else {
255 revbarstr = stringReverse(barstr);
256 start = !strncmp(revbarstr, CodeI2of5[CI25_START], 4);
257 stop = !strncmp(&revbarstr[len - 3], CodeI2of5[CI25_STOP], 3);
258 LEPT_FREE(revbarstr);
259 if (start && stop) {
260 *pvalid = 1;
261 if (preverse) *preverse = 1;
262 }
263 }
264 break;
265 case L_BF_CODE93:
266 start = !strncmp(barstr, Code93[C93_START], 6);
267 len = strlen(barstr);
268 if (len < 28)
269 return ERROR_INT("barstr too short for CODE93", procName, 1);
270 stop = !strncmp(&barstr[len - 7], Code93[C93_STOP], 6);
271 if (start && stop) {
272 *pvalid = 1;
273 } else {
274 revbarstr = stringReverse(barstr);
275 start = !strncmp(revbarstr, Code93[C93_START], 6);
276 stop = !strncmp(&revbarstr[len - 7], Code93[C93_STOP], 6);
277 LEPT_FREE(revbarstr);
278 if (start && stop) {
279 *pvalid = 1;
280 if (preverse) *preverse = 1;
281 }
282 }
283 break;
284 case L_BF_CODE39:
285 start = !strncmp(barstr, Code39[C39_START], 9);
286 len = strlen(barstr);
287 if (len < 30)
288 return ERROR_INT("barstr too short for CODE39", procName, 1);
289 stop = !strncmp(&barstr[len - 9], Code39[C39_STOP], 9);
290 if (start && stop) {
291 *pvalid = 1;
292 } else {
293 revbarstr = stringReverse(barstr);
294 start = !strncmp(revbarstr, Code39[C39_START], 9);
295 stop = !strncmp(&revbarstr[len - 9], Code39[C39_STOP], 9);
296 LEPT_FREE(revbarstr);
297 if (start && stop) {
298 *pvalid = 1;
299 if (preverse) *preverse = 1;
300 }
301 }
302 break;
303 case L_BF_CODABAR:
304 start = stop = 0;
305 len = strlen(barstr);
306 if (len < 26)
307 return ERROR_INT("barstr too short for CODABAR", procName, 1);
308 for (i = 16; i <= 19; i++) /* any of these will do */
309 start += !strncmp(barstr, Codabar[i], 7);
310 for (i = 16; i <= 19; i++) /* ditto */
311 stop += !strncmp(&barstr[len - 7], Codabar[i], 7);
312 if (start && stop) {
313 *pvalid = 1;
314 } else {
315 start = stop = 0;
316 revbarstr = stringReverse(barstr);
317 for (i = 16; i <= 19; i++)
318 start += !strncmp(revbarstr, Codabar[i], 7);
319 for (i = 16; i <= 19; i++)
320 stop += !strncmp(&revbarstr[len - 7], Codabar[i], 7);
321 LEPT_FREE(revbarstr);
322 if (start && stop) {
323 *pvalid = 1;
324 if (preverse) *preverse = 1;
325 }
326 }
327 break;
328 case L_BF_UPCA:
329 case L_BF_EAN13:
330 len = strlen(barstr);
331 if (len != 59)
332 return ERROR_INT("invalid length for UPCA or EAN13", procName, 1);
333 start = !strncmp(barstr, Upca[UPCA_START], 3);
334 mid = !strncmp(&barstr[27], Upca[UPCA_MID], 5);
335 stop = !strncmp(&barstr[len - 3], Upca[UPCA_STOP], 3);
336 if (start && mid && stop)
337 *pvalid = 1;
338 break;
339 default:
340 return ERROR_INT("format not supported", procName, 1);
341 }
342
343 return 0;
344}
345
346
347/*------------------------------------------------------------------------*
348 * Code 2 of 5 *
349 *------------------------------------------------------------------------*/
377static char *
378barcodeDecode2of5(char *barstr,
379 l_int32 debugflag)
380{
381char *data, *vbarstr;
382char code[10];
383l_int32 valid, reverse, i, j, len, error, ndigits, start, found;
384
385 PROCNAME("barcodeDecodeI2of5");
386
387 if (!barstr)
388 return (char *)ERROR_PTR("barstr not defined", procName, NULL);
389
390 /* Verify format; reverse if necessary */
391 barcodeVerifyFormat(barstr, L_BF_CODE2OF5, &valid, &reverse);
392 if (!valid)
393 return (char *)ERROR_PTR("barstr not in 2of5 format", procName, NULL);
394 if (reverse)
395 vbarstr = stringReverse(barstr);
396 else
397 vbarstr = stringNew(barstr);
398
399 /* Verify size */
400 len = strlen(vbarstr);
401 if ((len - 11) % 10 != 0) {
402 LEPT_FREE(vbarstr);
403 return (char *)ERROR_PTR("size not divisible by 10: invalid 2of5 code",
404 procName, NULL);
405 }
406
407 error = FALSE;
408 ndigits = (len - 11) / 10;
409 data = (char *)LEPT_CALLOC(ndigits + 1, sizeof(char));
410 memset(code, 0, 10);
411 for (i = 0; i < ndigits; i++) {
412 start = 6 + 10 * i;
413 for (j = 0; j < 9; j++)
414 code[j] = vbarstr[start + j];
415
416 if (debugflag)
417 lept_stderr("code: %s\n", code);
418
419 found = FALSE;
420 for (j = 0; j < 10; j++) {
421 if (!strcmp(code, Code2of5[j])) {
422 data[i] = 0x30 + j;
423 found = TRUE;
424 break;
425 }
426 }
427 if (!found) error = TRUE;
428 }
429 LEPT_FREE(vbarstr);
430
431 if (error) {
432 LEPT_FREE(data);
433 return (char *)ERROR_PTR("error in decoding", procName, NULL);
434 }
435
436 return data;
437}
438
439
440/*------------------------------------------------------------------------*
441 * Interleaved Code 2 of 5 *
442 *------------------------------------------------------------------------*/
457static char *
459 l_int32 debugflag)
460{
461char *data, *vbarstr;
462char code1[6], code2[6];
463l_int32 valid, reverse, i, j, len, error, npairs, start, found;
464
465 PROCNAME("barcodeDecodeI2of5");
466
467 if (!barstr)
468 return (char *)ERROR_PTR("barstr not defined", procName, NULL);
469
470 /* Verify format; reverse if necessary */
471 barcodeVerifyFormat(barstr, L_BF_CODEI2OF5, &valid, &reverse);
472 if (!valid)
473 return (char *)ERROR_PTR("barstr not in i2of5 format", procName, NULL);
474 if (reverse)
475 vbarstr = stringReverse(barstr);
476 else
477 vbarstr = stringNew(barstr);
478
479 /* Verify size */
480 len = strlen(vbarstr);
481 if ((len - 7) % 10 != 0) {
482 LEPT_FREE(vbarstr);
483 return (char *)ERROR_PTR("size not divisible by 10: invalid I2of5 code",
484 procName, NULL);
485 }
486
487 error = FALSE;
488 npairs = (len - 7) / 10;
489 data = (char *)LEPT_CALLOC(2 * npairs + 1, sizeof(char));
490 memset(code1, 0, 6);
491 memset(code2, 0, 6);
492 for (i = 0; i < npairs; i++) {
493 start = 4 + 10 * i;
494 for (j = 0; j < 5; j++) {
495 code1[j] = vbarstr[start + 2 * j];
496 code2[j] = vbarstr[start + 2 * j + 1];
497 }
498
499 if (debugflag)
500 lept_stderr("code1: %s, code2: %s\n", code1, code2);
501
502 found = FALSE;
503 for (j = 0; j < 10; j++) {
504 if (!strcmp(code1, CodeI2of5[j])) {
505 data[2 * i] = 0x30 + j;
506 found = TRUE;
507 break;
508 }
509 }
510 if (!found) error = TRUE;
511 found = FALSE;
512 for (j = 0; j < 10; j++) {
513 if (!strcmp(code2, CodeI2of5[j])) {
514 data[2 * i + 1] = 0x30 + j;
515 found = TRUE;
516 break;
517 }
518 }
519 if (!found) error = TRUE;
520 }
521 LEPT_FREE(vbarstr);
522
523 if (error) {
524 LEPT_FREE(data);
525 return (char *)ERROR_PTR("error in decoding", procName, NULL);
526 }
527
528 return data;
529}
530
531
532/*------------------------------------------------------------------------*
533 * Code 93 *
534 *------------------------------------------------------------------------*/
554static char *
555barcodeDecode93(char *barstr,
556 l_int32 debugflag)
557{
558const char *checkc, *checkk;
559char *data, *vbarstr;
560char code[7];
561l_int32 valid, reverse, i, j, len, error, nsymb, start, found, sum;
562l_int32 *index;
563
564 PROCNAME("barcodeDecode93");
565
566 if (!barstr)
567 return (char *)ERROR_PTR("barstr not defined", procName, NULL);
568
569 /* Verify format; reverse if necessary */
570 barcodeVerifyFormat(barstr, L_BF_CODE93, &valid, &reverse);
571 if (!valid)
572 return (char *)ERROR_PTR("barstr not in code93 format", procName, NULL);
573 if (reverse)
574 vbarstr = stringReverse(barstr);
575 else
576 vbarstr = stringNew(barstr);
577
578 /* Verify size; skip the first 6 and last 7 bars. */
579 len = strlen(vbarstr);
580 if ((len - 13) % 6 != 0) {
581 LEPT_FREE(vbarstr);
582 return (char *)ERROR_PTR("size not divisible by 6: invalid code 93",
583 procName, NULL);
584 }
585
586 /* Decode the symbols */
587 nsymb = (len - 13) / 6;
588 data = (char *)LEPT_CALLOC(nsymb + 1, sizeof(char));
589 index = (l_int32 *)LEPT_CALLOC(nsymb, sizeof(l_int32));
590 memset(code, 0, 7);
591 error = FALSE;
592 for (i = 0; i < nsymb; i++) {
593 start = 6 + 6 * i;
594 for (j = 0; j < 6; j++)
595 code[j] = vbarstr[start + j];
596
597 if (debugflag)
598 lept_stderr("code: %s\n", code);
599
600 found = FALSE;
601 for (j = 0; j < C93_START; j++) {
602 if (!strcmp(code, Code93[j])) {
603 data[i] = Code93Val[j];
604 index[i] = j;
605 found = TRUE;
606 break;
607 }
608 }
609 if (!found) error = TRUE;
610 }
611 LEPT_FREE(vbarstr);
612
613 if (error) {
614 LEPT_FREE(index);
615 LEPT_FREE(data);
616 return (char *)ERROR_PTR("error in decoding", procName, NULL);
617 }
618
619 /* Do check sums. For character "C", use only the
620 * actual data in computing the sum. For character "K",
621 * use the actual data plus the check character "C". */
622 sum = 0;
623 for (i = 0; i < nsymb - 2; i++) /* skip the "C" and "K" */
624 sum += ((i % 20) + 1) * index[nsymb - 3 - i];
625 if (data[nsymb - 2] != Code93Val[sum % 47])
626 L_WARNING("Error for check C\n", procName);
627
628 if (debugflag) {
629 checkc = Code93[sum % 47];
630 lept_stderr("checkc = %s\n", checkc);
631 }
632
633 sum = 0;
634 for (i = 0; i < nsymb - 1; i++) /* skip the "K" */
635 sum += ((i % 15) + 1) * index[nsymb - 2 - i];
636 if (data[nsymb - 1] != Code93Val[sum % 47])
637 L_WARNING("Error for check K\n", procName);
638
639 if (debugflag) {
640 checkk = Code93[sum % 47];
641 lept_stderr("checkk = %s\n", checkk);
642 }
643
644 /* Remove the two check codes from the output */
645 data[nsymb - 2] = '\0';
646
647 LEPT_FREE(index);
648 return data;
649}
650
651
652/*------------------------------------------------------------------------*
653 * Code 39 *
654 *------------------------------------------------------------------------*/
671static char *
672barcodeDecode39(char *barstr,
673 l_int32 debugflag)
674{
675char *data, *vbarstr;
676char code[10];
677l_int32 valid, reverse, i, j, len, error, nsymb, start, found;
678
679 PROCNAME("barcodeDecode39");
680
681 if (!barstr)
682 return (char *)ERROR_PTR("barstr not defined", procName, NULL);
683
684 /* Verify format; reverse if necessary */
685 barcodeVerifyFormat(barstr, L_BF_CODE39, &valid, &reverse);
686 if (!valid)
687 return (char *)ERROR_PTR("barstr not in code39 format", procName, NULL);
688 if (reverse)
689 vbarstr = stringReverse(barstr);
690 else
691 vbarstr = stringNew(barstr);
692
693 /* Verify size */
694 len = strlen(vbarstr);
695 if ((len + 1) % 10 != 0) {
696 LEPT_FREE(vbarstr);
697 return (char *)ERROR_PTR("size+1 not divisible by 10: invalid code 39",
698 procName, NULL);
699 }
700
701 /* Decode the symbols */
702 nsymb = (len - 19) / 10;
703 data = (char *)LEPT_CALLOC(nsymb + 1, sizeof(char));
704 memset(code, 0, 10);
705 error = FALSE;
706 for (i = 0; i < nsymb; i++) {
707 start = 10 + 10 * i;
708 for (j = 0; j < 9; j++)
709 code[j] = vbarstr[start + j];
710
711 if (debugflag)
712 lept_stderr("code: %s\n", code);
713
714 found = FALSE;
715 for (j = 0; j < C39_START; j++) {
716 if (!strcmp(code, Code39[j])) {
717 data[i] = Code39Val[j];
718 found = TRUE;
719 break;
720 }
721 }
722 if (!found) error = TRUE;
723 }
724 LEPT_FREE(vbarstr);
725
726 if (error) {
727 LEPT_FREE(data);
728 return (char *)ERROR_PTR("error in decoding", procName, NULL);
729 }
730
731 return data;
732}
733
734
735/*------------------------------------------------------------------------*
736 * Codabar *
737 *------------------------------------------------------------------------*/
754static char *
756 l_int32 debugflag)
757{
758char *data, *vbarstr;
759char code[8];
760l_int32 valid, reverse, i, j, len, error, nsymb, start, found;
761
762 PROCNAME("barcodeDecodeCodabar");
763
764 if (!barstr)
765 return (char *)ERROR_PTR("barstr not defined", procName, NULL);
766
767 /* Verify format; reverse if necessary */
768 barcodeVerifyFormat(barstr, L_BF_CODABAR, &valid, &reverse);
769 if (!valid)
770 return (char *)ERROR_PTR("barstr not in codabar format",
771 procName, NULL);
772 if (reverse)
773 vbarstr = stringReverse(barstr);
774 else
775 vbarstr = stringNew(barstr);
776
777 /* Verify size */
778 len = strlen(vbarstr);
779 if ((len + 1) % 8 != 0) {
780 LEPT_FREE(vbarstr);
781 return (char *)ERROR_PTR("size+1 not divisible by 8: invalid codabar",
782 procName, NULL);
783 }
784
785 /* Decode the symbols */
786 nsymb = (len - 15) / 8;
787 data = (char *)LEPT_CALLOC(nsymb + 1, sizeof(char));
788 memset(code, 0, 8);
789 error = FALSE;
790 for (i = 0; i < nsymb; i++) {
791 start = 8 + 8 * i;
792 for (j = 0; j < 7; j++)
793 code[j] = vbarstr[start + j];
794
795 if (debugflag)
796 lept_stderr("code: %s\n", code);
797
798 found = FALSE;
799 for (j = 0; j < 16; j++) {
800 if (!strcmp(code, Codabar[j])) {
801 data[i] = CodabarVal[j];
802 found = TRUE;
803 break;
804 }
805 }
806 if (!found) error = TRUE;
807 }
808 LEPT_FREE(vbarstr);
809
810 if (error) {
811 LEPT_FREE(data);
812 return (char *)ERROR_PTR("error in decoding", procName, NULL);
813 }
814
815 return data;
816}
817
818
819/*------------------------------------------------------------------------*
820 * Code UPC-A *
821 *------------------------------------------------------------------------*/
842static char *
843barcodeDecodeUpca(char *barstr,
844 l_int32 debugflag)
845{
846char *data, *vbarstr;
847char code[5];
848l_int32 valid, i, j, len, error, start, found, sum, checkdigit;
849
850 PROCNAME("barcodeDecodeUpca");
851
852 if (!barstr)
853 return (char *)ERROR_PTR("barstr not defined", procName, NULL);
854
855 /* Verify format; reverse has no meaning here -- we must test both */
856 barcodeVerifyFormat(barstr, L_BF_UPCA, &valid, NULL);
857 if (!valid)
858 return (char *)ERROR_PTR("barstr not in UPC-A format", procName, NULL);
859
860 /* Verify size */
861 len = strlen(barstr);
862 if (len != 59)
863 return (char *)ERROR_PTR("size not 59; invalid UPC-A barcode",
864 procName, NULL);
865
866 /* Check the first digit. If invalid, reverse the string. */
867 memset(code, 0, 5);
868 for (i = 0; i < 4; i++)
869 code[i] = barstr[i + 3];
870 found = FALSE;
871 for (i = 0; i < 10; i++) {
872 if (!strcmp(code, Upca[i])) {
873 found = TRUE;
874 break;
875 }
876 }
877 if (found == FALSE)
878 vbarstr = stringReverse(barstr);
879 else
880 vbarstr = stringNew(barstr);
881
882 /* Decode the 12 symbols */
883 data = (char *)LEPT_CALLOC(13, sizeof(char));
884 memset(code, 0, 5);
885 error = FALSE;
886 for (i = 0; i < 12; i++) {
887 if (i < 6)
888 start = 3 + 4 * i;
889 else
890 start = 32 + 4 * (i - 6);
891 for (j = 0; j < 4; j++)
892 code[j] = vbarstr[start + j];
893
894 if (debugflag)
895 lept_stderr("code: %s\n", code);
896
897 found = FALSE;
898 for (j = 0; j < 10; j++) {
899 if (!strcmp(code, Upca[j])) {
900 data[i] = 0x30 + j;
901 found = TRUE;
902 break;
903 }
904 }
905 if (!found) error = TRUE;
906 }
907 LEPT_FREE(vbarstr);
908
909 if (error) {
910 LEPT_FREE(data);
911 return (char *)ERROR_PTR("error in decoding", procName, NULL);
912 }
913
914 /* Calculate the check digit (data[11]). */
915 sum = 0;
916 for (i = 0; i < 12; i += 2) /* "even" digits */
917 sum += 3 * (data[i] - 0x30);
918 for (i = 1; i < 11; i += 2) /* "odd" digits */
919 sum += (data[i] - 0x30);
920 checkdigit = sum % 10;
921 if (checkdigit) /* not 0 */
922 checkdigit = 10 - checkdigit;
923 if (checkdigit + 0x30 != data[11])
924 L_WARNING("Error for UPC-A check character\n", procName);
925
926 return data;
927}
928
929
930/*------------------------------------------------------------------------*
931 * Code EAN-13 *
932 *------------------------------------------------------------------------*/
959static char *
961 l_int32 first,
962 l_int32 debugflag)
963{
964char *data, *vbarstr;
965char code[5];
966l_int32 valid, i, j, len, error, start, found, sum, checkdigit;
967
968 PROCNAME("barcodeDecodeEan13");
969
970 if (!barstr)
971 return (char *)ERROR_PTR("barstr not defined", procName, NULL);
972
973 /* Verify format. You can't tell the orientation by the start
974 * and stop codes, but you can by the location of the digits.
975 * Use the UPCA verifier for EAN 13 -- it is identical. */
976 barcodeVerifyFormat(barstr, L_BF_UPCA, &valid, NULL);
977 if (!valid)
978 return (char *)ERROR_PTR("barstr not in EAN 13 format", procName, NULL);
979
980 /* Verify size */
981 len = strlen(barstr);
982 if (len != 59)
983 return (char *)ERROR_PTR("size not 59; invalid EAN 13 barcode",
984 procName, NULL);
985
986 /* Check the first digit. If invalid, reverse the string. */
987 memset(code, 0, 5);
988 for (i = 0; i < 4; i++)
989 code[i] = barstr[i + 3];
990 found = FALSE;
991 for (i = 0; i < 10; i++) {
992 if (!strcmp(code, Upca[i])) {
993 found = TRUE;
994 break;
995 }
996 }
997 if (found == FALSE)
998 vbarstr = stringReverse(barstr);
999 else
1000 vbarstr = stringNew(barstr);
1001
1002 /* Decode the 12 symbols */
1003 data = (char *)LEPT_CALLOC(13, sizeof(char));
1004 memset(code, 0, 5);
1005 error = FALSE;
1006 for (i = 0; i < 12; i++) {
1007 if (i < 6)
1008 start = 3 + 4 * i;
1009 else
1010 start = 32 + 4 * (i - 6);
1011 for (j = 0; j < 4; j++)
1012 code[j] = vbarstr[start + j];
1013
1014 if (debugflag)
1015 lept_stderr("code: %s\n", code);
1016
1017 found = FALSE;
1018 for (j = 0; j < 10; j++) {
1019 if (!strcmp(code, Upca[j])) {
1020 data[i] = 0x30 + j;
1021 found = TRUE;
1022 break;
1023 }
1024 }
1025 if (!found) error = TRUE;
1026 }
1027 LEPT_FREE(vbarstr);
1028
1029 if (error) {
1030 LEPT_FREE(data);
1031 return (char *)ERROR_PTR("error in decoding", procName, NULL);
1032 }
1033
1034 /* Calculate the check digit (data[11]). */
1035 sum = 0;
1036 for (i = 0; i < 12; i += 2) /* "even" digits */
1037 sum += 3 * (data[i] - 0x30);
1038 for (i = 1; i < 12; i += 2) /* "odd" digits */
1039 sum += (data[i] - 0x30);
1040 checkdigit = sum % 10;
1041 if (checkdigit) /* not 0 */
1042 checkdigit = 10 - checkdigit;
1043 if (checkdigit + 0x30 != data[11])
1044 L_WARNING("Error for EAN-13 check character\n", procName);
1045
1046 return data;
1047}
static char * barcodeDecodeI2of5(char *barstr, l_int32 debugflag)
barcodeDecodeI2of5()
Definition: bardecode.c:458
static char * barcodeDecodeCodabar(char *barstr, l_int32 debugflag)
barcodeDecodeCodabar()
Definition: bardecode.c:755
static l_int32 barcodeFindFormat(char *barstr)
barcodeFindFormat()
Definition: bardecode.c:144
char * barcodeDispatchDecoder(char *barstr, l_int32 format, l_int32 debugflag)
barcodeDispatchDecoder()
Definition: bardecode.c:97
static char * barcodeDecodeUpca(char *barstr, l_int32 debugflag)
barcodeDecodeUpca()
Definition: bardecode.c:843
static char * barcodeDecode39(char *barstr, l_int32 debugflag)
barcodeDecode39()
Definition: bardecode.c:672
static char * barcodeDecode2of5(char *barstr, l_int32 debugflag)
barcodeDecode2of5()
Definition: bardecode.c:378
l_int32 barcodeFormatIsSupported(l_int32 format)
barcodeFormatIsSupported()
Definition: bardecode.c:174
static char * barcodeDecodeEan13(char *barstr, l_int32 first, l_int32 debugflag)
barcodeDecodeEan13()
Definition: bardecode.c:960
static char * barcodeDecode93(char *barstr, l_int32 debugflag)
barcodeDecode93()
Definition: bardecode.c:555
static l_int32 barcodeVerifyFormat(char *barstr, l_int32 format, l_int32 *pvalid, l_int32 *preverse)
barcodeVerifyFormat()
Definition: bardecode.c:208
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
char * stringReverse(const char *src)
stringReverse()
Definition: utils2.c:597
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:223