updated all actionscript files in accordance with the core library revision 1901

git-svn-id: https://zxing.googlecode.com/svn/trunk@2110 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
bas5winkel@gmail.com 2012-01-11 17:02:26 +00:00
parent 9ee56c0b61
commit 9117b2b164
28 changed files with 3512 additions and 0 deletions

View file

@ -0,0 +1,112 @@
/*
* 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 class AbstractRSSReader extends OneDReader {
private static var MAX_AVG_VARIANCE:int = Math.round(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.2);
private static var MAX_INDIVIDUAL_VARIANCE:int = Math.round(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.4);
private static var MIN_FINDER_PATTERN_RATIO:Number = 9.5 / 12.0;
private static var MAX_FINDER_PATTERN_RATIO:Number = 12.5 / 14.0;
protected var decodeFinderCounters:Array;
protected var dataCharacterCounters:Array;
protected var oddRoundingErrors:Array;
protected var evenRoundingErrors:Array;
protected var oddCounts:Array;
protected var evenCounts:Array;
public function AbstractRSSReader(){
decodeFinderCounters = new Array(4);
dataCharacterCounters = new Array(8);
oddRoundingErrors = new Array(4);
evenRoundingErrors = new Array(4);
oddCounts = new Array(dataCharacterCounters.length / 2);
evenCounts = new Array(dataCharacterCounters.length / 2);
}
protected static function parseFinderValue(counters:Array, finderPatterns:Array):int {
for (var value:int = 0; value < finderPatterns.length; value++) {
if (patternMatchVariance(counters, finderPatterns[value], MAX_INDIVIDUAL_VARIANCE) <
MAX_AVG_VARIANCE) {
return value;
}
}
throw NotFoundException.getNotFoundInstance();
}
protected static function count(array:Array):int {
var count:int = 0;
for (var i:int = 0; i < array.length; i++) {
count += array[i];
}
return count;
}
protected static function increment(array:Array, errors:Array):void {
var index:int = 0;
var biggestError:Number = errors[0];
for (var i:int = 1; i < array.length; i++) {
if (errors[i] > biggestError) {
biggestError = errors[i];
index = i;
}
}
array[index]++;
}
protected static function decrement(array:Array, errors:Array):void {
var index:int = 0;
var biggestError:Array = errors[0];
for (var i:int = 1; i < array.length; i++) {
if (errors[i] < biggestError) {
biggestError = errors[i];
index = i;
}
}
array[index]--;
}
protected static function isFinderPattern(counters:Array):Boolean {
var firstTwoSum:int = counters[0] + counters[1];
var sum:int = firstTwoSum + counters[2] + counters[3];
var ratio:Number = firstTwoSum / sum;
if (ratio >= MIN_FINDER_PATTERN_RATIO && ratio <= MAX_FINDER_PATTERN_RATIO) {
// passes ratio test in spec, but see if the counts are unreasonable
var minCounter:int = int.MAX_VALUE;
var maxCounter:int = int.MIN_VALUE;
for (var i:int = 0; i < counters.length; i++) {
var counter:int = counters[i];
if (counter > maxCounter) {
maxCounter = counter;
}
if (counter < minCounter) {
minCounter = counter;
}
}
return maxCounter < 10 * minCounter;
}
return false;
}
}
}

View file

@ -0,0 +1,39 @@
/*
* Copyright 2009 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
{
public class DataCharacter {
private var value:int;
private var checksumPortion:int;
public function DataCharacter(value:int, checksumPortion:int) {
this.value = value;
this.checksumPortion = checksumPortion;
}
public function getValue():int {
return value;
}
public function getChecksumPortion():int {
return checksumPortion;
}
}
}

View file

@ -0,0 +1,51 @@
/*
* Copyright 2009 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.ResultPoint;
public class FinderPattern {
protected var value:int;
protected var startEnd:Array;
protected var resultPoints:Array;
public function FinderPattern( value:int, startEnd:Array, start:int, end:int, rowNumber:int) {
this.value = value;
this.startEnd = startEnd;
this.resultPoints = [
new ResultPoint( start as Number, rowNumber as Number),
new ResultPoint( end as Number, rowNumber as Number),
];
}
public function getValue():int {
return value;
}
public function getStartEnd():Array {
return startEnd;
}
public function getResultPoints():Array {
return resultPoints;
}
}
}

View file

@ -0,0 +1,42 @@
/*
* Copyright 2009 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
{
public class Pair extends DataCharacter {
protected var finderPattern:FinderPattern;
protected var count:int;
public function Pair(value:int, checksumPortion:int, finderPattern:FinderPattern) {
super(value, checksumPortion);
this.finderPattern = finderPattern;
}
public function getFinderPattern():FinderPattern {
return finderPattern;
}
public function getCount():int {
return count;
}
public function incrementCount():void {
count++;
}
}
}

View file

@ -0,0 +1,509 @@
/*
* Copyright 2009 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.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.NotFoundException;
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.common.flexdatatypes.ArrayList;
import com.google.zxing.common.flexdatatypes.Enumeration;
import com.google.zxing.common.flexdatatypes.HashTable;
import com.google.zxing.common.flexdatatypes.StringBuilder;
/**
* Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006.
*/
public class RSS14Reader extends AbstractRSSReader
{
private static var OUTSIDE_EVEN_TOTAL_SUBSET:Array = [1,10,34,70,126];
private static var INSIDE_ODD_TOTAL_SUBSET:Array = [4,20,48,81];
private static var OUTSIDE_GSUM:Array = [0,161,961,2015,2715];
private static var INSIDE_GSUM:Array = [0,336,1036,1516];
private static var OUTSIDE_ODD_WIDEST:Array = [8,6,4,3,1];
private static var INSIDE_ODD_WIDEST:Array = [2,4,6,8];
private static var FINDER_PATTERNS:Array = [
[3,8,2,1],
[3,5,5,1],
[3,3,7,1],
[3,1,9,1],
[2,7,4,1],
[2,5,6,1],
[2,3,8,1],
[1,5,7,1],
[1,3,9,1],
];
private var possibleLeftPairs:ArrayList;
private var possibleRightPairs:ArrayList;
public function RSS14Reader()
{
possibleLeftPairs = new ArrayList();
possibleRightPairs = new ArrayList();
}
public override function decodeRow(rowNumber:Object , row:BitArray , o:Object ):Result
{
var leftPair:Pair = decodePair(row, false, rowNumber as int, o as HashTable);
addOrTally(possibleLeftPairs, leftPair);
row.reverse();
var rightPair:Pair = decodePair(row, true, rowNumber as int, o as HashTable);
addOrTally(possibleRightPairs, rightPair);
row.reverse();
var numLeftPairs:int = possibleLeftPairs.size();
var numRightPairs:int = possibleRightPairs.size();
for (var l:int = 0; l < numLeftPairs; l++) {
var left:Pair = possibleLeftPairs.elementAt(l) as Pair;
if (left.getCount() > 1) {
for (var r:int = 0; r < numRightPairs; r++) {
var right:Pair = possibleRightPairs.elementAt(r) as Pair;
if (right.getCount() > 1) {
if (checkChecksum(left, right)) {
return constructResult(left, right);
}
}
}
}
}
throw NotFoundException.getNotFoundInstance();
}
private static function addOrTally(possiblePairs:ArrayList, pair:Pair):void
{
if (pair != null)
{
//var e:Enumeration = new Enumeration(possiblePairs.elements());
var found:Boolean = false;
var cntr:int = 0;
var max:int = possiblePairs.Count;
for(var i:int=0;i<max;i++)
{
var other:Pair = possiblePairs.elementAt(i) as Pair;
if (other.getValue() == pair.getValue())
{
other.incrementCount();
found = true;
break;
}
}
if (!found) {
possiblePairs.addElement(pair);
}
}
}
public override function reset():void {
possibleLeftPairs.clearAll();//.setSize(0);
possibleRightPairs.clearAll();//.setSize(0);
}
private static function constructResult(leftPair:Pair, rightPair:Pair):Result {
var symbolValue:Number = 4537077 * leftPair.getValue() + rightPair.getValue();
var text:String = symbolValue.toString();
var buffer:StringBuilder = new StringBuilder(14);
for (var i:int = 13 - text.length; i > 0; i--) {
buffer.Append('0');
}
buffer.Append(text);
var checkDigit:int = 0;
for (i = 0; i < 13; i++) {
var digit:int = (buffer.charAt(i)).charCodeAt(0) - ('0' as String).charCodeAt(0);
checkDigit += (i & 0x01) == 0 ? 3 * digit : digit;
}
checkDigit = 10 - (checkDigit % 10);
if (checkDigit == 10) {
checkDigit = 0;
}
buffer.Append(checkDigit);
var leftPoints:Array = leftPair.getFinderPattern().getResultPoints();
var rightPoints:Array = rightPair.getFinderPattern().getResultPoints();
return new Result(
buffer.toString(),
null,
[ leftPoints[0], leftPoints[1], rightPoints[0], rightPoints[1], ],
BarcodeFormat.RSS_14);
}
private static function checkChecksum(leftPair:Pair, rightPair:Pair):Boolean {
var leftFPValue:int = leftPair.getFinderPattern().getValue();
var rightFPValue:int = rightPair.getFinderPattern().getValue();
if ((leftFPValue == 0 && rightFPValue == 8) ||
(leftFPValue == 8 && rightFPValue == 0)) {
}
var checkValue:int = (leftPair.getChecksumPortion() + 16 * rightPair.getChecksumPortion()) % 79;
var targetCheckValue:int =
9 * leftPair.getFinderPattern().getValue() + rightPair.getFinderPattern().getValue();
if (targetCheckValue > 72) {
targetCheckValue--;
}
if (targetCheckValue > 8) {
targetCheckValue--;
}
return checkValue == targetCheckValue;
}
private function decodePair( row:BitArray, right:Boolean, rowNumber:int, hints:HashTable):Pair
{
try {
var startEnd:Array = findFinderPattern(row, 0, right);
var pattern:FinderPattern = parseFoundFinderPattern(row, rowNumber, right, startEnd);
var resultPointCallback:ResultPointCallback = hints == null ? null :
(hints._get(DecodeHintType.NEED_RESULT_POINT_CALLBACK) as ResultPointCallback);
if (resultPointCallback != null) {
var center:Number = (startEnd[0] + startEnd[1]) / 2.0;
if (right) {
// row is actually reversed
center = row.getSize() - 1 - center;
}
resultPointCallback.foundPossibleResultPoint(new ResultPoint(center, rowNumber));
}
var outside:DataCharacter = decodeDataCharacter(row, pattern, true);
var inside:DataCharacter = decodeDataCharacter(row, pattern, false);
return new Pair(1597 * outside.getValue() + inside.getValue(),
outside.getChecksumPortion() + 4 * inside.getChecksumPortion(),
pattern);
} catch (re:NotFoundException) {
return null;
}
return null;//
}
private function decodeDataCharacter(row:BitArray, pattern:FinderPattern , outsideChar:Boolean ):DataCharacter {
var counters:Array = 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 (outsideChar) {
recordPatternInReverse(row, pattern.getStartEnd()[0], counters);
} else {
recordPattern(row, pattern.getStartEnd()[1] + 1, counters);
// reverse it
var j:int;
for (i = 0, j = counters.length - 1; i < j; i++, j--) {
var temp:int = counters[i];
counters[i] = counters[j];
counters[j] = temp;
}
}
var numModules:int = outsideChar ? 16 : 15;
var elementWidth:Number = count(counters) / numModules;
var oddCounts:Array = this.oddCounts;
var evenCounts:Array = this.evenCounts;
var oddRoundingErrors:Array = this.oddRoundingErrors;
var evenRoundingErrors:Array = this.evenRoundingErrors;
for (var i:int = 0; i < counters.length; i++)
{
var value:Number = counters[i] / elementWidth;
var count:int = int(value + 0.5); // Round
if (count < 1) {
count = 1;
} else if (count > 8) {
count = 8;
}
var offset:int = i >> 1;
if ((i & 0x01) == 0) {
oddCounts[offset] = count;
oddRoundingErrors[offset] = value - count;
} else {
evenCounts[offset] = count;
evenRoundingErrors[offset] = value - count;
}
}
adjustOddEvenCounts(outsideChar, numModules);
var oddSum:int = 0;
var oddChecksumPortion:int = 0;
for (i = oddCounts.length - 1; i >= 0; i--) {
oddChecksumPortion *= 9;
oddChecksumPortion += oddCounts[i];
oddSum += oddCounts[i];
}
var evenChecksumPortion:int = 0;
var evenSum:int = 0;
for (i = evenCounts.length - 1; i >= 0; i--) {
evenChecksumPortion *= 9;
evenChecksumPortion += evenCounts[i];
evenSum += evenCounts[i];
}
var checksumPortion:int = oddChecksumPortion + 3*evenChecksumPortion;
if (outsideChar) {
if ((oddSum & 0x01) != 0 || oddSum > 12 || oddSum < 4) {
throw NotFoundException.getNotFoundInstance();
}
var group:int = (12 - oddSum) / 2;
var oddWidest:int = OUTSIDE_ODD_WIDEST[group];
var evenWidest:int = 9 - oddWidest;
var vOdd:int = RSSUtils.getRSSvalue(oddCounts, oddWidest, false);
var vEven:int = RSSUtils.getRSSvalue(evenCounts, evenWidest, true);
var tEven:int = OUTSIDE_EVEN_TOTAL_SUBSET[group];
var gSum:int = OUTSIDE_GSUM[group];
return new DataCharacter(vOdd * tEven + vEven + gSum, checksumPortion);
} else {
if ((evenSum & 0x01) != 0 || evenSum > 10 || evenSum < 4) {
throw NotFoundException.getNotFoundInstance();
}
group = (10 - evenSum) / 2;
oddWidest = INSIDE_ODD_WIDEST[group];
evenWidest = 9 - oddWidest;
vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
var tOdd:int = INSIDE_ODD_TOTAL_SUBSET[group];
gSum = INSIDE_GSUM[group];
return new DataCharacter(vEven * tOdd + vOdd + gSum, checksumPortion);
}
}
private function findFinderPattern(row:BitArray , rowOffset:int, rightFinderPattern:Boolean ):Array
{
var counters:Array = decodeFinderCounters;
counters[0] = 0;
counters[1] = 0;
counters[2] = 0;
counters[3] = 0;
var width:int = row.getSize();
var isWhite:Boolean = false;
while (rowOffset < width) {
isWhite = !row._get(rowOffset);
if (rightFinderPattern == isWhite) {
// Will encounter white first when searching for right finder pattern
break;
}
rowOffset++;
}
var counterPosition:int = 0;
var patternStart:int = rowOffset;
for (var x:int = rowOffset; x < width; x++) {
var pixel:Boolean = row._get(x);
if (pixel != isWhite) {
counters[counterPosition]++;
} else {
if (counterPosition == 3) {
if (isFinderPattern(counters)) {
return [patternStart, x];
}
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 function parseFoundFinderPattern(row:BitArray, rowNumber:int, right:Boolean, startEnd:Array):FinderPattern {
// Actually we found elements 2-5
var firstIsBlack:Boolean = row._get(startEnd[0]);
var firstElementStart:int = startEnd[0] - 1;
// Locate element 1
while (firstElementStart >= 0 && (firstIsBlack != row._get(firstElementStart))) {
firstElementStart--;
}
firstElementStart++;
var firstCounter:int = startEnd[0] - firstElementStart;
// Make 'counters' hold 1-4
var counters:Array = decodeFinderCounters;
for (var i:int = counters.length - 1; i > 0; i--) {
counters[i] = counters[i-1];
}
counters[0] = firstCounter;
var value:int = parseFinderValue(counters, FINDER_PATTERNS);
var start :int= firstElementStart;
var end:int = startEnd[1];
if (right) {
// row is actually reversed
start = row.getSize() - 1 - start;
end = row.getSize() - 1 - end;
}
return new FinderPattern(value, [firstElementStart, startEnd[1]], start, end, rowNumber);
}
/*
private static int[] normalizeE2SEValues(int[] counters) {
int p = 0;
for (int i = 0; i < counters.length; i++) {
p += counters[i];
}
int[] normalized = new int[counters.length - 2];
for (int i = 0; i < normalized.length; i++) {
int e = counters[i] + counters[i+1];
float eRatio = (float) e / (float) p;
float E = ((eRatio * 32.0f) + 1.0f) / 2.0f;
normalized[i] = (int) E;
}
return normalized;
}
*/
private function adjustOddEvenCounts(outsideChar:Boolean, numModules:int):void {
var oddSum:int = count(oddCounts);
var evenSum:int = count(evenCounts);
var mismatch:int = oddSum + evenSum - numModules;
var oddParityBad:Boolean = (oddSum & 0x01) == (outsideChar ? 1 : 0);
var evenParityBad:Boolean = (evenSum & 0x01) == 1;
var incrementOdd:Boolean = false;
var decrementOdd:Boolean = false;
var incrementEven:Boolean = false;
var decrementEven:Boolean = false;
if (outsideChar) {
if (oddSum > 12) {
decrementOdd = true;
} else if (oddSum < 4) {
incrementOdd = true;
}
if (evenSum > 12) {
decrementEven = true;
} else if (evenSum < 4) {
incrementEven = true;
}
} else {
if (oddSum > 11) {
decrementOdd = true;
} else if (oddSum < 5) {
incrementOdd = true;
}
if (evenSum > 10) {
decrementEven = true;
} else if (evenSum < 4) {
incrementEven = true;
}
}
/*if (mismatch == 2) {
if (!(oddParityBad && evenParityBad)) {
throw ReaderException.getInstance();
}
decrementOdd = true;
decrementEven = true;
} else if (mismatch == -2) {
if (!(oddParityBad && evenParityBad)) {
throw ReaderException.getInstance();
}
incrementOdd = true;
incrementEven = true;
} else */
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(oddCounts, oddRoundingErrors);
}
if (decrementOdd) {
decrement(oddCounts, oddRoundingErrors);
}
if (incrementEven) {
if (decrementEven) {
throw NotFoundException.getNotFoundInstance();
}
increment(evenCounts, oddRoundingErrors);
}
if (decrementEven) {
decrement(evenCounts, evenRoundingErrors);
}
}
}
}

View file

@ -0,0 +1,159 @@
/*
* Copyright 2009 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
{
/** Adapted from listings in ISO/IEC 24724 Appendix B and Appendix G. */
public class RSSUtils {
public function RSSUtils() {}
public static function getRSSwidths(val:int, n:int, elements:int,maxWidth:int, noNarrow:Boolean):Array
{
var widths:Array = new Array(elements);
var bar:int;
var narrowMask:int = 0;
for (bar = 0; bar < elements - 1; bar++) {
narrowMask |= (1 << bar);
var elmWidth:int = 1;
var subVal:int;
while (true) {
subVal = combins(n - elmWidth - 1, elements - bar - 2);
if (noNarrow && (narrowMask == 0) &&
(n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
subVal -= combins(n - elmWidth - (elements - bar), elements - bar - 2);
}
if (elements - bar - 1 > 1) {
var lessVal:int = 0;
for (var mxwElement:int = n - elmWidth - (elements - bar - 2);
mxwElement > maxWidth;
mxwElement--) {
lessVal += combins(n - elmWidth - mxwElement - 1, elements - bar - 3);
}
subVal -= lessVal * (elements - 1 - bar);
} else if (n - elmWidth > maxWidth) {
subVal--;
}
val -= subVal;
if (val < 0) {
break;
}
elmWidth++;
narrowMask &= ~(1 << bar);
}
val += subVal;
n -= elmWidth;
widths[bar] = elmWidth;
}
widths[bar] = n;
return widths;
}
public static function getRSSvalue(widths:Array, maxWidth:int, noNarrow:Boolean):int {
var elements:int = widths.length;
var n:int = 0;
for (var i:int = 0; i < elements; i++) {
n += widths[i];
}
var val:int = 0;
var narrowMask:int = 0;
for (var bar:int = 0; bar < elements - 1; bar++) {
var elmWidth:int;
for (elmWidth = 1, narrowMask |= (1 << bar);
elmWidth < widths[bar];
elmWidth++, narrowMask &= ~(1 << bar)) {
var subVal:int = combins(n - elmWidth - 1, elements - bar - 2);
if (noNarrow && (narrowMask == 0) &&
(n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
subVal -= combins(n - elmWidth - (elements - bar),
elements - bar - 2);
}
if (elements - bar - 1 > 1) {
var lessVal:int = 0;
for (var mxwElement:int = n - elmWidth - (elements - bar - 2);
mxwElement > maxWidth; mxwElement--) {
lessVal += combins(n - elmWidth - mxwElement - 1,
elements - bar - 3);
}
subVal -= lessVal * (elements - 1 - bar);
} else if (n - elmWidth > maxWidth) {
subVal--;
}
val += subVal;
}
n -= elmWidth;
}
return val;
}
public static function combins(n:int, r:int):int {
var maxDenom:int;
var minDenom:int;
if (n - r > r) {
minDenom = r;
maxDenom = n - r;
} else {
minDenom = n - r;
maxDenom = r;
}
var val:int = 1;
var j:int = 1;
for (var i:int = n; i > maxDenom; i--) {
val *= i;
if (j <= minDenom) {
val /= j;
j++;
}
}
while (j <= minDenom) {
val /= j;
j++;
}
return val;
}
public static function elements(eDist:Array, N:int, K:int):Array {
var widths:Array = new Array(eDist.length + 2);
var twoK:int = K << 1;
widths[0] = 1;
var i:int;
var minEven:int = 10;
var barSum:int = 1;
for (i = 1; i < twoK - 2; i += 2) {
widths[i] = eDist[i - 1] - widths[i - 1];
widths[i + 1] = eDist[i] - widths[i];
barSum += widths[i] + widths[i + 1];
if (widths[i] < minEven) {
minEven = widths[i];
}
}
widths[twoK - 1] = N - barSum;
if (widths[twoK - 1] < minEven) {
minEven = widths[twoK - 1];
}
if (minEven > 1) {
for (i = 0; i < twoK; i += 2) {
widths[i] += minEven - 1;
widths[i + 1] -= minEven - 1;
}
}
return widths;
}
}
}

View file

@ -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 com.google.zxing.common.flexdatatypes.ArrayList;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class BitArrayBuilder {
public function BitArrayBuilder() {
}
public static function buildBitArray(pairs:ArrayList):BitArray {
var charNumber:int = (pairs.size() << 1) - 1;
if ((pairs.lastElement() as ExpandedPair).getRightChar() == null) {
charNumber -= 1;
}
var size:int = 12 * charNumber;
var binary:BitArray = new BitArray(size);
var accPos:int = 0;
var firstPair:ExpandedPair = pairs.elementAt(0) as ExpandedPair;
var firstValue:int = firstPair.getRightChar().getValue();
for(var i:int = 11; i >= 0; --i){
if ((firstValue & (1 << i)) != 0) {
binary._set(accPos);
}
accPos++;
}
for(i = 1; i < pairs.size(); ++i){
var currentPair:ExpandedPair = pairs.elementAt(i) as ExpandedPair;
var leftValue:int = currentPair.getLeftChar().getValue();
for(var j:int = 11; j >= 0; --j){
if ((leftValue & (1 << j)) != 0) {
binary._set(accPos);
}
accPos++;
}
if(currentPair.getRightChar() != null){
var rightValue:int = currentPair.getRightChar().getValue();
for(j = 11; j >= 0; --j){
if ((rightValue & (1 << j)) != 0) {
binary._set(accPos);
}
accPos++;
}
}
}
return binary;
}
}
}

View file

@ -0,0 +1,71 @@
/*
* 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@deusto.es)
*/
public class ExpandedPair {
protected var _mayBeLast:Boolean;
protected var leftChar:DataCharacter;
protected var rightChar:DataCharacter;
protected var finderPattern:FinderPattern;
public function ExpandedPair(leftChar:DataCharacter, rightChar:DataCharacter, finderPattern:FinderPattern, mayBeLast:Boolean)
{
this.leftChar = leftChar;
this.rightChar = rightChar;
this.finderPattern = finderPattern;
this._mayBeLast = mayBeLast;
}
public function mayBeLast():Boolean{
return this._mayBeLast;
}
public function getLeftChar():DataCharacter {
return this.leftChar;
}
public function getRightChar():DataCharacter {
return this.rightChar;
}
public function getFinderPattern():FinderPattern {
return this.finderPattern;
}
public function mustBeLast():Boolean {
return this.rightChar == null;
}
}
}

View file

@ -0,0 +1,582 @@
/*
* 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.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.flexdatatypes.ArrayList;
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@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class RSSExpandedReader extends AbstractRSSReader{
private static var SYMBOL_WIDEST:Array = [7, 5, 4, 3, 1];
private static var EVEN_TOTAL_SUBSET:Array = [4, 20, 52, 104, 204];
private static var GSUM:Array = [0, 348, 1388, 2948, 3988];
private static var FINDER_PATTERNS:Array = [
[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 var WEIGHTS:Array = [
[ 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 var FINDER_PAT_A:int = 0;
private static var FINDER_PAT_B:int = 1;
private static var FINDER_PAT_C:int = 2;
private static var FINDER_PAT_D:int = 3;
private static var FINDER_PAT_E:int = 4;
private static var FINDER_PAT_F:int = 5;
private static var FINDER_PATTERN_SEQUENCES:Array = [
[ 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 var LONGEST_SEQUENCE_SIZE:int = FINDER_PATTERN_SEQUENCES[FINDER_PATTERN_SEQUENCES.length - 1].length;
private static var MAX_PAIRS:int = 11;
private var pairs:ArrayList = new ArrayList(MAX_PAIRS);
private var startEnd:Array = new Array(2);
private var currentSequence:Array = new Array(LONGEST_SEQUENCE_SIZE);
public override function decodeRow(rowNumber:Object , row:BitArray , o:Object ):Result {
this.reset();
decodeRow2pairs(rowNumber as int, row);
return constructResult(this.pairs);
}
public override function reset():void {
this.pairs.clearAll();//.setSize(0);
}
// Not private for testing
public function decodeRow2pairs(rowNumber:int , row:BitArray ): ArrayList {
while(true){
var nextPair:ExpandedPair = retrieveNextPair(row, this.pairs, rowNumber);
this.pairs.addElement(nextPair);
if (nextPair.mayBeLast())
{
if (checkChecksum()) {
return this.pairs;
}
if (nextPair.mustBeLast()) {
throw NotFoundException.getNotFoundInstance();
}
}
}
throw NotFoundException.getNotFoundInstance
}
private static function constructResult(pairs:ArrayList):Result{
var binary:BitArray = BitArrayBuilder.buildBitArray(pairs);
var decoder:AbstractExpandedDecoder = AbstractExpandedDecoder.createDecoder(binary);
var resultingString:String = decoder.parseInformation();
var firstPoints:Array = (pairs.elementAt(0) as ExpandedPair).getFinderPattern().getResultPoints();
var lastPoints:Array = (pairs.lastElement() as ExpandedPair).getFinderPattern().getResultPoints();
return new Result(
resultingString,
null,
[firstPoints[0], firstPoints[1], lastPoints[0], lastPoints[1]],
BarcodeFormat.RSS_EXPANDED
);
}
private function checkChecksum():Boolean
{
var firstPair:ExpandedPair = this.pairs.elementAt(0) as ExpandedPair;
var checkCharacter:DataCharacter = firstPair.getLeftChar();
var firstCharacter:DataCharacter = firstPair.getRightChar();
var checksum:int = firstCharacter.getChecksumPortion();
var S:int = 2;
for(var i:int = 1; i < this.pairs.size(); ++i){
var currentPair:ExpandedPair = this.pairs.elementAt(i) as ExpandedPair;
checksum += currentPair.getLeftChar().getChecksumPortion();
S++;
if(currentPair.getRightChar() != null){
checksum += currentPair.getRightChar().getChecksumPortion();
S++;
}
}
checksum %= 211;
var checkCharacterValue:int = 211 * (S - 4) + checksum;
return checkCharacterValue == checkCharacter.getValue();
}
private static function getNextSecondBar(row:BitArray, initialPos:int):int{
var currentPos:int = initialPos;
var current:Boolean = 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
public function retrieveNextPair(row:BitArray, previousPairs:ArrayList, rowNumber:int):ExpandedPair{
var isOddPattern:Boolean = previousPairs.size() % 2 == 0;
var pattern:FinderPattern;
var keepFinding:Boolean = true;
var forcedOffset:int = -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);
var mayBeLast:Boolean = checkPairSequence(previousPairs, pattern);
var leftChar:DataCharacter = this.decodeDataCharacter(row, pattern, isOddPattern, true);
var rightChar:DataCharacter;
try{
rightChar = this.decodeDataCharacter(row, pattern, isOddPattern, false);
}catch(nfe:NotFoundException){
if(mayBeLast) {
rightChar = null;
} else {
throw nfe;
}
}
return new ExpandedPair(leftChar, rightChar, pattern, mayBeLast);
}
private function checkPairSequence(previousPairs:ArrayList, pattern:FinderPattern):Boolean{
var currentSequenceLength:int = previousPairs.size() + 1;
if(currentSequenceLength > this.currentSequence.length) {
throw NotFoundException.getNotFoundInstance();
}
for(var pos:int = 0; pos < previousPairs.size(); ++pos) {
this.currentSequence[pos] = (previousPairs.elementAt(pos) as ExpandedPair).getFinderPattern().getValue();
}
this.currentSequence[currentSequenceLength - 1] = pattern.getValue();
for(var i:int = 0; i < FINDER_PATTERN_SEQUENCES.length; ++i){
var validSequence:Array = FINDER_PATTERN_SEQUENCES[i];
if(validSequence.length >= currentSequenceLength){
var valid:Boolean = true;
for(pos = 0; pos < currentSequenceLength; ++pos) {
if (this.currentSequence[pos] != validSequence[pos]) {
valid = false;
break;
}
}
if(valid) {
return currentSequenceLength == validSequence.length;
}
}
}
throw NotFoundException.getNotFoundInstance();
}
private function findNextPair(row:BitArray, previousPairs:ArrayList, forcedOffset:int):void{
var counters:Array = this.decodeFinderCounters;
counters[0] = 0;
counters[1] = 0;
counters[2] = 0;
counters[3] = 0;
var width:int = row.getSize();
var rowOffset:int;
if (forcedOffset >= 0) {
rowOffset = forcedOffset;
} else if (previousPairs.isEmpty()) {
rowOffset = 0;
} else{
var lastPair:ExpandedPair = previousPairs.lastElement() as ExpandedPair;
rowOffset = lastPair.getFinderPattern().getStartEnd()[1];
}
var searchingEvenPair:Boolean = ((previousPairs.size() % 2) != 0);
var isWhite:Boolean = false;
while (rowOffset < width) {
isWhite = !row._get(rowOffset);
if (!isWhite) {
break;
}
rowOffset++;
}
var counterPosition:int = 0;
var patternStart:int = rowOffset;
for (var x:int = rowOffset; x < width; x++) {
var pixel:Boolean = row._get(x);
if (pixel != isWhite) {
counters[counterPosition]++;
} else {
if (counterPosition == 3) {
if (searchingEvenPair) {
reverseCounters(counters);
}
var ifp:Boolean = isFinderPattern(counters);
if (ifp)
{
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 function reverseCounters(counters:Array):void{
var length:int = counters.length;
for(var i:int = 0; i < int(length / 2); ++i){
var tmp:int = counters[i];
counters[i] = counters[length - i - 1];
counters[length - i - 1] = tmp;
}
}
private function parseFoundFinderPattern(row:BitArray, rowNumber:int, oddPattern:Boolean):FinderPattern {
// Actually we found elements 2-5.
var firstCounter:int;
var start:int;
var end:int;
if(oddPattern){
// If pattern number is odd, we need to locate element 1 *before* the current block.
var firstElementStart:int = 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];
firstElementStart = this.startEnd[1] + 1;
while (firstElementStart < row.Size && row._get(firstElementStart)) {
firstElementStart++;
}
end = firstElementStart;
firstCounter = end - this.startEnd[1];
}
// Make 'counters' hold 1-4
var counters:Array = this.decodeFinderCounters;
for (var i:int = counters.length - 1; i > 0; i--) {
counters[i] = counters[i - 1];
}
counters[0] = firstCounter;
var value:int;
try {
value = parseFinderValue(counters, FINDER_PATTERNS);
} catch (nfe:NotFoundException) {
return null;
}
return new FinderPattern(value, [start, end], start, end, rowNumber);
}
public function decodeDataCharacter(row:BitArray, pattern:FinderPattern, isOddPattern:Boolean, leftChar:Boolean):DataCharacter
{
var counters:Array = 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
var j:int = counters.length - 1;
for (var i:int = 0; i < j; i++, j--) {
var temp:int = counters[i];
counters[i] = counters[j];
counters[j] = temp;
}
}//counters[] has the pixels of the module
var numModules:int = 17; //left and right data characters have all the same length
var elementWidth:Number = count(counters) / numModules;
var oddCounts:Array = this.oddCounts;
var evenCounts:Array = this.evenCounts;
var oddRoundingErrors:Array = this.oddRoundingErrors;
var evenRoundingErrors:Array = this.evenRoundingErrors;
for (i = 0; i < counters.length; i++) {
var value1:Number = 1.0 * counters[i] / elementWidth;
var count:int = int(value1 + 0.5);
if (count < 1) {
count = 1;
} else if (count > 8) {
count = 8;
}
var offset:int = i >> 1;
if ((i & 0x01) == 0) {
oddCounts[offset] = count;
oddRoundingErrors[offset] = value1 - count;
} else {
evenCounts[offset] = count;
evenRoundingErrors[offset] = value1 - count;
}
}
adjustOddEvenCounts(numModules);
var weightRowNumber:int = 4 * pattern.getValue() + (isOddPattern?0:2) + (leftChar?0:1) - 1;
var oddSum:int = 0;
var oddChecksumPortion:int = 0;
for (i = oddCounts.length - 1; i >= 0; i--) {
if(isNotA1left(pattern, isOddPattern, leftChar)){
var weight:int = WEIGHTS[weightRowNumber][2 * i];
oddChecksumPortion += oddCounts[i] * weight;
}
oddSum += oddCounts[i];
}
var evenChecksumPortion:int = 0;
var evenSum:int = 0;
for (i = evenCounts.length - 1; i >= 0; i--) {
if(isNotA1left(pattern, isOddPattern, leftChar)){
weight = WEIGHTS[weightRowNumber][2 * i + 1];
evenChecksumPortion += evenCounts[i] * weight;
}
evenSum += evenCounts[i];
}
var checksumPortion:int = oddChecksumPortion + evenChecksumPortion;
if ((oddSum & 0x01) != 0 || oddSum > 13 || oddSum < 4) {
throw NotFoundException.getNotFoundInstance();
}
var group:int = int((13 - oddSum) / 2);
var oddWidest:int = SYMBOL_WIDEST[group];
var evenWidest:int = 9 - oddWidest;
var vOdd:int = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
var vEven:int = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
var tEven:int = EVEN_TOTAL_SUBSET[group];
var gSum:int = GSUM[group];
var value2:int = vOdd * tEven + vEven + gSum;
return new DataCharacter(value2, checksumPortion);
}
private static function isNotA1left(pattern:FinderPattern, isOddPattern:Boolean, leftChar:Boolean):Boolean {
// A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char
return !(pattern.getValue() == 0 && isOddPattern && leftChar);
}
private function adjustOddEvenCounts(numModules:int):void {
var oddSum:int = count(this.oddCounts);
var evenSum:int = count(this.evenCounts);
var mismatch:int = oddSum + evenSum - numModules;
var oddParityBad:Boolean = (oddSum & 0x01) == 1;
var evenParityBad:Boolean = (evenSum & 0x01) == 0;
var incrementOdd:Boolean = false;
var decrementOdd:Boolean = false;
if (oddSum > 13) {
decrementOdd = true;
} else if (oddSum < 4) {
incrementOdd = true;
}
var incrementEven:Boolean = false;
var decrementEven:Boolean = 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);
}
}
}
}

View file

@ -0,0 +1,50 @@
/*
* 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;
import com.google.zxing.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
*/
public class AI013103decoder extends AI013x0xDecoder {
public function AI013103decoder(information:BitArray) {
super(information);
}
protected override function addWeightCode(buf:StringBuilder, weight:int):void {
buf.Append("(3103)");
}
protected override function checkWeight(weight:int):int {
return weight;
}
}
}

View file

@ -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;
import com.google.zxing.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
*/
public class AI01320xDecoder extends AI013x0xDecoder {
public function AI01320xDecoder(information:BitArray) {
super(information);
}
protected override function addWeightCode(buf:StringBuilder , weight:int):void {
if (weight < 10000) {
buf.Append("(3202)");
} else {
buf.Append("(3203)");
}
}
protected override function checkWeight(weight:int):int {
if(weight < 10000) {
return weight;
}
return weight - 10000;
}
}
}

View file

@ -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
{
import com.google.zxing.NotFoundException;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
*/
public class AI01392xDecoder extends AI01decoder {
private static var HEADER_SIZE:int = 5 + 1 + 2;
private static var LAST_DIGIT_SIZE:int = 2;
public function AI01392xDecoder(information:BitArray) {
super(information);
}
public override function parseInformation():String {
if (this.information.Size < HEADER_SIZE + GTIN_SIZE) {
throw NotFoundException.getNotFoundInstance();
}
var buf:StringBuilder = new StringBuilder();
encodeCompressedGtin(buf, HEADER_SIZE);
var lastAIdigit:int =
this.generalDecoder.extractNumericValueFromBitArray2(HEADER_SIZE + GTIN_SIZE, LAST_DIGIT_SIZE);
buf.Append("(392");
buf.Append(lastAIdigit);
buf.Append(')');
var decodedInformation:DecodedInformation =
this.generalDecoder.decodeGeneralPurposeField(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE, null);
buf.Append(decodedInformation.getNewString());
return buf.toString();
}
}
}

View file

@ -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.oned.rss.expanded.decoders
{
import com.google.zxing.NotFoundException;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
*/
public class AI01393xDecoder extends AI01decoder {
private static var HEADER_SIZE:int = 5 + 1 + 2;
private static var LAST_DIGIT_SIZE:int = 2;
private static var FIRST_THREE_DIGITS_SIZE:int = 10;
public function AI01393xDecoder(information:BitArray) {
super(information);
}
public override function parseInformation():String {
if(this.information.Size < HEADER_SIZE + GTIN_SIZE) {
throw NotFoundException.getNotFoundInstance();
}
var buf:StringBuilder = new StringBuilder();
encodeCompressedGtin(buf, HEADER_SIZE);
var lastAIdigit:int =
this.generalDecoder.extractNumericValueFromBitArray2(HEADER_SIZE + GTIN_SIZE, LAST_DIGIT_SIZE);
buf.Append("(393");
buf.Append(lastAIdigit);
buf.Append(')');
var firstThreeDigits:int =
this.generalDecoder.extractNumericValueFromBitArray2(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE, FIRST_THREE_DIGITS_SIZE);
if(int(firstThreeDigits / 100) == 0) {
buf.Append('0');
}
if(int(firstThreeDigits / 10) == 0) {
buf.Append('0');
}
buf.Append(firstThreeDigits);
var generalInformation:DecodedInformation =
this.generalDecoder.decodeGeneralPurposeField(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE + FIRST_THREE_DIGITS_SIZE, null);
buf.Append(generalInformation.getNewString());
return buf.toString();
}
}
}

View file

@ -0,0 +1,108 @@
/*
* 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.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class AI013x0x1xDecoder extends AI01weightDecoder {
private static var HEADER_SIZE:int = 7 + 1;
private static var WEIGHT_SIZE:int = 20;
private static var DATE_SIZE:int = 16;
private var dateCode:String;
private var firstAIdigits:String;
public function AI013x0x1xDecoder(information:BitArray, firstAIdigits:String, dateCode:String) {
super(information);
this.dateCode = dateCode;
this.firstAIdigits = firstAIdigits;
}
public override function parseInformation():String {
if (this.information.Size != HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE + DATE_SIZE) {
throw NotFoundException.getNotFoundInstance();
}
var buf:StringBuilder = new StringBuilder();
encodeCompressedGtin(buf, HEADER_SIZE);
encodeCompressedWeight(buf, HEADER_SIZE + GTIN_SIZE, WEIGHT_SIZE);
encodeCompressedDate(buf, HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE);
return buf.toString();
}
private function encodeCompressedDate(buf:StringBuilder, currentPos:int):void {
var numericDate:int = this.generalDecoder.extractNumericValueFromBitArray2(currentPos, DATE_SIZE);
if(numericDate == 38400) {
return;
}
buf.Append('(');
buf.Append(this.dateCode);
buf.Append(')');
var day:int = numericDate % 32;
numericDate = int(numericDate / 32);
var month:int = numericDate % 12 + 1;
numericDate = int(numericDate / 12);
var year:int = numericDate;
if (int(year / 10) == 0) {
buf.Append('0');
}
buf.Append(year);
if (int(month / 10) == 0) {
buf.Append('0');
}
buf.Append(month);
if (day / 10 == 0) {
buf.Append('0');
}
buf.Append(day);
}
protected override function addWeightCode(buf:StringBuilder, weight:int):void {
var lastAI:int = int(weight / 100000);
buf.Append('(');
buf.Append(this.firstAIdigits);
buf.Append(lastAI);
buf.Append(')');
}
protected override function checkWeight(weight:int):int {
return weight % 100000;
}
}
}

View file

@ -0,0 +1,59 @@
/*
* 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.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
*/
public class AI013x0xDecoder extends AI01weightDecoder {
private static var HEADER_SIZE:int = 4 + 1;
private static var WEIGHT_SIZE:int = 15;
public function AI013x0xDecoder(information:BitArray) {
super(information);
}
public override function parseInformation():String {
if (this.information.Size != HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE) {
throw NotFoundException.getNotFoundInstance();
}
var buf:StringBuilder = new StringBuilder();
encodeCompressedGtin(buf, HEADER_SIZE);
encodeCompressedWeight(buf, HEADER_SIZE + GTIN_SIZE, WEIGHT_SIZE);
return buf.toString();
}
}
}

View file

@ -0,0 +1,59 @@
/*
* 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.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class AI01AndOtherAIs extends AI01decoder {
private static var HEADER_SIZE:int = 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
public function AI01AndOtherAIs(information:BitArray) {
super(information);
}
public override function parseInformation():String {
var buff:StringBuilder = new StringBuilder();
buff.Append("(01)");
var initialGtinPosition:int = buff.length;
var firstGtinDigit:int = this.generalDecoder.extractNumericValueFromBitArray2(HEADER_SIZE, 4);
buff.Append(firstGtinDigit);
this.encodeCompressedGtinWithoutAI(buff, HEADER_SIZE + 4, initialGtinPosition);
return this.generalDecoder.decodeAllCodes(buff, HEADER_SIZE + 44);
}
}
}

View file

@ -0,0 +1,84 @@
/*
* 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;
import com.google.zxing.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class AI01decoder extends AbstractExpandedDecoder {
protected static var GTIN_SIZE:int = 40;
public function AI01decoder(information:BitArray) {
super(information);
}
protected function encodeCompressedGtin(buf:StringBuilder, currentPos:int):void {
buf.Append("(01)");
var initialPosition:int = buf.length;
buf.Append('9');
encodeCompressedGtinWithoutAI(buf, currentPos, initialPosition);
}
protected function encodeCompressedGtinWithoutAI(buf:StringBuilder , currentPos:int, initialBufferPosition:int):void {
for(var i:int = 0; i < 4; ++i){
var currentBlock:int = this.generalDecoder.extractNumericValueFromBitArray2(currentPos + 10 * i, 10);
if (int(currentBlock / 100) == 0) {
buf.Append('0');
}
if (int(currentBlock / 10) == 0) {
buf.Append('0');
}
buf.Append(currentBlock);
}
appendCheckDigit(buf, initialBufferPosition);
}
private static function appendCheckDigit(buf:StringBuilder, currentPos:int):void{
var checkDigit:int = 0;
for (var i:int = 0; i < 13; i++) {
var digit:int = (buf.charAt(i + currentPos)).charCodeAt(0) - ('0' as String).charCodeAt(0);
checkDigit += (i & 0x01) == 0 ? 3 * digit : digit;
}
checkDigit = 10 - (checkDigit % 10);
if (checkDigit == 10) {
checkDigit = 0;
}
buf.Append(checkDigit);
}
}
}

View file

@ -0,0 +1,61 @@
/*
* 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;
import com.google.zxing.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
*/
public class AI01weightDecoder extends AI01decoder {
public function AI01weightDecoder(information:BitArray) {
super(information);
}
protected function encodeCompressedWeight(buf:StringBuilder, currentPos:int, weightSize:int):void {
var originalWeightNumeric:int = this.generalDecoder.extractNumericValueFromBitArray2(currentPos, weightSize);
addWeightCode(buf, originalWeightNumeric);
var weightNumeric:int = checkWeight(originalWeightNumeric);
var currentDivisor:int = 100000;
for(var i:int = 0; i < 5; ++i){
if (int(weightNumeric / currentDivisor) == 0) {
buf.Append('0');
}
currentDivisor = int(currentDivisor / 10);
}
buf.Append(weightNumeric);
}
protected function addWeightCode(buf:StringBuilder, weight:int):void{}
protected function checkWeight(weight:int):int{ return 0;}
}
}

