2 * Licensed under the Apache License, Version 2.0 (the "License");
\r
3 * you may not use this file except in compliance with the License.
\r
4 * You may obtain a copy of the License at
\r
6 * http://www.apache.org/licenses/LICENSE-2.0
\r
8 * Unless required by applicable law or agreed to in writing, software
\r
9 * distributed under the License is distributed on an "AS IS" BASIS,
\r
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
11 * See the License for the specific language governing permissions and
\r
12 * limitations under the License.
\r
14 namespace com.google.zxing.oned
\r
17 * <p>Implements decoding of the EAN-13 format.</p>
\r
19 * @author dswitkin@google.com (Daniel Switkin)
\r
21 * @author alasdair@google.com (Alasdair Mackintosh)
\r
25 using com.google.zxing.common;
\r
27 public sealed class EAN13Reader : AbstractUPCEANReader
\r
29 // For an EAN-13 barcode, the first digit is represented by the parities used
\r
30 // to encode the next six digits, according to the table below. For example,
\r
31 // if the barcode is 5 123456 789012 then the value of the first digit is
\r
32 // signified by using odd for '1', even for '2', even for '3', odd for '4',
\r
33 // odd for '5', and even for '6'. See http://en.wikipedia.org/wiki/EAN-13
\r
35 // Parity of next 6 digits
\r
36 // Digit 0 1 2 3 4 5
\r
37 // 0 Odd Odd Odd Odd Odd Odd
\r
38 // 1 Odd Odd Even Odd Even Even
\r
39 // 2 Odd Odd Even Even Odd Even
\r
40 // 3 Odd Odd Even Even Even Odd
\r
41 // 4 Odd Even Odd Odd Even Even
\r
42 // 5 Odd Even Even Odd Odd Even
\r
43 // 6 Odd Even Even Even Odd Odd
\r
44 // 7 Odd Even Odd Even Odd Even
\r
45 // 8 Odd Even Odd Even Even Odd
\r
46 // 9 Odd Even Even Odd Even Odd
\r
48 // Note that the encoding for '0' uses the same parity as a UPC barcode. Hence
\r
49 // a UPC barcode can be converted to an EAN-13 barcode by prepending a 0.
\r
51 // The encodong is represented by the following array, which is a bit pattern
\r
52 // using Odd = 0 and Even = 1. For example, 5 is represented by:
\r
54 // Odd Even Even Odd Odd Even
\r
56 // 0 1 1 0 0 1 == 0x19
\r
58 private static int[] FIRST_DIGIT_ENCODINGS = {
\r
59 0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A
\r
62 private int[] decodeMiddleCounters;
\r
64 public EAN13Reader() {
\r
65 decodeMiddleCounters = new int[4];
\r
68 protected override int decodeMiddle(BitArray row, int[] startRange, StringBuilder resultString) {
\r
69 int[] counters = decodeMiddleCounters;
\r
74 int end = row.getSize();
\r
75 int rowOffset = startRange[1];
\r
77 int lgPatternFound = 0;
\r
79 for (int x = 0; x < 6 && rowOffset < end; x++) {
\r
80 int bestMatch = decodeDigit(row, counters, rowOffset, L_AND_G_PATTERNS);
\r
81 resultString.Append((char) ('0' + bestMatch % 10));
\r
82 for (int i = 0; i < counters.Length; i++) {
\r
83 rowOffset += counters[i];
\r
85 if (bestMatch >= 10) {
\r
86 lgPatternFound |= 1 << (5 - x);
\r
90 determineFirstDigit(resultString, lgPatternFound);
\r
92 int[] middleRange = findGuardPattern(row, rowOffset, true, MIDDLE_PATTERN);
\r
93 rowOffset = middleRange[1];
\r
95 for (int x = 0; x < 6 && rowOffset < end; x++) {
\r
96 int bestMatch = decodeDigit(row, counters, rowOffset, L_PATTERNS);
\r
97 resultString.Append((char) ('0' + bestMatch));
\r
98 for (int i = 0; i < counters.Length; i++) {
\r
99 rowOffset += counters[i];
\r
106 public override BarcodeFormat getBarcodeFormat() {
\r
107 return BarcodeFormat.EAN_13;
\r
111 * Based on pattern of odd-even ('L' and 'G') patterns used to encoded the explicitly-encoded digits
\r
112 * in a barcode, determines the implicitly encoded first digit and adds it to the result string.
\r
114 * @param resultString string to insert decoded first digit into
\r
115 * @param lgPatternFound int whose bits indicates the pattern of odd/even L/G patterns used to
\r
117 * @throws ReaderException if first digit cannot be determined
\r
119 private static void determineFirstDigit(StringBuilder resultString, int lgPatternFound) {
\r
120 for (int d = 0; d < 10; d++) {
\r
121 if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d]) {
\r
122 resultString.Insert(0, (char) ('0' + d));
\r
126 throw new ReaderException();
\r