From 9cf93792d429ab397e5d52a9482b9f3308dd1de7 Mon Sep 17 00:00:00 2001 From: mmagician Date: Sun, 18 Oct 2015 23:39:03 +0100 Subject: [PATCH] Added a Code 93 encoder --- AUTHORS | 1 + .../com/google/zxing/MultiFormatWriter.java | 4 + .../com/google/zxing/oned/Code93Reader.java | 4 +- .../com/google/zxing/oned/Code93Writer.java | 115 ++++++++++++++++++ 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/com/google/zxing/oned/Code93Writer.java diff --git a/AUTHORS b/AUTHORS index acc1ad8f1..d6aeafeef 100644 --- a/AUTHORS +++ b/AUTHORS @@ -77,6 +77,7 @@ Luka Finžgar Malte Starostik Manuel Kasten Marcelo +Marcin Górny Markus Helm Mateusz Jędrasik Matthew Schulkind (Google) diff --git a/core/src/main/java/com/google/zxing/MultiFormatWriter.java b/core/src/main/java/com/google/zxing/MultiFormatWriter.java index 57a40dbf3..19c29a415 100644 --- a/core/src/main/java/com/google/zxing/MultiFormatWriter.java +++ b/core/src/main/java/com/google/zxing/MultiFormatWriter.java @@ -22,6 +22,7 @@ import com.google.zxing.datamatrix.DataMatrixWriter; import com.google.zxing.oned.CodaBarWriter; import com.google.zxing.oned.Code128Writer; import com.google.zxing.oned.Code39Writer; +import com.google.zxing.oned.Code93Writer; import com.google.zxing.oned.EAN13Writer; import com.google.zxing.oned.EAN8Writer; import com.google.zxing.oned.ITFWriter; @@ -74,6 +75,9 @@ public final class MultiFormatWriter implements Writer { case CODE_39: writer = new Code39Writer(); break; + case CODE_93: + writer = new Code93Writer(); + break; case CODE_128: writer = new Code128Writer(); break; diff --git a/core/src/main/java/com/google/zxing/oned/Code93Reader.java b/core/src/main/java/com/google/zxing/oned/Code93Reader.java index 0db67ea70..66c2953b3 100644 --- a/core/src/main/java/com/google/zxing/oned/Code93Reader.java +++ b/core/src/main/java/com/google/zxing/oned/Code93Reader.java @@ -37,14 +37,14 @@ import java.util.Map; public final class Code93Reader extends OneDReader { // Note that 'abcd' are dummy characters in place of control characters. - private static final String ALPHABET_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*"; + static final String ALPHABET_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*"; private static final char[] ALPHABET = ALPHABET_STRING.toCharArray(); /** * These represent the encodings of characters, as patterns of wide and narrow bars. * The 9 least-significant bits of each int correspond to the pattern of wide and narrow. */ - private static final int[] CHARACTER_ENCODINGS = { + static final int[] CHARACTER_ENCODINGS = { 0x114, 0x148, 0x144, 0x142, 0x128, 0x124, 0x122, 0x150, 0x112, 0x10A, // 0-9 0x1A8, 0x1A4, 0x1A2, 0x194, 0x192, 0x18A, 0x168, 0x164, 0x162, 0x134, // A-J 0x11A, 0x158, 0x14C, 0x146, 0x12C, 0x116, 0x1B4, 0x1B2, 0x1AC, 0x1A6, // K-T diff --git a/core/src/main/java/com/google/zxing/oned/Code93Writer.java b/core/src/main/java/com/google/zxing/oned/Code93Writer.java new file mode 100644 index 000000000..53db6ec2f --- /dev/null +++ b/core/src/main/java/com/google/zxing/oned/Code93Writer.java @@ -0,0 +1,115 @@ +/* + * Copyright 2015 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.zxing.oned; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; + +import java.util.Map; + +/** + * This object renders a CODE93 code as a BitMatrix + */ +public class Code93Writer extends OneDimensionalCodeWriter { + @Override + public BitMatrix encode(String contents, + BarcodeFormat format, + int width, + int height, + Map hints) throws WriterException { + if (format != BarcodeFormat.CODE_93) { + throw new IllegalArgumentException("Can only encode CODE_93, but got " + format); + } + return super.encode(contents, format, width, height, hints); + } + + @Override + public boolean[] encode(String contents) { + int length = contents.length(); + if (length > 80) { + throw new IllegalArgumentException( + "Requested contents should be less than 80 digits long, but got " + length); + } + //each character is encoded by 9 of 0/1's + int[] widths = new int[9]; + + //lenght of code + 2 start/stop characters + 2 checksums, each of 9 bits, plus a termination bar + int codeWidth = (contents.length() + 2 + 2) * 9 + 1; + + boolean[] result = new boolean[codeWidth]; + + //start character (*) + toIntArray(Code93Reader.CHARACTER_ENCODINGS[47], widths); + int pos = appendPattern(result, 0, widths, true); + + for (int i = 0; i < length; i++) { + int indexInString = Code93Reader.ALPHABET_STRING.indexOf(contents.charAt(i)); + toIntArray(Code93Reader.CHARACTER_ENCODINGS[indexInString], widths); + pos += appendPattern(result, pos, widths, true); + } + + //add two checksums + int check1 = computeChecksumIndex(contents, 20); + toIntArray(Code93Reader.CHARACTER_ENCODINGS[check1], widths); + pos += appendPattern(result, pos, widths, true); + + //append the contents to reflect the first checksum added + contents += Code93Reader.ALPHABET_STRING.charAt(check1); + + int check2 = computeChecksumIndex(contents, 15); + toIntArray(Code93Reader.CHARACTER_ENCODINGS[check2], widths); + pos += appendPattern(result, pos, widths, true); + + //end character (*) + toIntArray(Code93Reader.CHARACTER_ENCODINGS[47], widths); + pos += appendPattern(result, pos, widths, true); + + //termination bar (single black bar) + result[pos] = true; + + return result; + } + + private static void toIntArray(int a, int[] toReturn) { + for (int i = 0; i < 9; i++) { + int temp = a & (1 << (8 - i)); + toReturn[i] = temp == 0 ? 0 : 1; + } + } + + protected static int appendPattern(boolean[] target, int pos, int[] pattern, boolean startColor) { + for (int bit : pattern) { + target[pos++] = bit != 0; + } + return 9; + } + + private static int computeChecksumIndex(String contents, int maxWeight) { + int weight = 1; + int total = 0; + + for (int i = contents.length() - 1; i >= 0; i--) { + int indexInString = Code93Reader.ALPHABET_STRING.indexOf(contents.charAt(i)); + total += indexInString * weight; + if (++weight > maxWeight) { + weight = 1; + } + } + return total % 47; + } +}