View file

@ -0,0 +1,87 @@
/*
* 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@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class AbstractExpandedDecoder {
protected var information:BitArray;
protected var generalDecoder:GeneralAppIdDecoder;
public function AbstractExpandedDecoder(information:BitArray){
this.information = information;
this.generalDecoder = new GeneralAppIdDecoder(information);
}
public function parseInformation():String{ return '';}
public static function createDecoder(information:BitArray):AbstractExpandedDecoder{
if (information._get(1)) {
return new AI01AndOtherAIs(information);
}
if (!information._get(2)) {
return new AnyAIDecoder(information);
}
var fourBitEncodationMethod:int = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 4);
switch(fourBitEncodationMethod){
case 4: return new AI013103decoder(information);
case 5: return new AI01320xDecoder(information);
}
var fiveBitEncodationMethod:int = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 5);
switch(fiveBitEncodationMethod){
case 12: return new AI01392xDecoder(information);
case 13: return new AI01393xDecoder(information);
}
var sevenBitEncodationMethod:int = 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 Error("unknown decoder: " + information);
}
}
}

View file

@ -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 com.google.zxing.common.BitArray;
import com.google.zxing.common.flexdatatypes.StringBuilder;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class AnyAIDecoder extends AbstractExpandedDecoder {
private static var HEADER_SIZE:int = 2 + 1 + 2;
public function AnyAIDecoder(information:BitArray) {
super(information);
}
public override function parseInformation():String {
var buf:StringBuilder = new StringBuilder();
return this.generalDecoder.decodeAllCodes(buf, HEADER_SIZE);
}
}
}

View file

@ -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
{
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
* */
public class BlockParsedResult {
protected var decodedInformation:DecodedInformation;
protected var finished:Boolean;
/*
public function BlockParsedResult(finished:Boolean) {
this(null, finished);
}
*/
public function BlockParsedResult(information:DecodedInformation, finished:Boolean) {
this.finished = finished;
this.decodedInformation = information;
}
public function getDecodedInformation():DecodedInformation {
return this.decodedInformation;
}
public function isFinished():Boolean {
return this.finished;
}
}
}

View file

@ -0,0 +1,71 @@
/*
* 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@deusto.es)
*/
public class CurrentParsingState {
public var position:int;
protected var encoding:int;
public static var NUMERIC:int = 1;
public static var ALPHA:int = 2;
static public var ISO_IEC_646:int = 4;
public function CurrentParsingState(){
this.position = 0;
this.encoding = NUMERIC;
}
public function isAlpha():Boolean{
return this.encoding == ALPHA;
}
public function isNumeric():Boolean{
return this.encoding == NUMERIC;
}
public function isIsoIec646():Boolean{
return this.encoding == ISO_IEC_646;
}
public function setNumeric():void{
this.encoding = NUMERIC;
}
public function setAlpha():void{
this.encoding = ALPHA;
}
public function setIsoIec646():void{
this.encoding = ISO_IEC_646;
}
}
}

View file

@ -0,0 +1,53 @@
/*
* 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@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class DecodedChar extends DecodedObject {
protected var value:String;
public static var FNC1:String = '$'; // It's not in Alphanumeric neither in ISO/IEC 646 charset
public function DecodedChar(newPosition:int, value:String) {
super(newPosition);
this.value = value;
}
public function getValue():String{
return this.value;
}
public function isFNC1():Boolean{
return this.value == FNC1;
}
}
}

View file

@ -0,0 +1,67 @@
/*
* 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@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class DecodedInformation extends DecodedObject {
protected var newString:String;
protected var remainingValue:int;
protected var remaining:Boolean;
public function DecodedInformation(newPosition:int,newString:String, remainingValue:int=0){
super(newPosition);
this.remainingValue = remainingValue;
if (remainingValue != 0)
{
this.remaining = true;
}
else
{
this.remaining = false;
}
this.newString = newString;
}
public function getNewString():String{
return this.newString;
}
public function isRemaining():Boolean{
return this.remaining;
}
public function getRemainingValue():int{
return this.remainingValue;
}
}
}

View file

@ -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.flexdatatypes.IllegalArgumentException;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class DecodedNumeric extends DecodedObject {
protected var firstDigit:int;
protected var secondDigit:int;
public static var FNC1:int = 10;
public function DecodedNumeric(newPosition:int, firstDigit:int, secondDigit:int){
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);
}
}
public function getFirstDigit():int{
return this.firstDigit;
}
public function getSecondDigit():int{
return this.secondDigit;
}
public function getValue():int{
return this.firstDigit * 10 + this.secondDigit;
}
public function isFirstDigitFNC1():Boolean{
return this.firstDigit == FNC1;
}
public function isSecondDigitFNC1():Boolean{
return this.secondDigit == FNC1;
}
public function isAnyFNC1():Boolean{
return this.firstDigit == FNC1 || this.secondDigit == FNC1;
}
}
}

View file

@ -0,0 +1,45 @@
/*
* 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@deusto.es)
*/
public class DecodedObject {
protected var newPosition:int;
public function DecodedObject(newPosition:int):void{
this.newPosition = newPosition;
}
public function getNewPosition():int {
return this.newPosition;
}
}
}

View file

