Leptonica 1.68
C Image Processing Library

bardecode.c

Go to the documentation of this file.
00001 /*====================================================================*
00002  -  Copyright (C) 2001 Leptonica.  All rights reserved.
00003  -  This software is distributed in the hope that it will be
00004  -  useful, but with NO WARRANTY OF ANY KIND.
00005  -  No author or distributor accepts responsibility to anyone for the
00006  -  consequences of using this software, or for whether it serves any
00007  -  particular purpose or works at all, unless he or she says so in
00008  -  writing.  Everyone is granted permission to copy, modify and
00009  -  redistribute this source code, for commercial or non-commercial
00010  -  purposes, with the following restrictions: (1) the origin of this
00011  -  source code must not be misrepresented; (2) modified versions must
00012  -  be plainly marked as such; and (3) this notice may not be removed
00013  -  or altered from any source or modified source distribution.
00014  *====================================================================*/
00015 
00016 /*
00017  *  bardecode.c
00018  *
00019  *      Dispatcher
00020  *          char            *barcodeDispatchDecoder()
00021  *
00022  *      Format Determination
00023  *          static l_int32   barcodeFindFormat()
00024  *          l_int32          barcodeFormatIsSupported()
00025  *          static l_int32   barcodeVerifyFormat()
00026  *
00027  *      Decode 2 of 5
00028  *          static char     *barcodeDecode2of5()
00029  *
00030  *      Decode Interleaved 2 of 5
00031  *          static char     *barcodeDecodeI2of5()
00032  *
00033  *      Decode Code 93
00034  *          static char     *barcodeDecode93()
00035  *
00036  *      Decode Code 39
00037  *          static char     *barcodeDecode39()
00038  *
00039  *      Decode Codabar
00040  *          static char     *barcodeDecodeCodabar()
00041  *
00042  *      Decode UPC-A
00043  *          static char     *barcodeDecodeUpca()
00044  *
00045  *      Decode EAN 13
00046  *          static char     *barcodeDecodeEan13()
00047  */
00048 
00049 #include <stdio.h>
00050 #include <stdlib.h>
00051 #include <string.h>
00052 #include "allheaders.h"
00053 #include "readbarcode.h"
00054 
00055 
00056 static l_int32 barcodeFindFormat(char *barstr);
00057 static l_int32 barcodeVerifyFormat(char *barstr, l_int32 format,
00058                                    l_int32 *pvalid, l_int32 *preverse);
00059 static char *barcodeDecode2of5(char *barstr, l_int32 debugflag);
00060 static char *barcodeDecodeI2of5(char *barstr, l_int32 debugflag);
00061 static char *barcodeDecode93(char *barstr, l_int32 debugflag);
00062 static char *barcodeDecode39(char *barstr, l_int32 debugflag);
00063 static char *barcodeDecodeCodabar(char *barstr, l_int32 debugflag);
00064 static char *barcodeDecodeUpca(char *barstr, l_int32 debugflag);
00065 static char *barcodeDecodeEan13(char *barstr, l_int32 first, l_int32 debugflag);
00066 
00067 
00068 #ifndef  NO_CONSOLE_IO
00069 #define  DEBUG_CODES       0
00070 #endif  /* ~NO_CONSOLE_IO */
00071 
00072 
00073 /*------------------------------------------------------------------------*
00074  *                           Decoding dispatcher                          *
00075  *------------------------------------------------------------------------*/
00076 /*!
00077  *  barcodeDispatchDecoder()
00078  *
00079  *      Input:  barstr (string of integers in set {1,2,3,4} of bar widths)
00080  *              format (L_BF_ANY, L_BF_CODEI2OF5, L_BF_CODE93, ...)
00081  *              debugflag (use 1 to generate debug output)
00082  *      Return: data (string of decoded barcode data), or null on error
00083  */
00084 char *
00085 barcodeDispatchDecoder(char    *barstr,
00086                        l_int32  format,
00087                        l_int32  debugflag)
00088 {
00089 char  *data = NULL;
00090 
00091     PROCNAME("barcodeDispatchDecoder");
00092 
00093     if (!barstr)
00094         return (char *)ERROR_PTR("barstr not defined", procName, NULL);
00095 
00096     debugflag = FALSE;  /* not used yet */
00097 
00098     if (format == L_BF_ANY)
00099         format = barcodeFindFormat(barstr);
00100 
00101     if (format == L_BF_CODE2OF5)
00102         data = barcodeDecode2of5(barstr, debugflag);
00103     else if (format == L_BF_CODEI2OF5)
00104         data = barcodeDecodeI2of5(barstr, debugflag);
00105     else if (format == L_BF_CODE93)
00106         data = barcodeDecode93(barstr, debugflag);
00107     else if (format == L_BF_CODE39)
00108         data = barcodeDecode39(barstr, debugflag);
00109     else if (format == L_BF_CODABAR)
00110         data = barcodeDecodeCodabar(barstr, debugflag);
00111     else if (format == L_BF_UPCA)
00112         data = barcodeDecodeUpca(barstr, debugflag);
00113     else if (format == L_BF_EAN13)
00114         data = barcodeDecodeEan13(barstr, 0, debugflag);
00115     else
00116         return (char *)ERROR_PTR("format not implemented", procName, NULL);
00117 
00118     return data;
00119 }
00120 
00121 
00122 /*------------------------------------------------------------------------*
00123  *                      Barcode format determination                      *
00124  *------------------------------------------------------------------------*/
00125 /*!
00126  *  barcodeFindFormat()
00127  *
00128  *      Input:  barstr (of barcode widths, in set {1,2,3,4})
00129  *      Return: format (for barcode), or L_BF_UNKNOWN if not recognized
00130  */
00131 static l_int32
00132 barcodeFindFormat(char    *barstr)
00133 {
00134 l_int32  i, format, valid;
00135 
00136    PROCNAME("barcodeFindFormat");
00137 
00138    if (!barstr)
00139        return ERROR_INT("barstr not defined", procName, L_BF_UNKNOWN);
00140 
00141    for (i = 0; i < NumSupportedBarcodeFormats; i++) {
00142        format = SupportedBarcodeFormat[i];
00143        barcodeVerifyFormat(barstr, format, &valid, NULL);
00144        if (valid) {
00145            L_INFO_STRING("Barcode format: %s", procName,
00146                          SupportedBarcodeFormatName[i]);
00147            return format;
00148        }
00149    }
00150    return L_BF_UNKNOWN;
00151 }
00152 
00153 
00154 /*!
00155  *  barcodeFormatIsSupported()
00156  *
00157  *      Input:  format
00158  *      Return: 1 if format is one of those supported; 0 otherwise
00159  *
00160  */
00161 l_int32
00162 barcodeFormatIsSupported(l_int32  format)
00163 {
00164 l_int32  i;
00165 
00166    for (i = 0; i < NumSupportedBarcodeFormats; i++) {
00167        if (format == SupportedBarcodeFormat[i])
00168            return 1;
00169    }
00170    return 0;
00171 }
00172 
00173 
00174 /*!
00175  *  barcodeVerifyFormat()
00176  *
00177  *      Input:  barstr (of barcode widths, in set {1,2,3,4})
00178  *              format (L_BF_CODEI2OF5, L_BF_CODE93, ...)
00179  *              &valid (<return> 0 if not valid, 1 and 2 if valid)
00180  *              &reverse (<optional return> 1 if reversed; 0 otherwise)
00181  *      Return: 0 if OK, 1 on error
00182  *
00183  *  Notes:
00184  *      (1) If valid == 1, the barcode is of the given format in the
00185  *          forward order; if valid == 2, it is backwards.
00186  *      (2) If the barcode needs to be reversed to read it, and &reverse
00187  *          is provided, a 1 is put into @reverse.
00188  *      (3) Add to this as more formats are supported.
00189  */
00190 static l_int32
00191 barcodeVerifyFormat(char     *barstr,
00192                     l_int32   format,
00193                     l_int32  *pvalid,
00194                     l_int32  *preverse)
00195 {
00196 char    *revbarstr;
00197 l_int32  i, start, len, stop, mid;
00198 
00199     PROCNAME("barcodeVerifyFormat");
00200 
00201     if (!pvalid)
00202         return ERROR_INT("barstr not defined", procName, 1);
00203     *pvalid = 0;
00204     if (preverse) *preverse = 0;
00205     if (!barstr)
00206         return ERROR_INT("barstr not defined", procName, 1);
00207 
00208     switch (format)
00209     {
00210     case L_BF_CODE2OF5:
00211         start = !strncmp(barstr, Code2of5[C25_START], 3);
00212         len = strlen(barstr);
00213         stop = !strncmp(&barstr[len - 5], Code2of5[C25_STOP], 5);
00214         if (start && stop)
00215             *pvalid = 1;
00216         else {
00217             revbarstr = stringReverse(barstr);
00218             start = !strncmp(revbarstr, Code2of5[C25_START], 3);
00219             stop = !strncmp(&revbarstr[len - 5], Code2of5[C25_STOP], 5);
00220             FREE(revbarstr);
00221             if (start && stop) {
00222                 *pvalid = 1;
00223                 if (preverse) *preverse = 1;
00224             }
00225         }
00226         break;
00227     case L_BF_CODEI2OF5:
00228         start = !strncmp(barstr, CodeI2of5[CI25_START], 4);
00229         len = strlen(barstr);
00230         stop = !strncmp(&barstr[len - 3], CodeI2of5[CI25_STOP], 3);
00231         if (start && stop)
00232             *pvalid = 1;
00233         else {
00234             revbarstr = stringReverse(barstr);
00235             start = !strncmp(revbarstr, CodeI2of5[CI25_START], 4);
00236             stop = !strncmp(&revbarstr[len - 3], CodeI2of5[CI25_STOP], 3);
00237             FREE(revbarstr);
00238             if (start && stop) {
00239                 *pvalid = 1;
00240                 if (preverse) *preverse = 1;
00241             }
00242         }
00243         break;
00244     case L_BF_CODE93:
00245         start = !strncmp(barstr, Code93[C93_START], 6);
00246         len = strlen(barstr);
00247         stop = !strncmp(&barstr[len - 7], Code93[C93_STOP], 6);
00248         if (start && stop)
00249             *pvalid = 1;
00250         else {
00251             revbarstr = stringReverse(barstr);
00252             start = !strncmp(revbarstr, Code93[C93_START], 6);
00253             stop = !strncmp(&revbarstr[len - 7], Code93[C93_STOP], 6);
00254             FREE(revbarstr);
00255             if (start && stop) {
00256                 *pvalid = 1;
00257                 if (preverse) *preverse = 1;
00258             }
00259         }
00260         break;
00261     case L_BF_CODE39:
00262         start = !strncmp(barstr, Code39[C39_START], 9);
00263         len = strlen(barstr);
00264         stop = !strncmp(&barstr[len - 9], Code39[C39_STOP], 9);
00265         if (start && stop)
00266             *pvalid = 1;
00267         else {
00268             revbarstr = stringReverse(barstr);
00269             start = !strncmp(revbarstr, Code39[C39_START], 9);
00270             stop = !strncmp(&revbarstr[len - 9], Code39[C39_STOP], 9);
00271             FREE(revbarstr);
00272             if (start && stop) {
00273                 *pvalid = 1;
00274                 if (preverse) *preverse = 1;
00275             }
00276         }
00277         break;
00278     case L_BF_CODABAR:
00279         start = stop = 0;
00280         len = strlen(barstr);
00281         for (i = 16; i <= 19; i++)  /* any of these will do */
00282             start += !strncmp(barstr, Codabar[i], 7);
00283         for (i = 16; i <= 19; i++)  /* ditto */
00284             stop += !strncmp(&barstr[len - 7], Codabar[i], 7);
00285         if (start && stop)
00286             *pvalid = 1;
00287         else {
00288             start = stop = 0;
00289             revbarstr = stringReverse(barstr);
00290             for (i = 16; i <= 19; i++)
00291                 start += !strncmp(revbarstr, Codabar[i], 7);
00292             for (i = 16; i <= 19; i++)
00293                 stop += !strncmp(&revbarstr[len - 7], Codabar[i], 7);
00294             FREE(revbarstr);
00295             if (start && stop) {
00296                 *pvalid = 1;
00297                 if (preverse) *preverse = 1;
00298             }
00299         }
00300         break;
00301     case L_BF_UPCA:
00302     case L_BF_EAN13:
00303         len = strlen(barstr);
00304         if (len == 59) {
00305             start = !strncmp(barstr, Upca[UPCA_START], 3);
00306             mid = !strncmp(&barstr[27], Upca[UPCA_MID], 5);
00307             stop = !strncmp(&barstr[len - 3], Upca[UPCA_STOP], 3);
00308             if (start && mid && stop)
00309                 *pvalid = 1;
00310         }
00311         break;
00312     default:
00313         return ERROR_INT("format not supported", procName, 1);
00314     }
00315 
00316     return 0;
00317 }
00318 
00319 
00320 /*------------------------------------------------------------------------*
00321  *                             Code 2 of 5                                *
00322  *------------------------------------------------------------------------*/
00323 /*!
00324  *  barcodeDecode2of5()
00325  *
00326  *      Input:  barstr (of widths, in set {1, 2})
00327  *              debugflag
00328  *      Return: data (string of digits), or null if none found or on error
00329  *
00330  *  Notes:
00331  *      (1) Ref: http://en.wikipedia.org/wiki/Two-out-of-five_code (Note:
00332  *                 the codes given here are wrong!)
00333  *               http://morovia.com/education/symbology/code25.asp
00334  *      (2) This is a very low density encoding for the 10 digits.
00335  *          Each digit is encoded with 5 black bars, of which 2 are wide
00336  *          and 3 are narrow.  No information is carried in the spaces
00337  *          between the bars, which are all equal in width, represented by
00338  *          a "1" in our encoding.
00339  *      (3) The mapping from the sequence of five bar widths to the
00340  *          digit is identical to the mapping used by the interleaved
00341  *          2 of 5 code.  The start code is 21211, representing two
00342  *          wide bars and a narrow bar, and the interleaved "1" spaces
00343  *          are explicit.  The stop code is 21112.  For all codes
00344  *          (including start and stop), the trailing space "1" is
00345  *          implicit -- there is no reason to represent it in the
00346  *          Code2of5[] array.
00347  */
00348 static char *
00349 barcodeDecode2of5(char    *barstr,
00350                   l_int32  debugflag)
00351 {
00352 char    *data, *vbarstr;
00353 char     code[10];
00354 l_int32  valid, reverse, i, j, len, error, ndigits, start, found;
00355 
00356     PROCNAME("barcodeDecodeI2of5");
00357 
00358     if (!barstr)
00359         return (char *)ERROR_PTR("barstr not defined", procName, NULL);
00360 
00361         /* Verify format; reverse if necessary */
00362     barcodeVerifyFormat(barstr, L_BF_CODE2OF5, &valid, &reverse);
00363     if (!valid)
00364         return (char *)ERROR_PTR("barstr not in 2of5 format", procName, NULL);
00365     if (reverse)
00366         vbarstr = stringReverse(barstr);
00367     else
00368         vbarstr = stringNew(barstr);
00369 
00370         /* Verify size */
00371     len = strlen(vbarstr);
00372     if ((len - 11) % 10 != 0)
00373         return (char *)ERROR_PTR("size not divisible by 10: invalid 2of5 code",
00374                                  procName, NULL);
00375 
00376     error = FALSE;
00377     ndigits = (len - 11) / 10;
00378     data = (char *)CALLOC(ndigits + 1, sizeof(char));
00379     memset(code, 0, 10);
00380     for (i = 0; i < ndigits; i++) {
00381         start = 6 + 10 * i;
00382         for (j = 0; j < 9; j++)
00383             code[j] = vbarstr[start + j];
00384 
00385         if (debugflag)
00386             fprintf(stderr, "code: %s\n", code);
00387 
00388         found = FALSE;
00389         for (j = 0; j < 10; j++) {
00390             if (!strcmp(code, Code2of5[j])) {
00391                 data[i] = 0x30 + j;
00392                 found = TRUE;
00393                 break;
00394             }
00395         }
00396         if (!found) error = TRUE;
00397     }
00398     FREE(vbarstr);
00399 
00400     if (error) {
00401         FREE(data);
00402         return (char *)ERROR_PTR("error in decoding", procName, NULL);
00403     }
00404 
00405     return data;
00406 }
00407 
00408 
00409 /*------------------------------------------------------------------------*
00410  *                       Interleaved Code 2 of 5                          *
00411  *------------------------------------------------------------------------*/
00412 /*!
00413  *  barcodeDecodeI2of5()
00414  *
00415  *      Input:  barstr (of widths, in set {1, 2})
00416  *              debugflag
00417  *      Return: data (string of digits), or null if none found or on error
00418  *
00419  *  Notes:
00420  *      (1) Ref: http://en.wikipedia.org/wiki/Interleaved_2_of_5
00421  *      (2) This always encodes an even number of digits.
00422  *          The start code is 1111; the stop code is 211.
00423  */
00424 static char *
00425 barcodeDecodeI2of5(char    *barstr,
00426                    l_int32  debugflag)
00427 {
00428 char    *data, *vbarstr;
00429 char     code1[6], code2[6];
00430 l_int32  valid, reverse, i, j, len, error, npairs, start, found;
00431 
00432     PROCNAME("barcodeDecodeI2of5");
00433 
00434     if (!barstr)
00435         return (char *)ERROR_PTR("barstr not defined", procName, NULL);
00436 
00437         /* Verify format; reverse if necessary */
00438     barcodeVerifyFormat(barstr, L_BF_CODEI2OF5, &valid, &reverse);
00439     if (!valid)
00440         return (char *)ERROR_PTR("barstr not in i2of5 format", procName, NULL);
00441     if (reverse)
00442         vbarstr = stringReverse(barstr);
00443     else
00444         vbarstr = stringNew(barstr);
00445 
00446         /* Verify size */
00447     len = strlen(vbarstr);
00448     if ((len - 7) % 10 != 0)
00449         return (char *)ERROR_PTR("size not divisible by 10: invalid I2of5 code",
00450                                  procName, NULL);
00451 
00452     error = FALSE;
00453     npairs = (len - 7) / 10;
00454     data = (char *)CALLOC(2 * npairs + 1, sizeof(char));
00455     memset(code1, 0, 6);
00456     memset(code2, 0, 6);
00457     for (i = 0; i < npairs; i++) {
00458         start = 4 + 10 * i;
00459         for (j = 0; j < 5; j++) {
00460             code1[j] = vbarstr[start + 2 * j];
00461             code2[j] = vbarstr[start + 2 * j + 1];
00462         }
00463 
00464         if (debugflag)
00465             fprintf(stderr, "code1: %s, code2: %s\n", code1, code2);
00466 
00467         found = FALSE;
00468         for (j = 0; j < 10; j++) {
00469             if (!strcmp(code1, CodeI2of5[j])) {
00470                 data[2 * i] = 0x30 + j;
00471                 found = TRUE;
00472                 break;
00473             }
00474         }
00475         if (!found) error = TRUE;
00476         found = FALSE;
00477         for (j = 0; j < 10; j++) {
00478             if (!strcmp(code2, CodeI2of5[j])) {
00479                 data[2 * i + 1] = 0x30 + j;
00480                 found = TRUE;
00481                 break;
00482             }
00483         }
00484         if (!found) error = TRUE;
00485     }
00486     FREE(vbarstr);
00487 
00488     if (error) {
00489         FREE(data);
00490         return (char *)ERROR_PTR("error in decoding", procName, NULL);
00491     }
00492 
00493     return data;
00494 }
00495 
00496 
00497 /*------------------------------------------------------------------------*
00498  *                                 Code 93                                *
00499  *------------------------------------------------------------------------*/
00500 /*!
00501  *  barcodeDecode93()
00502  *
00503  *      Input:  barstr (of widths, in set {1, 2, 3, 4})
00504  *              debugflag
00505  *      Return: data (string of digits), or null if none found or on error
00506  *
00507  *  Notes:
00508  *      (1) Ref:  http://en.wikipedia.org/wiki/Code93
00509  *                http://morovia.com/education/symbology/code93.asp
00510  *      (2) Each symbol has 3 black and 3 white bars.
00511  *          The start and stop codes are 111141; the stop code then is
00512  *          terminated with a final (1) bar.
00513  *      (3) The last two codes are check codes.  We are checking them
00514  *          for correctness, and issuing a warning on failure.  Should
00515  *          probably not return any data on failure.
00516  */
00517 static char *
00518 barcodeDecode93(char    *barstr,
00519                 l_int32  debugflag)
00520 {
00521 const char  *checkc, *checkk;
00522 char        *data, *vbarstr;
00523 char         code[7];
00524 l_int32      valid, reverse, i, j, len, error, nsymb, start, found, sum;
00525 l_int32     *index;
00526 
00527     PROCNAME("barcodeDecode93");
00528 
00529     if (!barstr)
00530         return (char *)ERROR_PTR("barstr not defined", procName, NULL);
00531 
00532         /* Verify format; reverse if necessary */
00533     barcodeVerifyFormat(barstr, L_BF_CODE93, &valid, &reverse);
00534     if (!valid)
00535         return (char *)ERROR_PTR("barstr not in code93 format", procName, NULL);
00536     if (reverse)
00537         vbarstr = stringReverse(barstr);
00538     else
00539         vbarstr = stringNew(barstr);
00540 
00541         /* Verify size; skip the first 6 and last 7 bars. */
00542     len = strlen(vbarstr);
00543     if ((len - 13) % 6 != 0)
00544         return (char *)ERROR_PTR("size not divisible by 6: invalid code 93",
00545                                  procName, NULL);
00546 
00547         /* Decode the symbols */
00548     nsymb = (len - 13) / 6;
00549     data = (char *)CALLOC(nsymb + 1, sizeof(char));
00550     index = (l_int32 *)CALLOC(nsymb, sizeof(l_int32));
00551     memset(code, 0, 7);
00552     error = FALSE;
00553     for (i = 0; i < nsymb; i++) {
00554         start = 6 + 6 * i;
00555         for (j = 0; j < 6; j++)
00556             code[j] = vbarstr[start + j];
00557 
00558         if (debugflag)
00559             fprintf(stderr, "code: %s\n", code);
00560 
00561         found = FALSE;
00562         for (j = 0; j < C93_START; j++) {
00563             if (!strcmp(code, Code93[j])) {
00564                 data[i] = Code93Val[j];
00565                 index[i] = j;
00566                 found = TRUE;
00567                 break;
00568             }
00569         }
00570         if (!found) error = TRUE;
00571     }
00572     FREE(vbarstr);
00573 
00574     if (error) {
00575         FREE(index);
00576         FREE(data);
00577         return (char *)ERROR_PTR("error in decoding", procName, NULL);
00578     }
00579 
00580         /* Do check sums.  For character "C", use only the
00581          * actual data in computing the sum.  For character "K",
00582          * use the actual data plus the check character "C". */
00583     sum = 0;
00584     for (i = 0; i < nsymb - 2; i++)  /* skip the "C" and "K" */
00585         sum += ((i % 20) + 1) * index[nsymb - 3 - i];
00586     if (data[nsymb - 2] != Code93Val[sum % 47])
00587         L_WARNING("Error for check C", procName);
00588 
00589     if (debugflag) {
00590         checkc = Code93[sum % 47];
00591         fprintf(stderr, "checkc = %s\n", checkc);
00592     }
00593 
00594     sum = 0;
00595     for (i = 0; i < nsymb - 1; i++)  /* skip the "K" */
00596         sum += ((i % 15) + 1) * index[nsymb - 2 - i];
00597     if (data[nsymb - 1] != Code93Val[sum % 47])
00598         L_WARNING("Error for check K", procName);
00599 
00600     if (debugflag) {
00601         checkk = Code93[sum % 47];
00602         fprintf(stderr, "checkk = %s\n", checkk);
00603     }
00604 
00605         /* Remove the two check codes from the output */
00606     data[nsymb - 2] = '\0';
00607 
00608     FREE(index);
00609     return data;
00610 }
00611 
00612 
00613 /*------------------------------------------------------------------------*
00614  *                                 Code 39                                *
00615  *------------------------------------------------------------------------*/
00616 /*!
00617  *  barcodeDecode39()
00618  *
00619  *      Input:  barstr (of widths, in set {1, 2})
00620  *              debugflag
00621  *      Return: data (string of digits), or null if none found or on error
00622  *
00623  *  Notes:
00624  *      (1) Ref:  http://en.wikipedia.org/wiki/Code39
00625  *                http://morovia.com/education/symbology/code39.asp
00626  *      (2) Each symbol has 5 black and 4 white bars.
00627  *          The start and stop codes are 121121211 (the asterisk)
00628  *      (3) This decoder was contributed by Roger Hyde.
00629  */
00630 static char *
00631 barcodeDecode39(char    *barstr,
00632                 l_int32  debugflag)
00633 {
00634 char     *data, *vbarstr;
00635 char      code[10];
00636 l_int32   valid, reverse, i, j, len, error, nsymb, start, found;
00637 
00638     PROCNAME("barcodeDecode39");
00639 
00640     if (!barstr)
00641         return (char *)ERROR_PTR("barstr not defined", procName, NULL);
00642 
00643         /* Verify format; reverse if necessary */
00644     barcodeVerifyFormat(barstr, L_BF_CODE39, &valid, &reverse);
00645     if (!valid)
00646         return (char *)ERROR_PTR("barstr not in code39 format", procName, NULL);
00647     if (reverse)
00648         vbarstr = stringReverse(barstr);
00649     else
00650         vbarstr = stringNew(barstr);
00651 
00652         /* Verify size */
00653     len = strlen(vbarstr);
00654     if ((len + 1) % 10 != 0)
00655         return (char *)ERROR_PTR("size+1 not divisible by 10: invalid code 39",
00656                                  procName, NULL);
00657 
00658         /* Decode the symbols */
00659     nsymb = (len - 19) / 10;
00660     data = (char *)CALLOC(nsymb + 1, sizeof(char));
00661     memset(code, 0, 10);
00662     error = FALSE;
00663     for (i = 0; i < nsymb; i++) {
00664         start = 10 + 10 * i;
00665         for (j = 0; j < 9; j++)
00666             code[j] = vbarstr[start + j];
00667 
00668         if (debugflag)
00669             fprintf(stderr, "code: %s\n", code);
00670 
00671         found = FALSE;
00672         for (j = 0; j < C39_START; j++) {
00673             if (!strcmp(code, Code39[j])) {
00674                 data[i] = Code39Val[j];
00675                 found = TRUE;
00676                 break;
00677             }
00678         }
00679         if (!found) error = TRUE;
00680     }
00681     FREE(vbarstr);
00682 
00683     if (error) {
00684         FREE(data);
00685         return (char *)ERROR_PTR("error in decoding", procName, NULL);
00686     }
00687 
00688     return data;
00689 }
00690 
00691 
00692 /*------------------------------------------------------------------------*
00693  *                                 Codabar                                *
00694  *------------------------------------------------------------------------*/
00695 /*!
00696  *  barcodeDecodeCodabar()
00697  *
00698  *      Input:  barstr (of widths, in set {1, 2})
00699  *              debugflag
00700  *      Return: data (string of digits), or null if none found or on error
00701  *
00702  *  Notes:
00703  *      (1) Ref:  http://en.wikipedia.org/wiki/Codabar
00704  *                http://morovia.com/education/symbology/codabar.asp
00705  *      (2) Each symbol has 4 black and 3 white bars.  They represent the
00706  *          10 digits, and optionally 6 other characters.  The start and
00707  *          stop codes can be any of four (typically denoted A,B,C,D).
00708  */
00709 static char *
00710 barcodeDecodeCodabar(char    *barstr,
00711                      l_int32  debugflag)
00712 {
00713 char     *data, *vbarstr;
00714 char      code[8];
00715 l_int32   valid, reverse, i, j, len, error, nsymb, start, found;
00716 
00717     PROCNAME("barcodeDecodeCodabar");
00718 
00719     if (!barstr)
00720         return (char *)ERROR_PTR("barstr not defined", procName, NULL);
00721 
00722         /* Verify format; reverse if necessary */
00723     barcodeVerifyFormat(barstr, L_BF_CODABAR, &valid, &reverse);
00724     if (!valid)
00725         return (char *)ERROR_PTR("barstr not in codabar format",
00726                                  procName, NULL);
00727     if (reverse)
00728         vbarstr = stringReverse(barstr);
00729     else
00730         vbarstr = stringNew(barstr);
00731 
00732         /* Verify size */
00733     len = strlen(vbarstr);
00734     if ((len + 1) % 8 != 0)
00735         return (char *)ERROR_PTR("size+1 not divisible by 8: invalid codabar",
00736                                  procName, NULL);
00737 
00738         /* Decode the symbols */
00739     nsymb = (len - 15) / 8;
00740     data = (char *)CALLOC(nsymb + 1, sizeof(char));
00741     memset(code, 0, 8);
00742     error = FALSE;
00743     for (i = 0; i < nsymb; i++) {
00744         start = 8 + 8 * i;
00745         for (j = 0; j < 7; j++)
00746             code[j] = vbarstr[start + j];
00747 
00748         if (debugflag)
00749             fprintf(stderr, "code: %s\n", code);
00750 
00751         found = FALSE;
00752         for (j = 0; j < 16; j++) {
00753             if (!strcmp(code, Codabar[j])) {
00754                 data[i] = CodabarVal[j];
00755                 found = TRUE;
00756                 break;
00757             }
00758         }
00759         if (!found) error = TRUE;
00760     }
00761     FREE(vbarstr);
00762 
00763     if (error) {
00764         FREE(data);
00765         return (char *)ERROR_PTR("error in decoding", procName, NULL);
00766     }
00767 
00768     return data;
00769 }
00770 
00771 
00772 /*------------------------------------------------------------------------*
00773  *                               Code UPC-A                               *
00774  *------------------------------------------------------------------------*/
00775 /*!
00776  *  barcodeDecodeUpca()
00777  *
00778  *      Input:  barstr (of widths, in set {1, 2, 3, 4})
00779  *              debugflag
00780  *      Return: data (string of digits), or null if none found or on error
00781  *
00782  *  Notes:
00783  *      (1) Ref:  http://en.wikipedia.org/wiki/UniversalProductCode
00784  *                http://morovia.com/education/symbology/upc-a.asp
00785  *      (2) Each symbol has 2 black and 2 white bars, and encodes a digit.
00786  *          The start and stop codes are 111 and 111.  There are a total of
00787  *          30 black bars, encoding 12 digits in two sets of 6, with
00788  *          2 black bars separating the sets.
00789  *      (3) The last digit is a check digit.  We check for correctness, and
00790  *          issue a warning on failure.  Should probably not return any
00791  *          data on failure.
00792  */
00793 static char *
00794 barcodeDecodeUpca(char    *barstr,
00795                   l_int32  debugflag)
00796 {
00797 char     *data, *vbarstr;
00798 char      code[5];
00799 l_int32   valid, i, j, len, error, start, found, sum, checkdigit;
00800 
00801     PROCNAME("barcodeDecodeUpca");
00802 
00803     if (!barstr)
00804         return (char *)ERROR_PTR("barstr not defined", procName, NULL);
00805 
00806         /* Verify format; reverse has no meaning here -- we must test both */
00807     barcodeVerifyFormat(barstr, L_BF_UPCA, &valid, NULL);
00808     if (!valid)
00809         return (char *)ERROR_PTR("barstr not in UPC-A format", procName, NULL);
00810 
00811         /* Verify size */
00812     len = strlen(barstr);
00813     if (len != 59)
00814         return (char *)ERROR_PTR("size not 59; invalid UPC-A barcode",
00815                                  procName, NULL);
00816 
00817         /* Check the first digit.  If invalid, reverse the string. */
00818     memset(code, 0, 5);
00819     for (i = 0; i < 4; i++)
00820         code[i] = barstr[i + 3];
00821     found = FALSE;
00822     for (i = 0; i < 10; i++) {
00823         if (!strcmp(code, Upca[i])) {
00824             found = TRUE;
00825             break;
00826         }
00827     }
00828     if (found == FALSE)
00829         vbarstr = stringReverse(barstr);
00830     else
00831         vbarstr = stringNew(barstr);
00832 
00833         /* Decode the 12 symbols */
00834     data = (char *)CALLOC(13, sizeof(char));
00835     memset(code, 0, 5);
00836     error = FALSE;
00837     for (i = 0; i < 12; i++) {
00838         if (i < 6)
00839             start = 3 + 4 * i;
00840         else
00841             start = 32 + 4 * (i - 6);
00842         for (j = 0; j < 4; j++)
00843             code[j] = vbarstr[start + j];
00844 
00845         if (debugflag)
00846             fprintf(stderr, "code: %s\n", code);
00847 
00848         found = FALSE;
00849         for (j = 0; j < 10; j++) {
00850             if (!strcmp(code, Upca[j])) {
00851                 data[i] = 0x30 + j;
00852                 found = TRUE;
00853                 break;
00854             }
00855         }
00856         if (!found) error = TRUE;
00857     }
00858     FREE(vbarstr);
00859 
00860     if (error) {
00861         FREE(data);
00862         return (char *)ERROR_PTR("error in decoding", procName, NULL);
00863     }
00864 
00865         /* Calculate the check digit (data[11]). */
00866     sum = 0;
00867     for (i = 0; i < 12; i += 2)  /* "even" digits */
00868         sum += 3 * (data[i] - 0x30);
00869     for (i = 1; i < 11; i += 2)  /* "odd" digits */
00870         sum += (data[i] - 0x30);
00871     checkdigit = sum % 10;
00872     if (checkdigit)  /* not 0 */
00873         checkdigit = 10 - checkdigit;
00874     if (checkdigit + 0x30 != data[11])
00875         L_WARNING("Error for UPC-A check character", procName);
00876 
00877     return data;
00878 }
00879 
00880 
00881 /*------------------------------------------------------------------------*
00882  *                               Code EAN-13                              *
00883  *------------------------------------------------------------------------*/
00884 /*!
00885  *  barcodeDecodeEan13()
00886  *
00887  *      Input:  barstr (of widths, in set {1, 2, 3, 4})
00888  *              first (first digit: 0 - 9)
00889  *              debugflag
00890  *      Return: data (string of digits), or null if none found or on error
00891  *
00892  *  Notes:
00893  *      (1) Ref:  http://en.wikipedia.org/wiki/UniversalProductCode
00894  *                http://morovia.com/education/symbology/ean-13.asp
00895  *      (2) The encoding is essentially the same as UPC-A, except
00896  *          there are 13 digits in total, of which 12 are encoded
00897  *          by bars (as with UPC-A) and the 13th is a leading digit
00898  *          that determines the encoding of the next 6 digits,
00899  *          selecting each digit from one of two tables.
00900  *          encoded in the bars (as with UPC-A).  If the first digit
00901  *          is 0, the encoding is identical to UPC-A.
00902  *      (3) As with UPC-A, the last digit is a check digit.
00903  *      (4) For now, we assume the first digit is input to this function.
00904  *          Eventually, we will read it by pattern matching.
00905  *
00906  *    TODO: fix this for multiple tables, depending on the value of @first
00907  */
00908 static char *
00909 barcodeDecodeEan13(char    *barstr,
00910                    l_int32  first,
00911                    l_int32  debugflag)
00912 {
00913 char     *data, *vbarstr;
00914 char      code[5];
00915 l_int32   valid, i, j, len, error, start, found, sum, checkdigit;
00916 
00917     PROCNAME("barcodeDecodeEan13");
00918 
00919     if (!barstr)
00920         return (char *)ERROR_PTR("barstr not defined", procName, NULL);
00921 
00922         /* Verify format.  You can't tell the orientation by the start
00923          * and stop codes, but you can by the location of the digits.
00924          * Use the UPCA verifier for EAN 13 -- it is identical. */
00925     barcodeVerifyFormat(barstr, L_BF_UPCA, &valid, NULL);
00926     if (!valid)
00927         return (char *)ERROR_PTR("barstr not in EAN 13 format", procName, NULL);
00928 
00929         /* Verify size */
00930     len = strlen(barstr);
00931     if (len != 59)
00932         return (char *)ERROR_PTR("size not 59; invalid EAN 13 barcode",
00933                                  procName, NULL);
00934 
00935         /* Check the first digit.  If invalid, reverse the string. */
00936     memset(code, 0, 5);
00937     for (i = 0; i < 4; i++)
00938         code[i] = barstr[i + 3];
00939     found = FALSE;
00940     for (i = 0; i < 10; i++) {
00941         if (!strcmp(code, Upca[i])) {
00942             found = TRUE;
00943             break;
00944         }
00945     }
00946     if (found == FALSE)
00947         vbarstr = stringReverse(barstr);
00948     else
00949         vbarstr = stringNew(barstr);
00950 
00951         /* Decode the 12 symbols */
00952     data = (char *)CALLOC(13, sizeof(char));
00953     memset(code, 0, 5);
00954     error = FALSE;
00955     for (i = 0; i < 12; i++) {
00956         if (i < 6)
00957             start = 3 + 4 * i;
00958         else
00959             start = 32 + 4 * (i - 6);
00960         for (j = 0; j < 4; j++)
00961             code[j] = vbarstr[start + j];
00962 
00963         if (debugflag)
00964             fprintf(stderr, "code: %s\n", code);
00965 
00966         found = FALSE;
00967         for (j = 0; j < 10; j++) {
00968             if (!strcmp(code, Upca[j])) {
00969                 data[i] = 0x30 + j;
00970                 found = TRUE;
00971                 break;
00972             }
00973         }
00974         if (!found) error = TRUE;
00975     }
00976     FREE(vbarstr);
00977 
00978     if (error) {
00979         FREE(data);
00980         return (char *)ERROR_PTR("error in decoding", procName, NULL);
00981     }
00982 
00983         /* Calculate the check digit (data[11]). */
00984     sum = 0;
00985     for (i = 0; i < 12; i += 2)  /* "even" digits */
00986         sum += 3 * (data[i] - 0x30);
00987     for (i = 1; i < 12; i += 2)  /* "odd" digits */
00988         sum += (data[i] - 0x30);
00989     checkdigit = sum % 10;
00990     if (checkdigit)  /* not 0 */
00991         checkdigit = 10 - checkdigit;
00992     if (checkdigit + 0x30 != data[11])
00993         L_WARNING("Error for EAN-13 check character", procName);
00994 
00995     return data;
00996 }
00997 
00998 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines