--- /dev/null
+/*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+namespace com.google.zxing.oned\r
+{\r
+ /**\r
+ * <p>Implements decoding of the EAN-13 format.</p>\r
+ *\r
+ * @author dswitkin@google.com (Daniel Switkin)\r
+ * @author Sean Owen\r
+ * @author alasdair@google.com (Alasdair Mackintosh)\r
+ */\r
+\r
+ using System.Text;\r
+ using com.google.zxing.common;\r
+\r
+ public sealed class EAN13Reader : AbstractUPCEANReader \r
+ {\r
+ // For an EAN-13 barcode, the first digit is represented by the parities used\r
+ // to encode the next six digits, according to the table below. For example,\r
+ // if the barcode is 5 123456 789012 then the value of the first digit is\r
+ // signified by using odd for '1', even for '2', even for '3', odd for '4',\r
+ // odd for '5', and even for '6'. See http://en.wikipedia.org/wiki/EAN-13\r
+ //\r
+ // Parity of next 6 digits\r
+ // Digit 0 1 2 3 4 5\r
+ // 0 Odd Odd Odd Odd Odd Odd\r
+ // 1 Odd Odd Even Odd Even Even\r
+ // 2 Odd Odd Even Even Odd Even\r
+ // 3 Odd Odd Even Even Even Odd\r
+ // 4 Odd Even Odd Odd Even Even\r
+ // 5 Odd Even Even Odd Odd Even\r
+ // 6 Odd Even Even Even Odd Odd\r
+ // 7 Odd Even Odd Even Odd Even\r
+ // 8 Odd Even Odd Even Even Odd\r
+ // 9 Odd Even Even Odd Even Odd\r
+ //\r
+ // Note that the encoding for '0' uses the same parity as a UPC barcode. Hence\r
+ // a UPC barcode can be converted to an EAN-13 barcode by prepending a 0.\r
+ //\r
+ // The encodong is represented by the following array, which is a bit pattern\r
+ // using Odd = 0 and Even = 1. For example, 5 is represented by:\r
+ //\r
+ // Odd Even Even Odd Odd Even\r
+ // in binary:\r
+ // 0 1 1 0 0 1 == 0x19\r
+ //\r
+ private static int[] FIRST_DIGIT_ENCODINGS = {\r
+ 0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A\r
+ };\r
+\r
+ private int[] decodeMiddleCounters;\r
+\r
+ public EAN13Reader() {\r
+ decodeMiddleCounters = new int[4];\r
+ }\r
+\r
+ protected override int decodeMiddle(BitArray row, int[] startRange, StringBuilder resultString) {\r
+ int[] counters = decodeMiddleCounters;\r
+ counters[0] = 0;\r
+ counters[1] = 0;\r
+ counters[2] = 0;\r
+ counters[3] = 0;\r
+ int end = row.getSize();\r
+ int rowOffset = startRange[1];\r
+\r
+ int lgPatternFound = 0;\r
+\r
+ for (int x = 0; x < 6 && rowOffset < end; x++) {\r
+ int bestMatch = decodeDigit(row, counters, rowOffset, L_AND_G_PATTERNS);\r
+ resultString.Append((char) ('0' + bestMatch % 10));\r
+ for (int i = 0; i < counters.Length; i++) {\r
+ rowOffset += counters[i];\r
+ }\r
+ if (bestMatch >= 10) {\r
+ lgPatternFound |= 1 << (5 - x);\r
+ }\r
+ }\r
+\r
+ determineFirstDigit(resultString, lgPatternFound);\r
+\r
+ int[] middleRange = findGuardPattern(row, rowOffset, true, MIDDLE_PATTERN);\r
+ rowOffset = middleRange[1];\r
+\r
+ for (int x = 0; x < 6 && rowOffset < end; x++) {\r
+ int bestMatch = decodeDigit(row, counters, rowOffset, L_PATTERNS);\r
+ resultString.Append((char) ('0' + bestMatch));\r
+ for (int i = 0; i < counters.Length; i++) {\r
+ rowOffset += counters[i];\r
+ }\r
+ }\r
+\r
+ return rowOffset;\r
+ }\r
+\r
+ public override BarcodeFormat getBarcodeFormat() {\r
+ return BarcodeFormat.EAN_13;\r
+ }\r
+\r
+ /**\r
+ * Based on pattern of odd-even ('L' and 'G') patterns used to encoded the explicitly-encoded digits\r
+ * in a barcode, determines the implicitly encoded first digit and adds it to the result string.\r
+ *\r
+ * @param resultString string to insert decoded first digit into\r
+ * @param lgPatternFound int whose bits indicates the pattern of odd/even L/G patterns used to\r
+ * encode digits\r
+ * @throws ReaderException if first digit cannot be determined\r
+ */\r
+ private static void determineFirstDigit(StringBuilder resultString, int lgPatternFound) {\r
+ for (int d = 0; d < 10; d++) {\r
+ if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d]) {\r
+ resultString.Insert(0, (char) ('0' + d));\r
+ return;\r
+ }\r
+ }\r
+ throw new ReaderException();\r
+ }\r
+\r
+ \r
+ \r
+ }\r
+}
\ No newline at end of file