[SCM] Multi-format 1D/2D barcode image processing library branch, upstream, updated. 24d4480bc48cf9eabf7b2bd2f528248b0e458809
srowen
srowen at 59b500cc-1b3d-0410-9834-0bbf25fbcc57
Wed Aug 4 01:31:28 UTC 2010
The following commit has been merged in the upstream branch:
commit 1366f61518b0914bfdc8eff8bcbd863e780e3ffc
Author: srowen <srowen at 59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Date: Mon May 10 19:18:50 2010 +0000
Big RSS Expanded changelist -- thank you authors
git-svn-id: http://zxing.googlecode.com/svn/trunk@1350 59b500cc-1b3d-0410-9834-0bbf25fbcc57
diff --git a/AUTHORS b/AUTHORS
index 34401e7..cd9f5a8 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,11 +1,14 @@
This project consists of contributions from several people, recognized here for convenience,
in alphabetical order.
+Agustín Delgado (Servinform S.A.)
+Aitor Almeida (University of Deusto)
Alasdair Mackintosh (Google)
Alexander Martin (Haase & Martin GmbH)
Andreas Pillath
Andrey Sitnik
Androida.hu / http://www.androida.hu/
+Antonio Manuel Benjumea (Servinform S.A.)
Brian Brown (Google)
Christian Brunschen (Google)
Daniel Switkin (Google)
@@ -13,6 +16,7 @@ Dave MacLachlan (Google)
David Phillip Oster (Google)
David Albert (Bug Labs)
Diego Pierotto
+Eduardo Castillejo (University of Deusto)
Eric Kobrin (Velocitude)
Erik Barbara
Fred Lin (Anobiit)
@@ -32,6 +36,7 @@ Matthew Schulkind (Google)
Matt York (LifeMarks)
Mohamad Fairol
Nikolaos Ftylitakis
+Pablo Orduña (University of Deusto)
Paul Hackenberger
Randy Shen (Acer)
Rasmus Schrøder Sørensen
diff --git a/core/src/com/google/zxing/BarcodeFormat.java b/core/src/com/google/zxing/BarcodeFormat.java
index 360baf7..d4e1e70 100644
--- a/core/src/com/google/zxing/BarcodeFormat.java
+++ b/core/src/com/google/zxing/BarcodeFormat.java
@@ -62,6 +62,9 @@ public final class BarcodeFormat {
/** PDF417 format. */
public static final BarcodeFormat PDF417 = new BarcodeFormat("PDF417");
+ /** RSS EXPANDED */
+ public static final BarcodeFormat RSS_EXPANDED = new BarcodeFormat("RSS_EXPANDED");
+
private final String name;
private BarcodeFormat(String name) {
@@ -88,4 +91,4 @@ public final class BarcodeFormat {
return format;
}
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/zxing/MultiFormatReader.java b/core/src/com/google/zxing/MultiFormatReader.java
index 6685882..c198021 100644
--- a/core/src/com/google/zxing/MultiFormatReader.java
+++ b/core/src/com/google/zxing/MultiFormatReader.java
@@ -102,7 +102,8 @@ public final class MultiFormatReader implements Reader {
formats.contains(BarcodeFormat.CODE_39) ||
formats.contains(BarcodeFormat.CODE_128) ||
formats.contains(BarcodeFormat.ITF) ||
- formats.contains(BarcodeFormat.RSS14);
+ formats.contains(BarcodeFormat.RSS14) ||
+ formats.contains(BarcodeFormat.RSS_EXPANDED);
// Put 1D readers upfront in "normal" mode
if (addOneDReader && !tryHarder) {
readers.addElement(new MultiFormatOneDReader(hints));
diff --git a/core/src/com/google/zxing/client/result/ExpandedProductParsedResult.java b/core/src/com/google/zxing/client/result/ExpandedProductParsedResult.java
new file mode 100644
index 0000000..a5cd3dc
--- /dev/null
+++ b/core/src/com/google/zxing/client/result/ExpandedProductParsedResult.java
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.client.result;
+
+import java.util.Hashtable;
+
+/**
+ * @author Antonio Manuel Benjumea Conde, Servinform, S.A.
+ * @author Agustín Delgado, Servinform, S.A.
+ */
+public class ExpandedProductParsedResult extends ParsedResult {
+
+ public static final String KILOGRAM = "KG";
+ public static final String POUND = "LB";
+
+ private final String productID;
+ private final String sscc;
+ private final String lotNumber;
+ private final String productionDate;
+ private final String packagingDate;
+ private final String bestBeforeDate;
+ private final String expirationDate;
+ private final String weight;
+ private final String weightType;
+ private final String weightIncrement;
+ private final String price;
+ private final String priceIncrement;
+ private final String priceCurrency;
+ // For AIS that not exist in this object
+ private final Hashtable uncommonAIs;
+
+ ExpandedProductParsedResult() {
+ super(ParsedResultType.PRODUCT);
+ this.productID = "";
+ this.sscc = "";
+ this.lotNumber = "";
+ this.productionDate = "";
+ this.packagingDate = "";
+ this.bestBeforeDate = "";
+ this.expirationDate = "";
+ this.weight = "";
+ this.weightType = "";
+ this.weightIncrement = "";
+ this.price = "";
+ this.priceIncrement = "";
+ this.priceCurrency = "";
+ this.uncommonAIs = new Hashtable();
+ }
+
+ public ExpandedProductParsedResult(String productID, String sscc,
+ String lotNumber, String productionDate, String packagingDate,
+ String bestBeforeDate, String expirationDate, String weight,
+ String weightType, String weightIncrement, String price,
+ String priceIncrement, String priceCurrency, Hashtable uncommonAIs) {
+ super(ParsedResultType.PRODUCT);
+ this.productID = productID;
+ this.sscc = sscc;
+ this.lotNumber = lotNumber;
+ this.productionDate = productionDate;
+ this.packagingDate = packagingDate;
+ this.bestBeforeDate = bestBeforeDate;
+ this.expirationDate = expirationDate;
+ this.weight = weight;
+ this.weightType = weightType;
+ this.weightIncrement = weightIncrement;
+ this.price = price;
+ this.priceIncrement = priceIncrement;
+ this.priceCurrency = priceCurrency;
+ this.uncommonAIs = uncommonAIs;
+ }
+
+ public boolean equals(Object o){
+ if (!(o instanceof ExpandedProductParsedResult)) {
+ return false;
+ }
+
+ ExpandedProductParsedResult other = (ExpandedProductParsedResult)o;
+
+ return this.productID.equals( other.productID)
+ && this.sscc.equals( other.sscc)
+ && this.lotNumber.equals( other.lotNumber)
+ && this.productionDate.equals( other.productionDate)
+ && this.bestBeforeDate.equals( other.bestBeforeDate)
+ && this.expirationDate.equals( other.expirationDate)
+ && this.weight.equals( other.weight)
+ && this.weightType.equals( other.weightType)
+ && this.weightIncrement.equals( other.weightIncrement)
+ && this.price.equals( other.price)
+ && this.priceIncrement.equals( other.priceIncrement)
+ && this.priceCurrency.equals( other.priceCurrency)
+ && this.uncommonAIs.equals( other.uncommonAIs);
+ }
+
+ public int hashCode(){
+ int hash1 = this.productID.hashCode();
+ hash1 = 31 * hash1 + this.sscc.hashCode();
+ hash1 = 31 * hash1 + this.lotNumber.hashCode();
+ hash1 = 31 * hash1 + this.productionDate.hashCode();
+ hash1 = 31 * hash1 + this.bestBeforeDate.hashCode();
+ hash1 = 31 * hash1 + this.expirationDate.hashCode();
+ hash1 = 31 * hash1 + this.weight.hashCode();
+
+ int hash2 = this.weightType.hashCode();
+ hash2 = 31 * hash2 + this.weightIncrement.hashCode();
+ hash2 = 31 * hash2 + this.price.hashCode();
+ hash2 = 31 * hash2 + this.priceIncrement.hashCode();
+ hash2 = 31 * hash2 + this.priceCurrency.hashCode();
+ hash2 = 31 * hash2 + this.uncommonAIs.hashCode();
+ return hash1 ^ hash2;
+ }
+
+ public String getProductID() {
+ return productID;
+ }
+
+ public String getSscc() {
+ return sscc;
+ }
+
+ public String getLotNumber() {
+ return lotNumber;
+ }
+
+ public String getProductionDate() {
+ return productionDate;
+ }
+
+ public String getPackagingDate() {
+ return packagingDate;
+ }
+
+ public String getBestBeforeDate() {
+ return bestBeforeDate;
+ }
+
+ public String getExpirationDate() {
+ return expirationDate;
+ }
+
+ public String getWeight() {
+ return weight;
+ }
+
+ public String getWeightType() {
+ return weightType;
+ }
+
+ public String getWeightIncrement() {
+ return weightIncrement;
+ }
+
+ public String getPrice() {
+ return price;
+ }
+
+ public String getPriceIncrement() {
+ return priceIncrement;
+ }
+
+ public String getPriceCurrency() {
+ return priceCurrency;
+ }
+
+ public Hashtable getUncommonAIs() {
+ return uncommonAIs;
+ }
+
+ public String getDisplayResult() {
+ return productID;
+ }
+}
diff --git a/core/src/com/google/zxing/client/result/ExpandedProductResultParser.java b/core/src/com/google/zxing/client/result/ExpandedProductResultParser.java
new file mode 100644
index 0000000..3e3fd51
--- /dev/null
+++ b/core/src/com/google/zxing/client/result/ExpandedProductResultParser.java
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.client.result;
+
+import java.util.Hashtable;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.Result;
+
+/**
+ * Parses strings of digits that represent a RSS Extended code.
+ *
+ * @author Antonio Manuel Benjumea Conde, Servinform, S.A.
+ * @author Agustín Delgado, Servinform, S.A.
+ */
+final class ExpandedProductResultParser extends ResultParser {
+
+ private ExpandedProductResultParser() {
+ }
+
+ // Treat all RSS EXPANDED, in the sense that they are all
+ // product barcodes with complementary data.
+ public static ExpandedProductParsedResult parse(Result result) {
+ BarcodeFormat format = result.getBarcodeFormat();
+ if (!(BarcodeFormat.RSS_EXPANDED.equals(format))) {
+ // ExtendedProductParsedResult NOT created. Not a RSS Expanded barcode
+ return null;
+ }
+ // Really neither of these should happen:
+ String rawText = result.getText();
+ if (rawText == null) {
+ // ExtendedProductParsedResult NOT created. Input text is NULL
+ return null;
+ }
+
+ String productID = "-";
+ String sscc = "-";
+ String lotNumber = "-";
+ String productionDate = "-";
+ String packagingDate = "-";
+ String bestBeforeDate = "-";
+ String expirationDate = "-";
+ String weight = "-";
+ String weightType = "-";
+ String weightIncrement = "-";
+ String price = "-";
+ String priceIncrement = "-";
+ String priceCurrency = "-";
+ Hashtable uncommonAIs = new Hashtable();
+
+ int i = 0;
+
+ while (i < rawText.length()) {
+ String ai = findAIvalue(i, rawText);
+ if ("ERROR".equals(ai)) {
+ // Error. Code doesn't match with RSS expanded pattern
+ // ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern
+ return null;
+ }
+ i += ai.length() + 2;
+ String value = findValue(i, rawText);
+ i += value.length();
+
+ if ("00".equals(ai)) {
+ sscc = value;
+ } else if ("01".equals(ai)) {
+ productID = value;
+ } else if ("10".equals(ai)) {
+ lotNumber = value;
+ } else if ("11".equals(ai)) {
+ productionDate = value;
+ } else if ("13".equals(ai)) {
+ packagingDate = value;
+ } else if ("15".equals(ai)) {
+ bestBeforeDate = value;
+ } else if ("17".equals(ai)) {
+ expirationDate = value;
+ } else if ("3100".equals(ai) || "3101".equals(ai)
+ || "3102".equals(ai) || "3103".equals(ai)
+ || "3104".equals(ai) || "3105".equals(ai)
+ || "3106".equals(ai) || "3107".equals(ai)
+ || "3108".equals(ai) || "3109".equals(ai)) {
+ weight = value;
+ weightType = ExpandedProductParsedResult.KILOGRAM;
+ weightIncrement = ai.substring(3);
+ } else if ("3200".equals(ai) || "3201".equals(ai)
+ || "3202".equals(ai) || "3203".equals(ai)
+ || "3204".equals(ai) || "3205".equals(ai)
+ || "3206".equals(ai) || "3207".equals(ai)
+ || "3208".equals(ai) || "3209".equals(ai)) {
+ weight = value;
+ weightType = ExpandedProductParsedResult.POUND;
+ weightIncrement = ai.substring(3);
+ } else if ("3920".equals(ai) || "3921".equals(ai)
+ || "3922".equals(ai) || "3923".equals(ai)) {
+ price = value;
+ priceIncrement = ai.substring(3);
+ } else if ("3930".equals(ai) || "3931".equals(ai)
+ || "3932".equals(ai) || "3933".equals(ai)) {
+ if (value.length() < 4) {
+ // The value must have more of 3 symbols (3 for currency and
+ // 1 at least for the price)
+ // ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern
+ return null;
+ }
+ price = value.substring(3);
+ priceCurrency = value.substring(0, 3);
+ priceIncrement = ai.substring(3);
+ } else {
+ // No match with common AIs
+ uncommonAIs.put(ai, value);
+ }
+ }
+
+ return new ExpandedProductParsedResult(productID, sscc, lotNumber,
+ productionDate, packagingDate, bestBeforeDate, expirationDate,
+ weight, weightType, weightIncrement, price, priceIncrement,
+ priceCurrency, uncommonAIs);
+ }
+
+ private static String findAIvalue(int i, String rawText) {
+ StringBuffer buf = new StringBuffer();
+ char c = rawText.charAt(i);
+ // First character must be a open parenthesis.If not, ERROR
+ if (c != '(') {
+ return "ERROR";
+ }
+
+ String rawTextAux = rawText.substring(i + 1);
+
+ for (int index = 0; index < rawTextAux.length(); index++) {
+ char currentChar = rawTextAux.charAt(index);
+ switch (currentChar){
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ buf.append(currentChar);
+ break;
+ case ')':
+ return buf.toString();
+ default:
+ return "ERROR";
+ }
+ }
+ return buf.toString();
+ }
+
+ private static String findValue(int i, String rawText) {
+ StringBuffer buf = new StringBuffer();
+ String rawTextAux = rawText.substring(i);
+
+ for (int index = 0; index < rawTextAux.length(); index++) {
+ char c = rawTextAux.charAt(index);
+ if (c == '(') {
+ // We look for a new AI. If it doesn't exist (ERROR), we coninue
+ // with the iteration
+ if ("ERROR".equals(findAIvalue(index, rawTextAux))) {
+ buf.append(c);
+ } else {
+ break;
+ }
+ } else {
+ buf.append(c);
+ }
+ }
+ return buf.toString();
+ }
+}
diff --git a/core/src/com/google/zxing/client/result/ResultParser.java b/core/src/com/google/zxing/client/result/ResultParser.java
index ce29b55..f1b3476 100644
--- a/core/src/com/google/zxing/client/result/ResultParser.java
+++ b/core/src/com/google/zxing/client/result/ResultParser.java
@@ -72,6 +72,8 @@ public abstract class ResultParser {
return result;
} else if ((result = ProductResultParser.parse(theResult)) != null) {
return result;
+ } else if ((result = ExpandedProductResultParser.parse(theResult)) != null) {
+ return result;
}
return new TextParsedResult(theResult.getText(), null);
}
diff --git a/core/src/com/google/zxing/oned/MultiFormatOneDReader.java b/core/src/com/google/zxing/oned/MultiFormatOneDReader.java
index bc1d313..ccf63dd 100644
--- a/core/src/com/google/zxing/oned/MultiFormatOneDReader.java
+++ b/core/src/com/google/zxing/oned/MultiFormatOneDReader.java
@@ -24,6 +24,7 @@ import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.BitArray;
import com.google.zxing.oned.rss.RSS14Reader;
+import com.google.zxing.oned.rss.expanded.RSSExpandedReader;
import java.util.Hashtable;
import java.util.Vector;
@@ -61,6 +62,9 @@ public final class MultiFormatOneDReader extends OneDReader {
if (possibleFormats.contains(BarcodeFormat.RSS14)) {
readers.addElement(new RSS14Reader());
}
+ if (possibleFormats.contains(BarcodeFormat.RSS_EXPANDED)){
+ readers.addElement(new RSSExpandedReader());
+ }
}
if (readers.isEmpty()) {
readers.addElement(new MultiFormatUPCEANReader(hints));
@@ -68,6 +72,7 @@ public final class MultiFormatOneDReader extends OneDReader {
readers.addElement(new Code128Reader());
readers.addElement(new ITFReader());
readers.addElement(new RSS14Reader());
+ readers.addElement(new RSSExpandedReader());
}
}
diff --git a/core/src/com/google/zxing/oned/rss/AbstractRSSReader.java b/core/src/com/google/zxing/oned/rss/AbstractRSSReader.java
new file mode 100644
index 0000000..fce9e83
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/AbstractRSSReader.java
@@ -0,0 +1,110 @@
+/*
+ * 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.rss;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.oned.OneDReader;
+
+public abstract class AbstractRSSReader extends OneDReader {
+
+ private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.2f);
+ private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.4f);
+
+ private static final float MIN_FINDER_PATTERN_RATIO = 9.5f / 12.0f;
+ private static final float MAX_FINDER_PATTERN_RATIO = 12.5f / 14.0f;
+
+ protected final int[] decodeFinderCounters;
+ protected final int[] dataCharacterCounters;
+ protected final float[] oddRoundingErrors;
+ protected final float[] evenRoundingErrors;
+ protected final int[] oddCounts;
+ protected final int[] evenCounts;
+
+ protected AbstractRSSReader(){
+ decodeFinderCounters = new int[4];
+ dataCharacterCounters = new int[8];
+ oddRoundingErrors = new float[4];
+ evenRoundingErrors = new float[4];
+ oddCounts = new int[dataCharacterCounters.length / 2];
+ evenCounts = new int[dataCharacterCounters.length / 2];
+ }
+
+
+ protected static int parseFinderValue(int[] counters, int [][] finderPatterns) throws NotFoundException {
+ for (int value = 0; value < finderPatterns.length; value++) {
+ if (patternMatchVariance(counters, finderPatterns[value], MAX_INDIVIDUAL_VARIANCE) <
+ MAX_AVG_VARIANCE) {
+ return value;
+ }
+ }
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ protected static int count(int[] array) {
+ int count = 0;
+ for (int i = 0; i < array.length; i++) {
+ count += array[i];
+ }
+ return count;
+ }
+
+ protected static void increment(int[] array, float[] errors) {
+ int index = 0;
+ float biggestError = errors[0];
+ for (int i = 1; i < array.length; i++) {
+ if (errors[i] > biggestError) {
+ biggestError = errors[i];
+ index = i;
+ }
+ }
+ array[index]++;
+ }
+
+ protected static void decrement(int[] array, float[] errors) {
+ int index = 0;
+ float biggestError = errors[0];
+ for (int i = 1; i < array.length; i++) {
+ if (errors[i] < biggestError) {
+ biggestError = errors[i];
+ index = i;
+ }
+ }
+ array[index]--;
+ }
+
+ protected static boolean isFinderPattern(int[] counters) {
+ int firstTwoSum = counters[0] + counters[1];
+ int sum = firstTwoSum + counters[2] + counters[3];
+ float ratio = (float) firstTwoSum / (float) sum;
+ if (ratio >= MIN_FINDER_PATTERN_RATIO && ratio <= MAX_FINDER_PATTERN_RATIO) {
+ // passes ratio test in spec, but see if the counts are unreasonable
+ int minCounter = Integer.MAX_VALUE;
+ int maxCounter = Integer.MIN_VALUE;
+ for (int i = 0; i < counters.length; i++) {
+ int counter = counters[i];
+ if (counter > maxCounter) {
+ maxCounter = counter;
+ }
+ if (counter < minCounter) {
+ minCounter = counter;
+ }
+ }
+ return maxCounter < 10 * minCounter;
+ }
+ return false;
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/DataCharacter.java b/core/src/com/google/zxing/oned/rss/DataCharacter.java
index a6e5a05..9b5e311 100644
--- a/core/src/com/google/zxing/oned/rss/DataCharacter.java
+++ b/core/src/com/google/zxing/oned/rss/DataCharacter.java
@@ -16,22 +16,22 @@
package com.google.zxing.oned.rss;
-class DataCharacter {
+public class DataCharacter {
private final int value;
private final int checksumPortion;
- DataCharacter(int value, int checksumPortion) {
+ public DataCharacter(int value, int checksumPortion) {
this.value = value;
this.checksumPortion = checksumPortion;
}
- int getValue() {
+ public int getValue() {
return value;
}
- int getChecksumPortion() {
+ public int getChecksumPortion() {
return checksumPortion;
}
-}
\ No newline at end of file
+}
diff --git a/core/src/com/google/zxing/oned/rss/FinderPattern.java b/core/src/com/google/zxing/oned/rss/FinderPattern.java
index d1139b3..afc1a13 100644
--- a/core/src/com/google/zxing/oned/rss/FinderPattern.java
+++ b/core/src/com/google/zxing/oned/rss/FinderPattern.java
@@ -18,13 +18,13 @@ package com.google.zxing.oned.rss;
import com.google.zxing.ResultPoint;
-final class FinderPattern {
+public final class FinderPattern {
private final int value;
private final int[] startEnd;
private final ResultPoint[] resultPoints;
- FinderPattern(int value, int[] startEnd, int start, int end, int rowNumber) {
+ public FinderPattern(int value, int[] startEnd, int start, int end, int rowNumber) {
this.value = value;
this.startEnd = startEnd;
this.resultPoints = new ResultPoint[] {
@@ -33,15 +33,15 @@ final class FinderPattern {
};
}
- int getValue() {
+ public int getValue() {
return value;
}
- int[] getStartEnd() {
+ public int[] getStartEnd() {
return startEnd;
}
- ResultPoint[] getResultPoints() {
+ public ResultPoint[] getResultPoints() {
return resultPoints;
}
diff --git a/core/src/com/google/zxing/oned/rss/RSS14Reader.java b/core/src/com/google/zxing/oned/rss/RSS14Reader.java
index 941107a..1c99ac1 100644
--- a/core/src/com/google/zxing/oned/rss/RSS14Reader.java
+++ b/core/src/com/google/zxing/oned/rss/RSS14Reader.java
@@ -23,7 +23,6 @@ import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.ResultPointCallback;
import com.google.zxing.common.BitArray;
-import com.google.zxing.oned.OneDReader;
import java.util.Enumeration;
import java.util.Hashtable;
@@ -32,13 +31,7 @@ import java.util.Vector;
/**
* Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006.
*/
-public final class RSS14Reader extends OneDReader {
-
- private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.2f);
- private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.4f);
-
- private static final float MIN_FINDER_PATTERN_RATIO = 9.5f / 12.0f;
- private static final float MAX_FINDER_PATTERN_RATIO = 12.5f / 14.0f;
+public final class RSS14Reader extends AbstractRSSReader {
private static final int[] OUTSIDE_EVEN_TOTAL_SUBSET = {1,10,34,70,126};
private static final int[] INSIDE_ODD_TOTAL_SUBSET = {4,20,48,81};
@@ -59,22 +52,10 @@ public final class RSS14Reader extends OneDReader {
{1,3,9,1},
};
- private final int[] decodeFinderCounters;
- private final int[] dataCharacterCounters;
- private final float[] oddRoundingErrors;
- private final float[] evenRoundingErrors;
- private final int[] oddCounts;
- private final int[] evenCounts;
private final Vector possibleLeftPairs;
private final Vector possibleRightPairs;
public RSS14Reader() {
- decodeFinderCounters = new int[4];
- dataCharacterCounters = new int[8];
- oddRoundingErrors = new float[4];
- evenRoundingErrors = new float[4];
- oddCounts = new int[dataCharacterCounters.length / 2];
- evenCounts = new int[dataCharacterCounters.length / 2];
possibleLeftPairs = new Vector();
possibleRightPairs = new Vector();
}
@@ -348,28 +329,6 @@ public final class RSS14Reader extends OneDReader {
}
- private static boolean isFinderPattern(int[] counters) {
- int firstTwoSum = counters[0] + counters[1];
- int sum = firstTwoSum + counters[2] + counters[3];
- float ratio = (float) firstTwoSum / (float) sum;
- if (ratio >= MIN_FINDER_PATTERN_RATIO && ratio <= MAX_FINDER_PATTERN_RATIO) {
- // passes ratio test in spec, but see if the counts are unreasonable
- int minCounter = Integer.MAX_VALUE;
- int maxCounter = Integer.MIN_VALUE;
- for (int i = 0; i < counters.length; i++) {
- int counter = counters[i];
- if (counter > maxCounter) {
- maxCounter = counter;
- }
- if (counter < minCounter) {
- minCounter = counter;
- }
- }
- return maxCounter < 10 * minCounter;
- }
- return false;
- }
-
private FinderPattern parseFoundFinderPattern(BitArray row, int rowNumber, boolean right, int[] startEnd)
throws NotFoundException {
// Actually we found elements 2-5
@@ -387,7 +346,7 @@ public final class RSS14Reader extends OneDReader {
counters[i] = counters[i-1];
}
counters[0] = firstCounter;
- int value = parseFinderValue(counters);
+ int value = parseFinderValue(counters, FINDER_PATTERNS);
int start = firstElementStart;
int end = startEnd[1];
if (right) {
@@ -398,16 +357,6 @@ public final class RSS14Reader extends OneDReader {
return new FinderPattern(value, new int[] {firstElementStart, startEnd[1]}, start, end, rowNumber);
}
- private static int parseFinderValue(int[] counters) throws NotFoundException {
- for (int value = 0; value < FINDER_PATTERNS.length; value++) {
- if (patternMatchVariance(counters, FINDER_PATTERNS[value], MAX_INDIVIDUAL_VARIANCE) <
- MAX_AVG_VARIANCE) {
- return value;
- }
- }
- throw NotFoundException.getNotFoundInstance();
- }
-
/*
private static int[] normalizeE2SEValues(int[] counters) {
int p = 0;
@@ -425,38 +374,6 @@ public final class RSS14Reader extends OneDReader {
}
*/
- private static int count(int[] array) {
- int count = 0;
- for (int i = 0; i < array.length; i++) {
- count += array[i];
- }
- return count;
- }
-
- private static void increment(int[] array, float[] errors) {
- int index = 0;
- float biggestError = errors[0];
- for (int i = 1; i < array.length; i++) {
- if (errors[i] > biggestError) {
- biggestError = errors[i];
- index = i;
- }
- }
- array[index]++;
- }
-
- private static void decrement(int[] array, float[] errors) {
- int index = 0;
- float biggestError = errors[0];
- for (int i = 1; i < array.length; i++) {
- if (errors[i] < biggestError) {
- biggestError = errors[i];
- index = i;
- }
- }
- array[index]--;
- }
-
private void adjustOddEvenCounts(boolean outsideChar, int numModules) throws NotFoundException {
int oddSum = count(oddCounts);
diff --git a/core/src/com/google/zxing/oned/rss/RSSUtils.java b/core/src/com/google/zxing/oned/rss/RSSUtils.java
index f632439..6977fc2 100644
--- a/core/src/com/google/zxing/oned/rss/RSSUtils.java
+++ b/core/src/com/google/zxing/oned/rss/RSSUtils.java
@@ -61,7 +61,7 @@ public final class RSSUtils {
return widths;
}
- static int getRSSvalue(int[] widths, int maxWidth, boolean noNarrow) {
+ public static int getRSSvalue(int[] widths, int maxWidth, boolean noNarrow) {
int elements = widths.length;
int n = 0;
for (int i = 0; i < elements; i++) {
diff --git a/core/src/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java b/core/src/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java
new file mode 100644
index 0000000..0a78b8f
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import java.util.Vector;
+
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class BitArrayBuilder {
+
+ private BitArrayBuilder() {
+ }
+
+ static BitArray buildBitArray(Vector pairs) {
+ int charNumber = (pairs.size() << 1) - 1;
+ if ((((ExpandedPair)pairs.lastElement()).getRightChar()) == null) {
+ charNumber -= 1;
+ }
+
+ int size = 12 * charNumber;
+
+ BitArray binary = new BitArray(size);
+ int accPos = 0;
+
+ ExpandedPair firstPair = (ExpandedPair)pairs.get(0);
+ int firstValue = firstPair.getRightChar().getValue();
+ for(int i = 11; i >= 0; --i){
+ if ((firstValue & (1 << i)) != 0) {
+ binary.set(accPos);
+ }
+ accPos++;
+ }
+
+ for(int i = 1; i < pairs.size(); ++i){
+ ExpandedPair currentPair = (ExpandedPair)pairs.get(i);
+
+ int leftValue = currentPair.getLeftChar().getValue();
+ for(int j = 11; j >= 0; --j){
+ if ((leftValue & (1 << j)) != 0) {
+ binary.set(accPos);
+ }
+ accPos++;
+ }
+
+ if(currentPair.getRightChar() != null){
+ int rightValue = currentPair.getRightChar().getValue();
+ for(int j = 11; j >= 0; --j){
+ if ((rightValue & (1 << j)) != 0) {
+ binary.set(accPos);
+ }
+ accPos++;
+ }
+ }
+ }
+ return binary;
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/ExpandedPair.java b/core/src/com/google/zxing/oned/rss/expanded/ExpandedPair.java
new file mode 100644
index 0000000..cde1d02
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/ExpandedPair.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import com.google.zxing.oned.rss.DataCharacter;
+import com.google.zxing.oned.rss.FinderPattern;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+final class ExpandedPair {
+
+ private final boolean mayBeLast;
+ private final DataCharacter leftChar;
+ private final DataCharacter rightChar;
+ private final FinderPattern finderPattern;
+
+ ExpandedPair(DataCharacter leftChar, DataCharacter rightChar, FinderPattern finderPattern, boolean mayBeLast) {
+ this.leftChar = leftChar;
+ this.rightChar = rightChar;
+ this.finderPattern = finderPattern;
+ this.mayBeLast = mayBeLast;
+ }
+
+ boolean mayBeLast(){
+ return this.mayBeLast;
+ }
+
+ DataCharacter getLeftChar() {
+ return this.leftChar;
+ }
+
+ DataCharacter getRightChar() {
+ return this.rightChar;
+ }
+
+ FinderPattern getFinderPattern() {
+ return this.finderPattern;
+ }
+
+ public boolean mustBeLast() {
+ return this.rightChar == null;
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java b/core/src/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java
new file mode 100644
index 0000000..d9c822a
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java
@@ -0,0 +1,578 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.Result;
+import com.google.zxing.ResultPoint;
+import com.google.zxing.common.BitArray;
+import com.google.zxing.oned.rss.AbstractRSSReader;
+import com.google.zxing.oned.rss.DataCharacter;
+import com.google.zxing.oned.rss.FinderPattern;
+import com.google.zxing.oned.rss.RSSUtils;
+import com.google.zxing.oned.rss.expanded.decoders.AbstractExpandedDecoder;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public final class RSSExpandedReader extends AbstractRSSReader{
+
+ private static final int[] SYMBOL_WIDEST = {7, 5, 4, 3, 1};
+ private static final int[] EVEN_TOTAL_SUBSET = {4, 20, 52, 104, 204};
+ private static final int[] GSUM = {0, 348, 1388, 2948, 3988};
+
+ private static final int[][] FINDER_PATTERNS = {
+ {1,8,4,1}, // A
+ {3,6,4,1}, // B
+ {3,4,6,1}, // C
+ {3,2,8,1}, // D
+ {2,6,5,1}, // E
+ {2,2,9,1} // F
+ };
+
+ private static final int[][] WEIGHTS = {
+ { 1, 3, 9, 27, 81, 32, 96, 77},
+ { 20, 60, 180, 118, 143, 7, 21, 63},
+ {189, 145, 13, 39, 117, 140, 209, 205},
+ {193, 157, 49, 147, 19, 57, 171, 91},
+ { 62, 186, 136, 197, 169, 85, 44, 132},
+ {185, 133, 188, 142, 4, 12, 36, 108},
+ {113, 128, 173, 97, 80, 29, 87, 50},
+ {150, 28, 84, 41, 123, 158, 52, 156},
+ { 46, 138, 203, 187, 139, 206, 196, 166},
+ { 76, 17, 51, 153, 37, 111, 122, 155},
+ { 43, 129, 176, 106, 107, 110, 119, 146},
+ { 16, 48, 144, 10, 30, 90, 59, 177},
+ {109, 116, 137, 200, 178, 112, 125, 164},
+ { 70, 210, 208, 202, 184, 130, 179, 115},
+ {134, 191, 151, 31, 93, 68, 204, 190},
+ {148, 22, 66, 198, 172, 94, 71, 2},
+ { 6, 18, 54, 162, 64, 192,154, 40},
+ {120, 149, 25, 75, 14, 42,126, 167},
+ { 79, 26, 78, 23, 69, 207,199, 175},
+ {103, 98, 83, 38, 114, 131, 182, 124},
+ {161, 61, 183, 127, 170, 88, 53, 159},
+ { 55, 165, 73, 8, 24, 72, 5, 15},
+ { 45, 135, 194, 160, 58, 174, 100, 89}
+ };
+
+ private static final int FINDER_PAT_A = 0;
+ private static final int FINDER_PAT_B = 1;
+ private static final int FINDER_PAT_C = 2;
+ private static final int FINDER_PAT_D = 3;
+ private static final int FINDER_PAT_E = 4;
+ private static final int FINDER_PAT_F = 5;
+
+ private static final int [][] FINDER_PATTERN_SEQUENCES = {
+ { FINDER_PAT_A, FINDER_PAT_A },
+ { FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B },
+ { FINDER_PAT_A, FINDER_PAT_C, FINDER_PAT_B, FINDER_PAT_D },
+ { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_C },
+ { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_F },
+ { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },
+ { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D },
+ { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E },
+ { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },
+ { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },
+ };
+
+ private static final int LONGEST_SEQUENCE_SIZE = FINDER_PATTERN_SEQUENCES[FINDER_PATTERN_SEQUENCES.length - 1].length;
+
+ private static final int MAX_PAIRS = 11;
+ private final Vector pairs = new Vector(MAX_PAIRS);
+ private final int [] startEnd = new int[2];
+ private final int [] currentSequence = new int[LONGEST_SEQUENCE_SIZE];
+
+ public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws NotFoundException {
+ this.reset();
+ decodeRow2pairs(rowNumber, row);
+ return constructResult(this.pairs);
+ }
+
+ public void reset() {
+ this.pairs.setSize(0);
+ }
+
+ // Not private for testing
+ Vector decodeRow2pairs(int rowNumber, BitArray row) throws NotFoundException {
+ while(true){
+ ExpandedPair nextPair = retrieveNextPair(row, this.pairs, rowNumber);
+ this.pairs.add(nextPair);
+
+ if(nextPair.mayBeLast()){
+ if(checkChecksum()) {
+ return this.pairs;
+ }
+ if(nextPair.mustBeLast()) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ }
+ }
+ }
+
+ private static Result constructResult(Vector pairs) throws NotFoundException{
+ BitArray binary = BitArrayBuilder.buildBitArray(pairs);
+
+ AbstractExpandedDecoder decoder = AbstractExpandedDecoder.createDecoder(binary);
+ String resultingString = decoder.parseInformation();
+
+ ResultPoint [] firstPoints = ((ExpandedPair)pairs.get(0)).getFinderPattern().getResultPoints();
+ ResultPoint [] lastPoints = ((ExpandedPair)pairs.lastElement()).getFinderPattern().getResultPoints();
+
+ return new Result(
+ resultingString,
+ null,
+ new ResultPoint[]{firstPoints[0], firstPoints[1], lastPoints[0], lastPoints[1]},
+ BarcodeFormat.RSS_EXPANDED
+ );
+ }
+
+ private boolean checkChecksum(){
+ ExpandedPair firstPair = (ExpandedPair)this.pairs.get(0);
+ DataCharacter checkCharacter = firstPair.getLeftChar();
+ DataCharacter firstCharacter = firstPair.getRightChar();
+
+ int checksum = firstCharacter.getChecksumPortion();
+ int S = 2;
+
+ for(int i = 1; i < this.pairs.size(); ++i){
+ ExpandedPair currentPair = (ExpandedPair)this.pairs.get(i);
+ checksum += currentPair.getLeftChar().getChecksumPortion();
+ S++;
+ if(currentPair.getRightChar() != null){
+ checksum += currentPair.getRightChar().getChecksumPortion();
+ S++;
+ }
+ }
+
+ checksum %= 211;
+
+ int checkCharacterValue = 211 * (S - 4) + checksum;
+
+ return checkCharacterValue == checkCharacter.getValue();
+ }
+
+ private static int getNextSecondBar(BitArray row, int initialPos){
+ int currentPos = initialPos;
+ boolean current = row.get(currentPos);
+
+ while(currentPos < row.size && row.get(currentPos) == current) {
+ currentPos++;
+ }
+
+ current = !current;
+ while(currentPos < row.size && row.get(currentPos) == current) {
+ currentPos++;
+ }
+
+ return currentPos;
+ }
+
+ // not private for testing
+ ExpandedPair retrieveNextPair(BitArray row, Vector previousPairs, int rowNumber) throws NotFoundException{
+ boolean isOddPattern = previousPairs.size() % 2 == 0;
+
+ FinderPattern pattern;
+
+ boolean keepFinding = true;
+ int forcedOffset = -1;
+ do{
+ this.findNextPair(row, previousPairs, forcedOffset);
+ pattern = parseFoundFinderPattern(row, rowNumber, isOddPattern);
+ if(pattern == null){
+ forcedOffset = getNextSecondBar(row, this.startEnd[0]);
+ }else {
+ keepFinding = false;
+ }
+ }while(keepFinding);
+
+ boolean mayBeLast = checkPairSequence(previousPairs, pattern);
+
+ DataCharacter leftChar = this.decodeDataCharacter(row, pattern, isOddPattern, true);
+ DataCharacter rightChar;
+ try{
+ rightChar = this.decodeDataCharacter(row, pattern, isOddPattern, false);
+ }catch(NotFoundException nfe){
+ if(mayBeLast) {
+ rightChar = null;
+ } else {
+ throw nfe;
+ }
+ }
+
+ return new ExpandedPair(leftChar, rightChar, pattern, mayBeLast);
+ }
+
+ private boolean checkPairSequence(Vector previousPairs, FinderPattern pattern) throws NotFoundException{
+ int currentSequenceLength = previousPairs.size() + 1;
+ if(currentSequenceLength > this.currentSequence.length) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ for(int pos = 0; pos < previousPairs.size(); ++pos) {
+ this.currentSequence[pos] = ((ExpandedPair) previousPairs.get(pos)).getFinderPattern().getValue();
+ }
+
+ this.currentSequence[currentSequenceLength - 1] = pattern.getValue();
+
+ for(int i = 0; i < FINDER_PATTERN_SEQUENCES.length; ++i){
+ int [] validSequence = FINDER_PATTERN_SEQUENCES[i];
+ if(validSequence.length >= currentSequenceLength){
+ boolean valid = true;
+ for(int pos = 0; pos < currentSequenceLength; ++pos) {
+ if (this.currentSequence[pos] != validSequence[pos]) {
+ valid = false;
+ break;
+ }
+ }
+
+ if(valid) {
+ return currentSequenceLength == validSequence.length;
+ }
+ }
+ }
+
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ private void findNextPair(BitArray row, Vector previousPairs, int forcedOffset) throws NotFoundException{
+ int[] counters = this.decodeFinderCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+
+ int width = row.getSize();
+
+ int rowOffset;
+ if (forcedOffset >= 0) {
+ rowOffset = forcedOffset;
+ } else if (previousPairs.isEmpty()) {
+ rowOffset = 0;
+ } else{
+ ExpandedPair lastPair = ((ExpandedPair)previousPairs.lastElement());
+ rowOffset = lastPair.getFinderPattern().getStartEnd()[1];
+ }
+ boolean searchingEvenPair = previousPairs.size() % 2 != 0;
+
+ boolean isWhite = false;
+ while (rowOffset < width) {
+ isWhite = !row.get(rowOffset);
+ if (!isWhite) {
+ break;
+ }
+ rowOffset++;
+ }
+
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+ for (int x = rowOffset; x < width; x++) {
+ boolean pixel = row.get(x);
+ if (pixel ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == 3) {
+ if (searchingEvenPair) {
+ reverseCounters(counters);
+ }
+
+ if (isFinderPattern(counters)){
+ this.startEnd[0] = patternStart;
+ this.startEnd[1] = x;
+ return;
+ }
+
+ if (searchingEvenPair) {
+ reverseCounters(counters);
+ }
+
+ patternStart += counters[0] + counters[1];
+ counters[0] = counters[2];
+ counters[1] = counters[3];
+ counters[2] = 0;
+ counters[3] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ private static void reverseCounters(int [] counters){
+ int length = counters.length;
+ for(int i = 0; i < length / 2; ++i){
+ int tmp = counters[i];
+ counters[i] = counters[length - i - 1];
+ counters[length - i - 1] = tmp;
+ }
+ }
+
+ private FinderPattern parseFoundFinderPattern(BitArray row, int rowNumber, boolean oddPattern) {
+ // Actually we found elements 2-5.
+ int firstCounter;
+ int start;
+ int end;
+
+ if(oddPattern){
+ // If pattern number is odd, we need to locate element 1 *before* the current block.
+
+ int firstElementStart = this.startEnd[0] - 1;
+ // Locate element 1
+ while (firstElementStart >= 0 && !row.get(firstElementStart)) {
+ firstElementStart--;
+ }
+
+ firstElementStart++;
+ firstCounter = this.startEnd[0] - firstElementStart;
+ start = firstElementStart;
+ end = this.startEnd[1];
+
+ }else{
+ // If pattern number is even, the pattern is reversed, so we need to locate element 1 *after* the current block.
+
+ start = this.startEnd[0];
+
+ int firstElementStart = this.startEnd[1] + 1;
+ while(row.get(firstElementStart) && firstElementStart < row.size) {
+ firstElementStart++;
+ }
+
+ end = firstElementStart;
+ firstCounter = end - this.startEnd[1];
+ }
+
+ // Make 'counters' hold 1-4
+ int [] counters = this.decodeFinderCounters;
+ for (int i = counters.length - 1; i > 0; i--) {
+ counters[i] = counters[i - 1];
+ }
+
+ counters[0] = firstCounter;
+ int value;
+ try {
+ value = parseFinderValue(counters, FINDER_PATTERNS);
+ } catch (NotFoundException nfe) {
+ return null;
+ }
+ return new FinderPattern(value, new int[] {start, end}, start, end, rowNumber);
+ }
+
+ DataCharacter decodeDataCharacter(BitArray row, FinderPattern pattern, boolean isOddPattern, boolean leftChar)
+ throws NotFoundException {
+ int[] counters = this.dataCharacterCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+ counters[4] = 0;
+ counters[5] = 0;
+ counters[6] = 0;
+ counters[7] = 0;
+
+ if (leftChar) {
+ recordPatternInReverse(row, pattern.getStartEnd()[0], counters);
+ } else {
+ recordPattern(row, pattern.getStartEnd()[1] + 1, counters);
+ // reverse it
+ for (int i = 0, j = counters.length - 1; i < j; i++, j--) {
+ int temp = counters[i];
+ counters[i] = counters[j];
+ counters[j] = temp;
+ }
+ }//counters[] has the pixels of the module
+
+ int numModules = 17; //left and right data characters have all the same length
+ float elementWidth = (float) count(counters) / (float) numModules;
+
+ int[] oddCounts = this.oddCounts;
+ int[] evenCounts = this.evenCounts;
+ float[] oddRoundingErrors = this.oddRoundingErrors;
+ float[] evenRoundingErrors = this.evenRoundingErrors;
+
+ for (int i = 0; i < counters.length; i++) {
+ float value = 1.0f * counters[i] / elementWidth;
+ int count = (int) (value + 0.5f); // Round
+ if (count < 1) {
+ count = 1;
+ } else if (count > 8) {
+ count = 8;
+ }
+ int offset = i >> 1;
+ if ((i & 0x01) == 0) {
+ oddCounts[offset] = count;
+ oddRoundingErrors[offset] = value - count;
+ } else {
+ evenCounts[offset] = count;
+ evenRoundingErrors[offset] = value - count;
+ }
+ }
+
+ adjustOddEvenCounts(numModules);
+
+ int weightRowNumber = 4 * pattern.getValue() + (isOddPattern?0:2) + (leftChar?0:1) - 1;
+
+ int oddSum = 0;
+ int oddChecksumPortion = 0;
+ for (int i = oddCounts.length - 1; i >= 0; i--) {
+ if(isNotA1left(pattern, isOddPattern, leftChar)){
+ int weight = WEIGHTS[weightRowNumber][2 * i];
+ oddChecksumPortion += oddCounts[i] * weight;
+ }
+ oddSum += oddCounts[i];
+ }
+ int evenChecksumPortion = 0;
+ int evenSum = 0;
+ for (int i = evenCounts.length - 1; i >= 0; i--) {
+ if(isNotA1left(pattern, isOddPattern, leftChar)){
+ int weight = WEIGHTS[weightRowNumber][2 * i + 1];
+ evenChecksumPortion += evenCounts[i] * weight;
+ }
+ evenSum += evenCounts[i];
+ }
+ int checksumPortion = oddChecksumPortion + evenChecksumPortion;
+
+ if ((oddSum & 0x01) != 0 || oddSum > 13 || oddSum < 4) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ int group = (13 - oddSum) / 2;
+ int oddWidest = SYMBOL_WIDEST[group];
+ int evenWidest = 9 - oddWidest;
+ int vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
+ int vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
+ int tEven = EVEN_TOTAL_SUBSET[group];
+ int gSum = GSUM[group];
+ int value = vOdd * tEven + vEven + gSum;
+
+ return new DataCharacter(value, checksumPortion);
+ }
+
+ private static boolean isNotA1left(FinderPattern pattern, boolean isOddPattern, boolean leftChar) {
+ // A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char
+ return !(pattern.getValue() == 0 && isOddPattern && leftChar);
+ }
+
+ private void adjustOddEvenCounts(int numModules) throws NotFoundException {
+
+ int oddSum = count(this.oddCounts);
+ int evenSum = count(this.evenCounts);
+ int mismatch = oddSum + evenSum - numModules;
+ boolean oddParityBad = (oddSum & 0x01) == 1;
+ boolean evenParityBad = (evenSum & 0x01) == 0;
+
+ boolean incrementOdd = false;
+ boolean decrementOdd = false;
+
+ if (oddSum > 13) {
+ decrementOdd = true;
+ } else if (oddSum < 4) {
+ incrementOdd = true;
+ }
+ boolean incrementEven = false;
+ boolean decrementEven = false;
+ if (evenSum > 13) {
+ decrementEven = true;
+ } else if (evenSum < 4) {
+ incrementEven = true;
+ }
+
+ if (mismatch == 1) {
+ if (oddParityBad) {
+ if (evenParityBad) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ decrementOdd = true;
+ } else {
+ if (!evenParityBad) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ decrementEven = true;
+ }
+ } else if (mismatch == -1) {
+ if (oddParityBad) {
+ if (evenParityBad) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ incrementOdd = true;
+ } else {
+ if (!evenParityBad) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ incrementEven = true;
+ }
+ } else if (mismatch == 0) {
+ if (oddParityBad) {
+ if (!evenParityBad) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ // Both bad
+ if (oddSum < evenSum) {
+ incrementOdd = true;
+ decrementEven = true;
+ } else {
+ decrementOdd = true;
+ incrementEven = true;
+ }
+ } else {
+ if (evenParityBad) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ // Nothing to do!
+ }
+ } else {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ if (incrementOdd) {
+ if (decrementOdd) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ increment(this.oddCounts, this.oddRoundingErrors);
+ }
+ if (decrementOdd) {
+ decrement(this.oddCounts, this.oddRoundingErrors);
+ }
+ if (incrementEven) {
+ if (decrementEven) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+ increment(this.evenCounts, this.oddRoundingErrors);
+ }
+ if (decrementEven) {
+ decrement(this.evenCounts, this.evenRoundingErrors);
+ }
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013103decoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013103decoder.java
new file mode 100644
index 0000000..5ef3fed
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013103decoder.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+final class AI013103decoder extends AI013x0xDecoder {
+
+ AI013103decoder(BitArray information) {
+ super(information);
+ }
+
+ protected void addWeightCode(StringBuffer buf, int weight) {
+ buf.append("(3103)");
+ }
+
+ protected int checkWeight(int weight) {
+ return weight;
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01320xDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01320xDecoder.java
new file mode 100644
index 0000000..1fd7c0e
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01320xDecoder.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+final class AI01320xDecoder extends AI013x0xDecoder {
+
+ AI01320xDecoder(BitArray information) {
+ super(information);
+ }
+
+ protected void addWeightCode(StringBuffer buf, int weight) {
+ if (weight < 10000) {
+ buf.append("(3202)");
+ } else {
+ buf.append("(3203)");
+ }
+ }
+
+ protected int checkWeight(int weight) {
+ if(weight < 10000) {
+ return weight;
+ }
+ return weight - 10000;
+ }
+
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01392xDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01392xDecoder.java
new file mode 100644
index 0000000..e618d81
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01392xDecoder.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+final class AI01392xDecoder extends AI01decoder {
+
+ private static final int headerSize = 5 + 1 + 2;
+ private static final int lastDigitSize = 2;
+
+ AI01392xDecoder(BitArray information) {
+ super(information);
+ }
+
+ public String parseInformation() throws NotFoundException {
+ if (this.information.size < headerSize + gtinSize) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ StringBuffer buf = new StringBuffer();
+
+ encodeCompressedGtin(buf, headerSize);
+
+ int lastAIdigit =
+ this.generalDecoder.extractNumericValueFromBitArray(headerSize + gtinSize, lastDigitSize);
+ buf.append("(392");
+ buf.append(lastAIdigit);
+ buf.append(')');
+
+ DecodedInformation decodedInformation =
+ this.generalDecoder.decodeGeneralPurposeField(headerSize + gtinSize + lastDigitSize, null);
+ buf.append(decodedInformation.getNewString());
+
+ return buf.toString();
+ }
+
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01393xDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01393xDecoder.java
new file mode 100644
index 0000000..67db980
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01393xDecoder.java
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+final class AI01393xDecoder extends AI01decoder {
+
+ private static final int headerSize = 5 + 1 + 2;
+ private static final int lastDigitSize = 2;
+ private static final int firstThreeDigitsSize = 10;
+
+ AI01393xDecoder(BitArray information) {
+ super(information);
+ }
+
+ public String parseInformation() throws NotFoundException {
+ if(this.information.size < headerSize + gtinSize) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ StringBuffer buf = new StringBuffer();
+
+ encodeCompressedGtin(buf, headerSize);
+
+ int lastAIdigit =
+ this.generalDecoder.extractNumericValueFromBitArray(headerSize + gtinSize, lastDigitSize);
+
+ buf.append("(393");
+ buf.append(lastAIdigit);
+ buf.append(')');
+
+ int firstThreeDigits =
+ this.generalDecoder.extractNumericValueFromBitArray(headerSize + gtinSize + lastDigitSize, firstThreeDigitsSize);
+ if(firstThreeDigits / 100 == 0) {
+ buf.append('0');
+ }
+ if(firstThreeDigits / 10 == 0) {
+ buf.append('0');
+ }
+ buf.append(firstThreeDigits);
+
+ DecodedInformation generalInformation =
+ this.generalDecoder.decodeGeneralPurposeField(headerSize + gtinSize + lastDigitSize + firstThreeDigitsSize, null);
+ buf.append(generalInformation.getNewString());
+
+ return buf.toString();
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013x0x1xDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013x0x1xDecoder.java
new file mode 100644
index 0000000..0c373c3
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013x0x1xDecoder.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class AI013x0x1xDecoder extends AI01weightDecoder {
+
+ private static final int headerSize = 7 + 1;
+ private static final int weightSize = 20;
+ private static final int dateSize = 16;
+
+ private final String dateCode;
+ private final String firstAIdigits;
+
+ AI013x0x1xDecoder(BitArray information, String firstAIdigits, String dateCode) {
+ super(information);
+ this.dateCode = dateCode;
+ this.firstAIdigits = firstAIdigits;
+ }
+
+ public String parseInformation() throws NotFoundException {
+ if (this.information.size != headerSize + gtinSize + weightSize + dateSize) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ StringBuffer buf = new StringBuffer();
+
+ encodeCompressedGtin(buf, headerSize);
+ encodeCompressedWeight(buf, headerSize + gtinSize, weightSize);
+ encodeCompressedDate(buf, headerSize + gtinSize + weightSize);
+
+ return buf.toString();
+ }
+
+ private void encodeCompressedDate(StringBuffer buf, int currentPos) {
+ int numericDate = this.generalDecoder.extractNumericValueFromBitArray(currentPos, dateSize);
+ if(numericDate == 38400) {
+ return;
+ }
+
+ buf.append('(');
+ buf.append(this.dateCode);
+ buf.append(')');
+
+ int day = numericDate % 32;
+ numericDate /= 32;
+ int month = numericDate % 12 + 1;
+ numericDate /= 12;
+ int year = numericDate;
+
+ if (year / 10 == 0) {
+ buf.append('0');
+ }
+ buf.append(year);
+ if (month / 10 == 0) {
+ buf.append('0');
+ }
+ buf.append(month);
+ if (day / 10 == 0) {
+ buf.append('0');
+ }
+ buf.append(day);
+ }
+
+ protected void addWeightCode(StringBuffer buf, int weight) {
+ int lastAI = weight / 100000;
+ buf.append('(');
+ buf.append(this.firstAIdigits);
+ buf.append(lastAI);
+ buf.append(')');
+ }
+
+ protected int checkWeight(int weight) {
+ return weight % 100000;
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013x0xDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013x0xDecoder.java
new file mode 100644
index 0000000..96bdaff
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI013x0xDecoder.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+abstract class AI013x0xDecoder extends AI01weightDecoder {
+
+ private static final int headerSize = 4 + 1;
+ private static final int weightSize = 15;
+
+ AI013x0xDecoder(BitArray information) {
+ super(information);
+ }
+
+ public String parseInformation() throws NotFoundException {
+ if (this.information.size != headerSize + gtinSize + weightSize) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ StringBuffer buf = new StringBuffer();
+
+ encodeCompressedGtin(buf, headerSize);
+ encodeCompressedWeight(buf, headerSize + gtinSize, weightSize);
+
+ return buf.toString();
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01AndOtherAIs.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01AndOtherAIs.java
new file mode 100644
index 0000000..49f109b
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01AndOtherAIs.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class AI01AndOtherAIs extends AI01decoder {
+
+ private static final int HEADER_SIZE = 1 + 1 + 2; //first bit encodes the linkage flag,
+ //the second one is the encodation method, and the other two are for the variable length
+ AI01AndOtherAIs(BitArray information) {
+ super(information);
+ }
+
+ public String parseInformation() throws NotFoundException {
+ StringBuffer buff = new StringBuffer();
+
+ buff.append("(01)");
+ int initialGtinPosition = buff.length();
+ int firstGtinDigit = this.generalDecoder.extractNumericValueFromBitArray(HEADER_SIZE, 4);
+ buff.append(firstGtinDigit);
+
+ this.encodeCompressedGtinWithoutAI(buff, HEADER_SIZE + 4, initialGtinPosition);
+
+ return this.generalDecoder.decodeAllCodes(buff, HEADER_SIZE + 44);
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01decoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01decoder.java
new file mode 100644
index 0000000..62f878b
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01decoder.java
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+abstract class AI01decoder extends AbstractExpandedDecoder {
+
+ protected static final int gtinSize = 40;
+
+ AI01decoder(BitArray information) {
+ super(information);
+ }
+
+ protected void encodeCompressedGtin(StringBuffer buf, int currentPos) {
+ buf.append("(01)");
+ int initialPosition = buf.length();
+ buf.append('9');
+
+ encodeCompressedGtinWithoutAI(buf, currentPos, initialPosition);
+ }
+
+ protected void encodeCompressedGtinWithoutAI(StringBuffer buf, int currentPos, int initialBufferPosition) {
+ for(int i = 0; i < 4; ++i){
+ int currentBlock = this.generalDecoder.extractNumericValueFromBitArray(currentPos + 10 * i, 10);
+ if (currentBlock / 100 == 0) {
+ buf.append('0');
+ }
+ if (currentBlock / 10 == 0) {
+ buf.append('0');
+ }
+ buf.append(currentBlock);
+ }
+
+ appendCheckDigit(buf, initialBufferPosition);
+ }
+
+ private static void appendCheckDigit(StringBuffer buf, int currentPos){
+ int checkDigit = 0;
+ for (int i = 0; i < 13; i++) {
+ int digit = buf.charAt(i + currentPos) - '0';
+ checkDigit += (((i & 0x01) == 0) ? 3 * digit : digit);
+ }
+
+ checkDigit = 10 - (checkDigit % 10);
+ if (checkDigit == 10) {
+ checkDigit = 0;
+ }
+
+ buf.append(checkDigit);
+ }
+
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01weightDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01weightDecoder.java
new file mode 100644
index 0000000..f120cc0
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AI01weightDecoder.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+abstract class AI01weightDecoder extends AI01decoder {
+
+ AI01weightDecoder(BitArray information) {
+ super(information);
+ }
+
+ protected void encodeCompressedWeight(StringBuffer buf, int currentPos, int weightSize) {
+ int originalWeightNumeric = this.generalDecoder.extractNumericValueFromBitArray(currentPos, weightSize);
+ addWeightCode(buf, originalWeightNumeric);
+
+ int weightNumeric = checkWeight(originalWeightNumeric);
+
+ int currentDivisor = 100000;
+ for(int i = 0; i < 5; ++i){
+ if (weightNumeric / currentDivisor == 0) {
+ buf.append('0');
+ }
+ currentDivisor /= 10;
+ }
+ buf.append(weightNumeric);
+ }
+
+ protected abstract void addWeightCode(StringBuffer buf, int weight);
+ protected abstract int checkWeight(int weight);
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AbstractExpandedDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AbstractExpandedDecoder.java
new file mode 100644
index 0000000..84fae37
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AbstractExpandedDecoder.java
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public abstract class AbstractExpandedDecoder {
+
+ protected final BitArray information;
+ protected final GeneralAppIdDecoder generalDecoder;
+
+ AbstractExpandedDecoder(BitArray information){
+ this.information = information;
+ this.generalDecoder = new GeneralAppIdDecoder(information);
+ }
+
+ public abstract String parseInformation() throws NotFoundException;
+
+ public static AbstractExpandedDecoder createDecoder(BitArray information){
+ if (information.get(1)) {
+ return new AI01AndOtherAIs(information);
+ } else if (!information.get(2)) {
+ return new AnyAIDecoder(information);
+ }
+
+ int fourBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 4);
+
+ switch(fourBitEncodationMethod){
+ case 4: return new AI013103decoder(information);
+ case 5: return new AI01320xDecoder(information);
+ }
+
+ int fiveBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 5);
+ switch(fiveBitEncodationMethod){
+ case 12: return new AI01392xDecoder(information);
+ case 13: return new AI01393xDecoder(information);
+ }
+
+ int sevenBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 7);
+ switch(sevenBitEncodationMethod){
+ case 56: return new AI013x0x1xDecoder(information, "310", "11");
+ case 57: return new AI013x0x1xDecoder(information, "320", "11");
+ case 58: return new AI013x0x1xDecoder(information, "310", "13");
+ case 59: return new AI013x0x1xDecoder(information, "320", "13");
+ case 60: return new AI013x0x1xDecoder(information, "310", "15");
+ case 61: return new AI013x0x1xDecoder(information, "320", "15");
+ case 62: return new AI013x0x1xDecoder(information, "310", "17");
+ case 63: return new AI013x0x1xDecoder(information, "320", "17");
+ }
+
+ throw new IllegalStateException("unknown decoder: " + information);
+ }
+
+
+
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoder.java
new file mode 100644
index 0000000..4fcac27
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoder.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class AnyAIDecoder extends AbstractExpandedDecoder {
+
+ private static final int HEADER_SIZE = 2 + 1 + 2;
+
+ AnyAIDecoder(BitArray information) {
+ super(information);
+ }
+
+ public String parseInformation() throws NotFoundException {
+ StringBuffer buf = new StringBuffer();
+ return this.generalDecoder.decodeAllCodes(buf, HEADER_SIZE);
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/BlockParsedResult.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/BlockParsedResult.java
new file mode 100644
index 0000000..132ba55
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/BlockParsedResult.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class BlockParsedResult {
+
+ private final DecodedInformation decodedInformation;
+ private final boolean finished;
+
+ BlockParsedResult() {
+ this.finished = true;
+ this.decodedInformation = null;
+ }
+
+ BlockParsedResult(boolean finished) {
+ this.finished = finished;
+ this.decodedInformation = null;
+ }
+
+ BlockParsedResult(DecodedInformation information, boolean finished) {
+ this.finished = finished;
+ this.decodedInformation = information;
+ }
+
+ DecodedInformation getDecodedInformation() {
+ return this.decodedInformation;
+ }
+
+ boolean isFinished() {
+ return this.finished;
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/CurrentParsingState.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/CurrentParsingState.java
new file mode 100644
index 0000000..cf7d687
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/CurrentParsingState.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+final class CurrentParsingState {
+
+ int position;
+ private int encoding;
+
+ private static final int NUMERIC = 1;
+ private static final int ALPHA = 2;
+ private static final int ISO_IEC_646 = 4;
+
+ CurrentParsingState(){
+ this.position = 0;
+ this.encoding = NUMERIC;
+ }
+
+ boolean isAlpha(){
+ return this.encoding == ALPHA;
+ }
+
+ boolean isNumeric(){
+ return this.encoding == NUMERIC;
+ }
+
+ boolean isIsoIec646(){
+ return this.encoding == ISO_IEC_646;
+ }
+
+ void setNumeric(){
+ this.encoding = NUMERIC;
+ }
+
+ void setAlpha(){
+ this.encoding = ALPHA;
+ }
+
+ void setIsoIec646(){
+ this.encoding = ISO_IEC_646;
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedChar.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedChar.java
new file mode 100644
index 0000000..790b684
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedChar.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class DecodedChar extends DecodedObject {
+
+ private final char value;
+
+ static final char FNC1 = '$'; // It's not in Alphanumeric neither in ISO/IEC 646 charset
+
+ DecodedChar(int newPosition, char value) {
+ super(newPosition);
+ this.value = value;
+ }
+
+ char getValue(){
+ return this.value;
+ }
+
+ boolean isFNC1(){
+ return this.value == FNC1;
+ }
+
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedInformation.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedInformation.java
new file mode 100644
index 0000000..13eec5c
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedInformation.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class DecodedInformation extends DecodedObject {
+ private final String newString;
+ private final int remainingValue;
+ private final boolean remaining;
+
+ DecodedInformation(int newPosition, String newString){
+ super(newPosition);
+ this.newString = newString;
+ this.remaining = false;
+ this.remainingValue = 0;
+ }
+
+ DecodedInformation(int newPosition, String newString, int remainingValue){
+ super(newPosition);
+ this.remaining = true;
+ this.remainingValue = remainingValue;
+ this.newString = newString;
+ }
+
+ String getNewString(){
+ return this.newString;
+ }
+
+ boolean isRemaining(){
+ return this.remaining;
+ }
+
+ int getRemainingValue(){
+ return this.remainingValue;
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedNumeric.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedNumeric.java
new file mode 100644
index 0000000..1b1be42
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedNumeric.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class DecodedNumeric extends DecodedObject {
+
+ private final int firstDigit;
+ private final int secondDigit;
+
+ static final int FNC1 = 10;
+
+ DecodedNumeric(int newPosition, int firstDigit, int secondDigit){
+ super(newPosition);
+
+ this.firstDigit = firstDigit;
+ this.secondDigit = secondDigit;
+
+ if (this.firstDigit < 0 || this.firstDigit > 10) {
+ throw new IllegalArgumentException("Invalid firstDigit: " + firstDigit);
+ }
+
+ if (this.secondDigit < 0 || this.secondDigit > 10) {
+ throw new IllegalArgumentException("Invalid secondDigit: " + secondDigit);
+ }
+ }
+
+ int getFirstDigit(){
+ return this.firstDigit;
+ }
+
+ int getSecondDigit(){
+ return this.secondDigit;
+ }
+
+ int getValue(){
+ return this.firstDigit * 10 + this.secondDigit;
+ }
+
+ boolean isFirstDigitFNC1(){
+ return this.firstDigit == FNC1;
+ }
+
+ boolean isSecondDigitFNC1(){
+ return this.secondDigit == FNC1;
+ }
+
+ boolean isAnyFNC1(){
+ return this.firstDigit == FNC1 || this.secondDigit == FNC1;
+ }
+
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedObject.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedObject.java
new file mode 100644
index 0000000..7547384
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/DecodedObject.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+abstract class DecodedObject {
+
+ protected final int newPosition;
+
+ DecodedObject(int newPosition){
+ this.newPosition = newPosition;
+ }
+
+ int getNewPosition() {
+ return this.newPosition;
+ }
+
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/FieldParser.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/FieldParser.java
new file mode 100644
index 0000000..91c1d49
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/FieldParser.java
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class FieldParser {
+
+ private static final Object VARIABLE_LENGTH = new Object();
+
+ private static final Object [][] TWO_DIGIT_DATA_LENGTH = {
+ // "DIGITS", new Integer(LENGTH)
+ // or
+ // "DIGITS", VARIABLE_LENGTH, new Integer(MAX_SIZE)
+
+ { "00", new Integer(18) },
+ { "01", new Integer(14) },
+ { "02", new Integer(14) },
+
+ { "10", VARIABLE_LENGTH, new Integer(20) },
+ { "11", new Integer(6) },
+ { "12", new Integer(6) },
+ { "13", new Integer(6) },
+ { "15", new Integer(6) },
+ { "17", new Integer(6) },
+
+ { "20", new Integer(2) },
+ { "21", VARIABLE_LENGTH, new Integer(20) },
+ { "22", VARIABLE_LENGTH, new Integer(29) },
+
+ { "30", VARIABLE_LENGTH, new Integer( 8) },
+ { "37", VARIABLE_LENGTH, new Integer( 8) },
+
+ //internal company codes
+ { "90", VARIABLE_LENGTH, new Integer(30) },
+ { "91", VARIABLE_LENGTH, new Integer(30) },
+ { "92", VARIABLE_LENGTH, new Integer(30) },
+ { "93", VARIABLE_LENGTH, new Integer(30) },
+ { "94", VARIABLE_LENGTH, new Integer(30) },
+ { "95", VARIABLE_LENGTH, new Integer(30) },
+ { "96", VARIABLE_LENGTH, new Integer(30) },
+ { "97", VARIABLE_LENGTH, new Integer(30) },
+ { "98", VARIABLE_LENGTH, new Integer(30) },
+ { "99", VARIABLE_LENGTH, new Integer(30) },
+ };
+
+ private static final Object [][] THREE_DIGIT_DATA_LENGTH = {
+ // Same format as above
+
+ { "240", VARIABLE_LENGTH, new Integer(30) },
+ { "241", VARIABLE_LENGTH, new Integer(30) },
+ { "242", VARIABLE_LENGTH, new Integer( 6) },
+ { "250", VARIABLE_LENGTH, new Integer(30) },
+ { "251", VARIABLE_LENGTH, new Integer(30) },
+ { "253", VARIABLE_LENGTH, new Integer(17) },
+ { "254", VARIABLE_LENGTH, new Integer(20) },
+
+ { "400", VARIABLE_LENGTH, new Integer(30) },
+ { "401", VARIABLE_LENGTH, new Integer(30) },
+ { "402", new Integer(17) },
+ { "403", VARIABLE_LENGTH, new Integer(30) },
+ { "410", new Integer(13) },
+ { "411", new Integer(13) },
+ { "412", new Integer(13) },
+ { "413", new Integer(13) },
+ { "414", new Integer(13) },
+ { "420", VARIABLE_LENGTH, new Integer(20) },
+ { "421", VARIABLE_LENGTH, new Integer(15) },
+ { "422", new Integer( 3) },
+ { "423", VARIABLE_LENGTH, new Integer(15) },
+ { "424", new Integer(3) },
+ { "425", new Integer(3) },
+ { "426", new Integer(3) },
+ };
+
+ private static final Object [][] THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH = {
+ // Same format as above
+
+ { "310", new Integer(6) },
+ { "311", new Integer(6) },
+ { "312", new Integer(6) },
+ { "313", new Integer(6) },
+ { "314", new Integer(6) },
+ { "315", new Integer(6) },
+ { "316", new Integer(6) },
+ { "320", new Integer(6) },
+ { "321", new Integer(6) },
+ { "322", new Integer(6) },
+ { "323", new Integer(6) },
+ { "324", new Integer(6) },
+ { "325", new Integer(6) },
+ { "326", new Integer(6) },
+ { "327", new Integer(6) },
+ { "328", new Integer(6) },
+ { "329", new Integer(6) },
+ { "330", new Integer(6) },
+ { "331", new Integer(6) },
+ { "332", new Integer(6) },
+ { "333", new Integer(6) },
+ { "334", new Integer(6) },
+ { "335", new Integer(6) },
+ { "336", new Integer(6) },
+ { "340", new Integer(6) },
+ { "341", new Integer(6) },
+ { "342", new Integer(6) },
+ { "343", new Integer(6) },
+ { "344", new Integer(6) },
+ { "345", new Integer(6) },
+ { "346", new Integer(6) },
+ { "347", new Integer(6) },
+ { "348", new Integer(6) },
+ { "349", new Integer(6) },
+ { "350", new Integer(6) },
+ { "351", new Integer(6) },
+ { "352", new Integer(6) },
+ { "353", new Integer(6) },
+ { "354", new Integer(6) },
+ { "355", new Integer(6) },
+ { "356", new Integer(6) },
+ { "357", new Integer(6) },
+ { "360", new Integer(6) },
+ { "361", new Integer(6) },
+ { "362", new Integer(6) },
+ { "363", new Integer(6) },
+ { "364", new Integer(6) },
+ { "365", new Integer(6) },
+ { "366", new Integer(6) },
+ { "367", new Integer(6) },
+ { "368", new Integer(6) },
+ { "369", new Integer(6) },
+ { "390", VARIABLE_LENGTH, new Integer(15) },
+ { "391", VARIABLE_LENGTH, new Integer(18) },
+ { "392", VARIABLE_LENGTH, new Integer(15) },
+ { "393", VARIABLE_LENGTH, new Integer(18) },
+ { "703", VARIABLE_LENGTH, new Integer(30) }
+ };
+
+ private static final Object [][] FOUR_DIGIT_DATA_LENGTH = {
+ // Same format as above
+
+ { "7001", new Integer(13) },
+ { "7002", VARIABLE_LENGTH, new Integer(30) },
+ { "7003", new Integer(10) },
+
+ { "8001", new Integer(14) },
+ { "8002", VARIABLE_LENGTH, new Integer(20) },
+ { "8003", VARIABLE_LENGTH, new Integer(30) },
+ { "8004", VARIABLE_LENGTH, new Integer(30) },
+ { "8005", new Integer(6) },
+ { "8006", new Integer(18) },
+ { "8007", VARIABLE_LENGTH, new Integer(30) },
+ { "8008", VARIABLE_LENGTH, new Integer(12) },
+ { "8018", new Integer(18) },
+ { "8020", VARIABLE_LENGTH, new Integer(25) },
+ { "8100", new Integer(6) },
+ { "8101", new Integer(10) },
+ { "8102", new Integer(2) },
+ { "8110", VARIABLE_LENGTH, new Integer(30) },
+ };
+
+ private FieldParser() {
+ }
+
+ static String parseFieldsInGeneralPurpose(String rawInformation) throws NotFoundException{
+ if(rawInformation.length() == 0) {
+ return "";
+ }
+
+ // Processing 2-digit AIs
+
+ if(rawInformation.length() < 2) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ String firstTwoDigits = rawInformation.substring(0, 2);
+
+ for (int i=0; i<TWO_DIGIT_DATA_LENGTH.length; ++i){
+ if (TWO_DIGIT_DATA_LENGTH[i][0].equals(firstTwoDigits)){
+ if(TWO_DIGIT_DATA_LENGTH[i][1] == VARIABLE_LENGTH) {
+ return processVariableAI(2, ((Integer) TWO_DIGIT_DATA_LENGTH[i][2]).intValue(), rawInformation);
+ }
+ return processFixedAI(2, ((Integer)TWO_DIGIT_DATA_LENGTH[i][1]).intValue(), rawInformation);
+ }
+ }
+
+ if(rawInformation.length() < 3) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ String firstThreeDigits = rawInformation.substring(0, 3);
+
+ for (int i=0; i<THREE_DIGIT_DATA_LENGTH.length; ++i){
+ if (THREE_DIGIT_DATA_LENGTH[i][0].equals(firstThreeDigits)){
+ if (THREE_DIGIT_DATA_LENGTH[i][1] == VARIABLE_LENGTH) {
+ return processVariableAI(3, ((Integer) THREE_DIGIT_DATA_LENGTH[i][2]).intValue(), rawInformation);
+ }
+ return processFixedAI(3, ((Integer)THREE_DIGIT_DATA_LENGTH[i][1]).intValue(), rawInformation);
+ }
+ }
+
+
+ for (int i=0; i<THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.length; ++i){
+ if (THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][0].equals(firstThreeDigits)){
+ if (THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][1] == VARIABLE_LENGTH) {
+ return processVariableAI(4, ((Integer) THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][2]).intValue(), rawInformation);
+ }
+ return processFixedAI(4, ((Integer)THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][1]).intValue(), rawInformation);
+ }
+ }
+
+ if(rawInformation.length() < 4) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ String firstFourDigits = rawInformation.substring(0, 4);
+
+ for (int i=0; i<FOUR_DIGIT_DATA_LENGTH.length; ++i){
+ if (FOUR_DIGIT_DATA_LENGTH[i][0].equals(firstFourDigits)){
+ if (FOUR_DIGIT_DATA_LENGTH[i][1] == VARIABLE_LENGTH) {
+ return processVariableAI(4, ((Integer) FOUR_DIGIT_DATA_LENGTH[i][2]).intValue(), rawInformation);
+ }
+ return processFixedAI(4, ((Integer)FOUR_DIGIT_DATA_LENGTH[i][1]).intValue(), rawInformation);
+ }
+ }
+
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ private static String processFixedAI(int aiSize, int fieldSize, String rawInformation) throws NotFoundException{
+ if (rawInformation.length() < aiSize) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ String ai = rawInformation.substring(0, aiSize);
+
+ if(rawInformation.length() < aiSize + fieldSize) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ String field = rawInformation.substring(aiSize, aiSize + fieldSize);
+ String remaining = rawInformation.substring(aiSize + fieldSize);
+ return '(' + ai + ')' + field + parseFieldsInGeneralPurpose(remaining);
+ }
+
+ private static String processVariableAI(int aiSize, int variableFieldSize, String rawInformation) throws NotFoundException {
+ String ai = rawInformation.substring(0, aiSize);
+ int maxSize;
+ if (rawInformation.length() < aiSize + variableFieldSize) {
+ maxSize = rawInformation.length();
+ } else {
+ maxSize = aiSize + variableFieldSize;
+ }
+ String field = rawInformation.substring(aiSize, maxSize);
+ String remaining = rawInformation.substring(maxSize);
+ return '(' + ai + ')' + field + parseFieldsInGeneralPurpose(remaining);
+ }
+}
diff --git a/core/src/com/google/zxing/oned/rss/expanded/decoders/GeneralAppIdDecoder.java b/core/src/com/google/zxing/oned/rss/expanded/decoders/GeneralAppIdDecoder.java
new file mode 100644
index 0000000..821fbc4
--- /dev/null
+++ b/core/src/com/google/zxing/oned/rss/expanded/decoders/GeneralAppIdDecoder.java
@@ -0,0 +1,414 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+final class GeneralAppIdDecoder {
+
+ private final BitArray information;
+ private final CurrentParsingState current = new CurrentParsingState();
+ private final StringBuffer buffer = new StringBuffer();
+
+ GeneralAppIdDecoder(BitArray information){
+ this.information = information;
+ }
+
+ String decodeAllCodes(StringBuffer buff, int initialPosition) throws NotFoundException {
+ int currentPosition = initialPosition;
+ String remaining = null;
+ do{
+ DecodedInformation info = this.decodeGeneralPurposeField(currentPosition, remaining);
+ String parsedFields = FieldParser.parseFieldsInGeneralPurpose(info.getNewString());
+ buff.append(parsedFields);
+ if(info.isRemaining()) {
+ remaining = String.valueOf(info.getRemainingValue());
+ } else {
+ remaining = null;
+ }
+
+ if(currentPosition == info.getNewPosition()) {// No step forward!
+ break;
+ }
+ currentPosition = info.getNewPosition();
+ }while(true);
+
+ return buff.toString();
+ }
+
+ private boolean isStillNumeric(int pos) {
+ // It's numeric if it still has 7 positions
+ // and one of the first 4 bits is "1".
+ if(pos + 7 > this.information.size){
+ return pos + 4 <= this.information.size;
+ }
+
+ for(int i = pos; i < pos + 3; ++i) {
+ if (this.information.get(i)) {
+ return true;
+ }
+ }
+
+ return this.information.get(pos + 3);
+ }
+
+ private DecodedNumeric decodeNumeric(int pos) {
+ if(pos + 7 > this.information.size){
+ int numeric = extractNumericValueFromBitArray(pos, 4);
+ if(numeric == 0) {
+ return new DecodedNumeric(this.information.size, DecodedNumeric.FNC1, DecodedNumeric.FNC1);
+ }
+ return new DecodedNumeric(this.information.size, numeric - 1, DecodedNumeric.FNC1);
+ }
+ int numeric = extractNumericValueFromBitArray(pos, 7);
+
+ int digit1 = (numeric - 8) / 11;
+ int digit2 = (numeric - 8) % 11;
+
+ return new DecodedNumeric(pos + 7, digit1, digit2);
+ }
+
+ int extractNumericValueFromBitArray(int pos, int bits){
+ return extractNumericValueFromBitArray(this.information, pos, bits);
+ }
+
+ static int extractNumericValueFromBitArray(BitArray information, int pos, int bits) {
+ if(bits > 32) {
+ throw new IllegalArgumentException("extractNumberValueFromBitArray can't handle more than 32 bits");
+ }
+
+ int value = 0;
+ for(int i = 0; i < bits; ++i) {
+ if (information.get(pos + i)) {
+ value |= (1 << (bits - i - 1));
+ }
+ }
+
+ return value;
+ }
+
+ DecodedInformation decodeGeneralPurposeField(int pos, String remaining) {
+ this.buffer.setLength(0);
+
+ if(remaining != null) {
+ this.buffer.append(remaining);
+ }
+
+ this.current.position = pos;
+
+ DecodedInformation lastDecoded = parseBlocks();
+ if(lastDecoded != null && lastDecoded.isRemaining()) {
+ return new DecodedInformation(this.current.position, this.buffer.toString(), lastDecoded.getRemainingValue());
+ }
+ return new DecodedInformation(this.current.position, this.buffer.toString());
+ }
+
+ private DecodedInformation parseBlocks() {
+ boolean isFinished;
+ BlockParsedResult result;
+ do{
+ int initialPosition = current.position;
+
+ if (current.isAlpha()){
+ result = parseAlphaBlock();
+ isFinished = result.isFinished();
+ }else if (current.isIsoIec646()){
+ result = parseIsoIec646Block();
+ isFinished = result.isFinished();
+ }else{ // it must be numeric
+ result = parseNumericBlock();
+ isFinished = result.isFinished();
+ }
+
+ boolean positionChanged = initialPosition != current.position;
+ if(!positionChanged && !isFinished) {
+ break;
+ }
+ } while (!isFinished);
+
+ return result.getDecodedInformation();
+ }
+
+ private BlockParsedResult parseNumericBlock() {
+ while(isStillNumeric(current.position)){
+ DecodedNumeric numeric = decodeNumeric(current.position);
+ current.position = numeric.getNewPosition();
+
+ if(numeric.isFirstDigitFNC1()){
+ DecodedInformation information;
+ if (numeric.isSecondDigitFNC1()) {
+ information = new DecodedInformation(current.position, buffer.toString());
+ } else {
+ information = new DecodedInformation(current.position, buffer.toString(), numeric.getSecondDigit());
+ }
+ return new BlockParsedResult(information, true);
+ }
+ buffer.append(numeric.getFirstDigit());
+
+ if(numeric.isSecondDigitFNC1()){
+ DecodedInformation information = new DecodedInformation(current.position, buffer.toString());
+ return new BlockParsedResult(information, true);
+ }
+ buffer.append(numeric.getSecondDigit());
+ }
+
+ if(isNumericToAlphaNumericLatch(current.position)){
+ current.setAlpha();
+ current.position += 4;
+ }
+ return new BlockParsedResult(false);
+ }
+
+ private BlockParsedResult parseIsoIec646Block() {
+ while (isStillIsoIec646(current.position)) {
+ DecodedChar iso = decodeIsoIec646(current.position);
+ current.position = iso.getNewPosition();
+
+ if (iso.isFNC1()) {
+ DecodedInformation information = new DecodedInformation(current.position, buffer.toString());
+ return new BlockParsedResult(information, true);
+ }
+ buffer.append(iso.getValue());
+ }
+
+ if (isAlphaOr646ToNumericLatch(current.position)) {
+ current.position += 3;
+ current.setNumeric();
+ } else if (isAlphaTo646ToAlphaLatch(current.position)) {
+ if (current.position + 5 < this.information.size) {
+ current.position += 5;
+ } else {
+ current.position = this.information.size;
+ }
+
+ current.setAlpha();
+ }
+ return new BlockParsedResult(false);
+ }
+
+ private BlockParsedResult parseAlphaBlock() {
+ while (isStillAlpha(current.position)) {
+ DecodedChar alpha = decodeAlphanumeric(current.position);
+ current.position = alpha.getNewPosition();
+
+ if(alpha.isFNC1()) {
+ DecodedInformation information = new DecodedInformation(current.position, buffer.toString());
+ return new BlockParsedResult(information, true); //end of the char block
+ }
+
+ buffer.append(alpha.getValue());
+ }
+
+ if (isAlphaOr646ToNumericLatch(current.position)) {
+ current.position += 3;
+ current.setNumeric();
+ } else if (isAlphaTo646ToAlphaLatch(current.position)) {
+ if (current.position + 5 < this.information.size) {
+ current.position += 5;
+ } else {
+ current.position = this.information.size;
+ }
+
+ current.setIsoIec646();
+ }
+ return new BlockParsedResult(false);
+ }
+
+ private boolean isStillIsoIec646(int pos) {
+ if(pos + 5 > this.information.size) {
+ return false;
+ }
+
+ int fiveBitValue = extractNumericValueFromBitArray(pos, 5);
+ if(fiveBitValue >= 5 && fiveBitValue < 16) {
+ return true;
+ }
+
+ if(pos + 7 > this.information.size) {
+ return false;
+ }
+
+ int sevenBitValue = extractNumericValueFromBitArray(pos, 7);
+ if(sevenBitValue >= 64 && sevenBitValue < 116) {
+ return true;
+ }
+
+ if(pos + 8 > this.information.size) {
+ return false;
+ }
+
+ int eightBitValue = extractNumericValueFromBitArray(pos, 8);
+ return eightBitValue >= 232 && eightBitValue < 253;
+
+ }
+
+ private DecodedChar decodeIsoIec646(int pos) {
+ int fiveBitValue = extractNumericValueFromBitArray(pos, 5);
+ if(fiveBitValue == 15) {
+ return new DecodedChar(pos + 5, DecodedChar.FNC1);
+ }
+
+ if(fiveBitValue >= 5 && fiveBitValue < 15) {
+ return new DecodedChar(pos + 5, (char) ('0' + fiveBitValue - 5));
+ }
+
+ int sevenBitValue = extractNumericValueFromBitArray(pos, 7);
+
+ if(sevenBitValue >= 64 && sevenBitValue < 90) {
+ return new DecodedChar(pos + 7, (char) (sevenBitValue + 1));
+ }
+
+ if(sevenBitValue >= 90 && sevenBitValue < 116) {
+ return new DecodedChar(pos + 7, (char) (sevenBitValue + 7));
+ }
+
+ int eightBitValue = extractNumericValueFromBitArray(pos, 8);
+ switch (eightBitValue){
+ case 232: return new DecodedChar(pos + 8, '!');
+ case 233: return new DecodedChar(pos + 8, '"');
+ case 234: return new DecodedChar(pos + 8, '%');
+ case 235: return new DecodedChar(pos + 8, '&');
+ case 236: return new DecodedChar(pos + 8, '\'');
+ case 237: return new DecodedChar(pos + 8, '(');
+ case 238: return new DecodedChar(pos + 8, ')');
+ case 239: return new DecodedChar(pos + 8, '*');
+ case 240: return new DecodedChar(pos + 8, '+');
+ case 241: return new DecodedChar(pos + 8, ',');
+ case 242: return new DecodedChar(pos + 8, '-');
+ case 243: return new DecodedChar(pos + 8, '.');
+ case 244: return new DecodedChar(pos + 8, '/');
+ case 245: return new DecodedChar(pos + 8, ':');
+ case 246: return new DecodedChar(pos + 8, ';');
+ case 247: return new DecodedChar(pos + 8, '<');
+ case 248: return new DecodedChar(pos + 8, '=');
+ case 249: return new DecodedChar(pos + 8, '>');
+ case 250: return new DecodedChar(pos + 8, '?');
+ case 251: return new DecodedChar(pos + 8, '_');
+ case 252: return new DecodedChar(pos + 8, ' ');
+ }
+
+ throw new RuntimeException("Decoding invalid ISO/IEC 646 value: " + eightBitValue);
+ }
+
+ private boolean isStillAlpha(int pos) {
+ if(pos + 5 > this.information.size) {
+ return false;
+ }
+
+ // We now check if it's a valid 5-bit value (0..9 and FNC1)
+ int fiveBitValue = extractNumericValueFromBitArray(pos, 5);
+ if(fiveBitValue >= 5 && fiveBitValue < 16) {
+ return true;
+ }
+
+ if(pos + 6 > this.information.size) {
+ return false;
+ }
+
+ int sixBitValue = extractNumericValueFromBitArray(pos, 6);
+ return sixBitValue >= 16 && sixBitValue < 63; // 63 not included
+ }
+
+ private DecodedChar decodeAlphanumeric(int pos) {
+ int fiveBitValue = extractNumericValueFromBitArray(pos, 5);
+ if(fiveBitValue == 15) {
+ return new DecodedChar(pos + 5, DecodedChar.FNC1);
+ }
+
+ if(fiveBitValue >= 5 && fiveBitValue < 15) {
+ return new DecodedChar(pos + 5, (char) ('0' + fiveBitValue - 5));
+ }
+
+ int sixBitValue = extractNumericValueFromBitArray(pos, 6);
+
+ if(sixBitValue >= 32 && sixBitValue < 58) {
+ return new DecodedChar(pos + 6, (char) (sixBitValue + 33));
+ }
+
+ switch(sixBitValue){
+ case 58: return new DecodedChar(pos + 6, '*');
+ case 59: return new DecodedChar(pos + 6, ',');
+ case 60: return new DecodedChar(pos + 6, '-');
+ case 61: return new DecodedChar(pos + 6, '.');
+ case 62: return new DecodedChar(pos + 6, '/');
+ }
+
+ throw new RuntimeException("Decoding invalid alphanumeric value: " + sixBitValue);
+ }
+
+ private boolean isAlphaTo646ToAlphaLatch(int pos) {
+ if(pos + 1 > this.information.size) {
+ return false;
+ }
+
+ for(int i = 0; i < 5 && i + pos < this.information.size; ++i){
+ if(i == 2){
+ if(!this.information.get(pos + 2)) {
+ return false;
+ }
+ } else if(this.information.get(pos + i)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean isAlphaOr646ToNumericLatch(int pos) {
+ // Next is alphanumeric if there are 3 positions and they are all zeros
+ if (pos + 3 > this.information.size) {
+ return false;
+ }
+
+ for (int i = pos; i < pos + 3; ++i) {
+ if (this.information.get(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean isNumericToAlphaNumericLatch(int pos) {
+ // Next is alphanumeric if there are 4 positions and they are all zeros, or
+ // if there is a subset of this just before the end of the symbol
+ if (pos + 1 > this.information.size) {
+ return false;
+ }
+
+ for (int i = 0; i < 4 && i + pos < this.information.size; ++i) {
+ if (this.information.get(pos + i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/core/test/data/blackbox/rssexpanded-1/1.jpg b/core/test/data/blackbox/rssexpanded-1/1.jpg
new file mode 100644
index 0000000..3978c7f
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/1.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/1.txt b/core/test/data/blackbox/rssexpanded-1/1.txt
new file mode 100644
index 0000000..8b369b3
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/1.txt
@@ -0,0 +1 @@
+(11)100224(17)110224(3102)000100
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/10.png b/core/test/data/blackbox/rssexpanded-1/10.png
new file mode 100644
index 0000000..4c290bc
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/10.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/10.txt b/core/test/data/blackbox/rssexpanded-1/10.txt
new file mode 100644
index 0000000..09d4208
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/10.txt
@@ -0,0 +1 @@
+(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/11.png b/core/test/data/blackbox/rssexpanded-1/11.png
new file mode 100644
index 0000000..39a67ce
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/11.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/11.txt b/core/test/data/blackbox/rssexpanded-1/11.txt
new file mode 100644
index 0000000..abe2a81
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/11.txt
@@ -0,0 +1 @@
+(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/12.jpg b/core/test/data/blackbox/rssexpanded-1/12.jpg
new file mode 100644
index 0000000..4d0eeef
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/12.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/12.txt b/core/test/data/blackbox/rssexpanded-1/12.txt
new file mode 100644
index 0000000..32ad2da
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/12.txt
@@ -0,0 +1 @@
+(01)98898765432106(3103)001750
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/13.png b/core/test/data/blackbox/rssexpanded-1/13.png
new file mode 100644
index 0000000..5efd2c7
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/13.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/13.txt b/core/test/data/blackbox/rssexpanded-1/13.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/13.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/14.png b/core/test/data/blackbox/rssexpanded-1/14.png
new file mode 100644
index 0000000..1f5ad05
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/14.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/14.txt b/core/test/data/blackbox/rssexpanded-1/14.txt
new file mode 100644
index 0000000..fb00e31
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/14.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)0401234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/15.jpg b/core/test/data/blackbox/rssexpanded-1/15.jpg
new file mode 100644
index 0000000..e7c7550
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/15.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/15.txt b/core/test/data/blackbox/rssexpanded-1/15.txt
new file mode 100644
index 0000000..f2bfc4b
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/15.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(11)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/16.jpg b/core/test/data/blackbox/rssexpanded-1/16.jpg
new file mode 100644
index 0000000..11c21b2
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/16.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/16.txt b/core/test/data/blackbox/rssexpanded-1/16.txt
new file mode 100644
index 0000000..c9f248d
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/16.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(11)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/17.jpg b/core/test/data/blackbox/rssexpanded-1/17.jpg
new file mode 100644
index 0000000..4a29b41
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/17.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/17.txt b/core/test/data/blackbox/rssexpanded-1/17.txt
new file mode 100644
index 0000000..9b4fc49
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/17.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(13)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/18.jpg b/core/test/data/blackbox/rssexpanded-1/18.jpg
new file mode 100644
index 0000000..8fc343f
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/18.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/18.txt b/core/test/data/blackbox/rssexpanded-1/18.txt
new file mode 100644
index 0000000..cd15aa0
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/18.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(13)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/19.jpg b/core/test/data/blackbox/rssexpanded-1/19.jpg
new file mode 100644
index 0000000..0e823bd
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/19.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/19.txt b/core/test/data/blackbox/rssexpanded-1/19.txt
new file mode 100644
index 0000000..dcd1561
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/19.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(15)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/2.jpg b/core/test/data/blackbox/rssexpanded-1/2.jpg
new file mode 100644
index 0000000..693dd77
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/2.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/2.txt b/core/test/data/blackbox/rssexpanded-1/2.txt
new file mode 100644
index 0000000..b4113ac
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/2.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)001750
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/20.jpg b/core/test/data/blackbox/rssexpanded-1/20.jpg
new file mode 100644
index 0000000..eb96e4e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/20.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/20.txt b/core/test/data/blackbox/rssexpanded-1/20.txt
new file mode 100644
index 0000000..830845f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/20.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(15)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/21.jpg b/core/test/data/blackbox/rssexpanded-1/21.jpg
new file mode 100644
index 0000000..4901903
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/21.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/21.txt b/core/test/data/blackbox/rssexpanded-1/21.txt
new file mode 100644
index 0000000..506b17b
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/21.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(17)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/22.jpg b/core/test/data/blackbox/rssexpanded-1/22.jpg
new file mode 100644
index 0000000..6ec7052
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/22.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/22.txt b/core/test/data/blackbox/rssexpanded-1/22.txt
new file mode 100644
index 0000000..ca6045a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/22.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(17)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/23.png b/core/test/data/blackbox/rssexpanded-1/23.png
new file mode 100644
index 0000000..8919afa
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/23.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/23.txt b/core/test/data/blackbox/rssexpanded-1/23.txt
new file mode 100644
index 0000000..a6f7e24
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/23.txt
@@ -0,0 +1 @@
+(10)56789(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/24.png b/core/test/data/blackbox/rssexpanded-1/24.png
new file mode 100644
index 0000000..aabea10
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/24.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/24.txt b/core/test/data/blackbox/rssexpanded-1/24.txt
new file mode 100644
index 0000000..a7b3497
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/24.txt
@@ -0,0 +1 @@
+(10)567890(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/25.png b/core/test/data/blackbox/rssexpanded-1/25.png
new file mode 100644
index 0000000..cd52c3d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/25.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/25.txt b/core/test/data/blackbox/rssexpanded-1/25.txt
new file mode 100644
index 0000000..62c17f1
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/25.txt
@@ -0,0 +1 @@
+(10)123
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/26.png b/core/test/data/blackbox/rssexpanded-1/26.png
new file mode 100644
index 0000000..40f069c
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/26.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/26.txt b/core/test/data/blackbox/rssexpanded-1/26.txt
new file mode 100644
index 0000000..17966ee
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/26.txt
@@ -0,0 +1 @@
+(10)5678(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/27.png b/core/test/data/blackbox/rssexpanded-1/27.png
new file mode 100644
index 0000000..a541ca2
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/27.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/27.txt b/core/test/data/blackbox/rssexpanded-1/27.txt
new file mode 100644
index 0000000..5263f7f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/27.txt
@@ -0,0 +1 @@
+(10)1098-1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/28.png b/core/test/data/blackbox/rssexpanded-1/28.png
new file mode 100644
index 0000000..d03f073
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/28.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/28.txt b/core/test/data/blackbox/rssexpanded-1/28.txt
new file mode 100644
index 0000000..9208d92
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/28.txt
@@ -0,0 +1 @@
+(10)1098/1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/29.png b/core/test/data/blackbox/rssexpanded-1/29.png
new file mode 100644
index 0000000..9467691
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/29.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/29.txt b/core/test/data/blackbox/rssexpanded-1/29.txt
new file mode 100644
index 0000000..b78623a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/29.txt
@@ -0,0 +1 @@
+(10)1098.1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/3.jpg b/core/test/data/blackbox/rssexpanded-1/3.jpg
new file mode 100644
index 0000000..ce50ee5
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/3.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/3.txt b/core/test/data/blackbox/rssexpanded-1/3.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/3.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/30.png b/core/test/data/blackbox/rssexpanded-1/30.png
new file mode 100644
index 0000000..5468dc9
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/30.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/30.txt b/core/test/data/blackbox/rssexpanded-1/30.txt
new file mode 100644
index 0000000..82bfa6a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/30.txt
@@ -0,0 +1 @@
+(10)1098*1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/31.png b/core/test/data/blackbox/rssexpanded-1/31.png
new file mode 100644
index 0000000..eb00f82
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/31.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/31.txt b/core/test/data/blackbox/rssexpanded-1/31.txt
new file mode 100644
index 0000000..f6413d5
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/31.txt
@@ -0,0 +1 @@
+(10)1098,1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/32.png b/core/test/data/blackbox/rssexpanded-1/32.png
new file mode 100644
index 0000000..a94dcfc
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/32.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/32.txt b/core/test/data/blackbox/rssexpanded-1/32.txt
new file mode 100644
index 0000000..5e76631
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/32.txt
@@ -0,0 +1 @@
+(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/4.jpg b/core/test/data/blackbox/rssexpanded-1/4.jpg
new file mode 100644
index 0000000..8aa8b14
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/4.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/4.txt b/core/test/data/blackbox/rssexpanded-1/4.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/4.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/5.jpg b/core/test/data/blackbox/rssexpanded-1/5.jpg
new file mode 100644
index 0000000..8d42ad4
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/5.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-1/5.txt b/core/test/data/blackbox/rssexpanded-1/5.txt
new file mode 100644
index 0000000..4a70860
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/5.txt
@@ -0,0 +1 @@
+(01)90614141000015(3202)000150
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/6.png b/core/test/data/blackbox/rssexpanded-1/6.png
new file mode 100644
index 0000000..393eac3
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/6.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/6.txt b/core/test/data/blackbox/rssexpanded-1/6.txt
new file mode 100644
index 0000000..84f8807
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/6.txt
@@ -0,0 +1 @@
+(10)567(01)90012345678908(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/7.png b/core/test/data/blackbox/rssexpanded-1/7.png
new file mode 100644
index 0000000..818a86b
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/7.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/7.txt b/core/test/data/blackbox/rssexpanded-1/7.txt
new file mode 100644
index 0000000..e8c7268
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/7.txt
@@ -0,0 +1 @@
+(10)567(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/8.png b/core/test/data/blackbox/rssexpanded-1/8.png
new file mode 100644
index 0000000..b09e5a9
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/8.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/8.txt b/core/test/data/blackbox/rssexpanded-1/8.txt
new file mode 100644
index 0000000..56981cd
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/8.txt
@@ -0,0 +1 @@
+(10)567(11)010101(13)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-1/9.png b/core/test/data/blackbox/rssexpanded-1/9.png
new file mode 100644
index 0000000..12f2594
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-1/9.png differ
diff --git a/core/test/data/blackbox/rssexpanded-1/9.txt b/core/test/data/blackbox/rssexpanded-1/9.txt
new file mode 100644
index 0000000..84cf63c
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-1/9.txt
@@ -0,0 +1 @@
+(10)567(3102)123456
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/12.jpg b/core/test/data/blackbox/rssexpanded-2/12.jpg
new file mode 100644
index 0000000..4750557
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/12.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/12.txt b/core/test/data/blackbox/rssexpanded-2/12.txt
new file mode 100644
index 0000000..32ad2da
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/12.txt
@@ -0,0 +1 @@
+(01)98898765432106(3103)001750
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/13.jpg b/core/test/data/blackbox/rssexpanded-2/13.jpg
new file mode 100644
index 0000000..8ed2841
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/13.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/13.txt b/core/test/data/blackbox/rssexpanded-2/13.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/13.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/16.jpg b/core/test/data/blackbox/rssexpanded-2/16.jpg
new file mode 100644
index 0000000..cda424c
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/16.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/16.txt b/core/test/data/blackbox/rssexpanded-2/16.txt
new file mode 100644
index 0000000..c9f248d
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/16.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(11)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/17.jpg b/core/test/data/blackbox/rssexpanded-2/17.jpg
new file mode 100644
index 0000000..7601179
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/17.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/17.txt b/core/test/data/blackbox/rssexpanded-2/17.txt
new file mode 100644
index 0000000..9b4fc49
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/17.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(13)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/18.jpg b/core/test/data/blackbox/rssexpanded-2/18.jpg
new file mode 100644
index 0000000..f1f60c6
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/18.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/18.txt b/core/test/data/blackbox/rssexpanded-2/18.txt
new file mode 100644
index 0000000..cd15aa0
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/18.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(13)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/18b.jpg b/core/test/data/blackbox/rssexpanded-2/18b.jpg
new file mode 100644
index 0000000..1872739
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/18b.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/18b.txt b/core/test/data/blackbox/rssexpanded-2/18b.txt
new file mode 100644
index 0000000..cd15aa0
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/18b.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(13)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/19.jpg b/core/test/data/blackbox/rssexpanded-2/19.jpg
new file mode 100644
index 0000000..37db6cb
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/19.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/19.txt b/core/test/data/blackbox/rssexpanded-2/19.txt
new file mode 100644
index 0000000..dcd1561
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/19.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(15)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/21.jpg b/core/test/data/blackbox/rssexpanded-2/21.jpg
new file mode 100644
index 0000000..e4ef2f2
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/21.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/21.txt b/core/test/data/blackbox/rssexpanded-2/21.txt
new file mode 100644
index 0000000..506b17b
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/21.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(17)100312
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/3_01.jpg b/core/test/data/blackbox/rssexpanded-2/3_01.jpg
new file mode 100644
index 0000000..69b91e6
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/3_01.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/3_01.txt b/core/test/data/blackbox/rssexpanded-2/3_01.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/3_01.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/3_02.jpg b/core/test/data/blackbox/rssexpanded-2/3_02.jpg
new file mode 100644
index 0000000..7c386dd
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/3_02.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/3_02.txt b/core/test/data/blackbox/rssexpanded-2/3_02.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/3_02.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/3_03.jpg b/core/test/data/blackbox/rssexpanded-2/3_03.jpg
new file mode 100644
index 0000000..a8b2e50
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/3_03.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/3_03.txt b/core/test/data/blackbox/rssexpanded-2/3_03.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/3_03.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/3_04.jpg b/core/test/data/blackbox/rssexpanded-2/3_04.jpg
new file mode 100644
index 0000000..80c048d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/3_04.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/3_04.txt b/core/test/data/blackbox/rssexpanded-2/3_04.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/3_04.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/3_05.jpg b/core/test/data/blackbox/rssexpanded-2/3_05.jpg
new file mode 100644
index 0000000..fce80e0
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/3_05.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/3_05.txt b/core/test/data/blackbox/rssexpanded-2/3_05.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/3_05.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/3_06.jpg b/core/test/data/blackbox/rssexpanded-2/3_06.jpg
new file mode 100644
index 0000000..9a012bd
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/3_06.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/3_06.txt b/core/test/data/blackbox/rssexpanded-2/3_06.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/3_06.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/3_07.jpg b/core/test/data/blackbox/rssexpanded-2/3_07.jpg
new file mode 100644
index 0000000..8f66489
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/3_07.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/3_07.txt b/core/test/data/blackbox/rssexpanded-2/3_07.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/3_07.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/3_09.jpg b/core/test/data/blackbox/rssexpanded-2/3_09.jpg
new file mode 100644
index 0000000..2f5a460
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/3_09.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/3_09.txt b/core/test/data/blackbox/rssexpanded-2/3_09.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/3_09.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/4_00.jpg b/core/test/data/blackbox/rssexpanded-2/4_00.jpg
new file mode 100644
index 0000000..b6bfafa
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/4_00.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/4_00.txt b/core/test/data/blackbox/rssexpanded-2/4_00.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/4_00.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/4_01.jpg b/core/test/data/blackbox/rssexpanded-2/4_01.jpg
new file mode 100644
index 0000000..bed2601
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/4_01.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/4_01.txt b/core/test/data/blackbox/rssexpanded-2/4_01.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/4_01.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/4_02.jpg b/core/test/data/blackbox/rssexpanded-2/4_02.jpg
new file mode 100644
index 0000000..be1b66c
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/4_02.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/4_02.txt b/core/test/data/blackbox/rssexpanded-2/4_02.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/4_02.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/4_03.jpg b/core/test/data/blackbox/rssexpanded-2/4_03.jpg
new file mode 100644
index 0000000..d48028f
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/4_03.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/4_03.txt b/core/test/data/blackbox/rssexpanded-2/4_03.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/4_03.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/4_04.jpg b/core/test/data/blackbox/rssexpanded-2/4_04.jpg
new file mode 100644
index 0000000..2e64ec9
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/4_04.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/4_04.txt b/core/test/data/blackbox/rssexpanded-2/4_04.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/4_04.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/4_05.jpg b/core/test/data/blackbox/rssexpanded-2/4_05.jpg
new file mode 100644
index 0000000..1800a4e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/4_05.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/4_05.txt b/core/test/data/blackbox/rssexpanded-2/4_05.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/4_05.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-2/5.jpg b/core/test/data/blackbox/rssexpanded-2/5.jpg
new file mode 100644
index 0000000..204fa18
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-2/5.jpg differ
diff --git a/core/test/data/blackbox/rssexpanded-2/5.txt b/core/test/data/blackbox/rssexpanded-2/5.txt
new file mode 100644
index 0000000..4a70860
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-2/5.txt
@@ -0,0 +1 @@
+(01)90614141000015(3202)000150
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/1.png b/core/test/data/blackbox/rssexpanded-3/1.png
new file mode 100644
index 0000000..9a7769d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/1.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/1.txt b/core/test/data/blackbox/rssexpanded-3/1.txt
new file mode 100644
index 0000000..ed31c4d
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/1.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)012233(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/10.png b/core/test/data/blackbox/rssexpanded-3/10.png
new file mode 100644
index 0000000..bd28d8a
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/10.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/10.txt b/core/test/data/blackbox/rssexpanded-3/10.txt
new file mode 100644
index 0000000..e8f98fe
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/10.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)010000
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/100.png b/core/test/data/blackbox/rssexpanded-3/100.png
new file mode 100644
index 0000000..93dc882
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/100.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/100.txt b/core/test/data/blackbox/rssexpanded-3/100.txt
new file mode 100644
index 0000000..4339de9
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/100.txt
@@ -0,0 +1 @@
+(10)1098 1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/101.png b/core/test/data/blackbox/rssexpanded-3/101.png
new file mode 100644
index 0000000..e9cdd7a
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/101.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/101.txt b/core/test/data/blackbox/rssexpanded-3/101.txt
new file mode 100644
index 0000000..6f63fb0
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/101.txt
@@ -0,0 +1 @@
+(10)123456A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/102.png b/core/test/data/blackbox/rssexpanded-3/102.png
new file mode 100644
index 0000000..dd68bdf
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/102.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/102.txt b/core/test/data/blackbox/rssexpanded-3/102.txt
new file mode 100644
index 0000000..5c1b912
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/102.txt
@@ -0,0 +1 @@
+(10)123456A1
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/103.png b/core/test/data/blackbox/rssexpanded-3/103.png
new file mode 100644
index 0000000..519e39a
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/103.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/103.txt b/core/test/data/blackbox/rssexpanded-3/103.txt
new file mode 100644
index 0000000..d77a476
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/103.txt
@@ -0,0 +1 @@
+(10)123456A123
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/104.png b/core/test/data/blackbox/rssexpanded-3/104.png
new file mode 100644
index 0000000..a585805
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/104.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/104.txt b/core/test/data/blackbox/rssexpanded-3/104.txt
new file mode 100644
index 0000000..2e2ec43
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/104.txt
@@ -0,0 +1 @@
+(10)123456A1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/105.png b/core/test/data/blackbox/rssexpanded-3/105.png
new file mode 100644
index 0000000..97948c1
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/105.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/105.txt b/core/test/data/blackbox/rssexpanded-3/105.txt
new file mode 100644
index 0000000..b607d14
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/105.txt
@@ -0,0 +1 @@
+(10)123456A1234A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/106.png b/core/test/data/blackbox/rssexpanded-3/106.png
new file mode 100644
index 0000000..3965788
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/106.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/106.txt b/core/test/data/blackbox/rssexpanded-3/106.txt
new file mode 100644
index 0000000..389adca
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/106.txt
@@ -0,0 +1 @@
+(10)123456A123456
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/107.png b/core/test/data/blackbox/rssexpanded-3/107.png
new file mode 100644
index 0000000..5bb7801
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/107.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/107.txt b/core/test/data/blackbox/rssexpanded-3/107.txt
new file mode 100644
index 0000000..fffde5d
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/107.txt
@@ -0,0 +1 @@
+(10)123456A12345678
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/108.png b/core/test/data/blackbox/rssexpanded-3/108.png
new file mode 100644
index 0000000..d705f80
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/108.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/108.txt b/core/test/data/blackbox/rssexpanded-3/108.txt
new file mode 100644
index 0000000..1ad0fbd
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/108.txt
@@ -0,0 +1 @@
+(10)123456A1234A(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/109.png b/core/test/data/blackbox/rssexpanded-3/109.png
new file mode 100644
index 0000000..ee52aae
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/109.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/109.txt b/core/test/data/blackbox/rssexpanded-3/109.txt
new file mode 100644
index 0000000..ac79617
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/109.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/1234567
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/11.png b/core/test/data/blackbox/rssexpanded-3/11.png
new file mode 100644
index 0000000..eb18d4e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/11.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/11.txt b/core/test/data/blackbox/rssexpanded-3/11.txt
new file mode 100644
index 0000000..9895a67
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/11.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)032767
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/110.png b/core/test/data/blackbox/rssexpanded-3/110.png
new file mode 100644
index 0000000..9c6ce73
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/110.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/110.txt b/core/test/data/blackbox/rssexpanded-3/110.txt
new file mode 100644
index 0000000..163b64b
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/110.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/ABCDEFG
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/111.png b/core/test/data/blackbox/rssexpanded-3/111.png
new file mode 100644
index 0000000..216d52e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/111.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/111.txt b/core/test/data/blackbox/rssexpanded-3/111.txt
new file mode 100644
index 0000000..d359328
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/111.txt
@@ -0,0 +1 @@
+(10)1;:/ABCDEFGHIJKLM
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/112.png b/core/test/data/blackbox/rssexpanded-3/112.png
new file mode 100644
index 0000000..da42a90
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/112.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/112.txt b/core/test/data/blackbox/rssexpanded-3/112.txt
new file mode 100644
index 0000000..c25e84f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/112.txt
@@ -0,0 +1 @@
+(10)1;:/0123456789012
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/113.png b/core/test/data/blackbox/rssexpanded-3/113.png
new file mode 100644
index 0000000..5ab0ae5
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/113.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/113.txt b/core/test/data/blackbox/rssexpanded-3/113.txt
new file mode 100644
index 0000000..2914766
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/113.txt
@@ -0,0 +1 @@
+(10)1;:/0123
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/114.png b/core/test/data/blackbox/rssexpanded-3/114.png
new file mode 100644
index 0000000..8ab1daa
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/114.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/114.txt b/core/test/data/blackbox/rssexpanded-3/114.txt
new file mode 100644
index 0000000..c8be9f3
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/114.txt
@@ -0,0 +1 @@
+(10)1;:/0123(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/115.png b/core/test/data/blackbox/rssexpanded-3/115.png
new file mode 100644
index 0000000..2a89b68
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/115.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/115.txt b/core/test/data/blackbox/rssexpanded-3/115.txt
new file mode 100644
index 0000000..9a1581d
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/115.txt
@@ -0,0 +1 @@
+(10)1
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/116.png b/core/test/data/blackbox/rssexpanded-3/116.png
new file mode 100644
index 0000000..152483d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/116.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/116.txt b/core/test/data/blackbox/rssexpanded-3/116.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/116.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/117.png b/core/test/data/blackbox/rssexpanded-3/117.png
new file mode 100644
index 0000000..cd52c3d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/117.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/117.txt b/core/test/data/blackbox/rssexpanded-3/117.txt
new file mode 100644
index 0000000..62c17f1
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/117.txt
@@ -0,0 +1 @@
+(10)123
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/12.png b/core/test/data/blackbox/rssexpanded-3/12.png
new file mode 100644
index 0000000..f9abacc
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/12.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/12.txt b/core/test/data/blackbox/rssexpanded-3/12.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/12.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/13.png b/core/test/data/blackbox/rssexpanded-3/13.png
new file mode 100644
index 0000000..7fdf61d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/13.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/13.txt b/core/test/data/blackbox/rssexpanded-3/13.txt
new file mode 100644
index 0000000..0429d93
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/13.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/14.png b/core/test/data/blackbox/rssexpanded-3/14.png
new file mode 100644
index 0000000..6b0f448
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/14.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/14.txt b/core/test/data/blackbox/rssexpanded-3/14.txt
new file mode 100644
index 0000000..fb00e31
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/14.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)0401234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/15.png b/core/test/data/blackbox/rssexpanded-3/15.png
new file mode 100644
index 0000000..360b412
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/15.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/15.txt b/core/test/data/blackbox/rssexpanded-3/15.txt
new file mode 100644
index 0000000..9066194
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/15.txt
@@ -0,0 +1 @@
+(01)00012345678905(10)ABC123
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/16.png b/core/test/data/blackbox/rssexpanded-3/16.png
new file mode 100644
index 0000000..baf3120
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/16.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/16.txt b/core/test/data/blackbox/rssexpanded-3/16.txt
new file mode 100644
index 0000000..8f0841f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/16.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)UNIVERSITY-OF-DEUSTO
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/17.png b/core/test/data/blackbox/rssexpanded-3/17.png
new file mode 100644
index 0000000..49af6a6
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/17.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/17.txt b/core/test/data/blackbox/rssexpanded-3/17.txt
new file mode 100644
index 0000000..89fda98
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/17.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)PIRAMIDE-PROJECT
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/18.png b/core/test/data/blackbox/rssexpanded-3/18.png
new file mode 100644
index 0000000..fa774d0
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/18.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/18.txt b/core/test/data/blackbox/rssexpanded-3/18.txt
new file mode 100644
index 0000000..b120324
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/18.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)TREELOGIC
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/19.png b/core/test/data/blackbox/rssexpanded-3/19.png
new file mode 100644
index 0000000..40f069c
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/19.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/19.txt b/core/test/data/blackbox/rssexpanded-3/19.txt
new file mode 100644
index 0000000..17966ee
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/19.txt
@@ -0,0 +1 @@
+(10)5678(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/2.png b/core/test/data/blackbox/rssexpanded-3/2.png
new file mode 100644
index 0000000..1710366
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/2.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/2.txt b/core/test/data/blackbox/rssexpanded-3/2.txt
new file mode 100644
index 0000000..d7f0a6a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/2.txt
@@ -0,0 +1 @@
+(01)91234567980129(3103)012233(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/20.png b/core/test/data/blackbox/rssexpanded-3/20.png
new file mode 100644
index 0000000..305a71c
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/20.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/20.txt b/core/test/data/blackbox/rssexpanded-3/20.txt
new file mode 100644
index 0000000..b948648
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/20.txt
@@ -0,0 +1 @@
+(10)5678(11)001010
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/21.png b/core/test/data/blackbox/rssexpanded-3/21.png
new file mode 100644
index 0000000..aabea10
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/21.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/21.txt b/core/test/data/blackbox/rssexpanded-3/21.txt
new file mode 100644
index 0000000..a7b3497
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/21.txt
@@ -0,0 +1 @@
+(10)567890(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/22.png b/core/test/data/blackbox/rssexpanded-3/22.png
new file mode 100644
index 0000000..3bf678e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/22.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/22.txt b/core/test/data/blackbox/rssexpanded-3/22.txt
new file mode 100644
index 0000000..e8c7268
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/22.txt
@@ -0,0 +1 @@
+(10)567(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/23.png b/core/test/data/blackbox/rssexpanded-3/23.png
new file mode 100644
index 0000000..a541ca2
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/23.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/23.txt b/core/test/data/blackbox/rssexpanded-3/23.txt
new file mode 100644
index 0000000..5263f7f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/23.txt
@@ -0,0 +1 @@
+(10)1098-1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/24.png b/core/test/data/blackbox/rssexpanded-3/24.png
new file mode 100644
index 0000000..eb00f82
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/24.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/24.txt b/core/test/data/blackbox/rssexpanded-3/24.txt
new file mode 100644
index 0000000..f6413d5
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/24.txt
@@ -0,0 +1 @@
+(10)1098,1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/25.png b/core/test/data/blackbox/rssexpanded-3/25.png
new file mode 100644
index 0000000..d03f073
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/25.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/25.txt b/core/test/data/blackbox/rssexpanded-3/25.txt
new file mode 100644
index 0000000..9208d92
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/25.txt
@@ -0,0 +1 @@
+(10)1098/1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/26.png b/core/test/data/blackbox/rssexpanded-3/26.png
new file mode 100644
index 0000000..9467691
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/26.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/26.txt b/core/test/data/blackbox/rssexpanded-3/26.txt
new file mode 100644
index 0000000..b78623a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/26.txt
@@ -0,0 +1 @@
+(10)1098.1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/27.png b/core/test/data/blackbox/rssexpanded-3/27.png
new file mode 100644
index 0000000..5468dc9
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/27.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/27.txt b/core/test/data/blackbox/rssexpanded-3/27.txt
new file mode 100644
index 0000000..82bfa6a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/27.txt
@@ -0,0 +1 @@
+(10)1098*1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/28.png b/core/test/data/blackbox/rssexpanded-3/28.png
new file mode 100644
index 0000000..f330214
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/28.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/28.txt b/core/test/data/blackbox/rssexpanded-3/28.txt
new file mode 100644
index 0000000..6263d99
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/28.txt
@@ -0,0 +1 @@
+(10)1098a1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/29.png b/core/test/data/blackbox/rssexpanded-3/29.png
new file mode 100644
index 0000000..67fa5e5
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/29.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/29.txt b/core/test/data/blackbox/rssexpanded-3/29.txt
new file mode 100644
index 0000000..35fc529
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/29.txt
@@ -0,0 +1 @@
+(10)1098!1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/3.png b/core/test/data/blackbox/rssexpanded-3/3.png
new file mode 100644
index 0000000..3f54275
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/3.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/3.txt b/core/test/data/blackbox/rssexpanded-3/3.txt
new file mode 100644
index 0000000..ab93c97
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/3.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/30.png b/core/test/data/blackbox/rssexpanded-3/30.png
new file mode 100644
index 0000000..f70bf7a
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/30.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/30.txt b/core/test/data/blackbox/rssexpanded-3/30.txt
new file mode 100644
index 0000000..d0d95d0
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/30.txt
@@ -0,0 +1 @@
+(10)1098"1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/31.png b/core/test/data/blackbox/rssexpanded-3/31.png
new file mode 100644
index 0000000..c2fca02
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/31.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/31.txt b/core/test/data/blackbox/rssexpanded-3/31.txt
new file mode 100644
index 0000000..53bf781
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/31.txt
@@ -0,0 +1 @@
+(10)1098%1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/32.png b/core/test/data/blackbox/rssexpanded-3/32.png
new file mode 100644
index 0000000..76b885f
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/32.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/32.txt b/core/test/data/blackbox/rssexpanded-3/32.txt
new file mode 100644
index 0000000..5d1d351
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/32.txt
@@ -0,0 +1 @@
+(10)1098&1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/33.png b/core/test/data/blackbox/rssexpanded-3/33.png
new file mode 100644
index 0000000..387c976
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/33.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/33.txt b/core/test/data/blackbox/rssexpanded-3/33.txt
new file mode 100644
index 0000000..f00c6bb
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/33.txt
@@ -0,0 +1 @@
+(10)1098'1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/34.png b/core/test/data/blackbox/rssexpanded-3/34.png
new file mode 100644
index 0000000..10abfa3
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/34.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/34.txt b/core/test/data/blackbox/rssexpanded-3/34.txt
new file mode 100644
index 0000000..18b90ec
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/34.txt
@@ -0,0 +1 @@
+(10)1098+1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/35.png b/core/test/data/blackbox/rssexpanded-3/35.png
new file mode 100644
index 0000000..b439faf
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/35.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/35.txt b/core/test/data/blackbox/rssexpanded-3/35.txt
new file mode 100644
index 0000000..96f9049
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/35.txt
@@ -0,0 +1 @@
+(10)1098:1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/36.png b/core/test/data/blackbox/rssexpanded-3/36.png
new file mode 100644
index 0000000..c1d645e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/36.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/36.txt b/core/test/data/blackbox/rssexpanded-3/36.txt
new file mode 100644
index 0000000..2dd84d5
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/36.txt
@@ -0,0 +1 @@
+(10)1098;1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/37.png b/core/test/data/blackbox/rssexpanded-3/37.png
new file mode 100644
index 0000000..dfb6fc7
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/37.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/37.txt b/core/test/data/blackbox/rssexpanded-3/37.txt
new file mode 100644
index 0000000..a64a6db
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/37.txt
@@ -0,0 +1 @@
+(10)1098<1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/38.png b/core/test/data/blackbox/rssexpanded-3/38.png
new file mode 100644
index 0000000..5d52658
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/38.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/38.txt b/core/test/data/blackbox/rssexpanded-3/38.txt
new file mode 100644
index 0000000..c7cc606
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/38.txt
@@ -0,0 +1 @@
+(10)1098=1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/39.png b/core/test/data/blackbox/rssexpanded-3/39.png
new file mode 100644
index 0000000..8f505c3
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/39.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/39.txt b/core/test/data/blackbox/rssexpanded-3/39.txt
new file mode 100644
index 0000000..7345e4e
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/39.txt
@@ -0,0 +1 @@
+(10)1098>1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/4.png b/core/test/data/blackbox/rssexpanded-3/4.png
new file mode 100644
index 0000000..e42f0f9
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/4.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/4.txt b/core/test/data/blackbox/rssexpanded-3/4.txt
new file mode 100644
index 0000000..fca726b
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/4.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)000101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/40.png b/core/test/data/blackbox/rssexpanded-3/40.png
new file mode 100644
index 0000000..d137198
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/40.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/40.txt b/core/test/data/blackbox/rssexpanded-3/40.txt
new file mode 100644
index 0000000..5e152de
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/40.txt
@@ -0,0 +1 @@
+(10)1098?1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/41.png b/core/test/data/blackbox/rssexpanded-3/41.png
new file mode 100644
index 0000000..8910b83
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/41.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/41.txt b/core/test/data/blackbox/rssexpanded-3/41.txt
new file mode 100644
index 0000000..aad1b28
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/41.txt
@@ -0,0 +1 @@
+(10)1098_1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/42.png b/core/test/data/blackbox/rssexpanded-3/42.png
new file mode 100644
index 0000000..877e405
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/42.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/42.txt b/core/test/data/blackbox/rssexpanded-3/42.txt
new file mode 100644
index 0000000..4339de9
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/42.txt
@@ -0,0 +1 @@
+(10)1098 1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/43.png b/core/test/data/blackbox/rssexpanded-3/43.png
new file mode 100644
index 0000000..621aa88
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/43.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/43.txt b/core/test/data/blackbox/rssexpanded-3/43.txt
new file mode 100644
index 0000000..6f63fb0
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/43.txt
@@ -0,0 +1 @@
+(10)123456A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/44.png b/core/test/data/blackbox/rssexpanded-3/44.png
new file mode 100644
index 0000000..2ff0c3d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/44.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/44.txt b/core/test/data/blackbox/rssexpanded-3/44.txt
new file mode 100644
index 0000000..2e2ec43
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/44.txt
@@ -0,0 +1 @@
+(10)123456A1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/45.png b/core/test/data/blackbox/rssexpanded-3/45.png
new file mode 100644
index 0000000..d231946
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/45.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/45.txt b/core/test/data/blackbox/rssexpanded-3/45.txt
new file mode 100644
index 0000000..b607d14
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/45.txt
@@ -0,0 +1 @@
+(10)123456A1234A
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/46.png b/core/test/data/blackbox/rssexpanded-3/46.png
new file mode 100644
index 0000000..8832c69
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/46.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/46.txt b/core/test/data/blackbox/rssexpanded-3/46.txt
new file mode 100644
index 0000000..389adca
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/46.txt
@@ -0,0 +1 @@
+(10)123456A123456
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/47.png b/core/test/data/blackbox/rssexpanded-3/47.png
new file mode 100644
index 0000000..7f5de77
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/47.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/47.txt b/core/test/data/blackbox/rssexpanded-3/47.txt
new file mode 100644
index 0000000..fffde5d
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/47.txt
@@ -0,0 +1 @@
+(10)123456A12345678
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/48.png b/core/test/data/blackbox/rssexpanded-3/48.png
new file mode 100644
index 0000000..a9ec672
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/48.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/48.txt b/core/test/data/blackbox/rssexpanded-3/48.txt
new file mode 100644
index 0000000..ac79617
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/48.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/1234567
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/49.png b/core/test/data/blackbox/rssexpanded-3/49.png
new file mode 100644
index 0000000..5f65a42
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/49.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/49.txt b/core/test/data/blackbox/rssexpanded-3/49.txt
new file mode 100644
index 0000000..163b64b
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/49.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/ABCDEFG
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/5.png b/core/test/data/blackbox/rssexpanded-3/5.png
new file mode 100644
index 0000000..2c0ba26
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/5.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/5.txt b/core/test/data/blackbox/rssexpanded-3/5.txt
new file mode 100644
index 0000000..b4113ac
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/5.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)001750
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/50.png b/core/test/data/blackbox/rssexpanded-3/50.png
new file mode 100644
index 0000000..22c31e0
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/50.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/50.txt b/core/test/data/blackbox/rssexpanded-3/50.txt
new file mode 100644
index 0000000..d359328
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/50.txt
@@ -0,0 +1 @@
+(10)1;:/ABCDEFGHIJKLM
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/51.png b/core/test/data/blackbox/rssexpanded-3/51.png
new file mode 100644
index 0000000..604df03
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/51.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/51.txt b/core/test/data/blackbox/rssexpanded-3/51.txt
new file mode 100644
index 0000000..c25e84f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/51.txt
@@ -0,0 +1 @@
+(10)1;:/0123456789012
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/52.png b/core/test/data/blackbox/rssexpanded-3/52.png
new file mode 100644
index 0000000..fb71507
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/52.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/52.txt b/core/test/data/blackbox/rssexpanded-3/52.txt
new file mode 100644
index 0000000..2914766
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/52.txt
@@ -0,0 +1 @@
+(10)1;:/0123
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/53.png b/core/test/data/blackbox/rssexpanded-3/53.png
new file mode 100644
index 0000000..3e81195
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/53.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/53.txt b/core/test/data/blackbox/rssexpanded-3/53.txt
new file mode 100644
index 0000000..c8be9f3
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/53.txt
@@ -0,0 +1 @@
+(10)1;:/0123(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/54.png b/core/test/data/blackbox/rssexpanded-3/54.png
new file mode 100644
index 0000000..3f47cbf
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/54.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/54.txt b/core/test/data/blackbox/rssexpanded-3/54.txt
new file mode 100644
index 0000000..ed31c4d
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/54.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)012233(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/55.png b/core/test/data/blackbox/rssexpanded-3/55.png
new file mode 100644
index 0000000..5c47a88
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/55.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/55.txt b/core/test/data/blackbox/rssexpanded-3/55.txt
new file mode 100644
index 0000000..d7f0a6a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/55.txt
@@ -0,0 +1 @@
+(01)91234567980129(3103)012233(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/56.png b/core/test/data/blackbox/rssexpanded-3/56.png
new file mode 100644
index 0000000..c80fa6f
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/56.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/56.txt b/core/test/data/blackbox/rssexpanded-3/56.txt
new file mode 100644
index 0000000..ab93c97
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/56.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)991231
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/57.png b/core/test/data/blackbox/rssexpanded-3/57.png
new file mode 100644
index 0000000..401f53b
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/57.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/57.txt b/core/test/data/blackbox/rssexpanded-3/57.txt
new file mode 100644
index 0000000..fca726b
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/57.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)000101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/58.png b/core/test/data/blackbox/rssexpanded-3/58.png
new file mode 100644
index 0000000..c66572e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/58.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/58.txt b/core/test/data/blackbox/rssexpanded-3/58.txt
new file mode 100644
index 0000000..b4113ac
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/58.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)001750
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/59.png b/core/test/data/blackbox/rssexpanded-3/59.png
new file mode 100644
index 0000000..796e27d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/59.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/59.txt b/core/test/data/blackbox/rssexpanded-3/59.txt
new file mode 100644
index 0000000..57a2c64
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/59.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)032767
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/6.png b/core/test/data/blackbox/rssexpanded-3/6.png
new file mode 100644
index 0000000..024c2d5
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/6.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/6.txt b/core/test/data/blackbox/rssexpanded-3/6.txt
new file mode 100644
index 0000000..57a2c64
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/6.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)032767
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/60.png b/core/test/data/blackbox/rssexpanded-3/60.png
new file mode 100644
index 0000000..fcfca2a
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/60.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/60.txt b/core/test/data/blackbox/rssexpanded-3/60.txt
new file mode 100644
index 0000000..bfa4177
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/60.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)000000
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/61.png b/core/test/data/blackbox/rssexpanded-3/61.png
new file mode 100644
index 0000000..7f192b7
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/61.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/61.txt b/core/test/data/blackbox/rssexpanded-3/61.txt
new file mode 100644
index 0000000..e0da7fa
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/61.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)000156
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/62.png b/core/test/data/blackbox/rssexpanded-3/62.png
new file mode 100644
index 0000000..6334770
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/62.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/62.txt b/core/test/data/blackbox/rssexpanded-3/62.txt
new file mode 100644
index 0000000..01af485
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/62.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)009999
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/63.png b/core/test/data/blackbox/rssexpanded-3/63.png
new file mode 100644
index 0000000..d93e34e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/63.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/63.txt b/core/test/data/blackbox/rssexpanded-3/63.txt
new file mode 100644
index 0000000..e8f98fe
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/63.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)010000
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/64.png b/core/test/data/blackbox/rssexpanded-3/64.png
new file mode 100644
index 0000000..6feffd1
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/64.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/64.txt b/core/test/data/blackbox/rssexpanded-3/64.txt
new file mode 100644
index 0000000..9895a67
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/64.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)032767
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/65.png b/core/test/data/blackbox/rssexpanded-3/65.png
new file mode 100644
index 0000000..5efd2c7
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/65.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/65.txt b/core/test/data/blackbox/rssexpanded-3/65.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/65.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/66.png b/core/test/data/blackbox/rssexpanded-3/66.png
new file mode 100644
index 0000000..14e977a
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/66.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/66.txt b/core/test/data/blackbox/rssexpanded-3/66.txt
new file mode 100644
index 0000000..0429d93
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/66.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/67.png b/core/test/data/blackbox/rssexpanded-3/67.png
new file mode 100644
index 0000000..1f5ad05
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/67.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/67.txt b/core/test/data/blackbox/rssexpanded-3/67.txt
new file mode 100644
index 0000000..fb00e31
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/67.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)0401234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/68.png b/core/test/data/blackbox/rssexpanded-3/68.png
new file mode 100644
index 0000000..ced3f5c
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/68.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/68.txt b/core/test/data/blackbox/rssexpanded-3/68.txt
new file mode 100644
index 0000000..b5f3fe9
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/68.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)040EUR
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/69.png b/core/test/data/blackbox/rssexpanded-3/69.png
new file mode 100644
index 0000000..7b1b0f9
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/69.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/69.txt b/core/test/data/blackbox/rssexpanded-3/69.txt
new file mode 100644
index 0000000..e95bc8d
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/69.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)04055GBP
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/7.png b/core/test/data/blackbox/rssexpanded-3/7.png
new file mode 100644
index 0000000..d342a7d
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/7.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/7.txt b/core/test/data/blackbox/rssexpanded-3/7.txt
new file mode 100644
index 0000000..bfa4177
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/7.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)000000
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/70.png b/core/test/data/blackbox/rssexpanded-3/70.png
new file mode 100644
index 0000000..98d0413
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/70.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/70.txt b/core/test/data/blackbox/rssexpanded-3/70.txt
new file mode 100644
index 0000000..37c6cb3
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/70.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)04066USD778899
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/71.png b/core/test/data/blackbox/rssexpanded-3/71.png
new file mode 100644
index 0000000..d016ab4
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/71.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/71.txt b/core/test/data/blackbox/rssexpanded-3/71.txt
new file mode 100644
index 0000000..9066194
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/71.txt
@@ -0,0 +1 @@
+(01)00012345678905(10)ABC123
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/72.png b/core/test/data/blackbox/rssexpanded-3/72.png
new file mode 100644
index 0000000..54b2443
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/72.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/72.txt b/core/test/data/blackbox/rssexpanded-3/72.txt
new file mode 100644
index 0000000..8f0841f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/72.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)UNIVERSITY-OF-DEUSTO
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/73.png b/core/test/data/blackbox/rssexpanded-3/73.png
new file mode 100644
index 0000000..543d794
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/73.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/73.txt b/core/test/data/blackbox/rssexpanded-3/73.txt
new file mode 100644
index 0000000..89fda98
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/73.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)PIRAMIDE-PROJECT
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/74.png b/core/test/data/blackbox/rssexpanded-3/74.png
new file mode 100644
index 0000000..7d6770e
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/74.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/74.txt b/core/test/data/blackbox/rssexpanded-3/74.txt
new file mode 100644
index 0000000..b120324
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/74.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)TREELOGIC
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/75.png b/core/test/data/blackbox/rssexpanded-3/75.png
new file mode 100644
index 0000000..4c290bc
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/75.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/75.txt b/core/test/data/blackbox/rssexpanded-3/75.txt
new file mode 100644
index 0000000..09d4208
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/75.txt
@@ -0,0 +1 @@
+(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/76.png b/core/test/data/blackbox/rssexpanded-3/76.png
new file mode 100644
index 0000000..a94dcfc
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/76.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/76.txt b/core/test/data/blackbox/rssexpanded-3/76.txt
new file mode 100644
index 0000000..5e76631
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/76.txt
@@ -0,0 +1 @@
+(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/77.png b/core/test/data/blackbox/rssexpanded-3/77.png
new file mode 100644
index 0000000..8374733
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/77.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/77.txt b/core/test/data/blackbox/rssexpanded-3/77.txt
new file mode 100644
index 0000000..17966ee
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/77.txt
@@ -0,0 +1 @@
+(10)5678(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/78.png b/core/test/data/blackbox/rssexpanded-3/78.png
new file mode 100644
index 0000000..42b71cf
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/78.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/78.txt b/core/test/data/blackbox/rssexpanded-3/78.txt
new file mode 100644
index 0000000..b948648
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/78.txt
@@ -0,0 +1 @@
+(10)5678(11)001010
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/79.png b/core/test/data/blackbox/rssexpanded-3/79.png
new file mode 100644
index 0000000..dd37cd7
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/79.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/79.txt b/core/test/data/blackbox/rssexpanded-3/79.txt
new file mode 100644
index 0000000..a7b3497
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/79.txt
@@ -0,0 +1 @@
+(10)567890(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/8.png b/core/test/data/blackbox/rssexpanded-3/8.png
new file mode 100644
index 0000000..16a99bc
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/8.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/8.txt b/core/test/data/blackbox/rssexpanded-3/8.txt
new file mode 100644
index 0000000..e0da7fa
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/8.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)000156
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/80.png b/core/test/data/blackbox/rssexpanded-3/80.png
new file mode 100644
index 0000000..818a86b
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/80.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/80.txt b/core/test/data/blackbox/rssexpanded-3/80.txt
new file mode 100644
index 0000000..e8c7268
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/80.txt
@@ -0,0 +1 @@
+(10)567(11)010101
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/81.png b/core/test/data/blackbox/rssexpanded-3/81.png
new file mode 100644
index 0000000..9b96bc0
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/81.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/81.txt b/core/test/data/blackbox/rssexpanded-3/81.txt
new file mode 100644
index 0000000..5263f7f
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/81.txt
@@ -0,0 +1 @@
+(10)1098-1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/82.png b/core/test/data/blackbox/rssexpanded-3/82.png
new file mode 100644
index 0000000..7ad1cd1
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/82.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/82.txt b/core/test/data/blackbox/rssexpanded-3/82.txt
new file mode 100644
index 0000000..f6413d5
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/82.txt
@@ -0,0 +1 @@
+(10)1098,1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/83.png b/core/test/data/blackbox/rssexpanded-3/83.png
new file mode 100644
index 0000000..e19548f
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/83.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/83.txt b/core/test/data/blackbox/rssexpanded-3/83.txt
new file mode 100644
index 0000000..9208d92
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/83.txt
@@ -0,0 +1 @@
+(10)1098/1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/84.png b/core/test/data/blackbox/rssexpanded-3/84.png
new file mode 100644
index 0000000..6e410cc
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/84.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/84.txt b/core/test/data/blackbox/rssexpanded-3/84.txt
new file mode 100644
index 0000000..b78623a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/84.txt
@@ -0,0 +1 @@
+(10)1098.1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/85.png b/core/test/data/blackbox/rssexpanded-3/85.png
new file mode 100644
index 0000000..93138ad
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/85.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/85.txt b/core/test/data/blackbox/rssexpanded-3/85.txt
new file mode 100644
index 0000000..82bfa6a
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/85.txt
@@ -0,0 +1 @@
+(10)1098*1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/86.png b/core/test/data/blackbox/rssexpanded-3/86.png
new file mode 100644
index 0000000..fa0400a
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/86.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/86.txt b/core/test/data/blackbox/rssexpanded-3/86.txt
new file mode 100644
index 0000000..6263d99
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/86.txt
@@ -0,0 +1 @@
+(10)1098a1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/87.png b/core/test/data/blackbox/rssexpanded-3/87.png
new file mode 100644
index 0000000..73dc0c9
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/87.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/87.txt b/core/test/data/blackbox/rssexpanded-3/87.txt
new file mode 100644
index 0000000..35fc529
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/87.txt
@@ -0,0 +1 @@
+(10)1098!1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/88.png b/core/test/data/blackbox/rssexpanded-3/88.png
new file mode 100644
index 0000000..b308e8a
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/88.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/88.txt b/core/test/data/blackbox/rssexpanded-3/88.txt
new file mode 100644
index 0000000..d0d95d0
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/88.txt
@@ -0,0 +1 @@
+(10)1098"1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/89.png b/core/test/data/blackbox/rssexpanded-3/89.png
new file mode 100644
index 0000000..a07af51
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/89.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/89.txt b/core/test/data/blackbox/rssexpanded-3/89.txt
new file mode 100644
index 0000000..53bf781
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/89.txt
@@ -0,0 +1 @@
+(10)1098%1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/9.png b/core/test/data/blackbox/rssexpanded-3/9.png
new file mode 100644
index 0000000..b33b814
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/9.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/9.txt b/core/test/data/blackbox/rssexpanded-3/9.txt
new file mode 100644
index 0000000..01af485
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/9.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)009999
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/90.png b/core/test/data/blackbox/rssexpanded-3/90.png
new file mode 100644
index 0000000..2c345fd
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/90.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/90.txt b/core/test/data/blackbox/rssexpanded-3/90.txt
new file mode 100644
index 0000000..5d1d351
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/90.txt
@@ -0,0 +1 @@
+(10)1098&1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/91.png b/core/test/data/blackbox/rssexpanded-3/91.png
new file mode 100644
index 0000000..14bc535
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/91.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/91.txt b/core/test/data/blackbox/rssexpanded-3/91.txt
new file mode 100644
index 0000000..f00c6bb
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/91.txt
@@ -0,0 +1 @@
+(10)1098'1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/92.png b/core/test/data/blackbox/rssexpanded-3/92.png
new file mode 100644
index 0000000..2fd7c03
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/92.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/92.txt b/core/test/data/blackbox/rssexpanded-3/92.txt
new file mode 100644
index 0000000..18b90ec
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/92.txt
@@ -0,0 +1 @@
+(10)1098+1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/93.png b/core/test/data/blackbox/rssexpanded-3/93.png
new file mode 100644
index 0000000..cad7bca
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/93.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/93.txt b/core/test/data/blackbox/rssexpanded-3/93.txt
new file mode 100644
index 0000000..96f9049
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/93.txt
@@ -0,0 +1 @@
+(10)1098:1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/94.png b/core/test/data/blackbox/rssexpanded-3/94.png
new file mode 100644
index 0000000..33be65c
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/94.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/94.txt b/core/test/data/blackbox/rssexpanded-3/94.txt
new file mode 100644
index 0000000..2dd84d5
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/94.txt
@@ -0,0 +1 @@
+(10)1098;1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/95.png b/core/test/data/blackbox/rssexpanded-3/95.png
new file mode 100644
index 0000000..1c66547
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/95.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/95.txt b/core/test/data/blackbox/rssexpanded-3/95.txt
new file mode 100644
index 0000000..a64a6db
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/95.txt
@@ -0,0 +1 @@
+(10)1098<1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/96.png b/core/test/data/blackbox/rssexpanded-3/96.png
new file mode 100644
index 0000000..4237df9
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/96.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/96.txt b/core/test/data/blackbox/rssexpanded-3/96.txt
new file mode 100644
index 0000000..c7cc606
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/96.txt
@@ -0,0 +1 @@
+(10)1098=1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/97.png b/core/test/data/blackbox/rssexpanded-3/97.png
new file mode 100644
index 0000000..5254329
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/97.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/97.txt b/core/test/data/blackbox/rssexpanded-3/97.txt
new file mode 100644
index 0000000..7345e4e
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/97.txt
@@ -0,0 +1 @@
+(10)1098>1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/98.png b/core/test/data/blackbox/rssexpanded-3/98.png
new file mode 100644
index 0000000..980bfed
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/98.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/98.txt b/core/test/data/blackbox/rssexpanded-3/98.txt
new file mode 100644
index 0000000..5e152de
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/98.txt
@@ -0,0 +1 @@
+(10)1098?1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/99.png b/core/test/data/blackbox/rssexpanded-3/99.png
new file mode 100644
index 0000000..25f8106
Binary files /dev/null and b/core/test/data/blackbox/rssexpanded-3/99.png differ
diff --git a/core/test/data/blackbox/rssexpanded-3/99.txt b/core/test/data/blackbox/rssexpanded-3/99.txt
new file mode 100644
index 0000000..aad1b28
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/99.txt
@@ -0,0 +1 @@
+(10)1098_1234
\ No newline at end of file
diff --git a/core/test/data/blackbox/rssexpanded-3/generate.py b/core/test/data/blackbox/rssexpanded-3/generate.py
new file mode 100644
index 0000000..5ec05c4
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/generate.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+
+import os
+import glob
+import sys
+import subprocess
+import traceback
+import hashlib
+import urllib
+import urllib2
+
+ZINT = 'zint'
+ZINT_RSS_EXPANDED_CODE = 31
+ZINT_BINARY = "zint" # If available in PATH
+
+POSTSCRIPT = 'postscript'
+
+TEST_FILE = "../../../src/com/google/zxing/oned/rss/RSSExpandedBlackBox3TestCase.java"
+
+def check_zint():
+ try:
+ subprocess.Popen("zint", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except:
+ print >> sys.stderr, "zint not installed. Go to http://www.zint.org.uk/ and install it"
+ return False
+ return True
+
+def check_postscript():
+ return True
+
+GENERATORS = []
+if check_zint():
+ GENERATORS.append(ZINT)
+if check_postscript():
+ GENERATORS.append(POSTSCRIPT)
+
+def generate_image_zint(image_filename, barcode):
+ braces_barcode = barcode.replace("(","[").replace(")","]")
+ os.system('%s -o %s -b %s -d "%s"' % (ZINT_BINARY, image_filename, ZINT_RSS_EXPANDED_CODE, braces_barcode.replace('"','\\"')))
+
+def generate_image_postscript(image_filename, barcode):
+ hashname = "cache/%s.png" % hashlib.new("md5", barcode).hexdigest()
+ # If it exists in the cache, don't download it
+ if os.path.exists(hashname):
+ content = open(hashname).read()
+ open(image_filename,'w').write(content)
+ return
+
+ # We tried use the Python, Perl and LaTeX bindings without success :-(
+ baseurl = "http://www.terryburton.co.uk/barcodewriter/generator/"
+ encoded = urllib.urlencode({
+ "encoder" : "rssexpanded",
+ "data" : barcode,
+ "options" : "",
+ "translate_x" : "50", "translate_y" : "50",
+ "scale_x" : "2", "scale_y" : "2",
+ "rotate" : "0", "submit" : "Make Barcode"
+ })
+ web_urlobject = urllib2.urlopen(baseurl, data = encoded)
+ web_content = web_urlobject.read()
+ png_url = web_content.split('">PNG</a>')[0].split('<a href="')[-1]
+ if not png_url.startswith("tmp"):
+ raise Exception("There was an error processing barcode %s in postscript" % barcode)
+ full_url = baseurl + png_url
+ png_content = urllib2.urlopen(full_url).read()
+ open(hashname,'w').write(png_content)
+ open(image_filename,'w').write(png_content)
+
+def generate_image(image_filename, barcode, generator):
+ if generator == ZINT:
+ generate_image_zint(image_filename, barcode)
+ elif generator == POSTSCRIPT:
+ generate_image_postscript(image_filename, barcode)
+ else:
+ raise Exception("Unknown generator: %s" % generator)
+
+def extract_barcodes():
+ for line in open("generation.config"):
+ content = line.split("#")[0].strip()
+ if content != "":
+ if content[0] == '-':
+ pos = content[1:].find('-')
+ exceptions = content[1:pos+1].split(",")
+ barcode = content[pos + 2:]
+ yield exceptions, barcode
+ else:
+ yield (), content
+
+if __name__ == '__main__':
+ counter = 0
+
+ for image_to_delete in glob.glob("*.png"):
+ os.remove(image_to_delete)
+
+ for text_to_delete in glob.glob("*.txt"):
+ os.remove(text_to_delete)
+
+ for generator in GENERATORS:
+ for exceptions, barcode in extract_barcodes():
+ if generator in exceptions:
+ continue
+ try:
+ counter += 1
+ image_filename = str(counter) + ".png"
+ text_filename = str(counter) + ".txt"
+ open(text_filename, "w").write(barcode)
+ generate_image(image_filename, barcode, generator)
+ except Exception:
+ print "Error with generator %s and barcode %s" % (generator, barcode)
+ traceback.print_exc()
+ counter -= 1
+
+ open(TEST_FILE,'w').write("""package com.google.zxing.oned.rss;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.common.AbstractBlackBoxTestCase;
+
+public class RSSExpandedBlackBox3TestCase extends AbstractBlackBoxTestCase {
+
+ public RSSExpandedBlackBox3TestCase() {
+ super("test/data/blackbox/rssexpanded-3", new MultiFormatReader(), BarcodeFormat.RSS_EXPANDED);
+ addTest(%(number)s, %(number)s, 0.0f);
+ addTest(%(number)s, %(number)s, 180.0f);
+ }
+}
+ """ % {"number" : counter})
+
diff --git a/core/test/data/blackbox/rssexpanded-3/generation.config b/core/test/data/blackbox/rssexpanded-3/generation.config
new file mode 100644
index 0000000..7a973a3
--- /dev/null
+++ b/core/test/data/blackbox/rssexpanded-3/generation.config
@@ -0,0 +1,127 @@
+###########################################################
+#
+# Place codes in this file, and they will be automatically
+# generated by "generate.py". Everything placed after a "#"
+# will be ignored, as well as every space before and after
+# the codes and empty lines.
+#
+# If a generator can't generate a code, then place:
+# -LIBRARY-. For example, if zint doesn't support a code,
+# place -zint-. If neither zint or postscript support it,
+# place -zint,postscript-.
+#
+#
+
+#################################################
+# Fixed length examples
+
+# Encodation 0111000 - 0111111
+
+(01)90012345678908(3103)012233(15)991231 # Example taken from 7.2.5.4.4
+(01)91234567980129(3103)012233(15)991231 # Testing with other AI
+(01)91234567980129(3102)012233(15)991231 # Testing with 3102 instead of 3103
+(01)91234567980129(3102)012233(15)000101 # January 1st, 2000
+
+# Encodation 0100
+
+(01)90012345678908(3103)001750 # Example taken from 7.2.5.4.2
+(01)92109876543213(3103)032767 # Maximum weight value
+(01)92109876543213(3103)000000 # Minimum weight value
+
+# Encodation 0101
+
+(01)90012345678908(3202)000156 # Example taken from 7.2.5.4.3
+(01)90012345678908(3202)009999 # 9,999 has a different behaviour than 10,000
+(01)90012345678908(3203)010000 # 10,000 has a different behaviour than 9,999
+(01)90012345678908(3203)032767 # 10,000 has a different behaviour than 9,999
+
+#################################################
+# Variable length examples
+
+# Encodation 01100
+
+(01)90012345678908(3922)795 # Example taken from 7.2.5.4.5
+(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888 # Longer information
+
+# Encodation 01101
+
+(01)90012345678908(3932)0401234 # Example taken from 7.2.5.4.6
+
+# These three examples don't work due to a bug in zint. It has been reported.
+# However, they work with http://www.terryburton.co.uk/barcodewriter/generator/
+#
+-zint-(01)90012345678908(3932)040EUR # Testing with alphanumeric instead of numeric
+-zint-(01)90012345678908(3932)04055GBP # Testing with numeric + alphanumeric instead of only numeric
+-zint-(01)90012345678908(3932)04066USD778899 # Testing with numeric + alphanumeric + numeric instead of only numeric
+
+# Encodation 1
+
+(01)00012345678905(10)ABC123 # Example taken from 7.2.5.4.1
+(01)12345678901231(10)UNIVERSITY-OF-DEUSTO # Adding other type of information
+(01)12345678901231(10)PIRAMIDE-PROJECT # Adding other type of information
+(01)12345678901231(10)TREELOGIC # Adding other type of information
+
+#
+# Zint doesn't support this one because after 12A (alphanumeric) it goes back to numeric without a alpha to numeric latch
+-zint-(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901 # Adding a lot of information
+
+# Encodation 00
+
+# # Zint doesn't support this one because after 12A (alphanumeric) it goes back to numeric without a alpha to numeric latch
+-zint-(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012 # Adding a lot of information
+(10)5678(11)010101 # This one optimizes the last 4 bits as detailed in the end of 7.2.5.5.1
+(10)5678(11)001010
+(10)567890(11)010101
+(10)567(11)010101
+
+
+# Other tests with special characters, such as: '*',',','-','/','.',
+# and ISO/IEC646 encodation characters
+(10)1098-1234
+(10)1098,1234
+(10)1098/1234
+(10)1098.1234
+(10)1098*1234
+(10)1098a1234
+(10)1098!1234
+(10)1098"1234
+(10)1098%1234
+(10)1098&1234
+(10)1098'1234
+(10)1098+1234
+(10)1098:1234
+(10)1098;1234
+(10)1098<1234
+(10)1098=1234
+(10)1098>1234
+(10)1098?1234
+(10)1098_1234
+(10)1098 1234
+
+# Testing transitions
+
+(10)123456A # numeric -> alpha
+-zint-(10)123456A1 # numeric -> alpha
+-zint-(10)123456A123 # numeric -> alpha
+(10)123456A1234 # numeric -> alpha -> numeric
+(10)123456A1234A # numeric -> alpha
+(10)123456A123456 # numeric -> alpha -> numeric
+(10)123456A12345678 # numeric -> alpha -> numeric
+-zint-(10)123456A1234A(15)991231 # numeric -> alpha -> FNC1
+
+(10)1ABCDEF;:/1234567 # numeric -> alpha -> 646 -> numeric
+(10)1ABCDEF;:/ABCDEFG # numeric -> alpha -> 646 -> alpha
+
+(10)1;:/ABCDEFGHIJKLM # numeric -> 646 -> alpha
+(10)1;:/0123456789012 # numeric -> 646 -> numeric
+(10)1;:/0123 # numeric -> 646
+(10)1;:/0123(15)991231 # numeric -> 646 -> FNC1 numeric
+
+# Another tests, from 7.2.5.5.2
+-zint-(10)1
+
+# Another bug in zint, it works with http://www.terryburton.co.uk/barcodewriter/generator/
+-zint-(10)12A
+# Another bug in zint, it works with the http://www.terryburton.co.uk/barcodewriter/generator/
+-zint-(10)123
+
diff --git a/core/test/src/com/google/zxing/client/result/ExpandedProductParsedResultTestCase.java b/core/test/src/com/google/zxing/client/result/ExpandedProductParsedResultTestCase.java
new file mode 100644
index 0000000..1858bd4
--- /dev/null
+++ b/core/test/src/com/google/zxing/client/result/ExpandedProductParsedResultTestCase.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.client.result;
+
+import java.util.Hashtable;
+
+import junit.framework.TestCase;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.Result;
+
+/**
+ * @author Antonio Manuel Benjumea Conde, Servinform, S.A.
+ * @author Agustín Delgado, Servinform, S.A.
+ */
+public final class ExpandedProductParsedResultTestCase extends TestCase {
+
+ public void test_RSSExpanded() {
+ String text = "(01)66546(13)001205(3932)4455(3102)6544(123)544654";
+ String productID = "66546";
+ String sscc = "-";
+ String lotNumber = "-";
+ String productionDate = "-";
+ String packagingDate = "001205";
+ String bestBeforeDate = "-";
+ String expirationDate = "-";
+ String weight = "6544";
+ String weightType = "KG";
+ String weightIncrement = "2";
+ String price = "5";
+ String priceIncrement = "2";
+ String priceCurrency = "445";
+ Hashtable uncommonAIs = new Hashtable();
+ uncommonAIs.put("123", "544654");
+
+ Result result = new Result(text, null, null, BarcodeFormat.RSS_EXPANDED);
+ ExpandedProductParsedResult o = ExpandedProductResultParser
+ .parse(result);
+ assertEquals(productID, o.getProductID());
+ assertEquals(sscc, o.getSscc());
+ assertEquals(lotNumber, o.getLotNumber());
+ assertEquals(productionDate, o.getProductionDate());
+ assertEquals(packagingDate, o.getPackagingDate());
+ assertEquals(bestBeforeDate, o.getBestBeforeDate());
+ assertEquals(expirationDate, o.getExpirationDate());
+ assertEquals(weight, o.getWeight());
+ assertEquals(weightType, o.getWeightType());
+ assertEquals(weightIncrement, o.getWeightIncrement());
+ assertEquals(price, o.getPrice());
+ assertEquals(priceIncrement, o.getPriceIncrement());
+ assertEquals(priceCurrency, o.getPriceCurrency());
+ assertEquals(uncommonAIs, o.getUncommonAIs());
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/BinaryUtil.java b/core/test/src/com/google/zxing/oned/rss/expanded/BinaryUtil.java
new file mode 100644
index 0000000..d30281a
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/BinaryUtil.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import com.google.zxing.common.BitArray;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+public final class BinaryUtil {
+
+ private BinaryUtil() {
+ }
+
+ /*
+ * Constructs a BitArray from a String like the one returned from BitArray.toString()
+ */
+ public static BitArray buildBitArrayFromString(String data){
+ String dotsAndXs = data.replaceAll("1", "X").replaceAll("0",".");
+ BitArray binary = new BitArray(dotsAndXs.replaceAll(" ", "").length());
+ int counter = 0;
+
+ for(int i = 0; i < dotsAndXs.length(); ++i){
+ if(i % 9 == 0){ // spaces
+ if(dotsAndXs.charAt(i) != ' ') {
+ throw new IllegalStateException("space expected");
+ }
+ continue;
+ }
+
+ char currentChar = dotsAndXs.charAt(i);
+ if(currentChar == 'X' || currentChar == 'x') {
+ binary.set(counter);
+ }
+ counter++;
+ }
+ return binary;
+ }
+
+ public static BitArray buildBitArrayFromStringWithoutSpaces(String data){
+ StringBuilder sb = new StringBuilder();
+
+ String dotsAndXs = data.replaceAll("1", "X").replaceAll("0",".");
+
+ int current = 0;
+ while(current < dotsAndXs.length()){
+ sb.append(' ');
+ for(int i = 0; i < 8 && current < dotsAndXs.length(); ++i){
+ sb.append(dotsAndXs.charAt(current));
+ current++;
+ }
+ }
+
+ return buildBitArrayFromString(sb.toString());
+ }
+
+ public static int extractNumericValueFromBitArray(BitArray information, int pos, int bits) {
+ if(bits > 32) {
+ throw new IllegalArgumentException("extractNumberValueFromBitArray can't handle more than 32 bits");
+ }
+
+ BitArray numeric = new BitArray(bits);
+ for(int i = 0; i < bits; ++i) {
+ if (information.get(pos + i)) {
+ numeric.set(i);
+ }
+ }
+ numeric.reverse();
+ return numeric.bits[0];
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/BinaryUtilTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/BinaryUtilTest.java
new file mode 100644
index 0000000..88f42dc
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/BinaryUtilTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import com.google.zxing.common.BitArray;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+public final class BinaryUtilTest extends TestCase{
+
+ public void testBuildBitArrayFromString(){
+
+ String data = " ..X..X.. ..XXX... XXXXXXXX ........";
+ check(data);
+
+ data = " XXX..X..";
+ check(data);
+
+ data = " XX";
+ check(data);
+
+ data = " ....XX.. ..XX";
+ check(data);
+
+ data = " ....XX.. ..XX..XX ....X.X. ........";
+ check(data);
+ }
+
+ private static void check(String data){
+ BitArray binary = BinaryUtil.buildBitArrayFromString(data);
+ assertEquals(data, binary.toString());
+ }
+
+ public void testBuildBitArrayFromStringWithoutSpaces(){
+ String data;
+
+ data = " ..X..X.. ..XXX... XXXXXXXX ........";
+ checkWithoutSpaces(data);
+
+ data = " XXX..X..";
+ checkWithoutSpaces(data);
+
+ data = " XX";
+ checkWithoutSpaces(data);
+
+ data = " ....XX.. ..XX";
+ checkWithoutSpaces(data);
+
+ data = " ....XX.. ..XX..XX ....X.X. ........";
+ checkWithoutSpaces(data);
+ }
+
+ private static void checkWithoutSpaces(String data){
+ String dataWithoutSpaces = data.replaceAll(" ", "");
+ BitArray binary = BinaryUtil.buildBitArrayFromStringWithoutSpaces(dataWithoutSpaces);
+ assertEquals(data, binary.toString());
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/BitArrayBuilderTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/BitArrayBuilderTest.java
new file mode 100644
index 0000000..92cc13c
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/BitArrayBuilderTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import java.util.Vector;
+
+import com.google.zxing.common.BitArray;
+import com.google.zxing.oned.rss.DataCharacter;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public final class BitArrayBuilderTest extends TestCase {
+
+ public void testBuildBitArray1(){
+ int [][] pairValues = {
+ { 19 },
+ { 673, 16 }
+ };
+
+ String expected = " .......X ..XX..X. X.X....X .......X ....";
+
+ checkBinary(pairValues, expected);
+ }
+
+ private void checkBinary(int[][] pairValues, String expected) {
+ BitArray binary = buildBitArray(pairValues);
+ assertEquals(expected, binary.toString());
+ }
+
+ private static BitArray buildBitArray(int[][] pairValues) {
+ Vector pairs = new Vector();
+ for(int i = 0; i < pairValues.length; ++i){
+ int [] pair = pairValues[i];
+
+ DataCharacter leftChar;
+ if(i == 0) {
+ leftChar = null;
+ } else {
+ leftChar = new DataCharacter(pair[0], 0);
+ }
+
+ DataCharacter rightChar;
+ if(i == 0) {
+ rightChar = new DataCharacter(pair[0], 0);
+ } else if(pair.length == 2) {
+ rightChar = new DataCharacter(pair[1], 0);
+ } else {
+ rightChar = null;
+ }
+
+ ExpandedPair expandedPair = new ExpandedPair(leftChar, rightChar, null, true);
+ pairs.add(expandedPair);
+ }
+
+ BitArray binary = BitArrayBuilder.buildBitArray(pairs);
+ return binary;
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/ExpandedInformationDecoderTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/ExpandedInformationDecoderTest.java
new file mode 100644
index 0000000..a9a3e37
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/ExpandedInformationDecoderTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import com.google.zxing.common.BitArray;
+import com.google.zxing.oned.rss.expanded.decoders.AbstractExpandedDecoder;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public final class ExpandedInformationDecoderTest extends TestCase {
+
+ public void testNoAi() throws Exception {
+ BitArray information = BinaryUtil.buildBitArrayFromString(" .......X ..XX..X. X.X....X .......X ....");
+
+ AbstractExpandedDecoder decoder = AbstractExpandedDecoder.createDecoder(information);
+ String decoded = decoder.parseInformation();
+ assertEquals("(10)12A", decoded);
+ }
+
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox1TestCase.java b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox1TestCase.java
new file mode 100644
index 0000000..f4cfdfb
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox1TestCase.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.common.AbstractBlackBoxTestCase;
+
+public final class RSSExpandedBlackBox1TestCase extends AbstractBlackBoxTestCase {
+
+ public RSSExpandedBlackBox1TestCase() {
+ super("test/data/blackbox/rssexpanded-1", new MultiFormatReader(), BarcodeFormat.RSS_EXPANDED);
+ addTest(32, 32, 0.0f);
+ addTest(32, 32, 180.0f);
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox2TestCase.java b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox2TestCase.java
new file mode 100644
index 0000000..af18fd1
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox2TestCase.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.common.AbstractBlackBoxTestCase;
+
+public class RSSExpandedBlackBox2TestCase extends AbstractBlackBoxTestCase {
+
+ public RSSExpandedBlackBox2TestCase() {
+ super("test/data/blackbox/rssexpanded-2", new MultiFormatReader(), BarcodeFormat.RSS_EXPANDED);
+ addTest(21, 23, 0.0f);
+ addTest(19, 23, 180.0f);
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox3TestCase.java b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox3TestCase.java
new file mode 100644
index 0000000..f513fc7
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedBlackBox3TestCase.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.common.AbstractBlackBoxTestCase;
+
+public final class RSSExpandedBlackBox3TestCase extends AbstractBlackBoxTestCase {
+
+ public RSSExpandedBlackBox3TestCase() {
+ super("test/data/blackbox/rssexpanded-3", new MultiFormatReader(), BarcodeFormat.RSS_EXPANDED);
+ addTest(117, 117, 0.0f);
+ addTest(117, 117, 180.0f);
+ }
+}
+
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2binaryTestCase.java b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2binaryTestCase.java
new file mode 100644
index 0000000..2b45c09
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2binaryTestCase.java
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.Vector;
+
+import javax.imageio.ImageIO;
+
+import junit.framework.TestCase;
+
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.common.BitArray;
+import com.google.zxing.common.GlobalHistogramBinarizer;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public final class RSSExpandedImage2binaryTestCase extends TestCase {
+
+ public void testDecodeRow2binary_1() throws Exception{
+ // (11)100224(17)110224(3102)000100
+ String path = "test/data/blackbox/rssexpanded-1/1.jpg";
+ String expected = " ...X...X .X....X. .XX...X. X..X...X ...XX.X. ..X.X... ..X.X..X ...X..X. X.X....X .X....X. .....X.. X...X...";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_2() throws Exception{
+ // (01)90012345678908(3103)001750
+ String path = "test/data/blackbox/rssexpanded-1/2.jpg";
+ String expected = " ..X..... ......X. .XXX.X.X .X...XX. XXXXX.XX XX.X.... .XX.XX.X .XX.";
+
+ assertCorrectImage2binary(path, expected);
+
+ }
+
+ public void testDecodeRow2binary_3() throws Exception{
+ // (10)12A
+ String path = "test/data/blackbox/rssexpanded-1/3.jpg";
+ String expected = " .......X ..XX..X. X.X....X .......X ....";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_4() throws Exception{
+ // (01)98898765432106(3202)012345(15)991231
+ String path = "test/data/blackbox/rssexpanded-1/4.jpg";
+ String expected = " ..XXXX.X XX.XXXX. .XXX.XX. XX..X... .XXXXX.. XX.X..X. ..XX..XX XX.X.XXX X..XX..X .X.XXXXX XXXX";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_5() throws Exception{
+ // (01)90614141000015(3202)000150
+ String path = "test/data/blackbox/rssexpanded-1/5.jpg";
+ String expected = " ..X.X... .XXXX.X. XX..XXXX ....XX.. X....... ....X... ....X..X .XX.";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_10() throws Exception{
+ // (01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012
+ String path = "test/data/blackbox/rssexpanded-1/10.png";
+ String expected = " .X.XX..X XX.XXXX. .XXX.XX. XX..X... .XXXXX.. XX.X..X. ..XX...X XX.X.... X.X.X.X. X.X..X.X .X....X. XX...X.. ...XX.X. .XXXXXX. .X..XX.. X.X.X... .X...... XXXX.... XX.XX... XXXXX.X. ...XXXXX .....X.X ...X.... X.XXX..X X.X.X... XX.XX..X .X..X..X .X.X.X.X X.XX...X .XX.XXX. XXX.X.XX ..X.";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_11() throws Exception{
+ // (01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456
+ String expected = " .X.XX..X XX.XXXX. .XXX.XX. XX..X... .XXXXX.. XX.X..X. ..XX...X XX.X.... X.X.X.X. X.X..X.X .X....X. XX...X.. ...XX.X. .XXXXXX. .X..XX.. X.X.X... .X...... XXXX.... XX.XX... XXXXX.X. ...XXXXX .....X.X ...X.... X.XXX..X X.X.X... ....";
+ String path = "test/data/blackbox/rssexpanded-1/11.png";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_12() throws Exception{
+ // (01)98898765432106(3103)001750
+
+ String expected = " ..X..XX. XXXX..XX X.XX.XX. .X....XX XXX..XX. X..X.... .XX.XX.X .XX.";
+ String path = "test/data/blackbox/rssexpanded-1/12.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_13() throws Exception{
+ // (01)90012345678908(3922)795
+
+ String expected = " ..XX..X. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. X.X.XXXX .X..X..X ......X.";
+ String path = "test/data/blackbox/rssexpanded-1/13.png";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_14() throws Exception{
+ // (01)90012345678908(3932)0401234
+
+ String expected = " ..XX.X.. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. X.....X. X.....X. X.X.X.XX .X...... X...";
+ String path = "test/data/blackbox/rssexpanded-1/14.png";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_15() throws Exception{
+ // (01)90012345678908(3102)001750(11)100312
+
+ String expected = " ..XXX... ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ String path = "test/data/blackbox/rssexpanded-1/15.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_16() throws Exception{
+ // (01)90012345678908(3202)001750(11)100312
+
+ String expected = " ..XXX..X ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ String path = "test/data/blackbox/rssexpanded-1/16.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_17() throws Exception{
+ // (01)90012345678908(3102)001750(13)100312
+
+ String expected = " ..XXX.X. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ String path = "test/data/blackbox/rssexpanded-1/17.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_18() throws Exception{
+ // (01)90012345678908(3202)001750(13)100312
+
+ String expected = " ..XXX.XX ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ String path = "test/data/blackbox/rssexpanded-1/18.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_19() throws Exception{
+ // (01)90012345678908(3102)001750(15)100312
+
+ String expected = " ..XXXX.. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ String path = "test/data/blackbox/rssexpanded-1/19.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_20() throws Exception{
+ // (01)90012345678908(3202)001750(15)100312
+
+ String expected = " ..XXXX.X ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ String path = "test/data/blackbox/rssexpanded-1/20.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_21() throws Exception{
+ // (01)90012345678908(3102)001750(17)100312
+
+ String expected = " ..XXXXX. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ String path = "test/data/blackbox/rssexpanded-1/21.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ public void testDecodeRow2binary_22() throws Exception{
+ // (01)90012345678908(3202)001750(17)100312
+
+ String expected = " ..XXXXXX ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ String path = "test/data/blackbox/rssexpanded-1/22.jpg";
+
+ assertCorrectImage2binary(path, expected);
+ }
+
+ private static void assertCorrectImage2binary(String path,
+ String expected) throws IOException, NotFoundException {
+ RSSExpandedReader rssExpandedReader = new RSSExpandedReader();
+
+ BufferedImage image = ImageIO.read(new File(path));
+ BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(image)));
+ int rowNumber = binaryMap.getHeight() / 2;
+ BitArray row = binaryMap.getBlackRow(rowNumber, null);
+
+ Vector pairs = rssExpandedReader.decodeRow2pairs(rowNumber, row);
+ BitArray binary = BitArrayBuilder.buildBitArray(pairs);
+ assertEquals(expected, binary.toString());
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2resultTestCase.java b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2resultTestCase.java
new file mode 100644
index 0000000..d9083f3
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2resultTestCase.java
@@ -0,0 +1,83 @@
+/**
+ * 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.
+ *
+ * This software consists of contributions made by many individuals,
+ * listed below:
+ *
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ *
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", leaded by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ *
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.util.Hashtable;
+
+import javax.imageio.ImageIO;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.Result;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.client.result.ExpandedProductParsedResult;
+import com.google.zxing.client.result.ParsedResult;
+import com.google.zxing.client.result.ResultParser;
+import com.google.zxing.common.BitArray;
+import com.google.zxing.common.GlobalHistogramBinarizer;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public final class RSSExpandedImage2resultTestCase extends TestCase {
+
+ public void testDecodeRow2result_2() throws Exception{
+ // (01)90012345678908(3103)001750
+ String path = "test/data/blackbox/rssexpanded-1/2.jpg";
+ ExpandedProductParsedResult expected = new ExpandedProductParsedResult("90012345678908", "-", "-", "-", "-", "-", "-", "001750", ExpandedProductParsedResult.KILOGRAM, "3", "-", "-", "-", new Hashtable());
+
+ assertCorrectImage2result(path, expected);
+ }
+
+ private static void assertCorrectImage2result(String path, ExpandedProductParsedResult expected) throws Exception {
+ RSSExpandedReader rssExpandedReader = new RSSExpandedReader();
+
+ BufferedImage image = ImageIO.read(new File(path));
+ BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(image)));
+ int rowNumber = binaryMap.getHeight() / 2;
+ BitArray row = binaryMap.getBlackRow(rowNumber, null);
+
+ Result theResult = rssExpandedReader.decodeRow(rowNumber, row, new Hashtable());
+
+ assertEquals(BarcodeFormat.RSS_EXPANDED, theResult.getBarcodeFormat());
+
+ ParsedResult result = ResultParser.parseResult(theResult);
+
+ assertEquals(expected, result);
+ }
+
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2stringTestCase.java b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2stringTestCase.java
new file mode 100644
index 0000000..b512090
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedImage2stringTestCase.java
@@ -0,0 +1,253 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.util.Hashtable;
+
+import javax.imageio.ImageIO;
+
+import junit.framework.TestCase;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.Result;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.common.BitArray;
+import com.google.zxing.common.GlobalHistogramBinarizer;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public final class RSSExpandedImage2stringTestCase extends TestCase {
+
+ public void testDecodeRow2string_1() throws Exception{
+ String path = "test/data/blackbox/rssexpanded-1/1.jpg";
+ String expected = "(11)100224(17)110224(3102)000100";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_2() throws Exception{
+ String path = "test/data/blackbox/rssexpanded-1/2.jpg";
+ String expected = "(01)90012345678908(3103)001750";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_3() throws Exception{
+ String path = "test/data/blackbox/rssexpanded-1/3.jpg";
+ String expected = "(10)12A";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_4() throws Exception{
+ String path = "test/data/blackbox/rssexpanded-1/4.jpg";
+ String expected = "(01)98898765432106(3202)012345(15)991231";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_5() throws Exception{
+ String path = "test/data/blackbox/rssexpanded-1/5.jpg";
+ String expected = "(01)90614141000015(3202)000150";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_7() throws Exception{
+ String path = "test/data/blackbox/rssexpanded-1/7.png";
+ String expected = "(10)567(11)010101";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_10() throws Exception{
+ String path = "test/data/blackbox/rssexpanded-1/10.png";
+ String expected = "(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_11() throws Exception{
+ String expected = "(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456";
+ String path = "test/data/blackbox/rssexpanded-1/11.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_12() throws Exception{
+ String expected = "(01)98898765432106(3103)001750";
+ String path = "test/data/blackbox/rssexpanded-1/12.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_13() throws Exception{
+ String expected = "(01)90012345678908(3922)795";
+ String path = "test/data/blackbox/rssexpanded-1/13.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_14() throws Exception{
+ String expected = "(01)90012345678908(3932)0401234";
+ String path = "test/data/blackbox/rssexpanded-1/14.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_15() throws Exception{
+ String expected = "(01)90012345678908(3102)001750(11)100312";
+ String path = "test/data/blackbox/rssexpanded-1/15.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_16() throws Exception{
+ String expected = "(01)90012345678908(3202)001750(11)100312";
+ String path = "test/data/blackbox/rssexpanded-1/16.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_17() throws Exception{
+ String expected = "(01)90012345678908(3102)001750(13)100312";
+ String path = "test/data/blackbox/rssexpanded-1/17.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_18() throws Exception{
+ String expected = "(01)90012345678908(3202)001750(13)100312";
+ String path = "test/data/blackbox/rssexpanded-1/18.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_19() throws Exception{
+ String expected = "(01)90012345678908(3102)001750(15)100312";
+ String path = "test/data/blackbox/rssexpanded-1/19.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_20() throws Exception{
+ String expected = "(01)90012345678908(3202)001750(15)100312";
+ String path = "test/data/blackbox/rssexpanded-1/20.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_21() throws Exception{
+ String expected = "(01)90012345678908(3102)001750(17)100312";
+ String path = "test/data/blackbox/rssexpanded-1/21.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_22() throws Exception{
+ String expected = "(01)90012345678908(3202)001750(17)100312";
+ String path = "test/data/blackbox/rssexpanded-1/22.jpg";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_25() throws Exception{
+ String expected = "(10)123";
+ String path = "test/data/blackbox/rssexpanded-1/25.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_26() throws Exception{
+ String expected = "(10)5678(11)010101";
+ String path = "test/data/blackbox/rssexpanded-1/26.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_27() throws Exception{
+ String expected = "(10)1098-1234";
+ String path = "test/data/blackbox/rssexpanded-1/27.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_28() throws Exception{
+ String expected = "(10)1098/1234";
+ String path = "test/data/blackbox/rssexpanded-1/28.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_29() throws Exception{
+ String expected = "(10)1098.1234";
+ String path = "test/data/blackbox/rssexpanded-1/29.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_30() throws Exception{
+ String expected = "(10)1098*1234";
+ String path = "test/data/blackbox/rssexpanded-1/30.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_31() throws Exception{
+ String expected = "(10)1098,1234";
+ String path = "test/data/blackbox/rssexpanded-1/31.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ public void testDecodeRow2string_32() throws Exception{
+ String expected = "(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012";
+ String path = "test/data/blackbox/rssexpanded-1/32.png";
+
+ assertCorrectImage2string(path, expected);
+ }
+
+ private static void assertCorrectImage2string(String path, String expected) throws Exception {
+ RSSExpandedReader rssExpandedReader = new RSSExpandedReader();
+
+ BufferedImage image = ImageIO.read(new File(path));
+ BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(image)));
+ int rowNumber = binaryMap.getHeight() / 2;
+ BitArray row = binaryMap.getBlackRow(rowNumber, null);
+
+ Result result = rssExpandedReader.decodeRow(rowNumber, row, new Hashtable());
+
+ assertEquals(BarcodeFormat.RSS_EXPANDED, result.getBarcodeFormat());
+ assertEquals(expected, result.getText());
+ }
+
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedInternalTestCase.java b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedInternalTestCase.java
new file mode 100644
index 0000000..8d7fe0f
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/RSSExpandedInternalTestCase.java
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.util.Vector;
+
+import javax.imageio.ImageIO;
+
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.common.BitArray;
+import com.google.zxing.common.GlobalHistogramBinarizer;
+import com.google.zxing.oned.rss.DataCharacter;
+import com.google.zxing.oned.rss.FinderPattern;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public final class RSSExpandedInternalTestCase extends TestCase {
+
+ public void testFindFinderPatterns() throws Exception{
+ RSSExpandedReader rssExpandedReader = new RSSExpandedReader();
+
+ String path = "test/data/blackbox/rssexpanded-1/2.jpg";
+ BufferedImage image = ImageIO.read(new File(path));
+ BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(image)));
+ int rowNumber = binaryMap.getHeight() / 2;
+ BitArray row = binaryMap.getBlackRow(rowNumber, null);
+ Vector<ExpandedPair> previousPairs = new Vector<ExpandedPair>();
+
+ ExpandedPair pair1 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
+ previousPairs.add(pair1);
+ assertEquals(0, pair1.getFinderPattern().getValue());
+ assertFalse(pair1.mayBeLast());
+
+ ExpandedPair pair2 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
+ previousPairs.add(pair2);
+ assertEquals(1, pair2.getFinderPattern().getValue());
+ assertFalse(pair2.mayBeLast());
+
+ ExpandedPair pair3 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
+ previousPairs.add(pair3);
+ assertEquals(1, pair3.getFinderPattern().getValue());
+ assertTrue(pair3.mayBeLast());
+
+ try{
+ rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
+ // the previous was the last pair
+ fail(NotFoundException.class.getName() + " expected");
+ }catch(NotFoundException nfe){
+ // ok
+ }
+ }
+
+ public void testRetrieveNextPairPatterns() throws Exception{
+ RSSExpandedReader rssExpandedReader = new RSSExpandedReader();
+
+ String path = "test/data/blackbox/rssexpanded-1/3.jpg";
+ BufferedImage image = ImageIO.read(new File(path));
+ BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(image)));
+ int rowNumber = binaryMap.getHeight() / 2;
+ BitArray row = binaryMap.getBlackRow(rowNumber, null);
+ Vector<ExpandedPair> previousPairs = new Vector<ExpandedPair>();
+
+ ExpandedPair pair1 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
+ previousPairs.add(pair1);
+ assertEquals(0, pair1.getFinderPattern().getValue());
+ assertFalse(pair1.mayBeLast());
+
+ ExpandedPair pair2 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
+ previousPairs.add(pair2);
+ assertEquals(0, pair2.getFinderPattern().getValue());
+ assertTrue(pair2.mayBeLast());
+ }
+
+ public void testDecodeCheckCharacter() throws Exception{
+ RSSExpandedReader rssExpandedReader = new RSSExpandedReader();
+
+ String path = "test/data/blackbox/rssexpanded-1/3.jpg";
+ BufferedImage image = ImageIO.read(new File(path));
+ BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(image)));
+ BitArray row = binaryMap.getBlackRow(binaryMap.getHeight() / 2, null);
+
+ int[] startEnd = {145, 243};//image pixels where the A1 pattern starts (at 124) and ends (at 214)
+ int value = 0;// A
+ FinderPattern finderPatternA1 = new FinderPattern(value, startEnd, startEnd[0], startEnd[1], image.getHeight() / 2);
+ //{1, 8, 4, 1, 1};
+ DataCharacter dataCharacter = rssExpandedReader.decodeDataCharacter(row, finderPatternA1, true, true);
+
+ assertEquals(98, dataCharacter.getValue());
+ }
+
+ public void testDecodeDataCharacter() throws Exception{
+ RSSExpandedReader rssExpandedReader = new RSSExpandedReader();
+
+ String path = "test/data/blackbox/rssexpanded-1/3.jpg";
+ BufferedImage image = ImageIO.read(new File(path));
+ BinaryBitmap binaryMap = new BinaryBitmap(new GlobalHistogramBinarizer(new BufferedImageLuminanceSource(image)));
+ BitArray row = binaryMap.getBlackRow(binaryMap.getHeight() / 2, null);
+
+ int[] startEnd = {145, 243};//image pixels where the A1 pattern starts (at 124) and ends (at 214)
+ int value = 0; // A
+ FinderPattern finderPatternA1 = new FinderPattern(value, startEnd, startEnd[0], startEnd[1], image.getHeight() / 2);
+ //{1, 8, 4, 1, 1};
+ DataCharacter dataCharacter = rssExpandedReader.decodeDataCharacter(row, finderPatternA1, true, false);
+
+ assertEquals(19, dataCharacter.getValue());
+ assertEquals(1007, dataCharacter.getChecksumPortion());
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3103_DecoderTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3103_DecoderTest.java
new file mode 100644
index 0000000..d82f441
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3103_DecoderTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+public class AI01_3103_DecoderTest extends AbstractDecoderTest {
+
+ private static final String header = "..X..";
+
+ public void test01_3103_1() throws Exception {
+ String data = header + compressedGtin_900123456798908 + compressed15bitWeight_1750;
+ String expected = "(01)90012345678908(3103)001750";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_3103_2() throws Exception {
+ String data = header + compressedGtin_900000000000008 + compressed15bitWeight_0;
+ String expected = "(01)90000000000003(3103)000000";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_3103_invalid() throws Exception {
+ String data = header + compressedGtin_900123456798908 + compressed15bitWeight_1750 + "..";
+
+ try{
+ assertCorrectBinaryString(data, "");
+ fail(NotFoundException.class.getName() + " expected");
+ }catch(NotFoundException nfe){
+ // expected
+ }
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.java
new file mode 100644
index 0000000..1c7c0ae
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+public class AI01_3202_3203_DecoderTest extends AbstractDecoderTest {
+ private static final String header = "..X.X";
+
+ public void test01_3202_1() throws Exception {
+ String data = header + compressedGtin_900123456798908 + compressed15bitWeight_1750;
+ String expected = "(01)90012345678908(3202)001750";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_3203_1() throws Exception {
+ String data = header + compressedGtin_900123456798908 + compressed15bitWeight_11750;
+ String expected = "(01)90012345678908(3203)001750";
+
+ assertCorrectBinaryString(data, expected);
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.java
new file mode 100644
index 0000000..a9f3543
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+public class AI01_3X0X_1X_DecoderTest extends AbstractDecoderTest {
+
+ private static final String header_310x_11 = "..XXX...";
+ private static final String header_320x_11 = "..XXX..X";
+ private static final String header_310x_13 = "..XXX.X.";
+ private static final String header_320x_13 = "..XXX.XX";
+ private static final String header_310x_15 = "..XXXX..";
+ private static final String header_320x_15 = "..XXXX.X";
+ private static final String header_310x_17 = "..XXXXX.";
+ private static final String header_320x_17 = "..XXXXXX";
+
+ public void test01_310X_1X_endDate() throws Exception {
+ String data = header_310x_11 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_End;
+ String expected = "(01)90012345678908(3100)001750";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_310X_11_1() throws Exception {
+ String data = header_310x_11 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_March_12th_2010;
+ String expected = "(01)90012345678908(3100)001750(11)100312";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_320X_11_1() throws Exception {
+ String data = header_320x_11 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_March_12th_2010;
+ String expected = "(01)90012345678908(3200)001750(11)100312";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_310X_13_1() throws Exception {
+ String data = header_310x_13 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_March_12th_2010;
+ String expected = "(01)90012345678908(3100)001750(13)100312";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_320X_13_1() throws Exception {
+ String data = header_320x_13 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_March_12th_2010;
+ String expected = "(01)90012345678908(3200)001750(13)100312";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_310X_15_1() throws Exception {
+ String data = header_310x_15 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_March_12th_2010;
+ String expected = "(01)90012345678908(3100)001750(15)100312";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_320X_15_1() throws Exception {
+ String data = header_320x_15 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_March_12th_2010;
+ String expected = "(01)90012345678908(3200)001750(15)100312";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_310X_17_1() throws Exception {
+ String data = header_310x_17 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_March_12th_2010;
+ String expected = "(01)90012345678908(3100)001750(17)100312";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void test01_320X_17_1() throws Exception {
+ String data = header_320x_17 + compressedGtin_900123456798908 + compressed20bitWeight_1750 + compressedDate_March_12th_2010;
+ String expected = "(01)90012345678908(3200)001750(17)100312";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AbstractDecoderTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AbstractDecoderTest.java
new file mode 100644
index 0000000..29a5b28
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AbstractDecoderTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import com.google.zxing.common.BitArray;
+import com.google.zxing.oned.rss.expanded.BinaryUtil;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+public abstract class AbstractDecoderTest extends TestCase {
+
+ protected static final String numeric_10 = "..X..XX";
+ protected static final String numeric_12 = "..X.X.X";
+ protected static final String numeric_1FNC1 = "..XXX.X";
+ protected static final String numeric_FNC11 = "XXX.XXX";
+
+ protected static final String numeric2alpha = "....";
+
+ protected static final String alpha_A = "X.....";
+ protected static final String alpha_FNC1 = ".XXXX";
+ protected static final String alpha2numeric = "...";
+ protected static final String alpha2isoiec646 = "..X..";
+
+ protected static final String i646_B = "X.....X";
+ protected static final String i646_C = "X....X.";
+ protected static final String i646_FNC1 = ".XXXX";
+ protected static final String isoiec646_2alpha = "..X..";
+
+ protected static final String compressedGtin_900123456798908 = ".........X..XXX.X.X.X...XX.XXXXX.XXXX.X.";
+ protected static final String compressedGtin_900000000000008 = "........................................";
+
+ protected static final String compressed15bitWeight_1750 = "....XX.XX.X.XX.";
+ protected static final String compressed15bitWeight_11750 = ".X.XX.XXXX..XX.";
+ protected static final String compressed15bitWeight_0 = "...............";
+
+ protected static final String compressed20bitWeight_1750 = ".........XX.XX.X.XX.";
+
+ protected static final String compressedDate_March_12th_2010 = "....XXXX.X..XX..";
+ protected static final String compressedDate_End = "X..X.XX.........";
+
+ protected void assertCorrectBinaryString(String binaryString, String expectedNumber) throws NotFoundException {
+ BitArray binary = BinaryUtil.buildBitArrayFromStringWithoutSpaces(binaryString);
+ AbstractExpandedDecoder decoder = AbstractExpandedDecoder.createDecoder(binary);
+ String result = decoder.parseInformation();
+ assertEquals(expectedNumber, result);
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoderTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoderTest.java
new file mode 100644
index 0000000..1afaab3
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoderTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ */
+public class AnyAIDecoderTest extends AbstractDecoderTest {
+
+ private static final String header = ".....";
+
+ public void testAnyAIDecoder_1() throws Exception {
+ String data = header + numeric_10 + numeric_12 + numeric2alpha + alpha_A + alpha2numeric + numeric_12;
+ String expected = "(10)12A12";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void testAnyAIDecoder_2() throws Exception {
+ String data = header + numeric_10 + numeric_12 + numeric2alpha + alpha_A + alpha2isoiec646 + i646_B;
+ String expected = "(10)12AB";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void testAnyAIDecoder_3() throws Exception {
+ String data = header + numeric_10 + numeric2alpha + alpha2isoiec646 + i646_B + i646_C + isoiec646_2alpha + alpha_A + alpha2numeric + numeric_10;
+ String expected = "(10)BCA10";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void testAnyAIDecoder_numericFNC1_secondDigit() throws Exception {
+ String data = header + numeric_10 + numeric_1FNC1;
+ String expected = "(10)1";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void testAnyAIDecoder_alphaFNC1() throws Exception {
+ String data = header + numeric_10 + numeric2alpha + alpha_A + alpha_FNC1;
+ String expected = "(10)A";
+
+ assertCorrectBinaryString(data, expected);
+ }
+
+ public void testAnyAIDecoder_646FNC1() throws Exception {
+ String data = header + numeric_10 + numeric2alpha + alpha_A + isoiec646_2alpha + i646_B + i646_FNC1;
+ String expected = "(10)AB";
+
+ assertCorrectBinaryString(data, expected);
+ }
+}
diff --git a/core/test/src/com/google/zxing/oned/rss/expanded/decoders/FieldParserTest.java b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/FieldParserTest.java
new file mode 100644
index 0000000..e35c091
--- /dev/null
+++ b/core/test/src/com/google/zxing/oned/rss/expanded/decoders/FieldParserTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+package com.google.zxing.oned.rss.expanded.decoders;
+
+import com.google.zxing.NotFoundException;
+import junit.framework.TestCase;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna at deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo at deusto.es)
+ */
+public class FieldParserTest extends TestCase{
+
+ private static void checkFields(String expected) throws NotFoundException {
+ String field = expected.replace("(", "").replace(")","");
+ String actual = FieldParser.parseFieldsInGeneralPurpose(field);
+ assertEquals(expected, actual);
+ }
+
+ public void testParseField() throws Exception{
+ checkFields("(15)991231(3103)001750(10)12A");
+ }
+
+ public void testParseField2() throws Exception{
+ checkFields("(15)991231(15)991231(3103)001750(10)12A");
+ }
+}
--
Multi-format 1D/2D barcode image processing library
More information about the Pkg-google-commits
mailing list