@ -0,0 +1,304 @@
/*
* 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@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class FieldParser {
protected static var VARIABLE_LENGTH:Object = new Object();
private static var TWO_DIGIT_DATA_LENGTH:Array = [
// "DIGITS", new Integer(LENGTH)
// or
// "DIGITS", VARIABLE_LENGTH, new Integer(MAX_SIZE)
[ "00", new Array(18) ],
[ "01", new Array(14) ],
[ "02", new Array(14) ],
[ "10", VARIABLE_LENGTH, new Array(20) ],
[ "11", new Array(6) ],
[ "12", new Array(6) ],
[ "13", new Array(6) ],
[ "15", new Array(6) ],
[ "17", new Array(6) ],
[ "20", new Array(2) ],
[ "21", VARIABLE_LENGTH, new Array(20) ],
[ "22", VARIABLE_LENGTH, new Array(29) ],
[ "30", VARIABLE_LENGTH, new Array( 8) ],
[ "37", VARIABLE_LENGTH, new Array( 8) ],
//internal company codes
[ "90", VARIABLE_LENGTH, new Array(30) ],
[ "91", VARIABLE_LENGTH, new Array(30) ],
[ "92", VARIABLE_LENGTH, new Array(30) ],
[ "93", VARIABLE_LENGTH, new Array(30) ],
[ "94", VARIABLE_LENGTH, new Array(30) ],
[ "95", VARIABLE_LENGTH, new Array(30) ],
[ "96", VARIABLE_LENGTH, new Array(30) ],
[ "97", VARIABLE_LENGTH, new Array(30) ],
[ "98", VARIABLE_LENGTH, new Array(30) ],
[ "99", VARIABLE_LENGTH, new Array(30) ],
];
private static var THREE_DIGIT_DATA_LENGTH:Array = [
// Same format as above
[ "240", VARIABLE_LENGTH, new Array(30) ],
[ "241", VARIABLE_LENGTH, new Array(30) ],
[ "242", VARIABLE_LENGTH, new Array( 6) ],
[ "250", VARIABLE_LENGTH, new Array(30) ],
[ "251", VARIABLE_LENGTH, new Array(30) ],
[ "253", VARIABLE_LENGTH, new Array(17) ],
[ "254", VARIABLE_LENGTH, new Array(20) ],
[ "400", VARIABLE_LENGTH, new Array(30) ],
[ "401", VARIABLE_LENGTH, new Array(30) ],
[ "402", new Array(17) ],
[ "403", VARIABLE_LENGTH, new Array(30) ],
[ "410", new Array(13) ],
[ "411", new Array(13) ],
[ "412", new Array(13) ],
[ "413", new Array(13) ],
[ "414", new Array(13) ],
[ "420", VARIABLE_LENGTH, new Array(20) ],
[ "421", VARIABLE_LENGTH, new Array(15) ],
[ "422", new Array( 3) ],
[ "423", VARIABLE_LENGTH, new Array(15) ],
[ "424", new Array(3) ],
[ "425", new Array(3) ],
[ "426", new Array(3) ],
];
private static var THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH:Array = [
// Same format as above
[ "310", new Array(6) ],
[ "311", new Array(6) ],
[ "312", new Array(6) ],
[ "313", new Array(6) ],
[ "314", new Array(6) ],
[ "315", new Array(6) ],
[ "316", new Array(6) ],
[ "320", new Array(6) ],
[ "321", new Array(6) ],
[ "322", new Array(6) ],
[ "323", new Array(6) ],
[ "324", new Array(6) ],
[ "325", new Array(6) ],
[ "326", new Array(6) ],
[ "327", new Array(6) ],
[ "328", new Array(6) ],
[ "329", new Array(6) ],
[ "330", new Array(6) ],
[ "331", new Array(6) ],
[ "332", new Array(6) ],
[ "333", new Array(6) ],
[ "334", new Array(6) ],
[ "335", new Array(6) ],
[ "336", new Array(6) ],
[ "340", new Array(6) ],
[ "341", new Array(6) ],
[ "342", new Array(6) ],
[ "343", new Array(6) ],
[ "344", new Array(6) ],
[ "345", new Array(6) ],
[ "346", new Array(6) ],
[ "347", new Array(6) ],
[ "348", new Array(6) ],
[ "349", new Array(6) ],
[ "350", new Array(6) ],
[ "351", new Array(6) ],
[ "352", new Array(6) ],
[ "353", new Array(6) ],
[ "354", new Array(6) ],
[ "355", new Array(6) ],
[ "356", new Array(6) ],
[ "357", new Array(6) ],
[ "360", new Array(6) ],
[ "361", new Array(6) ],
[ "362", new Array(6) ],
[ "363", new Array(6) ],
[ "364", new Array(6) ],
[ "365", new Array(6) ],
[ "366", new Array(6) ],
[ "367", new Array(6) ],
[ "368", new Array(6) ],
[ "369", new Array(6) ],
[ "390", VARIABLE_LENGTH, new Array(15) ],
[ "391", VARIABLE_LENGTH, new Array(18) ],
[ "392", VARIABLE_LENGTH, new Array(15) ],
[ "393", VARIABLE_LENGTH, new Array(18) ],
[ "703", VARIABLE_LENGTH, new Array(30) ]
];
private static var FOUR_DIGIT_DATA_LENGTH:Array = [
// Same format as above
[ "7001", new Array(13) ],
[ "7002", VARIABLE_LENGTH, new Array(30) ],
[ "7003", new Array(10) ],
[ "8001", new Array(14) ],
[ "8002", VARIABLE_LENGTH, new Array(20) ],
[ "8003", VARIABLE_LENGTH, new Array(30) ],
[ "8004", VARIABLE_LENGTH, new Array(30) ],
[ "8005", new Array(6) ],
[ "8006", new Array(18) ],
[ "8007", VARIABLE_LENGTH, new Array(30) ],
[ "8008", VARIABLE_LENGTH, new Array(12) ],
[ "8018", new Array(18) ],
[ "8020", VARIABLE_LENGTH, new Array(25) ],
[ "8100", new Array(6) ],
[ "8101", new Array(10) ],
[ "8102", new Array(2) ],
[ "8110", VARIABLE_LENGTH, new Array(30) ],
];
public function FieldParser() {
}
public static function parseFieldsInGeneralPurpose(rawInformation:String):String{
if(rawInformation.length == 0) {
return null;
}
// Processing 2-digit AIs
if(rawInformation.length < 2)
{
throw NotFoundException.getNotFoundInstance();
}
var firstTwoDigits:String = rawInformation.substring(0, 2);
for (var i:int=0; i<TWO_DIGIT_DATA_LENGTH.length; ++i)
{
if (TWO_DIGIT_DATA_LENGTH[i][0] == firstTwoDigits)
{
if(TWO_DIGIT_DATA_LENGTH[i][1] == VARIABLE_LENGTH)
{
return processVariableAI(2, (TWO_DIGIT_DATA_LENGTH[i][2] as Array).length, rawInformation);
}
return processFixedAI(2,( TWO_DIGIT_DATA_LENGTH[i][1] as Array).length, rawInformation);
}
}
if(rawInformation.length < 3) {
throw NotFoundException.getNotFoundInstance();
}
var firstThreeDigits:String = rawInformation.substring(0, 3);
for (i=0; i<THREE_DIGIT_DATA_LENGTH.length; ++i)
{
if (THREE_DIGIT_DATA_LENGTH[i][0] == firstThreeDigits)
{
if (THREE_DIGIT_DATA_LENGTH[i][1] == VARIABLE_LENGTH)
{
return processVariableAI(3, (THREE_DIGIT_DATA_LENGTH[i][2] as Array).length, rawInformation);
}
return processFixedAI(3, (THREE_DIGIT_DATA_LENGTH[i][1] as Array).length, rawInformation);
}
}
for (i=0; i<THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.length; ++i)
{
if (THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][0] == firstThreeDigits)
{
if (THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][1] == VARIABLE_LENGTH)
{
return processVariableAI(4, (THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][2] as Array).length, rawInformation);
}
return processFixedAI(4, (THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][1] as Array).length, rawInformation);
}
}
if(rawInformation.length < 4)
{
throw NotFoundException.getNotFoundInstance();
}
var firstFourDigits:String = rawInformation.substring(0, 4);
for (i=0; i<FOUR_DIGIT_DATA_LENGTH.length; ++i)
{
if (FOUR_DIGIT_DATA_LENGTH[i][0] == firstFourDigits)
{
if (FOUR_DIGIT_DATA_LENGTH[i][1] == VARIABLE_LENGTH)
{
return processVariableAI(4, (FOUR_DIGIT_DATA_LENGTH[i][2] as Array).length, rawInformation);
}
return processFixedAI(4, (FOUR_DIGIT_DATA_LENGTH[i][1] as Array).length, rawInformation);
}
}
throw NotFoundException.getNotFoundInstance();
}
private static function processFixedAI(aiSize:int, fieldSize:int, rawInformation:String):String{
if (rawInformation.length < aiSize) {
throw NotFoundException.getNotFoundInstance();
}
var ai:String = rawInformation.substring(0, aiSize);
if(rawInformation.length < aiSize + fieldSize) {
throw NotFoundException.getNotFoundInstance();
}
var field:String = rawInformation.substring(aiSize, aiSize + fieldSize);
var remaining:String = rawInformation.substring(aiSize + fieldSize);
var result:String = '(' + ai + ')' + field;
var parsedAI:String = parseFieldsInGeneralPurpose(remaining);
return parsedAI == null ? result : result + parsedAI;
}
private static function processVariableAI(aiSize:int, variableFieldSize:int, rawInformation:String):String {
var ai:String = rawInformation.substring(0, aiSize);
var maxSize:int;
if (rawInformation.length < aiSize + variableFieldSize) {
maxSize = rawInformation.length;
} else {
maxSize = aiSize + variableFieldSize;
}
var field:String = rawInformation.substring(aiSize, maxSize);
var remaining:String = rawInformation.substring(maxSize);
var result:String = '(' + ai + ')' + field;
var parsedAI:String = parseFieldsInGeneralPurpose(remaining);
return parsedAI == null ? result : result + parsedAI;
}
}
}

View file

@ -0,0 +1,422 @@
/*
* 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;
import com.google.zxing.common.flexdatatypes.StringBuilder;
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
public class GeneralAppIdDecoder {
protected var information:BitArray;
protected var current:CurrentParsingState = new CurrentParsingState();
protected var buffer:StringBuilder = new StringBuilder();
public function GeneralAppIdDecoder(information:BitArray ){
this.information = information;
}
public function decodeAllCodes(buff:StringBuilder, initialPosition:int):String {
var currentPosition:int = initialPosition;
var remaining:String = null;
do{
var info:DecodedInformation = this.decodeGeneralPurposeField(currentPosition, remaining);
var parsedFields:String = FieldParser.parseFieldsInGeneralPurpose(info.getNewString());
if (parsedFields != null) {
buff.Append(parsedFields);
}
if(info.isRemaining()) {
remaining = info.getRemainingValue().toString();
} else {
remaining = null;
}
if(currentPosition == info.getNewPosition()) {// No step forward!
break;
}
currentPosition = info.getNewPosition();
}while(true);
return buff.toString();
}
private function isStillNumeric(pos:int):Boolean {
// 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(var i:int = pos; i < pos + 3; ++i) {
if (this.information._get(i)) {
return true;
}
}
return this.information._get(pos + 3);
}
private function decodeNumeric(pos:int):DecodedNumeric {
if(pos + 7 > this.information.Size){
var numeric:int = extractNumericValueFromBitArray2(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);
}
numeric = extractNumericValueFromBitArray2(pos, 7);
var digit1:int = int((numeric - 8) / 11);
var digit2:int = (numeric - 8) % 11;
return new DecodedNumeric(pos + 7, digit1, digit2);
}
public function extractNumericValueFromBitArray2(pos:int, bits:int):int{
return extractNumericValueFromBitArray(this.information, pos, bits);
}
public static function extractNumericValueFromBitArray(information:BitArray, pos:int, bits:int):int {
if(bits > 32) {
throw new IllegalArgumentException("extractNumberValueFromBitArray can't handle more than 32 bits");
}
var value:int = 0;
for(var i:int = 0; i < bits; ++i) {
if (information._get(pos + i)) {
value |= (1 << (bits - i - 1));
}
}
return value;
}
public function decodeGeneralPurposeField(pos:int, remaining:String):DecodedInformation {
this.buffer.setLength(0);
if(remaining != null) {
this.buffer.Append(remaining);
}
this.current.position = pos;
var lastDecoded:DecodedInformation = 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 function parseBlocks():DecodedInformation {
var isFinished:Boolean;
var result:BlockParsedResult;
do{
var initialPosition:int = 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();
}
var positionChanged:Boolean = initialPosition != current.position;
if(!positionChanged && !isFinished) {
break;
}
} while (!isFinished);
return result.getDecodedInformation();
}
private function parseNumericBlock():BlockParsedResult {
while(isStillNumeric(current.position)){
var numeric:DecodedNumeric = decodeNumeric(current.position);
current.position = numeric.getNewPosition();
if(numeric.isFirstDigitFNC1()){
var information:DecodedInformation;
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(String.fromCharCode(48+numeric.getFirstDigit()));
if(numeric.isSecondDigitFNC1()){
information = new DecodedInformation(current.position, buffer.toString());
return new BlockParsedResult(information, true);
}
buffer.Append(String.fromCharCode(48+numeric.getSecondDigit()));
}
if(isNumericToAlphaNumericLatch(current.position)){
current.setAlpha();
current.position += 4;
}
return new BlockParsedResult(null,false);
}
private function parseIsoIec646Block():BlockParsedResult {
while (isStillIsoIec646(current.position)) {
var iso:DecodedChar = decodeIsoIec646(current.position);
current.position = iso.getNewPosition();
if (iso.isFNC1()) {
var information:DecodedInformation = 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(null,false);
}
private function parseAlphaBlock():BlockParsedResult {
while (isStillAlpha(current.position)) {
var alpha:DecodedChar = decodeAlphanumeric(current.position);
current.position = alpha.getNewPosition();
if(alpha.isFNC1()) {
var information:DecodedInformation = 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(null,false);
}
private function isStillIsoIec646(pos:int):Boolean
{
if(pos + 5 > this.information.Size) {
return false;
}
var fiveBitValue:int = extractNumericValueFromBitArray2(pos, 5);
if(fiveBitValue >= 5 && fiveBitValue < 16) {
return true;
}
if(pos + 7 > this.information.Size) {
return false;
}
var sevenBitValue:int = extractNumericValueFromBitArray2(pos, 7);
if(sevenBitValue >= 64 && sevenBitValue < 116) {
return true;
}
if(pos + 8 > this.information.Size) {
return false;
}
var eightBitValue:int = extractNumericValueFromBitArray2(pos, 8);
return eightBitValue >= 232 && eightBitValue < 253;
}
private function decodeIsoIec646(pos:int):DecodedChar {
var fiveBitValue:int = extractNumericValueFromBitArray2(pos, 5);
if(fiveBitValue == 15) {
return new DecodedChar(pos + 5, DecodedChar.FNC1);
}
if(fiveBitValue >= 5 && fiveBitValue < 15) {
return new DecodedChar(pos + 5, String.fromCharCode((48 + fiveBitValue - 5) as int));
}
var sevenBitValue:int = extractNumericValueFromBitArray2(pos, 7);
if(sevenBitValue >= 64 && sevenBitValue < 90) {
return new DecodedChar(pos + 7, (sevenBitValue + 1).toString());
}
if(sevenBitValue >= 90 && sevenBitValue < 116) {
return new DecodedChar(pos + 7, String.fromCharCode(sevenBitValue + 7));
}
var eightBitValue:int = extractNumericValueFromBitArray2(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 Error("Decoding invalid ISO/IEC 646 value: " + eightBitValue);
}
private function isStillAlpha(pos:int):Boolean {
if(pos + 5 > this.information.Size) {
return false;
}
// We now check if it's a valid 5-bit value (0..9 and FNC1)
var fiveBitValue:int = extractNumericValueFromBitArray2(pos, 5);
if(fiveBitValue >= 5 && fiveBitValue < 16) {
return true;
}
if(pos + 6 > this.information.Size) {
return false;
}
var sixBitValue:int = extractNumericValueFromBitArray2(pos, 6);
return sixBitValue >= 16 && sixBitValue < 63; // 63 not included
}
private function decodeAlphanumeric(pos:int):DecodedChar {
var fiveBitValue:int = extractNumericValueFromBitArray2(pos, 5);
if(fiveBitValue == 15) {
return new DecodedChar(pos + 5, DecodedChar.FNC1);
}
if(fiveBitValue >= 5 && fiveBitValue < 15) {
return new DecodedChar(pos + 5, String.fromCharCode((('0' as String).charCodeAt(0) + fiveBitValue - 5)as int));
}
var sixBitValue:int = extractNumericValueFromBitArray2(pos, 6);
if(sixBitValue >= 32 && sixBitValue < 58) {
return new DecodedChar(pos + 6, String.fromCharCode(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 Error("Decoding invalid alphanumeric value: " + sixBitValue);
}
private function isAlphaTo646ToAlphaLatch(pos:int):Boolean {
if(pos + 1 > this.information.Size) {
return false;
}
for(var i:int = 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 function isAlphaOr646ToNumericLatch(pos:int):Boolean {
// Next is alphanumeric if there are 3 positions and they are all zeros
if (pos + 3 > this.information.Size) {
return false;
}
for (var i:int = pos; i < pos + 3; ++i) {
if (this.information._get(i)) {
return false;
}
}
return true;
}
private function isNumericToAlphaNumericLatch(pos:int):Boolean {
// 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 (var i:int = 0; i < 4 && i + pos < this.information.Size; ++i) {
if (this.information._get(pos + i)) {
return false;
}
}
return true;
}
}
}