Display possible country origin info on product scan

git-svn-id: https://zxing.googlecode.com/svn/trunk@1438 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2010-06-16 21:13:47 +00:00
parent 627cd6cab0
commit 2d7b4138ab
6 changed files with 228 additions and 16 deletions

View file

@ -68,7 +68,6 @@ import java.io.IOException;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Date;
import java.util.Map;
@ -132,10 +131,11 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
private static final Set<ResultMetadataType> DISPLAYABLE_METADATA_TYPES;
static {
DISPLAYABLE_METADATA_TYPES = new HashSet<ResultMetadataType>(3);
DISPLAYABLE_METADATA_TYPES = new HashSet<ResultMetadataType>(5);
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.ISSUE_NUMBER);
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.SUGGESTED_PRICE);
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.ERROR_CORRECTION_LEVEL);
DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.POSSIBLE_COUNTRY);
}
private enum Source {

View file

@ -74,6 +74,12 @@ public final class ResultMetadataType {
*/
public static final ResultMetadataType SUGGESTED_PRICE = new ResultMetadataType("SUGGESTED_PRICE");
/**
* For some products, the possible country of manufacture as a {@link String} denoting the
* ISO country code. Some map to multiple possible countries, like "US/CA".
*/
public static final ResultMetadataType POSSIBLE_COUNTRY = new ResultMetadataType("POSSIBLE_COUNTRY");
private final String name;
private ResultMetadataType(String name) {

View file

@ -0,0 +1,170 @@
/*
* Copyright (C) 2010 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 java.util.Vector;
/**
* Records EAN prefix to GS1 Member Organization, where the member organization
* correlates strongly with a country. This is an imperfect means of identifying
* a country of origin by EAN-13 barcode value. See
* <a href="http://en.wikipedia.org/wiki/List_of_GS1_country_codes">
* http://en.wikipedia.org/wiki/List_of_GS1_country_codes</a>.
*
* @author Sean Owen
*/
final class EANManufacturerOrgSupport {
private final Vector ranges = new Vector();
private final Vector countryIdentifiers = new Vector();
String lookupCountryIdentifier(String productCode) {
initIfNeeded();
int prefix = Integer.parseInt(productCode.substring(0, 3));
int max = ranges.size();
for (int i = 0; i < max; i++) {
int[] range = (int[]) ranges.elementAt(i);
int start = range[0];
if (prefix < start) {
return null;
}
int end = range.length == 1 ? start : range[1];
if (prefix <= end) {
return (String) countryIdentifiers.elementAt(i);
}
}
return null;
}
private void add(int[] range, String id) {
ranges.addElement(range);
countryIdentifiers.addElement(id);
}
private synchronized void initIfNeeded() {
if (!ranges.isEmpty()) {
return;
}
add(new int[] {0,19}, "US/CA");
add(new int[] {30,39}, "US");
add(new int[] {60,139}, "US/CA");
add(new int[] {300,379}, "FR");
add(new int[] {380}, "BG");
add(new int[] {383}, "SI");
add(new int[] {385}, "HR");
add(new int[] {387}, "BA");
add(new int[] {400,440}, "DE");
add(new int[] {450,459}, "JP");
add(new int[] {460,469}, "RU");
add(new int[] {471}, "TW");
add(new int[] {474}, "EE");
add(new int[] {475}, "LV");
add(new int[] {476}, "AZ");
add(new int[] {477}, "LT");
add(new int[] {478}, "UZ");
add(new int[] {479}, "LK");
add(new int[] {480}, "PH");
add(new int[] {481}, "BY");
add(new int[] {482}, "UA");
add(new int[] {484}, "MD");
add(new int[] {485}, "AM");
add(new int[] {486}, "GE");
add(new int[] {487}, "KZ");
add(new int[] {489}, "HK");
add(new int[] {490,499}, "JP");
add(new int[] {500,509}, "GB");
add(new int[] {520}, "GR");
add(new int[] {528}, "LB");
add(new int[] {529}, "CY");
add(new int[] {531}, "MK");
add(new int[] {535}, "MT");
add(new int[] {539}, "IE");
add(new int[] {540,549}, "BE/LU");
add(new int[] {560}, "PT");
add(new int[] {569}, "IS");
add(new int[] {570,579}, "DK");
add(new int[] {590}, "PL");
add(new int[] {594}, "RO");
add(new int[] {599}, "HU");
add(new int[] {600,601}, "ZA");
add(new int[] {603}, "GH");
add(new int[] {608}, "BH");
add(new int[] {609}, "MU");
add(new int[] {611}, "MA");
add(new int[] {613}, "DZ");
add(new int[] {616}, "KE");
add(new int[] {618}, "CI");
add(new int[] {619}, "TN");
add(new int[] {621}, "SY");
add(new int[] {622}, "EG");
add(new int[] {624}, "LY");
add(new int[] {625}, "JO");
add(new int[] {626}, "IR");
add(new int[] {627}, "KW");
add(new int[] {628}, "SA");
add(new int[] {629}, "AE");
add(new int[] {640,649}, "FI");
add(new int[] {690,695}, "CN");
add(new int[] {700,709}, "NO");
add(new int[] {729}, "IL");
add(new int[] {730,739}, "SE");
add(new int[] {740}, "GT");
add(new int[] {741}, "SV");
add(new int[] {742}, "HN");
add(new int[] {743}, "NI");
add(new int[] {744}, "CR");
add(new int[] {745}, "PA");
add(new int[] {746}, "DO");
add(new int[] {750}, "MX");
add(new int[] {754,755}, "CA");
add(new int[] {759}, "VE");
add(new int[] {760,769}, "CH");
add(new int[] {770}, "CO");
add(new int[] {773}, "UY");
add(new int[] {775}, "PE");
add(new int[] {777}, "BO");
add(new int[] {779}, "AR");
add(new int[] {780}, "CL");
add(new int[] {784}, "PY");
add(new int[] {785}, "PE");
add(new int[] {786}, "EC");
add(new int[] {789,790}, "BR");
add(new int[] {800,839}, "IT");
add(new int[] {840,849}, "ES");
add(new int[] {850}, "CU");
add(new int[] {858}, "SK");
add(new int[] {859}, "CZ");
add(new int[] {860}, "YU");
add(new int[] {865}, "MN");
add(new int[] {867}, "KP");
add(new int[] {868,869}, "TR");
add(new int[] {870,879}, "NL");
add(new int[] {880}, "KR");
add(new int[] {885}, "TH");
add(new int[] {888}, "SG");
add(new int[] {890}, "IN");
add(new int[] {893}, "VN");
add(new int[] {896}, "PK");
add(new int[] {899}, "ID");
add(new int[] {900,919}, "AT");
add(new int[] {930,939}, "AU");
add(new int[] {940,949}, "AZ");
add(new int[] {955}, "MY");
add(new int[] {958}, "MO");
}
}

View file

@ -30,10 +30,8 @@ final class UPCEANExtensionSupport {
private static final int[] CHECK_DIGIT_ENCODINGS = {
0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05
};
private static final int[][] SEPARATOR_PATTERNS = {{1,1}};
private final int[] decodeMiddleCounters = new int[4];
private final int[] separatorCounters = new int[2];
private final StringBuffer decodeRowStringBuffer = new StringBuffer();
Result decodeRow(BitArray row, int rowOffset) throws NotFoundException {
@ -60,9 +58,6 @@ final class UPCEANExtensionSupport {
counters[1] = 0;
counters[2] = 0;
counters[3] = 0;
int[] separatorCounters = this.separatorCounters;
separatorCounters[0] = 0;
separatorCounters[1] = 0;
int end = row.getSize();
int rowOffset = startRange[1];
@ -78,14 +73,6 @@ final class UPCEANExtensionSupport {
lgPatternFound |= 1 << (4 - x);
}
// Read off separator
/*
try {
UPCEANReader.decodeDigit(row, separatorCounters, rowOffset, SEPARATOR_PATTERNS);
rowOffset += separatorCounters[0] + separatorCounters[1];
} catch (NotFoundException nfe) {
break;
}
*/
while (rowOffset < end && !row.get(rowOffset)) {
rowOffset++;
}

View file

@ -23,6 +23,7 @@ import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.ResultMetadataType;
import com.google.zxing.ResultPoint;
import com.google.zxing.ResultPointCallback;
import com.google.zxing.common.BitArray;
@ -93,10 +94,12 @@ public abstract class UPCEANReader extends OneDReader {
private final StringBuffer decodeRowStringBuffer;
private final UPCEANExtensionSupport extensionReader;
private final EANManufacturerOrgSupport eanManSupport;
protected UPCEANReader() {
decodeRowStringBuffer = new StringBuffer(20);
extensionReader = new UPCEANExtensionSupport();
eanManSupport = new EANManufacturerOrgSupport();
}
static int[] findStartGuardPattern(BitArray row) throws NotFoundException {
@ -174,12 +177,13 @@ public abstract class UPCEANReader extends OneDReader {
float left = (float) (startGuardRange[1] + startGuardRange[0]) / 2.0f;
float right = (float) (endRange[1] + endRange[0]) / 2.0f;
BarcodeFormat format = getBarcodeFormat();
Result decodeResult = new Result(resultString,
null, // no natural byte representation for these barcodes
new ResultPoint[]{
new ResultPoint(left, (float) rowNumber),
new ResultPoint(right, (float) rowNumber)},
getBarcodeFormat());
format);
try {
Result extensionResult = extensionReader.decodeRow(row, endRange[1]);
@ -187,6 +191,14 @@ public abstract class UPCEANReader extends OneDReader {
} catch (ReaderException re) {
// continue
}
if (BarcodeFormat.EAN_13.equals(format) || BarcodeFormat.UPC_A.equals(format)) {
String countryID = eanManSupport.lookupCountryIdentifier(resultString);
if (countryID != null) {
decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);
}
}
return decodeResult;
}

View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2010 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 junit.framework.TestCase;
/**
* Tests {@link EANManufacturerOrgSupport}.
*
* @author Sean Owen
*/
public final class EANManufacturerOrgSupportTest extends TestCase {
public void testLookup() {
EANManufacturerOrgSupport support = new EANManufacturerOrgSupport();
assertNull(support.lookupCountryIdentifier("472000"));
assertEquals("US/CA", support.lookupCountryIdentifier("000000"));
assertEquals("MO", support.lookupCountryIdentifier("958000"));
assertEquals("GB", support.lookupCountryIdentifier("500000"));
assertEquals("GB", support.lookupCountryIdentifier("509000"));
}
}