mirror of
https://github.com/zxing/zxing.git
synced 2024-11-09 20:44:03 -08:00
Retire actionscript
This commit is contained in:
parent
c2afa60303
commit
49e1127e06
|
@ -35,16 +35,16 @@ There are also additional modules which are contributed and/or intermittently ma
|
|||
|
||||
| Module | Description
|
||||
| ------------ | -----------
|
||||
| actionscript | partial port to Actionscript
|
||||
| jruby | JRuby wrapper
|
||||
|
||||
### Available in previous releases
|
||||
|
||||
| Module | Description
|
||||
| ------ | -----------
|
||||
| [cpp](https://github.com/zxing/zxing/tree/00f634024ceeee591f54e6984ea7dd666fab22ae/cpp) | C++ port
|
||||
| [iphone](https://github.com/zxing/zxing/tree/00f634024ceeee591f54e6984ea7dd666fab22ae/iphone) | iPhone client
|
||||
| [objc](https://github.com/zxing/zxing/tree/00f634024ceeee591f54e6984ea7dd666fab22ae/objc) | Objective C port
|
||||
| [cpp](https://github.com/zxing/zxing/tree/00f634024ceeee591f54e6984ea7dd666fab22ae/cpp) | C++ port
|
||||
| [iphone](https://github.com/zxing/zxing/tree/00f634024ceeee591f54e6984ea7dd666fab22ae/iphone) | iPhone client
|
||||
| [objc](https://github.com/zxing/zxing/tree/00f634024ceeee591f54e6984ea7dd666fab22ae/objc) | Objective C port
|
||||
| [actionscript](https://github.com/zxing/zxing/tree/c1df162b95e07928afbd4830798cc1408af1ac67/actionscript) | Partial ActionScript port
|
||||
|
||||
### Related third-party open source projects
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<actionScriptProperties mainApplicationPath="zxing.as" version="3">
|
||||
<compiler additionalCompilerArguments="" copyDependentFiles="false" enableModuleDebug="true" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersion="9.0.28" htmlPlayerVersionCheck="true" outputFolderPath="bin" strict="true" useApolloConfig="false" verifyDigests="true" warn="true">
|
||||
<compilerSourcePath/>
|
||||
<libraryPath defaultLinkType="1">
|
||||
<libraryPathEntry kind="4" path=""/>
|
||||
</libraryPath>
|
||||
<sourceAttachmentPath/>
|
||||
</compiler>
|
||||
<applications>
|
||||
<application path="zxing.as"/>
|
||||
</applications>
|
||||
<modules/>
|
||||
<buildCSSFiles/>
|
||||
</actionScriptProperties>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flexLibProperties version="1">
|
||||
<includeClasses/>
|
||||
<includeResources/>
|
||||
<namespaceManifests/>
|
||||
</flexLibProperties>
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>zxing</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.adobe.flexbuilder.project.flexbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.adobe.flexbuilder.project.flexlibnature</nature>
|
||||
<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,3 +0,0 @@
|
|||
#Thu Nov 05 11:41:58 CET 2009
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=utf-8
|
|
@ -1,96 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
* Copyright 2011 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.
|
||||
-->
|
||||
<project name="ZXing" default="build" basedir="../">
|
||||
<property environment="env" />
|
||||
<property file="${basedir}/build.properties.local" />
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<property name="FLEX_HOME" location="${env.FLEX_HOME}" />
|
||||
<property name="dist" location="${basedir}/core/bin" />
|
||||
<property name="src" location="${basedir}/core/src" />
|
||||
<property name="test" location="${basedir}/core/test" />
|
||||
<property name="assets" location="${basedir}/../core/test/data" />
|
||||
<property name="libs" location="${basedir}/core/libs" />
|
||||
<property name="output" location="${basedir}/core/bin/output" />
|
||||
<property name="report" location="${basedir}/core/bin/report" />
|
||||
|
||||
<fail unless="FLEX_HOME"
|
||||
message="Error: define FLEX_HOME env. var. with a path to Flex4 SDK" />
|
||||
<fail unless="version"
|
||||
message="Error: version is undefined." />
|
||||
|
||||
<property name="libraryName" value="zxing-${version}.swc" />
|
||||
|
||||
<taskdef resource="flexTasks.tasks"
|
||||
classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
|
||||
<taskdef resource="flexUnitTasks.tasks"
|
||||
classpath="${libs}/flexUnitTasks-4.1.0-8.jar" />
|
||||
|
||||
<target name="clean">
|
||||
<delete>
|
||||
<fileset dir="${dist}" includes="**/${libraryName}"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${dist}"/>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="init">
|
||||
<fileset id="srcFiles" dir="${src}">
|
||||
<include name="**/*.as"/>
|
||||
</fileset>
|
||||
<pathconvert property="classes" pathsep="," refid="srcFiles">
|
||||
<chainedmapper>
|
||||
<globmapper from="${src}/*" to="*"></globmapper>
|
||||
<mapper type="package" from="*.as" to="*"/>
|
||||
</chainedmapper>
|
||||
</pathconvert>
|
||||
<compc output="${dist}/${libraryName}" include-classes="${classes}">
|
||||
<source-path path-element="${src}"/>
|
||||
<include-sources dir="${basedir}/core/src" includes="*" />
|
||||
</compc>
|
||||
</target>
|
||||
|
||||
<target name="compile.tests" depends="build">
|
||||
<mxmlc file="${test}/com/google/zxing/testrunner/ZXingTestsRunner.mxml"
|
||||
output="${output}/ZXingTestsRunner.swf"
|
||||
debug="true">
|
||||
<library-path dir="${dist}" append="true">
|
||||
<include name="*.swc"/>
|
||||
</library-path>
|
||||
<library-path dir="${libs}" append="true">
|
||||
<include name="*.swc"/>
|
||||
</library-path>
|
||||
<library-path dir="${FLEX_HOME}/frameworks/libs/air" append="true">
|
||||
<include name="*.swc"/>
|
||||
</library-path>
|
||||
<library-path dir="${FLEX_HOME}/frameworks/libs" append="true">
|
||||
<include name="framework.swc"/>
|
||||
</library-path>
|
||||
<source-path path-element="${test}" />
|
||||
<source-path path-element="${assets}" />
|
||||
<compiler.verbose-stacktraces>true</compiler.verbose-stacktraces>
|
||||
<compiler.headless-server>true</compiler.headless-server>
|
||||
</mxmlc>
|
||||
<copy todir="${output}">
|
||||
<fileset dir="${test}/com/google/zxing/testrunner">
|
||||
<include name="zxing*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
</project>
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
/**
|
||||
* Enumerates barcode formats known to this package.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
public class BarcodeFormat
|
||||
{
|
||||
// No, we can't use an enum here. J2ME doesn't support it.
|
||||
|
||||
private static var VALUES:HashTable = new HashTable();
|
||||
|
||||
/** Aztec 2D barcode format. */
|
||||
public static var AZTEC:BarcodeFormat = new BarcodeFormat("AZTEC");
|
||||
/** CODABAR 1D format. */
|
||||
public static var CODABAR:BarcodeFormat = new BarcodeFormat("CODABAR");
|
||||
/** QR Code 2D barcode format. */
|
||||
public static var QR_CODE:BarcodeFormat = new BarcodeFormat("QR_CODE");
|
||||
/** DataMatrix 2D barcode format. */
|
||||
public static var DATAMATRIX:BarcodeFormat = new BarcodeFormat("DATAMATRIX");
|
||||
/** UPC-E 1D format. */
|
||||
public static var UPC_E:BarcodeFormat = new BarcodeFormat("UPC_E");
|
||||
/** UPC-A 1D format. */
|
||||
public static var UPC_A:BarcodeFormat = new BarcodeFormat("UPC_A");
|
||||
/** UPC/EAN extension format. Not a stand-alone format. */
|
||||
public static var UPC_EAN_EXTENSION:BarcodeFormat = new BarcodeFormat("UPC_EAN_EXTENSION");
|
||||
/** EAN-8 1D format. */
|
||||
public static var EAN_8:BarcodeFormat = new BarcodeFormat("EAN_8");
|
||||
/** EAN-13 1D format. */
|
||||
public static var EAN_13:BarcodeFormat = new BarcodeFormat("EAN_13");
|
||||
/** Code 128 1D format. */
|
||||
public static var CODE_128:BarcodeFormat = new BarcodeFormat("CODE_128");
|
||||
/** Code 93 1D format. */
|
||||
public static var CODE_93:BarcodeFormat = new BarcodeFormat("CODE_93");
|
||||
/** Code 39 1D format. */
|
||||
public static var CODE_39:BarcodeFormat = new BarcodeFormat("CODE_39");
|
||||
/** ITF (Interleaved Two of Five) 1D format. */
|
||||
public static var ITF:BarcodeFormat = new BarcodeFormat("ITF");
|
||||
/** PDF417 format. */
|
||||
public static var PDF417:BarcodeFormat = new BarcodeFormat("PDF417");
|
||||
/** RSS 14 */
|
||||
public static var RSS_14:BarcodeFormat = new BarcodeFormat("RSS_14");
|
||||
/** RSS EXPANDED */
|
||||
public static var RSS_EXPANDED:BarcodeFormat = new BarcodeFormat("RSS_EXPANDED");
|
||||
/** MAXICODE */
|
||||
public static var MAXICODE:BarcodeFormat = new BarcodeFormat("MAXICODE");
|
||||
|
||||
private var _name:String;
|
||||
|
||||
public function BarcodeFormat(name:String)
|
||||
{
|
||||
this._name = name;
|
||||
VALUES._put(name, this);
|
||||
}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
|
||||
public function get name():String
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public static function valueOf(name:String):BarcodeFormat
|
||||
{
|
||||
if (name == null || name.length == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
var format:BarcodeFormat = (VALUES._get(name) as BarcodeFormat);
|
||||
if (format == null)
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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
|
||||
{
|
||||
/**
|
||||
* This class hierarchy provides a set of methods to convert luminance data to 1 bit data.
|
||||
* It allows the algorithm to vary polymorphically, for example allowing a very expensive
|
||||
* thresholding technique for servers and a fast one for mobile. It also permits the implementation
|
||||
* to vary, e.g. a JNI version for Android and a Java fallback version for other platforms.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
|
||||
public class Binarizer
|
||||
{
|
||||
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
private var source:LuminanceSource;
|
||||
|
||||
public function Binarizer(source:LuminanceSource)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Source must be non-null.");
|
||||
}
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public function getLuminanceSource():LuminanceSource
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
|
||||
* cached data. Callers should assume this method is expensive and call it as seldom as possible.
|
||||
* This method is intended for decoding 1D barcodes and may choose to apply sharpening.
|
||||
* For callers which only examine one row of pixels at a time, the same BitArray should be reused
|
||||
* and passed in with each call for performance. However it is legal to keep more than one row
|
||||
* at a time if needed.
|
||||
*
|
||||
* @param y The row to fetch, 0 <= y < bitmap height.
|
||||
* @param row An optional preallocated array. If null or too small, it will be ignored.
|
||||
* If used, the Binarizer will call BitArray.clear(). Always use the returned object.
|
||||
* @return The array of bits for this row (true means black).
|
||||
*/
|
||||
public function getBlackRow(y:int, row:BitArray):BitArray
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a 2D array of luminance data to 1 bit data. As above, assume this method is expensive
|
||||
* and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
|
||||
* may not apply sharpening. Therefore, a row from this matrix may not be identical to one
|
||||
* fetched using getBlackRow(), so don't mix and match between them.
|
||||
*
|
||||
* @return The 2D array of bits for the image (true means black).
|
||||
*/
|
||||
public function getBlackMatrix():BitMatrix
|
||||
{
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object with the same type as this Binarizer implementation, but with pristine
|
||||
* state. This is needed because Binarizer implementations may be stateful, e.g. keeping a cache
|
||||
* of 1 bit data. See Effective Java for why we can't use Java's clone() method.
|
||||
*
|
||||
* @param source The LuminanceSource this Binarizer will operate on.
|
||||
* @return A new concrete Binarizer implementation object.
|
||||
*/
|
||||
public function createBinarizer(source:LuminanceSource ):Binarizer
|
||||
{
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
{
|
||||
/**
|
||||
* This class is the core bitmap class used by ZXing to represent 1 bit data. Reader objects
|
||||
* accept a BinaryBitmap and attempt to decode it.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
public final class BinaryBitmap
|
||||
{
|
||||
private var binarizer:Binarizer;
|
||||
private var matrix:BitMatrix;
|
||||
|
||||
public function BinaryBitmap( binarizer:Binarizer)
|
||||
{
|
||||
if (binarizer == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Binarizer must be non-null.");
|
||||
}
|
||||
this.binarizer = binarizer;
|
||||
matrix = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The width of the bitmap.
|
||||
*/
|
||||
public function getWidth():int
|
||||
{
|
||||
return binarizer.getLuminanceSource().getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The height of the bitmap.
|
||||
*/
|
||||
public function getHeight():int
|
||||
{
|
||||
return binarizer.getLuminanceSource().getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
|
||||
* cached data. Callers should assume this method is expensive and call it as seldom as possible.
|
||||
* This method is intended for decoding 1D barcodes and may choose to apply sharpening.
|
||||
*
|
||||
* @param y The row to fetch, 0 <= y < bitmap height.
|
||||
* @param row An optional preallocated array. If null or too small, it will be ignored.
|
||||
* If used, the Binarizer will call BitArray.clear(). Always use the returned object.
|
||||
* @return The array of bits for this row (true means black).
|
||||
*/
|
||||
public function getBlackRow(y:int, row:BitArray) :BitArray
|
||||
{
|
||||
return binarizer.getBlackRow(y, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive
|
||||
* and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
|
||||
* may not apply sharpening. Therefore, a row from this matrix may not be identical to one
|
||||
* fetched using getBlackRow(), so don't mix and match between them.
|
||||
*
|
||||
* @return The 2D array of bits for the image (true means black).
|
||||
*/
|
||||
public function getBlackMatrix():BitMatrix
|
||||
{
|
||||
// The matrix is created on demand the first time it is requested, then cached. There are two
|
||||
// reasons for this:
|
||||
// 1. This work will never be done if the caller only installs 1D Reader objects, or if a
|
||||
// 1D Reader finds a barcode before the 2D Readers run.
|
||||
// 2. This work will only be done once even if the caller installs multiple 2D Readers.
|
||||
if (matrix == null)
|
||||
{
|
||||
matrix = binarizer.getBlackMatrix();
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this bitmap can be cropped.
|
||||
*/
|
||||
public function isCropSupported():Boolean
|
||||
{
|
||||
return binarizer.getLuminanceSource().isCropSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new object with cropped image data. Implementations may keep a reference to the
|
||||
* original data rather than a copy. Only callable if isCropSupported() is true.
|
||||
*
|
||||
* @param left The left coordinate, 0 <= left < getWidth().
|
||||
* @param top The top coordinate, 0 <= top <= getHeight().
|
||||
* @param width The width of the rectangle to crop.
|
||||
* @param height The height of the rectangle to crop.
|
||||
* @return A cropped version of this object.
|
||||
*/
|
||||
public function crop(left:int, top:int, width:int, height:int ):BinaryBitmap {
|
||||
var newSource:LuminanceSource = binarizer.getLuminanceSource().crop(left, top, width, height);
|
||||
return new BinaryBitmap(binarizer.createBinarizer(newSource));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this bitmap supports counter-clockwise rotation.
|
||||
*/
|
||||
public function isRotateSupported():Boolean
|
||||
{
|
||||
return binarizer.getLuminanceSource().isRotateSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new object with rotated image data. Only callable if isRotateSupported() is true.
|
||||
*
|
||||
* @return A rotated version of this object.
|
||||
*/
|
||||
public function rotateCounterClockwise():BinaryBitmap
|
||||
{
|
||||
var newSource:LuminanceSource = binarizer.getLuminanceSource().rotateCounterClockwise();
|
||||
return new BinaryBitmap(binarizer.createBinarizer(newSource));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
{
|
||||
|
||||
import com.google.zxing.LuminanceSource;
|
||||
import mx.controls.Image;
|
||||
import flash.display.BitmapData;
|
||||
|
||||
/**
|
||||
* This LuminanceSource implementation is meant for J2SE clients and our blackbox unit tests.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class BufferedImageLuminanceSource extends LuminanceSource
|
||||
{
|
||||
|
||||
private var image:BitmapData ;
|
||||
private var left:int;
|
||||
private var top:int;
|
||||
private var rgbData:Array;
|
||||
|
||||
|
||||
public function getRGB(left:int, top:int, width:int, height:int, rgb:Array, value:int, numPixels:int):void
|
||||
{
|
||||
var cntr:int = 0;
|
||||
for (var i:int=top;i<(top+height);i++)
|
||||
{
|
||||
for (var j:int=left;j<(left+width);j++)
|
||||
{
|
||||
rgb[cntr] = image.getPixel(j,i);
|
||||
cntr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function BufferedImageLuminanceSource(image:BitmapData, left:int=0, top:int=0, width:int=0, height:int=0)
|
||||
{
|
||||
if ((width==0) && (height==0))
|
||||
{
|
||||
width = image.width;
|
||||
height = image.height;
|
||||
}
|
||||
super(width,height);
|
||||
|
||||
var sourceWidth:int = image.width;
|
||||
var sourceHeight:int = image.height;
|
||||
if (left + width > sourceWidth || top + height > sourceHeight) {
|
||||
throw new Error("Crop rectangle does not fit within image data.");
|
||||
}
|
||||
|
||||
this.image = image;
|
||||
this.left = left;
|
||||
this.top = top;
|
||||
}
|
||||
|
||||
// These methods use an integer calculation for luminance derived from:
|
||||
// <code>Y = 0.299R + 0.587G + 0.114B</code>
|
||||
public override function getRow(y:int, row:Array):Array {
|
||||
if (y < 0 || y >= image.height) {
|
||||
throw new Error("Requested row is outside the image: " + y);
|
||||
}
|
||||
var width:int = image.width;
|
||||
if (row == null || row.length < width) {
|
||||
row = new Array(width);
|
||||
}
|
||||
|
||||
if (rgbData == null || rgbData.length < width)
|
||||
{
|
||||
rgbData = new Array(width);
|
||||
}
|
||||
this.getRGB(left, top + y, width, 1, rgbData, 0, image.width);
|
||||
for (var x:int = 0; x < width; x++) {
|
||||
var pixel:int = rgbData[x];
|
||||
var luminance:int = (306 * ((pixel >> 16) & 0xFF) +
|
||||
601 * ((pixel >> 8) & 0xFF) +
|
||||
117 * (pixel & 0xFF)) >> 10;
|
||||
row[x] = luminance;
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
public override function getMatrix():Array {
|
||||
var width:int = image.width;
|
||||
var height:int = image.height;
|
||||
var area:int = width * height;
|
||||
var matrix:Array = new Array(area);
|
||||
|
||||
var rgb:Array = new Array(area);
|
||||
this.getRGB(left, top, width, height, rgb, 0, image.width);
|
||||
for (var y:int = 0; y < height; y++) {
|
||||
var offset:int = y * width;
|
||||
for (var x:int = 0; x < width; x++) {
|
||||
var pixel:int = rgb[offset + x];
|
||||
var luminance:int = (306 * ((pixel >> 16) & 0xFF) +
|
||||
601 * ((pixel >> 8) & 0xFF) +
|
||||
117 * (pixel & 0xFF)) >> 10;
|
||||
matrix[offset + x] = luminance;
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public override function isCropSupported():Boolean
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override function crop(left:int, top:int, width:int, height:int):LuminanceSource
|
||||
{
|
||||
return new BufferedImageLuminanceSource(image, left, top, width, height);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Can't run AffineTransforms on images of unknown format.
|
||||
public override function isRotateSupported():Boolean
|
||||
{
|
||||
return false;
|
||||
//return image.getType() != BufferedImage.TYPE_CUSTOM;
|
||||
}
|
||||
|
||||
|
||||
public override function rotateCounterClockwise():LuminanceSource
|
||||
{
|
||||
if (!isRotateSupported())
|
||||
{
|
||||
throw new Error("Rotate not supported");
|
||||
}
|
||||
// todo
|
||||
return null;
|
||||
/*
|
||||
var sourceWidth:int = image.getWidth();
|
||||
var sourceHeight:int = image.getHeight();
|
||||
|
||||
// Rotate 90 degrees counterclockwise.
|
||||
var transform:AffineTransform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);
|
||||
var op:BufferedImageOp = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
|
||||
|
||||
// Note width/height are flipped since we are rotating 90 degrees.
|
||||
var rotatedImage:BufferedImage = new BufferedImage(sourceHeight, sourceWidth, image.getType());
|
||||
op.filter(image, rotatedImage);
|
||||
|
||||
// Maintain the cropped region, but rotate it too.
|
||||
var width:int = getWidth();
|
||||
return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width),
|
||||
getHeight(), width);
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
|
||||
/**
|
||||
* Thrown when a barcode was successfully detected and decoded, but
|
||||
* was not returned because its checksum feature failed.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class ChecksumException extends ReaderException {
|
||||
|
||||
private static var instance:ChecksumException = new ChecksumException();
|
||||
|
||||
public function ChecksumException() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public static function getChecksumInstance():ChecksumException {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
/**
|
||||
* Encapsulates a type of hint that a caller may pass to a barcode reader to help it
|
||||
* more quickly or accurately decode it. It is up to implementations to decide what,
|
||||
* if anything, to do with the information that is supplied.
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
* @see Reader#decode(BinaryBitmap,java.util.Hashtable)
|
||||
*/
|
||||
|
||||
public class DecodeHintType
|
||||
{
|
||||
/**
|
||||
* Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
|
||||
*/
|
||||
public static var OTHER:DecodeHintType = new DecodeHintType("OTHER");
|
||||
|
||||
/**
|
||||
* Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
|
||||
* use {@link Boolean#TRUE}.
|
||||
*/
|
||||
public static var PURE_BARCODE:DecodeHintType = new DecodeHintType("PURE_BARCODE");
|
||||
|
||||
/**
|
||||
*
|
||||
* Image is known to be of one of a few possible formats.
|
||||
* Maps to a {@link java.util.Vector} of {@link BarcodeFormat}s.
|
||||
*/
|
||||
public static var POSSIBLE_FORMATS:DecodeHintType = new DecodeHintType("POSSIBLE_FORMATS");
|
||||
|
||||
/**
|
||||
* Spend more time to try to find a barcode; optimize for accuracy, not speed.
|
||||
* Doesn't matter what it maps to; use {@link Boolean#TRUE}.
|
||||
*/
|
||||
public static var TRY_HARDER:DecodeHintType = new DecodeHintType("TRY_HARDER");
|
||||
|
||||
/**
|
||||
* Specifies what character encoding to use when decoding, where applicable (type String)
|
||||
*/
|
||||
public static var CHARACTER_SET:DecodeHintType = new DecodeHintType("CHARACTER_SET");
|
||||
|
||||
/**
|
||||
* Allowed lengths of encoded data -- reject anything else. Maps to an int[].
|
||||
*/
|
||||
public static var ALLOWED_LENGTHS:DecodeHintType = new DecodeHintType("ALLOWED_LENGTHS");
|
||||
|
||||
/**
|
||||
* Assume Code 39 codes employ a check digit. Maps to {@link Boolean}.
|
||||
*/
|
||||
public static var ASSUME_CODE_39_CHECK_DIGIT:DecodeHintType = new DecodeHintType("ASSUME_CODE_39_CHECK_DIGIT");
|
||||
|
||||
/**
|
||||
* The caller needs to be notified via callback when a possible {@link ResultPoint}
|
||||
* is found. Maps to a {@link ResultPointCallback}.
|
||||
*/
|
||||
public static var NEED_RESULT_POINT_CALLBACK:DecodeHintType = new DecodeHintType("NEED_RESULT_POINT_CALLBACK");
|
||||
|
||||
public var DHtype:String;
|
||||
|
||||
public function DecodeHintType(aType:String)
|
||||
{
|
||||
DHtype = aType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright 2008 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
|
||||
{
|
||||
/**
|
||||
* These are a set of hints that you may pass to Writers to specify their behavior.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
|
||||
public class EncodeHintType
|
||||
{
|
||||
/**
|
||||
* Specifies what degree of error correction to use, for example in QR Codes (type Integer).
|
||||
*/
|
||||
public static var ERROR_CORRECTION:EncodeHintType = new EncodeHintType();
|
||||
|
||||
/**
|
||||
* Specifies what character encoding to use where applicable (type String)
|
||||
*/
|
||||
public static var CHARACTER_SET:EncodeHintType = new EncodeHintType();
|
||||
|
||||
|
||||
public function EncodeHintType()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
|
||||
/**
|
||||
* Thrown when a barcode was successfully detected, but some aspect of
|
||||
* the content did not conform to the barcode's format rules. This could have
|
||||
* been due to a mis-detection.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class FormatException extends ReaderException {
|
||||
|
||||
private static var instance:FormatException = new FormatException();
|
||||
|
||||
public function FormatException() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public static function getFormatInstance():FormatException {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
{
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
|
||||
public class LuminanceSource
|
||||
{
|
||||
/**
|
||||
* The purpose of this class hierarchy is to abstract different bitmap implementations across
|
||||
* platforms into a standard interface for requesting greyscale luminance values. The interface
|
||||
* only provides immutable methods; therefore crop and rotation create copies. This is to ensure
|
||||
* that one Reader does not modify the original luminance source and leave it in an unknown state
|
||||
* for other Readers in the chain.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
private var width:int;
|
||||
private var height:int;
|
||||
|
||||
public function LuminanceSource(width:int, height:int)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches one row of luminance data from the underlying platform's bitmap. Values range from
|
||||
* 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have
|
||||
* to bitwise and with 0xff for each value. It is preferrable for implementations of this method
|
||||
* to only fetch this row rather than the whole image, since no 2D Readers may be installed and
|
||||
* getMatrix() may never be called.
|
||||
*
|
||||
* @param y The row to fetch, 0 <= y < getHeight().
|
||||
* @param row An optional preallocated array. If null or too small, it will be ignored.
|
||||
* Always use the returned object, and ignore the .length of the array.
|
||||
* @return An array containing the luminance data.
|
||||
*/
|
||||
public function getRow(y:int, row:Array):Array{ return null};
|
||||
|
||||
/**
|
||||
* Fetches luminance data for the underlying bitmap. Values should be fetched using:
|
||||
* int luminance = array[y * width + x] & 0xff;
|
||||
*
|
||||
* @return A row-major 2D array of luminance values. Do not use result.length as it may be
|
||||
* larger than width * height bytes on some platforms. Do not modify the contents
|
||||
* of the result.
|
||||
*/
|
||||
public function getMatrix():Array{ return null};
|
||||
|
||||
/**
|
||||
* @return The width of the bitmap.
|
||||
*/
|
||||
public final function getWidth():int {
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The height of the bitmap.
|
||||
*/
|
||||
public final function getHeight():int {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this subclass supports cropping.
|
||||
*/
|
||||
public function isCropSupported():Boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new object with cropped image data. Implementations may keep a reference to the
|
||||
* original data rather than a copy. Only callable if isCropSupported() is true.
|
||||
*
|
||||
* @param left The left coordinate, 0 <= left < getWidth().
|
||||
* @param top The top coordinate, 0 <= top <= getHeight().
|
||||
* @param width The width of the rectangle to crop.
|
||||
* @param height The height of the rectangle to crop.
|
||||
* @return A cropped version of this object.
|
||||
*/
|
||||
public function crop(left:int , top:int , width:int , height:int ):LuminanceSource {
|
||||
throw new Error("This luminance source does not support cropping.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this subclass supports counter-clockwise rotation.
|
||||
*/
|
||||
public function isRotateSupported():Boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new object with rotated image data. Only callable if isRotateSupported() is true.
|
||||
*
|
||||
* @return A rotated version of this object.
|
||||
*/
|
||||
public function rotateCounterClockwise():LuminanceSource {
|
||||
throw new Error("This luminance source does not support rotation.");
|
||||
}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
var row:Array = new Array(width);
|
||||
var result:StringBuilder = new StringBuilder(height * (width + 1));
|
||||
for (var y:int = 0; y < height; y++) {
|
||||
row = getRow(y, row);
|
||||
for (var x:int = 0; x < width; x++) {
|
||||
var luminance:int = row[x] & 0xFF;
|
||||
var c:String;
|
||||
if (luminance < 0x40) {
|
||||
c = '#';
|
||||
} else if (luminance < 0x80) {
|
||||
c = '+';
|
||||
} else if (luminance < 0xC0) {
|
||||
c = '.';
|
||||
} else {
|
||||
c = ' ';
|
||||
}
|
||||
result.Append(c);
|
||||
}
|
||||
result.Append('\n');
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
import com.google.zxing.aztec.AztecReader;
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
import com.google.zxing.datamatrix.DataMatrixReader;
|
||||
import com.google.zxing.oned.MultiFormatOneDReader;
|
||||
import com.google.zxing.pdf417.PDF417Reader;
|
||||
import com.google.zxing.qrcode.QRCodeReader;
|
||||
import com.google.zxing.maxicode.MaxiCodeReader;
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
|
||||
/**
|
||||
* MultiFormatReader is a convenience class and the main entry point into the library for most uses.
|
||||
* By default it attempts to decode all barcode formats that the library supports. Optionally, you
|
||||
* can provide a hints object to request different behavior, for example only decoding QR codes.
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public class MultiFormatReader implements Reader
|
||||
{
|
||||
|
||||
protected var hints:HashTable;
|
||||
protected var readers:ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Decode an image using the hints provided. Does not honor existing state.
|
||||
*
|
||||
* @param image The pixel data to decode
|
||||
* @param hints The hints to use, clearing the previous state.
|
||||
* @return The contents of the image
|
||||
* @throws ReaderException Any errors which occurred
|
||||
*/
|
||||
public function decode( image:BinaryBitmap, hints:HashTable=null):Result
|
||||
{
|
||||
setHints(hints);
|
||||
return decodeInternal(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an image using the state set up by calling setHints() previously. Continuous scan
|
||||
* clients will get a <b>large</b> speed increase by using this instead of decode().
|
||||
*
|
||||
* @param image The pixel data to decode
|
||||
* @return The contents of the image
|
||||
* @throws ReaderException Any errors which occurred
|
||||
*/
|
||||
public function decodeWithState(image:BinaryBitmap):Result{
|
||||
// Make sure to set up the default state so we don't crash
|
||||
if (readers == null) {
|
||||
setHints(null);
|
||||
}
|
||||
return decodeInternal(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls
|
||||
* to decodeWithState(image) can reuse the same set of readers without reallocating memory. This
|
||||
* is important for performance in continuous scan clients.
|
||||
*
|
||||
* @param hints The set of hints to use for subsequent calls to decode(image)
|
||||
*/
|
||||
public function setHints(hints:HashTable):void
|
||||
{
|
||||
this.hints = hints;
|
||||
|
||||
var tryHarder:Boolean = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
|
||||
var formats:ArrayList = ((hints == null) ? null : hints.getValuesByKey(DecodeHintType.POSSIBLE_FORMATS));
|
||||
readers = new ArrayList();
|
||||
if (formats != null)
|
||||
{
|
||||
var addOneDReader:Boolean =
|
||||
(formats.indexOf(BarcodeFormat.UPC_A) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.UPC_E) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.CODABAR) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.ITF) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.EAN_13) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.EAN_8) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.RSS_14) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.RSS_EXPANDED) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.CODE_39) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.CODE_93) != -1)||
|
||||
(formats.indexOf(BarcodeFormat.CODE_128) != -1);
|
||||
// Put 1D readers upfront in "normal" mode
|
||||
|
||||
if (addOneDReader && !tryHarder)
|
||||
{
|
||||
readers.Add(new MultiFormatOneDReader(hints));
|
||||
}
|
||||
|
||||
if (formats.indexOf(BarcodeFormat.QR_CODE) != -1)
|
||||
{
|
||||
readers.Add(new QRCodeReader());
|
||||
}
|
||||
if (formats.indexOf(BarcodeFormat.PDF417) != -1) {
|
||||
readers.addElement(new PDF417Reader());
|
||||
}
|
||||
if (formats.indexOf(BarcodeFormat.AZTEC) != -1) {
|
||||
readers.addElement(new AztecReader());
|
||||
}
|
||||
// TODO re-enable once Data Matrix is ready
|
||||
if (formats.indexOf(BarcodeFormat.DATAMATRIX) != -1) {
|
||||
readers.Add(new DataMatrixReader());
|
||||
}
|
||||
if (formats.Contains(BarcodeFormat.MAXICODE)) {
|
||||
readers.addElement(new MaxiCodeReader());
|
||||
}
|
||||
|
||||
// At end in "try harder" mode
|
||||
if (addOneDReader && tryHarder)
|
||||
{
|
||||
readers.Add(new MultiFormatOneDReader(hints));
|
||||
}
|
||||
}
|
||||
|
||||
if (readers.Count == 0)
|
||||
{
|
||||
if (!tryHarder)
|
||||
{
|
||||
var reader:MultiFormatOneDReader = new MultiFormatOneDReader(hints);
|
||||
readers.Add(reader);
|
||||
}
|
||||
readers.Add(new QRCodeReader());
|
||||
readers.Add(new DataMatrixReader());
|
||||
readers.Add(new AztecReader());
|
||||
readers.Add(new PDF417Reader());
|
||||
readers.Add(new MaxiCodeReader());
|
||||
|
||||
if (tryHarder)
|
||||
{
|
||||
readers.Add(new MultiFormatOneDReader(hints));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public function reset():void
|
||||
{
|
||||
var size:int = readers.size();
|
||||
for (var i:int = 0; i < size; i++)
|
||||
{
|
||||
var reader:Reader = Reader(readers.elementAt(i));
|
||||
reader.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private function decodeInternal( image:BinaryBitmap):Result
|
||||
{
|
||||
var size:int = readers.Count;
|
||||
for (var i:int = 0; i < size; i++)
|
||||
{
|
||||
var reader:Reader = (readers.getObjectByIndex(i)) as Reader;
|
||||
try{
|
||||
try
|
||||
{
|
||||
var res:Result = reader.decode(image, hints);
|
||||
return res;
|
||||
}
|
||||
catch ( re:ReaderException)
|
||||
{
|
||||
// continue
|
||||
var a:int =3;
|
||||
}
|
||||
}
|
||||
catch (e:Error)
|
||||
{
|
||||
var b:int = 4;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// no decoder could decode the barcode
|
||||
return null;
|
||||
//throw new ReaderException("MultiFormatReader : decodeInternal :could not decode");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright 2008 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
|
||||
{
|
||||
public class MultiFormatWriter implements Writer
|
||||
{
|
||||
import com.google.zxing.common.ByteMatrix;
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
import com.google.zxing.qrcode.QRCodeWriter
|
||||
import com.google.zxing.oned.Code128Writer;
|
||||
import com.google.zxing.oned.Code39Writer;
|
||||
import com.google.zxing.oned.EAN13Writer;
|
||||
import com.google.zxing.oned.EAN8Writer;
|
||||
import com.google.zxing.oned.ITFWriter;
|
||||
import com.google.zxing.oned.UPCAWriter;
|
||||
import com.google.zxing.pdf417.encoder.PDF417Writer;
|
||||
|
||||
public function encode(contents:String, format:BarcodeFormat=null,width:int=0,height:int=0, hints:HashTable=null):Object{
|
||||
|
||||
var writer:Writer;
|
||||
if (format == BarcodeFormat.EAN_8) {
|
||||
writer = new EAN8Writer();
|
||||
} else if (format == BarcodeFormat.EAN_13) {
|
||||
writer = new EAN13Writer();
|
||||
} else if (format == BarcodeFormat.UPC_A) {
|
||||
writer = new UPCAWriter();
|
||||
} else if (format == BarcodeFormat.CODE_39) {
|
||||
writer = new Code39Writer();
|
||||
} else if (format == BarcodeFormat.CODE_128) {
|
||||
writer = new Code128Writer();
|
||||
} else if (format == BarcodeFormat.ITF) {
|
||||
writer = new ITFWriter();
|
||||
} else if (format == BarcodeFormat.PDF417) {
|
||||
writer = new PDF417Writer();
|
||||
} else if (format == BarcodeFormat.QR_CODE) {
|
||||
writer = new QRCodeWriter();
|
||||
} else {
|
||||
throw new IllegalArgumentException("No encoder available for format " + format);
|
||||
}
|
||||
return writer.encode(contents, format, width, height, hints);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
|
||||
/**
|
||||
* Thrown when a barcode was not found in the image. It might have been
|
||||
* partially detected but could not be confirmed.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class NotFoundException extends ReaderException {
|
||||
|
||||
private static var instance:NotFoundException = new NotFoundException();
|
||||
|
||||
public function NotFoundException() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public static function getNotFoundInstance():NotFoundException {
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
/**
|
||||
* Implementations of this interface can decode an image of a barcode in some format into
|
||||
* the String it encodes. For example, {@link com.google.zxing.qrcode.QRCodeReader} can
|
||||
* decode a QR code. The decoder may optionally receive hints from the caller which may help
|
||||
* it decode more quickly or accurately.
|
||||
*
|
||||
* See {@link com.google.zxing.MultiFormatReader}, which attempts to determine what barcode
|
||||
* format is present within the image as well, and then decodes it accordingly.
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
|
||||
public interface Reader
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
|
||||
|
||||
/**
|
||||
* Locates and decodes a barcode in some format within an image. This method also accepts
|
||||
* hints, each possibly associated to some data, which may help the implementation decode.
|
||||
*
|
||||
* @param image image of barcode to decode
|
||||
* @param hints passed as a {@link java.util.Hashtable} from {@link com.google.zxing.DecodeHintType} to aribtrary data. The
|
||||
* meaning of the data depends upon the hint type. The implementation may or may not do
|
||||
* anything with these hints.
|
||||
* @return String which the barcode encodes
|
||||
* @throws ReaderException if the barcode cannot be located or decoded for any reason
|
||||
*/
|
||||
function decode(image:BinaryBitmap, hints:HashTable=null):Result;
|
||||
function reset():void;
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
/**
|
||||
* The general exception class throw when something goes wrong during decoding of a barcode.
|
||||
* This includes, but is not limited to, failing checksums / error correction algorithms, being
|
||||
* unable to locate finder timing patterns, and so on.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
|
||||
public class ReaderException extends Error
|
||||
{
|
||||
// TODO: Currently we throw up to 400 ReaderExceptions while scanning a single 240x240 image before
|
||||
// rejecting it. This involves a lot of overhead and memory allocation, and affects both performance
|
||||
// and latency on continuous scan clients. In the future, we should change all the decoders not to
|
||||
// throw exceptions for routine events, like not finding a barcode on a given row. Instead, we
|
||||
// should return error codes back to the callers, and simply delete this class. In the mean time, I
|
||||
// have altered this class to be as lightweight as possible, by ignoring the exception string, and
|
||||
// by disabling the generation of stack traces, which is especially time consuming. These are just
|
||||
// temporary measures, pending the big cleanup.
|
||||
|
||||
private static var instance:ReaderException = new ReaderException();
|
||||
|
||||
public function ReaderException(message:String=""):void {
|
||||
super(message);
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public static function getInstance():ReaderException {
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Prevent stack traces from being taken
|
||||
// srowen says: huh, my IDE is saying this is not an override. native methods can't be overridden?
|
||||
// This, at least, does not hurt. Because we use a singleton pattern here, it doesn't matter anyhow.
|
||||
/*public function fillInStackTrace():Throwable {
|
||||
return null;
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
/**
|
||||
* <p>Encapsulates the result of decoding a barcode within an image.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class Result
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
import com.google.zxing.common.flexdatatypes.Enumeration;
|
||||
|
||||
protected var text:String;
|
||||
protected var rawBytes:Array;
|
||||
protected var resultPoints:Array;
|
||||
protected var format:BarcodeFormat;
|
||||
protected var resultMetadata:HashTable;
|
||||
protected var timestamp:Number;
|
||||
|
||||
public function Result( text:String,
|
||||
rawBytes:Array,
|
||||
resultPoints:Array,
|
||||
format:BarcodeFormat,
|
||||
timestamp:Number = 0)
|
||||
{
|
||||
if (text == null && rawBytes == null) {
|
||||
throw new IllegalArgumentException("Result : Text and bytes are both null");
|
||||
}
|
||||
|
||||
|
||||
if (timestamp == 0) { timestamp = Math.round((new Date()).getTime()/1000); }
|
||||
this.text = text;
|
||||
this.rawBytes = rawBytes;
|
||||
this.resultPoints = resultPoints;
|
||||
this.format = format;
|
||||
this.resultMetadata = null;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return raw text encoded by the barcode, if applicable, otherwise <code>null</code>
|
||||
*/
|
||||
public function getText():String {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return raw bytes encoded by the barcode, if applicable, otherwise <code>null</code>
|
||||
*/
|
||||
public function getRawBytes():Array {
|
||||
return rawBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return points related to the barcode in the image. These are typically points
|
||||
* identifying finder patterns or the corners of the barcode. The exact meaning is
|
||||
* specific to the type of barcode that was decoded.
|
||||
*/
|
||||
public function getResultPoints():Array {
|
||||
return resultPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link BarcodeFormat} representing the format of the barcode that was recognized and decoded
|
||||
*/
|
||||
public function getBarcodeFormat():BarcodeFormat {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link HashTable} mapping {@link ResultMetadataType} keys to values. May be <code>null</code>.
|
||||
* This contains optional metadata about what was detected about the barcode, like orientation.
|
||||
*/
|
||||
public function getResultMetadata():HashTable {
|
||||
return resultMetadata;
|
||||
}
|
||||
|
||||
public function putMetadata(type:ResultMetadataType, value:Object ):void {
|
||||
if (resultMetadata == null) {
|
||||
resultMetadata = new HashTable(3);
|
||||
}
|
||||
resultMetadata.Add(type, value);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
if (text == null) {
|
||||
return "[" + rawBytes.length + " bytes]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
public function putAllMetadata(metadata:HashTable ):void
|
||||
{
|
||||
if (metadata != null) {
|
||||
if (resultMetadata == null) {
|
||||
resultMetadata = metadata;
|
||||
} else {
|
||||
var e:Enumeration = new Enumeration(metadata.keys());
|
||||
while (e.hasMoreElement()) {
|
||||
var key:ResultMetadataType = (e.nextElement() as ResultMetadataType);
|
||||
var value:Object = metadata._get(key);
|
||||
resultMetadata._put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function addResultPoints(newPoints:Array):void
|
||||
{
|
||||
if (resultPoints == null) {
|
||||
resultPoints = newPoints;
|
||||
} else if (newPoints != null && newPoints.length > 0) {
|
||||
var allPoints:Array = new Array(resultPoints.length + newPoints.length);
|
||||
//System.arraycopy(resultPoints, 0, allPoints, 0, resultPoints.length);
|
||||
for (var i:int=0;i<resultPoints.length;i++)
|
||||
{
|
||||
allPoints[i] = resultPoints[i];
|
||||
}
|
||||
for (var j:int=0;j<newPoints.length;j++)
|
||||
{
|
||||
allPoints[i + resultPoints.length] = newPoints[i];
|
||||
}
|
||||
|
||||
//System.arraycopy(newPoints, 0, allPoints, resultPoints.length, newPoints.length);
|
||||
resultPoints = allPoints;
|
||||
}
|
||||
}
|
||||
|
||||
public function getTimestamp():Number
|
||||
{
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
|
||||
public class ResultMetadataType
|
||||
{
|
||||
// No, we can't use an enum here. J2ME doesn't support it.
|
||||
|
||||
/**
|
||||
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
|
||||
*/
|
||||
public static var OTHER:ResultMetadataType = new ResultMetadataType("OTHER");
|
||||
|
||||
/**
|
||||
* Denotes the likely approximate orientation of the barcode in the image. This value
|
||||
* is given as degrees rotated clockwise from the normal, upright orientation.
|
||||
* For example a 1D barcode which was found by reading top-to-bottom would be
|
||||
* said to have orientation "90". This key maps to an {@link Integer} whose
|
||||
* value is in the range [0,360).
|
||||
*/
|
||||
public static var ORIENTATION:ResultMetadataType = new ResultMetadataType("ORIENTATION");
|
||||
|
||||
/**
|
||||
* <p>2D barcode formats typically encode text, but allow for a sort of 'byte mode'
|
||||
* which is sometimes used to encode binary data. While {@link Result} makes available
|
||||
* the complete raw bytes in the barcode for these formats, it does not offer the bytes
|
||||
* from the byte segments alone.</p>
|
||||
*
|
||||
* <p>This maps to a {@link java.util.Vector} of byte arrays corresponding to the
|
||||
* raw bytes in the byte segments in the barcode, in order.</p>
|
||||
*/
|
||||
public static var BYTE_SEGMENTS:ResultMetadataType = new ResultMetadataType("BYTE SEGMENTS");
|
||||
|
||||
/**
|
||||
* Error correction level used, if applicable. The value type depends on the
|
||||
* format, but is typically a String.
|
||||
*/
|
||||
public static var ERROR_CORRECTION_LEVEL:ResultMetadataType = new ResultMetadataType("ORIENTATION");
|
||||
|
||||
|
||||
/**
|
||||
* For some periodicals, indicates the issue number as an {@link Integer}.
|
||||
*/
|
||||
public static var ISSUE_NUMBER:ResultMetadataType = new ResultMetadataType("ISSUE_NUMBER");
|
||||
|
||||
/**
|
||||
* For some products, indicates the suggested retail price in the barcode as a
|
||||
* formatted {@link String}.
|
||||
*/
|
||||
public static var SUGGESTED_PRICE:ResultMetadataType = new ResultMetadataType("SUGGESTED_PRICE");
|
||||
|
||||
/**
|
||||
* For some products, the possible country of manufacture as a {@link String} denoting the
|
||||
* ISO country code. Some map to multiple possible countries, like "US/CA".
|
||||
*/
|
||||
public static var POSSIBLE_COUNTRY:ResultMetadataType = new ResultMetadataType("POSSIBLE_COUNTRY");
|
||||
|
||||
private var name:String ;
|
||||
|
||||
private static var VALUES:HashTable = new HashTable();
|
||||
|
||||
public function ResultMetadataType(name:String = "") {
|
||||
this.name = name;
|
||||
//VALUES.put(name, this);
|
||||
}
|
||||
|
||||
public function getName():String {
|
||||
return name;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static function valueOf(name:String):ResultMetadataType
|
||||
{
|
||||
if (name == null || name.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
var format:ResultMetadataType = ResultMetadataType(VALUES._get(name));
|
||||
if (format == null)
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
{
|
||||
/**
|
||||
* <p>Encapsulates a point of interest in an image containing a barcode. Typically, this
|
||||
* would be the location of a finder pattern or the corner of the barcode, for example.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
|
||||
public class ResultPoint
|
||||
{
|
||||
protected var x:Number;
|
||||
protected var y:Number;
|
||||
|
||||
public function ResultPoint(x:Number, y:Number)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public final function getX():Number
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
public final function getY():Number
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
public function equals(other:Object ):Boolean
|
||||
{
|
||||
if (other is ResultPoint)
|
||||
{
|
||||
var otherPoint:ResultPoint = other as ResultPoint;
|
||||
return x == otherPoint.x && y == otherPoint.y;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* no default method to determine a hashcode for Number in Actionscript
|
||||
|
||||
public function hashCode():int
|
||||
{
|
||||
return 31 * identityHashCode(x) + identityHashCode(y);
|
||||
}
|
||||
*/
|
||||
public function toString():String
|
||||
{
|
||||
var result:StringBuilder = new StringBuilder(25);
|
||||
result.Append('(');
|
||||
result.Append(x);
|
||||
result.Append(',');
|
||||
result.Append(y);
|
||||
result.Append(')');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
|
||||
* BC < AC and the angle between BC and BA is less than 180 degrees.
|
||||
*/
|
||||
public static function orderBestPatterns(patterns:Array):void
|
||||
{
|
||||
|
||||
// Find distances between pattern centers
|
||||
var zeroOneDistance:Number = distance(patterns[0], patterns[1]);
|
||||
var oneTwoDistance:Number = distance(patterns[1], patterns[2]);
|
||||
var zeroTwoDistance:Number = distance(patterns[0], patterns[2]);
|
||||
|
||||
var pointA:ResultPoint;
|
||||
var pointB:ResultPoint;
|
||||
var pointC:ResultPoint;
|
||||
// Assume one closest to other two is B; A and C will just be guesses at first
|
||||
if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance)
|
||||
{
|
||||
pointB = patterns[0];
|
||||
pointA = patterns[1];
|
||||
pointC = patterns[2];
|
||||
}
|
||||
else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance)
|
||||
{
|
||||
pointB = patterns[1];
|
||||
pointA = patterns[0];
|
||||
pointC = patterns[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
pointB = patterns[2];
|
||||
pointA = patterns[0];
|
||||
pointC = patterns[1];
|
||||
}
|
||||
|
||||
// Use cross product to figure out whether A and C are correct or flipped.
|
||||
// This asks whether BC x BA has a positive z component, which is the arrangement
|
||||
// we want for A, B, C. If it's negative, then we've got it flipped around and
|
||||
// should swap A and C.
|
||||
if (crossProductZ(pointA, pointB, pointC) < 0.0) {
|
||||
var temp:ResultPoint = pointA;
|
||||
pointA = pointC;
|
||||
pointC = temp;
|
||||
}
|
||||
|
||||
patterns[0] = pointA;
|
||||
patterns[1] = pointB;
|
||||
patterns[2] = pointC;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return distance between two points
|
||||
*/
|
||||
public static function distance(pattern1:ResultPoint, pattern2:ResultPoint):Number
|
||||
{
|
||||
var xDiff:Number = pattern1.getX() - pattern2.getX();
|
||||
var yDiff:Number = pattern1.getY() - pattern2.getY();
|
||||
return Math.sqrt(xDiff * xDiff + yDiff * yDiff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the z component of the cross product between vectors BC and BA.
|
||||
*/
|
||||
public static function crossProductZ(pointA:ResultPoint, pointB:ResultPoint, pointC:ResultPoint):Number
|
||||
{
|
||||
var bX:Number = pointB.x;
|
||||
var bY:Number = pointB.y;
|
||||
return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback which is invoked when a possible result point (significant
|
||||
* point in the barcode image such as a corner) is found.
|
||||
*
|
||||
* @see DecodeHintType#NEED_RESULT_POINT_CALLBACK
|
||||
*/
|
||||
public interface ResultPointCallback {
|
||||
|
||||
function foundPossibleResultPoint(point:ResultPoint ):void;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright 2008 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
|
||||
{
|
||||
/**
|
||||
* The base class for all objects which encode/generate a barcode image.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public interface Writer
|
||||
{
|
||||
import com.google.zxing.common.ByteMatrix;
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param contents The contents to encode in the barcode
|
||||
* @param format The barcode format to generate
|
||||
* @param width The preferred width in pixels
|
||||
* @param height The preferred height in pixels
|
||||
* @param hints Additional parameters to supply to the encoder
|
||||
* @return The generated barcode as a Matrix of unsigned bytes (0 == black, 255 == white)
|
||||
*/
|
||||
function encode(contents:String, format:BarcodeFormat=null, width:int=0, height:int=0, hints:HashTable=null):Object;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2008 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
|
||||
{
|
||||
/**
|
||||
* A base class which covers the range of exceptions which may occur when encoding a barcode using
|
||||
* the Writer framework.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
|
||||
public class WriterException extends Error
|
||||
{
|
||||
public function WriterException(message:String=undefined)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright 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.aztec
|
||||
{
|
||||
import com.google.zxing.common.DetectorResult;
|
||||
|
||||
public final class AztecDetectorResult extends DetectorResult
|
||||
{
|
||||
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.DetectorResult;
|
||||
|
||||
|
||||
private var compact:Boolean;
|
||||
private var nbDatablocks:int;
|
||||
private var nbLayers:int;
|
||||
|
||||
public function AztecDetectorResult(bits:BitMatrix , points:Array, compact:Boolean, nbDatablocks:int, nbLayers:int)
|
||||
{
|
||||
super(bits, points);
|
||||
this.compact = compact;
|
||||
this.nbDatablocks = nbDatablocks;
|
||||
this.nbLayers = nbLayers;
|
||||
}
|
||||
|
||||
public function getNbLayers():int
|
||||
{
|
||||
return nbLayers;
|
||||
}
|
||||
|
||||
public function getNbDatablocks():int
|
||||
{
|
||||
return nbDatablocks;
|
||||
}
|
||||
|
||||
public function isCompact():Boolean
|
||||
{
|
||||
return compact;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* Copyright 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.aztec
|
||||
{
|
||||
import com.google.zxing.Reader;
|
||||
import com.google.zxing.ResultPointCallback;
|
||||
|
||||
public final class AztecReader implements Reader
|
||||
{
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.ChecksumException;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.FormatException;
|
||||
import com.google.zxing.NotFoundException;
|
||||
import com.google.zxing.Reader;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.ResultMetadataType;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.DecoderResult;
|
||||
import com.google.zxing.aztec.decoder.Decoder;
|
||||
import com.google.zxing.aztec.detector.Detector;
|
||||
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
|
||||
/**
|
||||
* This implementation can detect and decode Aztec codes in an image.
|
||||
*
|
||||
* @author David Olivier
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Locates and decodes a Data Matrix code in an image.
|
||||
*
|
||||
* @return a String representing the content encoded by the Data Matrix code
|
||||
* @throws NotFoundException if a Data Matrix code cannot be found
|
||||
* @throws FormatException if a Data Matrix code cannot be decoded
|
||||
* @throws ChecksumException if error correction fails
|
||||
*/
|
||||
public function decode(image:BinaryBitmap, hints:HashTable=null ):Result
|
||||
{
|
||||
if (hints == null) {return decode(image, null);}
|
||||
|
||||
var detectorResult:AztecDetectorResult = new Detector(image.getBlackMatrix()).detect();
|
||||
var points:Array = detectorResult.getPoints();
|
||||
|
||||
if ((hints != null) && (detectorResult.getPoints() != null))
|
||||
{
|
||||
var rpcb:ResultPointCallback = hints._get(DecodeHintType.NEED_RESULT_POINT_CALLBACK) as ResultPointCallback;
|
||||
if (rpcb != null)
|
||||
{
|
||||
for (var i:int = 0; i < detectorResult.getPoints().length; i++)
|
||||
{
|
||||
rpcb.foundPossibleResultPoint(detectorResult.getPoints()[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var decoderResult:DecoderResult = new Decoder().decode(detectorResult);
|
||||
|
||||
var result:Result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.AZTEC);
|
||||
|
||||
if (decoderResult.getByteSegments() != null)
|
||||
{
|
||||
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.getByteSegments());
|
||||
}
|
||||
|
||||
if (decoderResult.getECLevel() != null)
|
||||
{
|
||||
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel().toString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public function reset():void
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.aztec
|
||||
{
|
||||
import com.google.zxing.ResultPoint;
|
||||
|
||||
public class Point {
|
||||
public var x:int;
|
||||
public var y:int;
|
||||
|
||||
public function toResultPoint():ResultPoint {
|
||||
return new ResultPoint(x, y);
|
||||
}
|
||||
|
||||
public function Point( x:int, y:int) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,469 +0,0 @@
|
|||
/*
|
||||
* Copyright 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.aztec.decoder
|
||||
{
|
||||
|
||||
import com.google.zxing.FormatException;
|
||||
import com.google.zxing.aztec.AztecDetectorResult;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.DecoderResult;
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
import com.google.zxing.common.reedsolomon.GenericGF;
|
||||
import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
|
||||
import com.google.zxing.common.reedsolomon.ReedSolomonException;
|
||||
|
||||
/**
|
||||
* <p>The main class which implements Aztec Code decoding -- as opposed to locating and extracting
|
||||
* the Aztec Code from an image.</p>
|
||||
*
|
||||
* @author David Olivier
|
||||
*/
|
||||
public class Decoder
|
||||
{
|
||||
|
||||
private static var UPPER:int = 0;
|
||||
private static var LOWER:int = 1;
|
||||
private static var MIXED:int = 2;
|
||||
private static var DIGIT:int = 3;
|
||||
private static var PUNCT:int = 4;
|
||||
private static var BINARY:int = 5;
|
||||
|
||||
private static var NB_BITS_COMPACT:Array = [0, 104, 240, 408, 608];
|
||||
|
||||
private static var NB_BITS:Array = [
|
||||
0, 128, 288, 480, 704, 960, 1248, 1568, 1920, 2304, 2720, 3168, 3648, 4160, 4704, 5280, 5888, 6528,
|
||||
7200, 7904, 8640, 9408, 10208, 11040, 11904, 12800, 13728, 14688, 15680, 16704, 17760, 18848, 19968
|
||||
];
|
||||
|
||||
private static var NB_DATABLOCK_COMPACT:Array = [
|
||||
0, 17, 40, 51, 76
|
||||
];
|
||||
|
||||
private static var NB_DATABLOCK:Array = [
|
||||
0, 21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588, 652, 720, 790, 864,
|
||||
940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664
|
||||
];
|
||||
|
||||
private static var UPPER_TABLE:Array = [
|
||||
"CTRL_PS", " ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
|
||||
"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "CTRL_LL", "CTRL_ML", "CTRL_DL", "CTRL_BS"
|
||||
];
|
||||
|
||||
private static var LOWER_TABLE:Array = [
|
||||
"CTRL_PS", " ", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
|
||||
"q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "CTRL_US", "CTRL_ML", "CTRL_DL", "CTRL_BS"
|
||||
];
|
||||
|
||||
private static var MIXED_TABLE:Array = [
|
||||
"CTRL_PS", " ", "\1", "\2", "\3", "\4", "\5", "\6", "\7", "\b", "\t", "\n",
|
||||
"\13", "\f", "\r", "\33", "\34", "\35", "\36", "\37", "@", "\\", "^", "_",
|
||||
"`", "|", "~", "\177", "CTRL_LL", "CTRL_UL", "CTRL_PL", "CTRL_BS"
|
||||
];
|
||||
|
||||
private static var PUNCT_TABLE:Array = [
|
||||
"", "\r", "\r\n", ". ", ", ", ": ", "!", "\"", "#", "$", "%", "&", "'", "(", ")",
|
||||
"*", "+", ",", "-", ".", "/", ":", ";", "<", "=", ">", "?", "[", "]", "{", "}", "CTRL_UL"
|
||||
];
|
||||
|
||||
private static var DIGIT_TABLE:Array = [
|
||||
"CTRL_PS", " ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ",", ".", "CTRL_UL", "CTRL_US"
|
||||
];
|
||||
|
||||
private var numCodewords:int;
|
||||
private var codewordSize:int;
|
||||
private var ddata:AztecDetectorResult;
|
||||
private var invertedBitCount:int;
|
||||
|
||||
public function decode( detectorResult:AztecDetectorResult):DecoderResult {
|
||||
ddata = detectorResult;
|
||||
var matrix:BitMatrix = detectorResult.getBits();
|
||||
|
||||
if (!ddata.isCompact()) {
|
||||
matrix = removeDashedLines(ddata.getBits());
|
||||
}
|
||||
|
||||
var rawbits:Array = extractBits(matrix);
|
||||
var rawbitsString:String = "";for(var k:int=0;k<rawbits.length;k++){ rawbitsString += ((rawbits[k])?"T":"F");}
|
||||
|
||||
var correctedBits:Array = correctBits(rawbits);
|
||||
var correctedBitsString:String = "";for(var k1:int=0;k1<correctedBits.length;k1++){ correctedBitsString += ((correctedBits[k1])?"T":"F");}
|
||||
|
||||
var result:String = getEncodedData(correctedBits);
|
||||
|
||||
return new DecoderResult(null, result, null, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the string encoded in the aztec code bits
|
||||
*
|
||||
* @return the decoded string
|
||||
* @throws FormatException if the input is not valid
|
||||
*/
|
||||
private function getEncodedData(correctedBits:Array):String {
|
||||
|
||||
var endIndex:int = codewordSize * ddata.getNbDatablocks() - invertedBitCount;
|
||||
if (endIndex > correctedBits.length) {
|
||||
throw FormatException.getFormatInstance();
|
||||
}
|
||||
|
||||
var lastTable:int = UPPER;
|
||||
var table:int = UPPER;
|
||||
var startIndex:int = 0;
|
||||
var result:StringBuilder = new StringBuilder(20);
|
||||
var end:Boolean = false;
|
||||
var shift:Boolean = false;
|
||||
var switchShift:Boolean = false;
|
||||
|
||||
while (!end) {
|
||||
|
||||
if (shift) {
|
||||
// the table is for the next character only
|
||||
switchShift = true;
|
||||
} else {
|
||||
// save the current table in case next one is a shift
|
||||
lastTable = table;
|
||||
}
|
||||
|
||||
var code:int;
|
||||
switch (table) {
|
||||
case BINARY:
|
||||
if (endIndex - startIndex < 8) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
code = readCode(correctedBits, startIndex, 8);
|
||||
startIndex += 8;
|
||||
|
||||
result.Append(String.fromCharCode(code));
|
||||
break;
|
||||
|
||||
default:
|
||||
var size:int = 5;
|
||||
|
||||
if (table == DIGIT) {
|
||||
size = 4;
|
||||
}
|
||||
|
||||
if (endIndex - startIndex < size) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
|
||||
code = readCode(correctedBits, startIndex, size);
|
||||
startIndex += size;
|
||||
|
||||
var str:String = getCharacter(table, code);
|
||||
if (str.substr(0,5) == "CTRL_") {
|
||||
// Table changes
|
||||
table = getTable(str.charAt(5));
|
||||
|
||||
if (str.charAt(6) == 'S') {
|
||||
shift = true;
|
||||
}
|
||||
} else {
|
||||
result.Append(str);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (switchShift) {
|
||||
table = lastTable;
|
||||
shift = false;
|
||||
switchShift = false;
|
||||
}
|
||||
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gets the table corresponding to the char passed
|
||||
*/
|
||||
private static function getTable(t:String):int {
|
||||
var table:int = UPPER;
|
||||
|
||||
switch (t) {
|
||||
case 'U':
|
||||
table = UPPER;
|
||||
break;
|
||||
case 'L':
|
||||
table = LOWER;
|
||||
break;
|
||||
case 'P':
|
||||
table = PUNCT;
|
||||
break;
|
||||
case 'M':
|
||||
table = MIXED;
|
||||
break;
|
||||
case 'D':
|
||||
table = DIGIT;
|
||||
break;
|
||||
case 'B':
|
||||
table = BINARY;
|
||||
break;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the character (or string) corresponding to the passed code in the given table
|
||||
*
|
||||
* @param table the table used
|
||||
* @param code the code of the character
|
||||
*/
|
||||
private static function getCharacter(table:int, code:int):String {
|
||||
switch (table) {
|
||||
case UPPER:
|
||||
return UPPER_TABLE[code];
|
||||
case LOWER:
|
||||
return LOWER_TABLE[code];
|
||||
case MIXED:
|
||||
return MIXED_TABLE[code];
|
||||
case PUNCT:
|
||||
return PUNCT_TABLE[code];
|
||||
case DIGIT:
|
||||
return DIGIT_TABLE[code];
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <p> performs RS error correction on an array of bits </p>
|
||||
*
|
||||
* @return the corrected array
|
||||
* @throws FormatException if the input contains too many errors
|
||||
*/
|
||||
private function correctBits(rawbits:Array):Array {
|
||||
var gf:GenericGF;
|
||||
|
||||
if (ddata.getNbLayers() <= 2) {
|
||||
codewordSize = 6;
|
||||
gf = GenericGF.AZTEC_DATA_6;
|
||||
} else if (ddata.getNbLayers() <= 8) {
|
||||
codewordSize = 8;
|
||||
gf = GenericGF.AZTEC_DATA_8;
|
||||
} else if (ddata.getNbLayers() <= 22) {
|
||||
codewordSize = 10;
|
||||
gf = GenericGF.AZTEC_DATA_10;
|
||||
} else {
|
||||
codewordSize = 12;
|
||||
gf = GenericGF.AZTEC_DATA_12;
|
||||
|
||||
}
|
||||
|
||||
var numDataCodewords:int = ddata.getNbDatablocks();
|
||||
var numECCodewords:int;
|
||||
var offset:int;
|
||||
|
||||
if (ddata.isCompact()) {
|
||||
offset = NB_BITS_COMPACT[ddata.getNbLayers()] - numCodewords*codewordSize;
|
||||
numECCodewords = NB_DATABLOCK_COMPACT[ddata.getNbLayers()] - numDataCodewords;
|
||||
} else {
|
||||
offset = NB_BITS[ddata.getNbLayers()] - numCodewords*codewordSize;
|
||||
numECCodewords = NB_DATABLOCK[ddata.getNbLayers()] - numDataCodewords;
|
||||
}
|
||||
|
||||
var dataWords:Array = new Array(numCodewords);
|
||||
for (var m:int=0;m<dataWords.length;m++) { dataWords[m] = 0;}
|
||||
|
||||
for (var ii:int = 0; ii < numCodewords; ii++)
|
||||
{
|
||||
var flag:int = 1;
|
||||
for (var j2:int = 1; j2 <= codewordSize; j2++) {
|
||||
if (rawbits[codewordSize*ii + codewordSize - j2 + offset]) {
|
||||
dataWords[ii] += flag;
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
|
||||
//if (dataWords[i] >= flag) {
|
||||
// flag++;
|
||||
//}
|
||||
}
|
||||
|
||||
try {
|
||||
var rsDecoder:ReedSolomonDecoder = new ReedSolomonDecoder(gf);
|
||||
rsDecoder.decode(dataWords, numECCodewords);
|
||||
} catch (rse:ReedSolomonException ) {
|
||||
throw FormatException.getFormatInstance();
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
invertedBitCount = 0;
|
||||
|
||||
var correctedBits:Array = new Array(numDataCodewords*codewordSize);
|
||||
for(var z:int=0;z<(numDataCodewords*codewordSize);z++) {correctedBits[z] = 0; }
|
||||
|
||||
for (var i:int = 0; i < numDataCodewords; i ++) {
|
||||
|
||||
var seriesColor:Boolean = false;
|
||||
var seriesCount:int = 0;
|
||||
var _flag:int = 1 << (codewordSize - 1);
|
||||
|
||||
for (var j:int = 0; j < codewordSize; j++) {
|
||||
|
||||
var color:Boolean = (dataWords[i] & _flag) == _flag;
|
||||
|
||||
if (seriesCount == codewordSize - 1) {
|
||||
|
||||
if (color == seriesColor) {
|
||||
//bit must be inverted
|
||||
throw FormatException.getFormatInstance();
|
||||
}
|
||||
|
||||
seriesColor = false;
|
||||
seriesCount = 0;
|
||||
offset++;
|
||||
invertedBitCount++;
|
||||
} else {
|
||||
|
||||
if (seriesColor == color) {
|
||||
seriesCount++;
|
||||
} else {
|
||||
seriesCount = 1;
|
||||
seriesColor = color;
|
||||
}
|
||||
|
||||
correctedBits[i * codewordSize + j - offset] = color;
|
||||
|
||||
}
|
||||
|
||||
_flag >>>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return correctedBits;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the array of bits from an Aztec Code matrix
|
||||
*
|
||||
* @return the array of bits
|
||||
* @throws FormatException if the matrix is not a valid aztec code
|
||||
*/
|
||||
private function extractBits(matrix:BitMatrix ):Array {
|
||||
|
||||
var rawbits:Array;
|
||||
if (ddata.isCompact()) {
|
||||
if (ddata.getNbLayers() > NB_BITS_COMPACT.length) {
|
||||
throw FormatException.getFormatInstance();
|
||||
}
|
||||
rawbits = new Array(NB_BITS_COMPACT[ddata.getNbLayers()]);
|
||||
numCodewords = NB_DATABLOCK_COMPACT[ddata.getNbLayers()];
|
||||
} else {
|
||||
if (ddata.getNbLayers() > NB_BITS.length) {
|
||||
throw FormatException.getFormatInstance();
|
||||
}
|
||||
rawbits = new Array(NB_BITS[ddata.getNbLayers()]);
|
||||
numCodewords = NB_DATABLOCK[ddata.getNbLayers()];
|
||||
}
|
||||
|
||||
var layer:int = ddata.getNbLayers();
|
||||
var size:int = matrix.getHeight();
|
||||
var rawbitsOffset:int = 0;
|
||||
var matrixOffset:int = 0;
|
||||
|
||||
while (layer != 0) {
|
||||
|
||||
var flip:int = 0;
|
||||
for (var i:int = 0; i < 2*size - 4; i++)
|
||||
{
|
||||
rawbits[rawbitsOffset+i] = matrix._get(matrixOffset + flip, matrixOffset + int(i/2));
|
||||
rawbits[rawbitsOffset+2*size - 4 + i] = matrix._get(matrixOffset + int(i/2), matrixOffset + size-1-flip);
|
||||
flip = int((flip + 1)%2);
|
||||
}
|
||||
|
||||
flip = 0;
|
||||
for (i = 2*size+1; i > 5; i--) {
|
||||
rawbits[rawbitsOffset+4*size - 8 + (2*size-i) + 1] = matrix._get(matrixOffset + size-1-flip, matrixOffset + int(i/2) - 1);
|
||||
rawbits[rawbitsOffset+6*size - 12 + (2*size-i) + 1] = matrix._get(matrixOffset + int(i/2) - 1, matrixOffset + flip);
|
||||
flip = int((flip + 1)%2);
|
||||
}
|
||||
|
||||
matrixOffset += 2;
|
||||
rawbitsOffset += 8*size-16;
|
||||
layer--;
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
return rawbits;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms an Aztec code matrix by removing the control dashed lines
|
||||
*/
|
||||
private static function removeDashedLines(matrix:BitMatrix):BitMatrix
|
||||
{
|
||||
|
||||
var nbDashed:int = 1+ 2* int(int((matrix.getWidth() - 1)/2) / 16); // Bas : int casts added to make calculation the same as Java
|
||||
var newMatrix:BitMatrix = new BitMatrix(matrix.getWidth() - nbDashed, matrix.getHeight() - nbDashed);
|
||||
|
||||
var nx:int = 0;
|
||||
|
||||
for (var x:int = 0; x < matrix.getWidth(); x++) {
|
||||
var term1:int = int(int((int(matrix.getWidth() / 2)) - x)%16);
|
||||
if (term1 == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var ny:int = 0;
|
||||
for (var y:int = 0; y < matrix.getHeight(); y++) {
|
||||
var term2:int = int(int((int(matrix.getWidth() / 2)) - y)%16);
|
||||
if (term2 == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (matrix._get(x, y))
|
||||
{
|
||||
newMatrix._set(nx, ny);
|
||||
}
|
||||
ny++;
|
||||
}
|
||||
nx++;
|
||||
}
|
||||
|
||||
return newMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a code of given length and at given index in an array of bits
|
||||
*/
|
||||
private static function readCode(rawbits:Array, startIndex:int, length:int):int {
|
||||
var res:int = 0;
|
||||
|
||||
for (var i:int = startIndex; i < startIndex + length; i++) {
|
||||
res <<= 1;
|
||||
if (rawbits[i]) {
|
||||
res++;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,655 +0,0 @@
|
|||
/*
|
||||
* Copyright 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.aztec.detector
|
||||
{
|
||||
import com.google.zxing.common.detector.WhiteRectangleDetector;
|
||||
|
||||
public class Detector
|
||||
{
|
||||
|
||||
import com.google.zxing.NotFoundException;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.aztec.AztecDetectorResult;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.GridSampler;
|
||||
//import com.google.zxing.common.detector.WhiteRectangleDetector;
|
||||
import com.google.zxing.common.reedsolomon.GenericGF;
|
||||
import com.google.zxing.common.reedsolomon.GenericGFPoly;
|
||||
import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
|
||||
import com.google.zxing.common.reedsolomon.ReedSolomonException;
|
||||
import com.google.zxing.aztec.Point;
|
||||
|
||||
/**
|
||||
* <p>Encapsulates logic that can detect an Aztec Code in an image, even if the Aztec Code
|
||||
* is rotated or skewed, or partially obscured.</p>
|
||||
*
|
||||
* @author David Olivier
|
||||
*/
|
||||
|
||||
|
||||
private var image:BitMatrix;
|
||||
|
||||
private var compact:Boolean;
|
||||
private var nbLayers:int;
|
||||
private var nbDataBlocks:int;
|
||||
private var nbCenterLayers:int;
|
||||
private var shift:int;
|
||||
|
||||
public function Detector(image:BitMatrix)
|
||||
{
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Detects an Aztec Code in an image.</p>
|
||||
*
|
||||
* @return {@link AztecDetectorResult} encapsulating results of detecting an Aztec Code
|
||||
* @throws NotFoundException if no Aztec Code can be found
|
||||
*/
|
||||
public function detect():AztecDetectorResult
|
||||
{
|
||||
|
||||
// 1. Get the center of the aztec matrix
|
||||
var pCenter:Point = getMatrixCenter();
|
||||
|
||||
// 2. Get the corners of the center bull's eye
|
||||
var bullEyeCornerPoints:Array = getBullEyeCornerPoints(pCenter);
|
||||
|
||||
// 3. Get the size of the matrix from the bull's eye
|
||||
extractParameters(bullEyeCornerPoints);
|
||||
|
||||
// 4. Get the corners of the matrix
|
||||
var corners:Array = getMatrixCornerPoints(bullEyeCornerPoints);
|
||||
|
||||
// 5. Sample the grid
|
||||
var bits:BitMatrix = sampleGrid(image, corners[shift%4], corners[(shift+3)%4], corners[(shift+2)%4], corners[(shift+1)%4]);
|
||||
// tot hier correct
|
||||
return new AztecDetectorResult(bits, corners, compact, nbDataBlocks, nbLayers);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Extracts the number of data layers and data blocks from the layer around the bull's eye </p>
|
||||
*
|
||||
* @param bullEyeCornerPoints the array of bull's eye corners
|
||||
* @throws NotFoundException in case of too many errors or invalid parameters
|
||||
*/
|
||||
public function extractParameters(bullEyeCornerPoints:Array ):void
|
||||
{
|
||||
|
||||
// Get the bits around the bull's eye
|
||||
var resab:Array = sampleLine(bullEyeCornerPoints[0], bullEyeCornerPoints[1], 2*nbCenterLayers+1);
|
||||
var resbc:Array = sampleLine(bullEyeCornerPoints[1], bullEyeCornerPoints[2], 2*nbCenterLayers+1);
|
||||
var rescd:Array = sampleLine(bullEyeCornerPoints[2], bullEyeCornerPoints[3], 2*nbCenterLayers+1);
|
||||
var resda:Array = sampleLine(bullEyeCornerPoints[3], bullEyeCornerPoints[0], 2*nbCenterLayers+1);
|
||||
|
||||
// Determine the orientation of the matrix
|
||||
if (resab[0] && resab[2 * nbCenterLayers])
|
||||
{
|
||||
shift = 0;
|
||||
}
|
||||
else if (resbc[0] && resbc[2 * nbCenterLayers])
|
||||
{
|
||||
shift = 1;
|
||||
}
|
||||
else if (rescd[0] && rescd[2 * nbCenterLayers])
|
||||
{
|
||||
shift = 2;
|
||||
}
|
||||
else if (resda[0] && resda[2 * nbCenterLayers])
|
||||
{
|
||||
shift = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
//d a
|
||||
//
|
||||
//c b
|
||||
|
||||
// Flatten the bits in a single array
|
||||
var parameterData:Array;
|
||||
var shiftedParameterData:Array;
|
||||
if (compact)
|
||||
{
|
||||
shiftedParameterData = new Array();
|
||||
for (var i:int = 0; i < 7; i++)
|
||||
{
|
||||
shiftedParameterData[i] = resab[2+i];
|
||||
shiftedParameterData[i+7] = resbc[2+i];
|
||||
shiftedParameterData[i+14] = rescd[2+i];
|
||||
shiftedParameterData[i+21] = resda[2+i];
|
||||
}
|
||||
|
||||
parameterData = new Array();
|
||||
for (var iiii:int = 0; iiii < 28; iiii++)
|
||||
{
|
||||
parameterData[iiii] = shiftedParameterData[(iiii+shift*7)%28];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftedParameterData = new Array();
|
||||
for (var iii:int = 0; iii < 11; iii++)
|
||||
{
|
||||
if (iii < 5)
|
||||
{
|
||||
shiftedParameterData[iii] = resab[2+iii];
|
||||
shiftedParameterData[iii+10] = resbc[2+iii];
|
||||
shiftedParameterData[iii+20] = rescd[2+iii];
|
||||
shiftedParameterData[iii+30] = resda[2+iii];
|
||||
}
|
||||
if (iii > 5)
|
||||
{
|
||||
shiftedParameterData[iii-1] = resab[2+iii];
|
||||
shiftedParameterData[iii+10-1] = resbc[2+iii];
|
||||
shiftedParameterData[iii+20-1] = rescd[2+iii];
|
||||
shiftedParameterData[iii+30-1] = resda[2+iii];
|
||||
}
|
||||
}
|
||||
|
||||
parameterData = new Array();
|
||||
for (var ij:int = 0; ij < 40; ij++)
|
||||
{
|
||||
parameterData[ij] = shiftedParameterData[int((ij+shift*10)%40)];
|
||||
}
|
||||
}
|
||||
|
||||
// corrects the error using RS algorithm
|
||||
correctParameterData(parameterData, compact);
|
||||
|
||||
// gets the parameters from the bit array
|
||||
getParameters(parameterData);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Gets the Aztec code corners from the bull's eye corners and the parameters </p>
|
||||
*
|
||||
* @param bullEyeCornerPoints the array of bull's eye corners
|
||||
* @return the array of aztec code corners
|
||||
* @throws NotFoundException if the corner points do not fit in the image
|
||||
*/
|
||||
private function getMatrixCornerPoints(bullEyeCornerPoints:Array):Array
|
||||
{
|
||||
|
||||
var ratio:Number = (2 * nbLayers + (nbLayers > 4 ? 1 : 0) + int((nbLayers - 4) / 8)) / (2.0 * nbCenterLayers);//BAS : added int cast in order to do the same calculation as Java
|
||||
|
||||
var dx:int = bullEyeCornerPoints[0].x-bullEyeCornerPoints[2].x;
|
||||
dx+=dx>0?1:-1;
|
||||
var dy:int = bullEyeCornerPoints[0].y-bullEyeCornerPoints[2].y;
|
||||
dy+=dy>0?1:-1;
|
||||
|
||||
var targetcx:int = round(bullEyeCornerPoints[2].x-ratio*dx);
|
||||
var targetcy:int = round(bullEyeCornerPoints[2].y-ratio*dy);
|
||||
|
||||
var targetax:int = round(bullEyeCornerPoints[0].x+ratio*dx);
|
||||
var targetay:int = round(bullEyeCornerPoints[0].y+ratio*dy);
|
||||
|
||||
dx = bullEyeCornerPoints[1].x-bullEyeCornerPoints[3].x;
|
||||
dx+=dx>0?1:-1;
|
||||
dy = bullEyeCornerPoints[1].y-bullEyeCornerPoints[3].y;
|
||||
dy+=dy>0?1:-1;
|
||||
|
||||
var targetdx:int = round(bullEyeCornerPoints[3].x-ratio*dx);
|
||||
var targetdy:int = round(bullEyeCornerPoints[3].y-ratio*dy);
|
||||
var targetbx:int = round(bullEyeCornerPoints[1].x+ratio*dx);
|
||||
var targetby:int = round(bullEyeCornerPoints[1].y+ratio*dy);
|
||||
|
||||
if (!isValid(targetax, targetay) || !isValid(targetbx, targetby) || !isValid(targetcx, targetcy) || !isValid(targetdx, targetdy))
|
||||
{
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
return new Array(new ResultPoint(targetax, targetay), new ResultPoint(targetbx, targetby), new ResultPoint(targetcx, targetcy), new ResultPoint(targetdx, targetdy));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <p> Corrects the parameter bits using Reed-Solomon algorithm </p>
|
||||
*
|
||||
* @param parameterData paremeter bits
|
||||
* @param compact true if this is a compact Aztec code
|
||||
* @throws NotFoundException if the array contains too many errors
|
||||
*/
|
||||
private static function correctParameterData(parameterData:Array, compact:Boolean):void
|
||||
{
|
||||
|
||||
var numCodewords:int;
|
||||
var numDataCodewords:int;
|
||||
|
||||
if (compact) {
|
||||
numCodewords = 7;
|
||||
numDataCodewords = 2;
|
||||
} else {
|
||||
numCodewords = 10;
|
||||
numDataCodewords = 4;
|
||||
}
|
||||
|
||||
var numECCodewords:int = numCodewords - numDataCodewords;
|
||||
var parameterWords:Array = new Array(numCodewords);//new int[numCodewords];
|
||||
for(var m:int=0;m<parameterWords.length;m++) { parameterWords[m] = 0; }
|
||||
|
||||
var codewordSize:int = 4;
|
||||
for (var i:int = 0; i < numCodewords; i++) {
|
||||
var flag:int = 1;
|
||||
for (var j:int = 1; j <= codewordSize; j++) {
|
||||
if (parameterData[codewordSize*i + codewordSize - j]) {
|
||||
parameterWords[i] += flag;
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var rsDecoder:ReedSolomonDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM);
|
||||
rsDecoder.decode(parameterWords, numECCodewords);
|
||||
}
|
||||
catch (rse:ReedSolomonException )
|
||||
{
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
for (var i2:int = 0; i2 < numDataCodewords; i2 ++) {
|
||||
flag = 1;
|
||||
for (var jk:int = 1; jk <= codewordSize; jk++) {
|
||||
parameterData[i2*codewordSize+codewordSize-jk] = (parameterWords[i2] & flag) == flag;
|
||||
flag <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <p> Finds the corners of a bull-eye centered on the passed point </p>
|
||||
*
|
||||
* @param pCenter Center point
|
||||
* @return The corners of the bull-eye
|
||||
* @throws NotFoundException If no valid bull-eye can be found
|
||||
*/
|
||||
private function getBullEyeCornerPoints(pCenter:Point ):Array
|
||||
{
|
||||
|
||||
var pina:Point = pCenter;
|
||||
var pinb:Point = pCenter;
|
||||
var pinc:Point = pCenter;
|
||||
var pind:Point = pCenter;
|
||||
|
||||
var color:Boolean = true;
|
||||
|
||||
for (nbCenterLayers = 1; nbCenterLayers < 9; nbCenterLayers++) {
|
||||
var pouta:Point = getFirstDifferent(pina, color, 1, -1);
|
||||
var poutb:Point = getFirstDifferent(pinb, color, 1, 1);
|
||||
var poutc:Point = getFirstDifferent(pinc, color, -1, 1);
|
||||
var poutd:Point = getFirstDifferent(pind, color, -1, -1);
|
||||
|
||||
//d a
|
||||
//
|
||||
//c b
|
||||
|
||||
if (nbCenterLayers>2) {
|
||||
var q:Number = distance(poutd, pouta)*nbCenterLayers/(distance(pind, pina)*(nbCenterLayers+2));
|
||||
if ( q < 0.75 || q > 1.25 || !isWhiteOrBlackRectangle(pouta, poutb, poutc, poutd)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pina = pouta;
|
||||
pinb = poutb;
|
||||
pinc = poutc;
|
||||
pind = poutd;
|
||||
|
||||
color = !color;
|
||||
}
|
||||
|
||||
if (nbCenterLayers != 5 && nbCenterLayers != 7)
|
||||
{
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
compact = nbCenterLayers==5;
|
||||
|
||||
var ratio:Number = 0.75*2/(2*nbCenterLayers-3);
|
||||
|
||||
var dx:int = pina.x-pinc.x;
|
||||
var dy:int = pina.y-pinc.y;
|
||||
var targetcx:int = round(pinc.x-ratio*dx);
|
||||
var targetcy:int = round(pinc.y-ratio*dy);
|
||||
var targetax:int = round(pina.x+ratio*dx);
|
||||
var targetay:int = round(pina.y+ratio*dy);
|
||||
|
||||
dx = pinb.x-pind.x;
|
||||
dy = pinb.y-pind.y;
|
||||
|
||||
var targetdx:int = round(pind.x-ratio*dx);
|
||||
var targetdy:int = round(pind.y-ratio*dy);
|
||||
var targetbx:int = round(pinb.x+ratio*dx);
|
||||
var targetby:int = round(pinb.y+ratio*dy);
|
||||
|
||||
if (!isValid(targetax, targetay) || !isValid(targetbx, targetby)
|
||||
|| !isValid(targetcx, targetcy) || !isValid(targetdx, targetdy)) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
var pa:Point = new Point(targetax,targetay);
|
||||
var pb:Point = new Point(targetbx,targetby);
|
||||
var pc:Point = new Point(targetcx,targetcy);
|
||||
var pd:Point = new Point(targetdx,targetdy);
|
||||
|
||||
return new Array(pa, pb, pc, pd);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Finds a candidate center point of an Aztec code from an image
|
||||
*
|
||||
* @return the center point
|
||||
*/
|
||||
private function getMatrixCenter():Point {
|
||||
|
||||
var pointA:ResultPoint ;
|
||||
var pointB:ResultPoint ;
|
||||
var pointC:ResultPoint ;
|
||||
var pointD:ResultPoint ;
|
||||
|
||||
//Get a white rectangle that can be the border of the matrix in center bull's eye or
|
||||
try {
|
||||
|
||||
var cornerPoints:Array = new WhiteRectangleDetector(image).detect();
|
||||
pointA = cornerPoints[0];
|
||||
pointB = cornerPoints[1];
|
||||
pointC = cornerPoints[2];
|
||||
pointD = cornerPoints[3];
|
||||
|
||||
} catch (e:NotFoundException) {
|
||||
|
||||
// This exception can be in case the initial rectangle is white
|
||||
// In that case, surely in the bull's eye, we try to expand the rectangle.
|
||||
var cx:int = int(image.getWidth()/2);
|
||||
var cy:int = int(image.getHeight()/2);
|
||||
pointA = getFirstDifferent(new Point(cx+int(15/2), cy-int(15/2)), false, 1, -1).toResultPoint();
|
||||
pointB = getFirstDifferent(new Point(cx+int(15/2), cy+int(15/2)), false, 1, 1).toResultPoint();
|
||||
pointC = getFirstDifferent(new Point(cx-int(15/2), cy+int(15/2)), false, -1, 1).toResultPoint();
|
||||
pointD = getFirstDifferent(new Point(cx-int(15/2), cy-int(15/2)), false, -1, -1).toResultPoint();
|
||||
|
||||
}
|
||||
|
||||
//Compute the center of the rectangle
|
||||
var cx2:int = round((pointA.getX() + pointD.getX() + pointB.getX() + pointC.getX())/4);
|
||||
var cy2:int = round((pointA.getY() + pointD.getY() + pointB.getY() + pointC.getY())/4);
|
||||
|
||||
// Redetermine the white rectangle starting from previously computed center.
|
||||
// This will ensure that we end up with a white rectangle in center bull's eye
|
||||
// in order to compute a more accurate center.
|
||||
try {
|
||||
var cornerPoints2:Array = new WhiteRectangleDetector(image, 15, cx2, cy2).detect();
|
||||
pointA = cornerPoints2[0];
|
||||
pointB = cornerPoints2[1];
|
||||
pointC = cornerPoints2[2];
|
||||
pointD = cornerPoints2[3];
|
||||
} catch (e:NotFoundException) {
|
||||
|
||||
// This exception can be in case the initial rectangle is white
|
||||
// In that case we try to expand the rectangle.
|
||||
pointA = getFirstDifferent(new Point(cx2+int(15/2), cy2-int(15/2)), false, 1, -1).toResultPoint();
|
||||
pointB = getFirstDifferent(new Point(cx2+int(15/2), cy2+int(15/2)), false, 1, 1).toResultPoint();
|
||||
pointC = getFirstDifferent(new Point(cx2-int(15/2), cy2+int(15/2)), false, -1, 1).toResultPoint();
|
||||
pointD = getFirstDifferent(new Point(cx2-int(15/2), cy2-int(15/2)), false, -1, -1).toResultPoint();
|
||||
|
||||
}
|
||||
|
||||
// Recompute the center of the rectangle
|
||||
cx = round((pointA.getX() + pointD.getX() + pointB.getX() + pointC.getX())/4);
|
||||
cy = round((pointA.getY() + pointD.getY() + pointB.getY() + pointC.getY())/4);
|
||||
|
||||
return new Point(cx, cy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Samples an Aztec matrix from an image
|
||||
*/
|
||||
private function sampleGrid(image:BitMatrix ,
|
||||
topLeft:ResultPoint ,
|
||||
bottomLeft:ResultPoint ,
|
||||
bottomRight:ResultPoint ,
|
||||
topRight:ResultPoint ):BitMatrix {
|
||||
|
||||
var dimension:int;
|
||||
if (compact) {
|
||||
dimension = 4*nbLayers+11;
|
||||
} else {
|
||||
if (nbLayers <= 4) {
|
||||
dimension = 4*nbLayers + 15;
|
||||
} else {
|
||||
dimension = 4*nbLayers + 2*(int((nbLayers-4)/8) + 1) + 15 ;
|
||||
}
|
||||
}
|
||||
|
||||
var sampler:GridSampler = GridSampler.getGridSamplerInstance();
|
||||
|
||||
return sampler.sampleGrid2(image,
|
||||
dimension,
|
||||
dimension,
|
||||
0.5,
|
||||
0.5,
|
||||
dimension - 0.5,
|
||||
0.5,
|
||||
dimension - 0.5,
|
||||
dimension - 0.5,
|
||||
0.5,
|
||||
dimension - 0.5,
|
||||
topLeft.getX(),
|
||||
topLeft.getY(),
|
||||
topRight.getX(),
|
||||
topRight.getY(),
|
||||
bottomRight.getX(),
|
||||
bottomRight.getY(),
|
||||
bottomLeft.getX(),
|
||||
bottomLeft.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets number of layers and number of datablocks from parameter bits
|
||||
*/
|
||||
private function getParameters(parameterData:Array):void {
|
||||
|
||||
var nbBitsForNbLayers:int;
|
||||
var nbBitsForNbDatablocks:int;
|
||||
|
||||
if (compact) {
|
||||
nbBitsForNbLayers = 2;
|
||||
nbBitsForNbDatablocks = 6;
|
||||
} else {
|
||||
nbBitsForNbLayers = 5;
|
||||
nbBitsForNbDatablocks = 11;
|
||||
}
|
||||
|
||||
for (var i:int = 0; i < nbBitsForNbLayers; i++) {
|
||||
nbLayers <<= 1;
|
||||
if (parameterData[i]) {
|
||||
nbLayers += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i3:int = nbBitsForNbLayers; i3 < nbBitsForNbLayers + nbBitsForNbDatablocks; i3++) {
|
||||
nbDataBlocks <<= 1;
|
||||
if (parameterData[i3]) {
|
||||
nbDataBlocks += 1;
|
||||
}
|
||||
}
|
||||
|
||||
nbLayers ++;
|
||||
nbDataBlocks ++;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Samples a line
|
||||
*
|
||||
* @param p1 first point
|
||||
* @param p2 second point
|
||||
* @param size number of bits
|
||||
* @return the array of bits
|
||||
*/
|
||||
private function sampleLine(p1:Point, p2:Point,size:int):Array {
|
||||
|
||||
var res:Array = new Array(size);
|
||||
var d:Number = distance(p1,p2);
|
||||
var moduleSize:Number = d/(size-1);
|
||||
var dx:Number = moduleSize*(p2.x - p1.x)/d;
|
||||
var dy:Number = moduleSize*(p2.y - p1.y)/d;
|
||||
|
||||
var px:Number = p1.x;
|
||||
var py:Number = p1.y;
|
||||
|
||||
for (var i:int = 0; i < size; i++) {
|
||||
res[i] = image._get(round(px), round(py));
|
||||
px+=dx;
|
||||
py+=dy;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the border of the rectangle passed in parameter is compound of white points only
|
||||
* or black points only
|
||||
*/
|
||||
private function isWhiteOrBlackRectangle(p1:Point, p2:Point, p3:Point, p4:Point):Boolean {
|
||||
|
||||
var corr:int = 3;
|
||||
|
||||
p1 = new Point(p1.x-corr, p1.y+corr);
|
||||
p2 = new Point(p2.x-corr, p2.y-corr);
|
||||
p3 = new Point(p3.x+corr, p3.y-corr);
|
||||
p4 = new Point(p4.x+corr, p4.y+corr);
|
||||
|
||||
var cInit:int = getColor(p4, p1);
|
||||
|
||||
if (cInit == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var c:int = getColor(p1, p2);
|
||||
|
||||
if (c!=cInit || c == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
c = getColor(p2, p3);
|
||||
|
||||
if (c!=cInit || c == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
c = getColor(p3, p4);
|
||||
|
||||
return c == cInit && c != 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color of a segment
|
||||
*
|
||||
* @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else
|
||||
*/
|
||||
private function getColor( p1:Point, p2:Point):int {
|
||||
var d:Number = distance(p1,p2);
|
||||
var dx:Number = (p2.x - p1.x)/d;
|
||||
var dy:Number = (p2.y - p1.y)/d;
|
||||
var error:int = 0;
|
||||
|
||||
var px:Number = p1.x;
|
||||
var py:Number = p1.y;
|
||||
|
||||
var colorModel:Boolean = image._get(p1.x, p1.y);
|
||||
|
||||
for (var i:int = 0; i < d; i++) {
|
||||
px+=dx;
|
||||
py+=dy;
|
||||
if (image._get(round(px), round(py)) != colorModel) {
|
||||
error++;
|
||||
}
|
||||
}
|
||||
|
||||
var errRatio:Number = Number(error/d);
|
||||
|
||||
if (errRatio > 0.1 && errRatio < 0.9) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (errRatio <= 0.1) {
|
||||
return colorModel?1:-1;
|
||||
} else {
|
||||
return colorModel?-1:1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the coordinate of the first point with a different color in the given direction
|
||||
*/
|
||||
private function getFirstDifferent(init:Point, color:Boolean, dx:int, dy:int):Point {
|
||||
var x:int = init.x+dx;
|
||||
var y:int = init.y+dy;
|
||||
|
||||
while(isValid(x,y) && image._get(x,y) == color) {
|
||||
x+=dx;
|
||||
y+=dy;
|
||||
}
|
||||
|
||||
x-=dx;
|
||||
y-=dy;
|
||||
|
||||
while(isValid(x,y) && image._get(x, y) == color) {
|
||||
x+=dx;
|
||||
}
|
||||
x-=dx;
|
||||
|
||||
while(isValid(x,y) && image._get(x, y) == color) {
|
||||
y+=dy;
|
||||
}
|
||||
y-=dy;
|
||||
|
||||
return new Point(x,y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function isValid(x:int, y:int):Boolean {
|
||||
return x >= 0 && x < image.getWidth() && y > 0 && y < image.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends up being a bit faster than Math.round(). This merely rounds its
|
||||
* argument to the nearest int, where x.5 rounds up.
|
||||
*/
|
||||
private static function round(d:Number):int {
|
||||
return (int) (d + 0.5);
|
||||
}
|
||||
|
||||
// L2 distance
|
||||
private static function distance(a:Point, b:Point ):Number
|
||||
{
|
||||
return Math.sqrt((a.x - b.x)
|
||||
* (a.x - b.x) + (a.y - b.y)
|
||||
* (a.y - b.y));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* <p>See
|
||||
* <a href="http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/about/s2.html">
|
||||
* DoCoMo's documentation</a> about the result types represented by subclasses of this class.</p>
|
||||
*
|
||||
* <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
|
||||
* on exception-based mechanisms during parsing.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class AbstractDoCoMoResultParser extends ResultParser
|
||||
{
|
||||
|
||||
public static function matchDoCoMoPrefixedField(prefix:String , rawText:String, trim:Boolean):Array {
|
||||
return matchPrefixedField(prefix, rawText, ';', trim);
|
||||
}
|
||||
|
||||
public static function matchSingleDoCoMoPrefixedField(prefix:String, rawText:String, trim:Boolean):String {
|
||||
return matchSinglePrefixedField(prefix, rawText, ';', trim);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
import com.google.zxing.Result;
|
||||
|
||||
/**
|
||||
* Implements KDDI AU's address book format. See
|
||||
* <a href="http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html">
|
||||
* http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html</a>.
|
||||
* (Thanks to Yuzo for translating!)
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class AddressBookDocomoResultParser extends ResultParser {
|
||||
|
||||
public static function parse(result:Result ):AddressBookParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
// MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF
|
||||
if (rawText == null || rawText.indexOf("MEMORY") < 0 || rawText.indexOf("\r\n") < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NAME1 and NAME2 have specific uses, namely written name and pronunciation, respectively.
|
||||
// Therefore we treat them specially instead of as an array of names.
|
||||
var name:String = matchSinglePrefixedField("NAME1:", rawText, '\r', true);
|
||||
var pronunciation:String = matchSinglePrefixedField("NAME2:", rawText, '\r', true);
|
||||
|
||||
var phoneNumbers:Array = matchMultipleValuePrefix("TEL", 3, rawText, true);
|
||||
var emails:Array = matchMultipleValuePrefix("MAIL", 3, rawText, true);
|
||||
var note:String = matchSinglePrefixedField("MEMORY:", rawText, '\r', false);
|
||||
var address:String = matchSinglePrefixedField("ADD:", rawText, '\r', true);
|
||||
return new AddressBookParsedResult(maybeWrap(name), pronunciation, phoneNumbers, emails, note,
|
||||
address, null, null, null, null);
|
||||
}
|
||||
|
||||
public static function matchMultipleValuePrefix(prefix:String , max:int , rawText:String , trim:Boolean ):Array
|
||||
{
|
||||
var values:ArrayList = null;
|
||||
for (var i:int = 1; i <= max; i++)
|
||||
{
|
||||
var value:String = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', trim);
|
||||
if (value == null) {
|
||||
break;
|
||||
}
|
||||
if (values == null) {
|
||||
values = new ArrayList(max); // lazy init
|
||||
}
|
||||
values.addElement(value);
|
||||
}
|
||||
if (values == null) {
|
||||
return null;
|
||||
}
|
||||
return toStringArray(values);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class AddressBookParsedResult extends ParsedResult
|
||||
{
|
||||
|
||||
private var names:Array;
|
||||
private var pronunciation:String;
|
||||
private var phoneNumbers:Array;
|
||||
private var emails:Array;
|
||||
private var note:String;
|
||||
private var address:String;
|
||||
private var org:String;
|
||||
private var birthday:String;
|
||||
private var title:String;
|
||||
private var url:String;
|
||||
|
||||
public function AddressBookParsedResult(names:Array,
|
||||
pronunciation:String,
|
||||
phoneNumbers:Array,
|
||||
emails:Array,
|
||||
note:String,
|
||||
address:String,
|
||||
org:String,
|
||||
birthday:String,
|
||||
title:String,
|
||||
url:String) {
|
||||
super(ParsedResultType.ADDRESSBOOK);
|
||||
this.names = names;
|
||||
this.pronunciation = pronunciation;
|
||||
this.phoneNumbers = phoneNumbers;
|
||||
this.emails = emails;
|
||||
this.note = note;
|
||||
this.address = address;
|
||||
this.org = org;
|
||||
this.birthday = birthday;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public function getNames():Array {
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* In Japanese, the name is written in kanji, which can have multiple readings. Therefore a hint
|
||||
* is often provided, called furigana, which spells the name phonetically.
|
||||
*
|
||||
* @return The pronunciation of the getNames() field, often in hiragana or katakana.
|
||||
*/
|
||||
public function getPronunciation():String {
|
||||
return pronunciation;
|
||||
}
|
||||
|
||||
public function getPhoneNumbers():Array {
|
||||
return phoneNumbers;
|
||||
}
|
||||
|
||||
public function getEmails():Array {
|
||||
return emails;
|
||||
}
|
||||
|
||||
public function getNote():String {
|
||||
return note;
|
||||
}
|
||||
|
||||
public function getAddress():String {
|
||||
return address;
|
||||
}
|
||||
|
||||
public function getTitle():String {
|
||||
return title;
|
||||
}
|
||||
|
||||
public function getOrg():String {
|
||||
return org;
|
||||
}
|
||||
|
||||
public function getURL():String {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return birthday formatted as yyyyMMdd (e.g. 19780917)
|
||||
*/
|
||||
public function getBirthday():String {
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
var result:StringBuilder = new StringBuilder();
|
||||
maybeAppend(names, result);
|
||||
maybeAppend(pronunciation, result);
|
||||
maybeAppend(title, result);
|
||||
maybeAppend(org, result);
|
||||
maybeAppend(address, result);
|
||||
maybeAppend(phoneNumbers, result);
|
||||
maybeAppend(emails, result);
|
||||
maybeAppend(url, result);
|
||||
maybeAppend(birthday, result);
|
||||
maybeAppend(note, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
import com.google.zxing.Result;
|
||||
|
||||
/**
|
||||
* Implements the "BIZCARD" address book entry format, though this has been
|
||||
* largely reverse-engineered from examples observed in the wild -- still
|
||||
* looking for a definitive reference.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class BizcardResultParser extends AbstractDoCoMoResultParser
|
||||
{
|
||||
|
||||
// Yes, we extend AbstractDoCoMoResultParser since the format is very much
|
||||
// like the DoCoMo MECARD format, but this is not technically one of
|
||||
// DoCoMo's proposed formats
|
||||
|
||||
public static function parse(result:Result):AddressBookParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null || !(rawText.substr(0,8) == "BIZCARD:")) {
|
||||
return null;
|
||||
}
|
||||
var firstName:String = matchSingleDoCoMoPrefixedField("N:", rawText, true);
|
||||
var lastName:String = matchSingleDoCoMoPrefixedField("X:", rawText, true);
|
||||
var fullName:String = buildName(firstName, lastName);
|
||||
var title:String = matchSingleDoCoMoPrefixedField("T:", rawText, true);
|
||||
var org:String = matchSingleDoCoMoPrefixedField("C:", rawText, true);
|
||||
var address:String = matchSingleDoCoMoPrefixedField("A:", rawText, true);
|
||||
var phoneNumber1:String = matchSingleDoCoMoPrefixedField("B:", rawText, true);
|
||||
var phoneNumber2:String = matchSingleDoCoMoPrefixedField("M:", rawText, true);
|
||||
var phoneNumber3:String = matchSingleDoCoMoPrefixedField("F:", rawText, true);
|
||||
var email:String = matchSingleDoCoMoPrefixedField("E:", rawText, true);
|
||||
|
||||
return new AddressBookParsedResult(maybeWrap(fullName),
|
||||
null,
|
||||
buildPhoneNumbers(phoneNumber1, phoneNumber2, phoneNumber3),
|
||||
maybeWrap(email),
|
||||
null,
|
||||
address,
|
||||
org,
|
||||
null,
|
||||
title,
|
||||
null);
|
||||
}
|
||||
|
||||
private static function buildPhoneNumbers(number1:String, number2:String, number3:String ):Array {
|
||||
var numbers:ArrayList = new ArrayList(3);
|
||||
if (number1 != null) {
|
||||
numbers.addElement(number1);
|
||||
}
|
||||
if (number2 != null) {
|
||||
numbers.addElement(number2);
|
||||
}
|
||||
if (number3 != null) {
|
||||
numbers.addElement(number3);
|
||||
}
|
||||
var size:int = numbers.size();
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
var result:Array = new Array(size);
|
||||
for (var i:int = 0; i < size; i++) {
|
||||
result[i] = String(numbers.elementAt(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static function buildName(firstName:String, lastName:String):String
|
||||
{
|
||||
if (firstName == null) {
|
||||
return lastName;
|
||||
} else {
|
||||
return lastName == null ? firstName : firstName + ' ' + lastName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser
|
||||
{
|
||||
|
||||
public function BookmarkDoCoMoResultParser()
|
||||
{
|
||||
}
|
||||
|
||||
public static function parse(result:Result):URIParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null || (rawText.substr(0,6) != "MEBKM:")) {
|
||||
return null;
|
||||
}
|
||||
var title:String = matchSingleDoCoMoPrefixedField("TITLE:", rawText, true);
|
||||
var rawUri:Array = matchDoCoMoPrefixedField("URL:", rawText, true);
|
||||
if (rawUri == null) {
|
||||
return null;
|
||||
}
|
||||
var uri:String = rawUri[0];
|
||||
if (!URIResultParser.isBasicallyValidURI(uri)) {
|
||||
return null;
|
||||
}
|
||||
return new URIParsedResult(uri, title);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class CalendarParsedResult extends ParsedResult
|
||||
{
|
||||
|
||||
private var summary:String;
|
||||
private var start:String;
|
||||
private var end:String;
|
||||
private var location:String;
|
||||
private var attendee:String;
|
||||
private var title:String;
|
||||
|
||||
public function CalendarParsedResult(summary:String,
|
||||
start:String,
|
||||
end:String,
|
||||
location:String,
|
||||
attendee:String,
|
||||
title:String)
|
||||
{
|
||||
super(ParsedResultType.CALENDAR);
|
||||
// Start is required, end is not
|
||||
if (start == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
validateDate(start);
|
||||
validateDate(end);
|
||||
this.summary = summary;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.location = location;
|
||||
this.attendee = attendee;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public function getSummary():String
|
||||
{
|
||||
return summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>We would return the start and end date as a {@link java.util.Date} except that this code
|
||||
* needs to work under JavaME / MIDP and there is no date parsing library available there, such
|
||||
* as <code>java.text.SimpleDateFormat</code>.</p> See validateDate() for the return format.
|
||||
*
|
||||
* @return start time formatted as a RFC 2445 DATE or DATE-TIME.</p>
|
||||
*/
|
||||
public function getStart():String
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getStart(). May return null if the event has no duration.
|
||||
*/
|
||||
public function getEnd():String
|
||||
{
|
||||
return end;
|
||||
}
|
||||
|
||||
public function getLocation():String
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
public function getAttendee():String {
|
||||
return attendee;
|
||||
}
|
||||
|
||||
public function getTitle():String {
|
||||
return title;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
var result:StringBuilder = new StringBuilder();
|
||||
maybeAppend(summary, result);
|
||||
maybeAppend(start, result);
|
||||
maybeAppend(end, result);
|
||||
maybeAppend(location, result);
|
||||
maybeAppend(attendee, result);
|
||||
maybeAppend(title, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021) or DATE-TIME
|
||||
* (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).
|
||||
*
|
||||
* @param date The string to validate
|
||||
*/
|
||||
private static function validateDate( date:String):void {
|
||||
if (date != null) {
|
||||
var length:int = date.length;
|
||||
if (length != 8 && length != 15 && length != 16) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
for (var i:int = 0; i < 8; i++) {
|
||||
if (!Utils.isDigit(date.charAt(i))) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
if (length > 8) {
|
||||
if (date.charAt(8) != 'T') {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
for (var ii:int = 9; ii < 15; i++) {
|
||||
if (!Utils.isDigit(date.charAt(ii))) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
if (length == 16 && date.charAt(15) != 'Z') {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class EmailAddressParsedResult extends ParsedResult
|
||||
{
|
||||
|
||||
private var emailAddress:String;
|
||||
private var subject:String;
|
||||
private var body:String;
|
||||
private var mailtoURI:String;
|
||||
|
||||
public function EmailAddressParsedResult(emailAddress:String, subject:String, body:String , mailtoURI:String )
|
||||
{
|
||||
super(ParsedResultType.EMAIL_ADDRESS);
|
||||
this.emailAddress = emailAddress;
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
this.mailtoURI = mailtoURI;
|
||||
}
|
||||
|
||||
public function getEmailAddress():String
|
||||
{
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public function getSubject():String
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
|
||||
public function getBody():String
|
||||
{
|
||||
return body;
|
||||
}
|
||||
|
||||
public function getMailtoURI():String
|
||||
{
|
||||
return mailtoURI;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String
|
||||
{
|
||||
var result:StringBuilder = new StringBuilder();
|
||||
maybeAppend(emailAddress, result);
|
||||
maybeAppend(subject, result);
|
||||
maybeAppend(body, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,62 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
|
||||
/**
|
||||
* Represents a result that encodes an e-mail address, either as a plain address
|
||||
* like "joe@example.org" or a mailto: URL like "mailto:joe@example.org".
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class EmailAddressResultParser extends ResultParser {
|
||||
|
||||
public static function parse(result:Result):EmailAddressParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null) {
|
||||
return null;
|
||||
}
|
||||
var emailAddress:String;
|
||||
if ((rawText.substr(0,7) == "mailto:") || (rawText.substr(0,7) == "MAILTO:")) {
|
||||
// If it starts with mailto:, assume it is definitely trying to be an email address
|
||||
emailAddress = rawText.substring(7);
|
||||
var queryStart:int = emailAddress.indexOf('?');
|
||||
if (queryStart >= 0) {
|
||||
emailAddress = emailAddress.substring(0, queryStart);
|
||||
}
|
||||
var nameValues:HashTable = parseNameValuePairs(rawText);
|
||||
var subject:String = null;
|
||||
var body:String = null;
|
||||
if (nameValues != null) {
|
||||
if (emailAddress.length == 0) {
|
||||
emailAddress = String( nameValues._get("to"));
|
||||
}
|
||||
subject = String(nameValues._get("subject"));
|
||||
body = String(nameValues._get("body"));
|
||||
}
|
||||
return new EmailAddressParsedResult(emailAddress, subject, body, rawText);
|
||||
} else {
|
||||
if (!EmailDoCoMoResultParser.isBasicallyValidEmailAddress(rawText)) {
|
||||
return null;
|
||||
}
|
||||
emailAddress = rawText;
|
||||
return new EmailAddressParsedResult(emailAddress, null, null, "mailto:" + emailAddress);
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,88 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* Implements the "MATMSG" email message entry format.
|
||||
*
|
||||
* Supported keys: TO, SUB, BODY
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
|
||||
|
||||
private static var ATEXT_SYMBOLS:Array = ['@','.','!','#','$','%','&','\'','*','+','-','/','=','?','^','_','`','{','|','}','~'];
|
||||
|
||||
public static function parse(result:Result):EmailAddressParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null || !Utils.startsWith(rawText,"MATMSG:")) {
|
||||
return null;
|
||||
}
|
||||
var rawTo:Array = matchDoCoMoPrefixedField("TO:", rawText, true);
|
||||
if (rawTo == null) {
|
||||
return null;
|
||||
}
|
||||
var _to:String = rawTo[0];
|
||||
if (!isBasicallyValidEmailAddress(_to)) {
|
||||
return null;
|
||||
}
|
||||
var subject:String = matchSingleDoCoMoPrefixedField("SUB:", rawText, false);
|
||||
var body:String = matchSingleDoCoMoPrefixedField("BODY:", rawText, false);
|
||||
return new EmailAddressParsedResult(_to, subject, body, "mailto:" + _to);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implements only the most basic checking for an email address's validity -- that it contains
|
||||
* an '@' contains no characters disallowed by RFC 2822. This is an overly lenient definition of
|
||||
* validity. We want to generally be lenient here since this class is only intended to encapsulate what's
|
||||
* in a barcode, not "judge" it.
|
||||
*/
|
||||
public static function isBasicallyValidEmailAddress(email:String):Boolean {
|
||||
if (email == null) {
|
||||
return false;
|
||||
}
|
||||
var atFound:Boolean = false;
|
||||
for (var i:int = 0; i < email.length; i++) {
|
||||
var c:String = email.charAt(i);
|
||||
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') &&
|
||||
!isAtextSymbol(c)) {
|
||||
return false;
|
||||
}
|
||||
if (c == '@') {
|
||||
if (atFound) {
|
||||
return false;
|
||||
}
|
||||
atFound = true;
|
||||
}
|
||||
}
|
||||
return atFound;
|
||||
}
|
||||
|
||||
private static function isAtextSymbol(c:String):Boolean {
|
||||
for (var i:int = 0; i < ATEXT_SYMBOLS.length; i++) {
|
||||
if (c == ATEXT_SYMBOLS[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class GeoParsedResult extends ParsedResult {
|
||||
|
||||
private var geoURI:String;
|
||||
private var latitude:Number;
|
||||
private var longitude:Number;
|
||||
private var altitude:Number;
|
||||
|
||||
public function GeoParsedResult(geoURI:String, latitude:Number, longitude:Number, altitude:Number ) {
|
||||
super(ParsedResultType.GEO);
|
||||
this.geoURI = geoURI;
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.altitude = altitude;
|
||||
}
|
||||
|
||||
public function getGeoURI():String {
|
||||
return geoURI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return latitude in degrees
|
||||
*/
|
||||
public function getLatitude():Number {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return longitude in degrees
|
||||
*/
|
||||
public function getLongitude():Number {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return altitude in meters. If not specified, in the geo URI, returns 0.0
|
||||
*/
|
||||
public function getAltitude():Number {
|
||||
return altitude;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
var result:StringBuilder = new StringBuilder(50);
|
||||
result.Append(latitude);
|
||||
result.Append(", ");
|
||||
result.Append(longitude);
|
||||
if (altitude > 0.0) {
|
||||
result.Append(", ");
|
||||
result.Append(altitude);
|
||||
result.Append('m');
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a URI link to Google Maps which display the point on the Earth described
|
||||
* by this instance, and sets the zoom level in a way that roughly reflects the
|
||||
* altitude, if specified
|
||||
*/
|
||||
/*
|
||||
public String getGoogleMapsURI() {
|
||||
StringBuffer result = new StringBuffer(50);
|
||||
result.append("http://maps.google.com/?ll=");
|
||||
result.append(latitude);
|
||||
result.append(',');
|
||||
result.append(longitude);
|
||||
if (altitude > 0.0f) {
|
||||
// Map altitude to zoom level, cleverly. Roughly, zoom level 19 is like a
|
||||
// view from 1000ft, 18 is like 2000ft, 17 like 4000ft, and so on.
|
||||
double altitudeInFeet = altitude * 3.28;
|
||||
int altitudeInKFeet = (int) (altitudeInFeet / 1000.0);
|
||||
// No Math.log() available here, so compute log base 2 the old fashioned way
|
||||
// Here logBaseTwo will take on a value between 0 and 18 actually
|
||||
int logBaseTwo = 0;
|
||||
while (altitudeInKFeet > 1 && logBaseTwo < 18) {
|
||||
altitudeInKFeet >>= 1;
|
||||
logBaseTwo++;
|
||||
}
|
||||
int zoom = 19 - logBaseTwo;
|
||||
result.append("&z=");
|
||||
result.append(zoom);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
*/
|
||||
|
||||
}}
|
|
@ -1,65 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
|
||||
/**
|
||||
* Parses a "geo:" URI result, which specifices a location on the surface of
|
||||
* the Earth as well as an optional altitude above the surface. See
|
||||
* <a href="http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00">
|
||||
* http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00</a>.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class GeoResultParser extends ResultParser {
|
||||
|
||||
public function GeoResultParser() {
|
||||
}
|
||||
|
||||
public static function parse(result:Result ):GeoParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null || (!(rawText.substr(0,4) == "geo:") && !(rawText.substr(0,4) == "GEO:"))) {
|
||||
return null;
|
||||
}
|
||||
// Drop geo, query portion
|
||||
var queryStart:int = rawText.indexOf('?', 4);
|
||||
var geoURIWithoutQuery:String = queryStart < 0 ? rawText.substring(4) : rawText.substring(4, queryStart);
|
||||
var latitudeEnd:int = geoURIWithoutQuery.indexOf(',');
|
||||
if (latitudeEnd < 0) {
|
||||
return null;
|
||||
}
|
||||
var longitudeEnd:int = geoURIWithoutQuery.indexOf(',', latitudeEnd + 1);
|
||||
var latitude:Number, longitude:Number, altitude:Number;
|
||||
try {
|
||||
latitude = Number(geoURIWithoutQuery.substring(0, latitudeEnd));
|
||||
if (longitudeEnd < 0) {
|
||||
longitude = Number(geoURIWithoutQuery.substring(latitudeEnd + 1));
|
||||
altitude = 0.0;
|
||||
} else {
|
||||
longitude = Number(geoURIWithoutQuery.substring(latitudeEnd + 1, longitudeEnd));
|
||||
altitude = Number(geoURIWithoutQuery.substring(longitudeEnd + 1));
|
||||
}
|
||||
} catch (nfe:Error) {
|
||||
return null;
|
||||
}
|
||||
return new GeoParsedResult((rawText.substr(0,4) == "GEO:") ? "geo:" + rawText.substring(4) : rawText,
|
||||
latitude, longitude, altitude);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @author jbreiden@google.com (Jeff Breidenbach)
|
||||
*/
|
||||
public final class ISBNParsedResult extends ParsedResult {
|
||||
|
||||
private var isbn:String;
|
||||
|
||||
public function ISBNParsedResult(isbn:String) {
|
||||
super(ParsedResultType.ISBN);
|
||||
this.isbn = isbn;
|
||||
}
|
||||
|
||||
public function getISBN():String {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* Parses strings of digits that represent a ISBN.
|
||||
*
|
||||
* @author jbreiden@google.com (Jeff Breidenbach)
|
||||
*/
|
||||
public class ISBNResultParser extends ResultParser {
|
||||
|
||||
public function ISBNResultParser() {
|
||||
}
|
||||
|
||||
// ISBN-13 For Dummies
|
||||
// http://www.bisg.org/isbn-13/for.dummies.html
|
||||
public static function parse(result:Result):ISBNParsedResult
|
||||
{
|
||||
var format:BarcodeFormat = result.getBarcodeFormat();
|
||||
if (BarcodeFormat.EAN_13 != format) {
|
||||
return null;
|
||||
}
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null) {
|
||||
return null;
|
||||
}
|
||||
var length:int = rawText.length;
|
||||
if (length != 13) {
|
||||
return null;
|
||||
}
|
||||
if (!Utils.startsWith(rawText,"978") && !Utils.startsWith(rawText,"979")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ISBNParsedResult(rawText);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
|
||||
/**
|
||||
* <p>Abstract class representing the result of decoding a barcode, as more than
|
||||
* a String -- as some type of structured data. This might be a subclass which represents
|
||||
* a URL, or an e-mail address. {@link ResultParser#parseResult(Result)} will turn a raw
|
||||
* decoded string into the most appropriate type of structured representation.</p>
|
||||
*
|
||||
* <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
|
||||
* on exception-based mechanisms during parsing.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class ParsedResult {
|
||||
|
||||
private var type:ParsedResultType;
|
||||
|
||||
public function ParsedResult(type:ParsedResultType ) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public function getType():ParsedResultType {
|
||||
return type;
|
||||
}
|
||||
|
||||
public function getDisplayResult():String{return '';}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
return getDisplayResult();
|
||||
}
|
||||
|
||||
public static function maybeAppend(value1:Object, result:StringBuilder ):void
|
||||
{
|
||||
var value:Array;
|
||||
if (value1 is Array) { value = value1 as Array; }
|
||||
else if (value1 is String) { value = [value1]; }
|
||||
if (value != null) {
|
||||
for (var i:int = 0; i < value.length; i++) {
|
||||
if (value[i] != null && value[i].length > 0) {
|
||||
if (result.length > 0) {
|
||||
result.Append('\n');
|
||||
}
|
||||
result.Append(value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the type of data encoded by a barcode -- from plain text, to a
|
||||
* URI, to an e-mail address, etc.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class ParsedResultType {
|
||||
|
||||
public static var ADDRESSBOOK:ParsedResultType = new ParsedResultType("ADDRESSBOOK");
|
||||
public static var EMAIL_ADDRESS:ParsedResultType = new ParsedResultType("EMAIL_ADDRESS");
|
||||
public static var PRODUCT:ParsedResultType = new ParsedResultType("PRODUCT");
|
||||
public static var URI:ParsedResultType = new ParsedResultType("URI");
|
||||
public static var TEXT:ParsedResultType = new ParsedResultType("TEXT");
|
||||
public static var ANDROID_INTENT:ParsedResultType = new ParsedResultType("ANDROID_INTENT");
|
||||
public static var GEO:ParsedResultType = new ParsedResultType("GEO");
|
||||
public static var TEL:ParsedResultType = new ParsedResultType("TEL");
|
||||
public static var SMS:ParsedResultType = new ParsedResultType("SMS");
|
||||
public static var CALENDAR:ParsedResultType = new ParsedResultType("CALENDAR");
|
||||
// "optional" types
|
||||
public static var NDEF_SMART_POSTER:ParsedResultType = new ParsedResultType("NDEF_SMART_POSTER");
|
||||
public static var MOBILETAG_RICH_WEB:ParsedResultType = new ParsedResultType("MOBILETAG_RICH_WEB");
|
||||
public static var ISBN:ParsedResultType = new ParsedResultType("ISBN");
|
||||
|
||||
private var name:String;
|
||||
|
||||
public function ParsedResultType(name:String) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public final class ProductParsedResult extends ParsedResult {
|
||||
|
||||
public var productID:String;
|
||||
public var normalizedProductID:String;
|
||||
|
||||
/*
|
||||
public function ProductParsedResult(productID:String)
|
||||
{
|
||||
this(productID, productID);
|
||||
}
|
||||
*/
|
||||
public function ProductParsedResult(productID:String, normalizedProductID:String='')
|
||||
{
|
||||
if (normalizedProductID == '')
|
||||
{
|
||||
normalizedProductID = productID
|
||||
}
|
||||
super(ParsedResultType.PRODUCT);
|
||||
this.productID = productID;
|
||||
this.normalizedProductID = normalizedProductID;
|
||||
}
|
||||
|
||||
public function getProductID():String {
|
||||
return productID;
|
||||
}
|
||||
|
||||
public function getNormalizedProductID():String {
|
||||
return normalizedProductID;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
return productID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.oned.UPCEReader;
|
||||
|
||||
/**
|
||||
* Parses strings of digits that repesent a UPC code.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public final class ProductResultParser extends ResultParser {
|
||||
|
||||
public function ProductResultParser() {
|
||||
}
|
||||
|
||||
// Treat all UPC and EAN variants as UPCs, in the sense that they are all product barcodes.
|
||||
public static function parse(result:Result):ProductParsedResult {
|
||||
var format:BarcodeFormat = result.getBarcodeFormat();
|
||||
if (!((BarcodeFormat.UPC_A == format) || (BarcodeFormat.UPC_E == format) ||
|
||||
(BarcodeFormat.EAN_8 == format) || (BarcodeFormat.EAN_13 == format))) {
|
||||
return null;
|
||||
}
|
||||
// Really neither of these should happen:
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var length:int = rawText.length;
|
||||
for (var x:int = 0; x < length; x++) {
|
||||
var c:int = rawText.charCodeAt(x);//.charAt(x);
|
||||
if (c < ('0').charCodeAt(0) || c > ('9').charCodeAt(0)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Not actually checking the checksum again here
|
||||
|
||||
var normalizedProductID:String;
|
||||
// Expand UPC-E for purposes of searching
|
||||
if (BarcodeFormat.UPC_E == format) {
|
||||
normalizedProductID = UPCEReader.convertUPCEtoUPCA(rawText);
|
||||
} else {
|
||||
normalizedProductID = rawText;
|
||||
}
|
||||
|
||||
return new ProductParsedResult(rawText, normalizedProductID);
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,292 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
import mx.utils.StringUtil;
|
||||
|
||||
/**
|
||||
* <p>Abstract class representing the result of decoding a barcode, as more than
|
||||
* a String -- as some type of structured data. This might be a subclass which represents
|
||||
* a URL, or an e-mail address. {@link #parseResult(com.google.zxing.Result)} will turn a raw
|
||||
* decoded string into the most appropriate type of structured representation.</p>
|
||||
*
|
||||
* <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
|
||||
* on exception-based mechanisms during parsing.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class ResultParser {
|
||||
|
||||
public static function parseResult(theResult:Result):ParsedResult {
|
||||
// This is a bit messy, but given limited options in MIDP / CLDC, this may well be the simplest
|
||||
// way to go about this. For example, we have no reflection available, really.
|
||||
// Order is important here.
|
||||
var result:ParsedResult;
|
||||
if ((result = BookmarkDoCoMoResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = AddressBookDocomoResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = EmailDoCoMoResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = AddressBookDocomoResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = VCardResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = BizcardResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = VEventResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = EmailAddressResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = TelResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = SMSMMSResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = GeoResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = URLTOResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = URIResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
} else if ((result = ISBNResultParser.parse(theResult)) != null) {
|
||||
// We depend on ISBN parsing coming before UPC, as it is a subset.
|
||||
return result;
|
||||
} else if ((result = ProductResultParser.parse(theResult)) != null) {
|
||||
return result;
|
||||
}
|
||||
return new TextParsedResult(theResult.getText(), null);
|
||||
}
|
||||
|
||||
protected static function maybeAppend(value:String, result:StringBuilder):void {
|
||||
if (value != null) {
|
||||
result.Append('\n');
|
||||
result.Append(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected static function maybeWrap(value:String ):Array {
|
||||
return value == null ? null : [ value ];
|
||||
}
|
||||
|
||||
protected static function unescapeBackslash(escaped:String):String {
|
||||
if (escaped != null) {
|
||||
var backslash:int = escaped.indexOf('\\');
|
||||
if (backslash >= 0) {
|
||||
var max:int = escaped.length;
|
||||
var unescaped:StringBuilder = new StringBuilder(max - 1);
|
||||
unescaped.Append(escaped.split(""), 0, backslash);
|
||||
var nextIsEscaped:Boolean = false;
|
||||
for (var i:int = backslash; i < max; i++) {
|
||||
var c:String = escaped.charAt(i);
|
||||
if (nextIsEscaped || c != '\\') {
|
||||
unescaped.Append(c);
|
||||
nextIsEscaped = false;
|
||||
} else {
|
||||
nextIsEscaped = true;
|
||||
}
|
||||
}
|
||||
return unescaped.toString();
|
||||
}
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
public static function urlDecode(escaped:String):String {
|
||||
|
||||
// No we can't use java.net.URLDecoder here. JavaME doesn't have it.
|
||||
if (escaped == null) {
|
||||
return null;
|
||||
}
|
||||
var escapedArray:Array = escaped.split("");
|
||||
|
||||
var first:int = findFirstEscape(escapedArray);
|
||||
if (first < 0) {
|
||||
return escaped;
|
||||
}
|
||||
|
||||
var max:int = escapedArray.length;
|
||||
// final length is at most 2 less than original due to at least 1 unescaping
|
||||
var unescaped:StringBuilder = new StringBuilder(max - 2);
|
||||
// Can append everything up to first escape character
|
||||
unescaped.Append(escapedArray, 0, first);
|
||||
|
||||
for (var i:int = first; i < max; i++) {
|
||||
var c:String = escapedArray[i];
|
||||
if (c == '+') {
|
||||
// + is translated directly into a space
|
||||
unescaped.Append(' ');
|
||||
} else if (c == '%') {
|
||||
// Are there even two more chars? if not we will just copy the escaped sequence and be done
|
||||
if (i >= max - 2) {
|
||||
unescaped.Append('%'); // append that % and move on
|
||||
} else {
|
||||
var firstDigitValue:int = parseHexDigit(escapedArray[++i]);
|
||||
var secondDigitValue:int = parseHexDigit(escapedArray[++i]);
|
||||
if (firstDigitValue < 0 || secondDigitValue < 0) {
|
||||
// bad digit, just move on
|
||||
unescaped.Append('%');
|
||||
unescaped.Append(escapedArray[i-1]);
|
||||
unescaped.Append(escapedArray[i]);
|
||||
}
|
||||
unescaped.Append(String.fromCharCode((firstDigitValue << 4) + secondDigitValue));
|
||||
}
|
||||
} else {
|
||||
unescaped.Append(c);
|
||||
}
|
||||
}
|
||||
return unescaped.toString();
|
||||
}
|
||||
|
||||
private static function findFirstEscape(escapedArray:Array):int {
|
||||
var max:int = escapedArray.length;
|
||||
for (var i:int = 0; i < max; i++) {
|
||||
var c:String = escapedArray[i];
|
||||
if (c == '+' || c == '%') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static function parseHexDigit(c:String):int {
|
||||
if (c.charCodeAt(0) >= ('a').charCodeAt(0)) {
|
||||
if (c.charCodeAt(0) <= ('f').charCodeAt(0)) {
|
||||
return 10 + (c.charCodeAt(0) - ('a').charCodeAt(0));
|
||||
}
|
||||
} else if (c.charCodeAt(0) >= ('A').charCodeAt(0)) {
|
||||
if (c.charCodeAt(0) <= ('F').charCodeAt(0)) {
|
||||
return 10 + (c.charCodeAt(0) - ('A').charCodeAt(0));
|
||||
}
|
||||
} else if (c.charCodeAt(0) >= ('0').charCodeAt(0)) {
|
||||
if (c.charCodeAt(0) <= ('9').charCodeAt(0)) {
|
||||
return c.charCodeAt(0) - ('0').charCodeAt(0);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected static function isStringOfDigits(value:String,length:int):Boolean {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
var stringLength:int = value.length;
|
||||
if (length != stringLength) {
|
||||
return false;
|
||||
}
|
||||
for (var i:int = 0; i < length; i++) {
|
||||
var c:String = value.charAt(i);
|
||||
if (c < '0' || c > '9') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function parseNameValuePairs(uri:String):HashTable {
|
||||
var paramStart:int = uri.indexOf('?');
|
||||
if (paramStart < 0) {
|
||||
return null;
|
||||
}
|
||||
var result:HashTable = new HashTable(3);
|
||||
paramStart++;
|
||||
var paramEnd:int;
|
||||
while ((paramEnd = uri.indexOf('&', paramStart)) >= 0) {
|
||||
appendKeyValue(uri, paramStart, paramEnd, result);
|
||||
paramStart = paramEnd + 1;
|
||||
}
|
||||
appendKeyValue(uri, paramStart, uri.length, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static function appendKeyValue(uri:String , paramStart:int , paramEnd:int, result:HashTable):void {
|
||||
var separator:int = uri.indexOf('=', paramStart);
|
||||
if (separator >= 0) {
|
||||
// key = value
|
||||
var key:String = uri.substring(paramStart, separator);
|
||||
var value:String = uri.substring(separator + 1, paramEnd);
|
||||
value = urlDecode(value);
|
||||
result._put(key, value);
|
||||
}
|
||||
// Can't put key, null into a hashtable
|
||||
}
|
||||
|
||||
public static function matchPrefixedField(prefix:String, rawText:String, endChar:String, trim:Boolean):Array {
|
||||
var matches:ArrayList = null;
|
||||
var i:int = 0;
|
||||
var max:int = rawText.length;
|
||||
while (i < max) {
|
||||
i = rawText.indexOf(prefix, i);
|
||||
if (i < 0) {
|
||||
break;
|
||||
}
|
||||
i += prefix.length; // Skip past this prefix we found to start
|
||||
var start:int = i; // Found the start of a match here
|
||||
var done:Boolean = false;
|
||||
while (!done) {
|
||||
i = rawText.indexOf( endChar, i);
|
||||
if (i < 0) {
|
||||
// No terminating end character? uh, done. Set i such that loop terminates and break
|
||||
i = rawText.length;
|
||||
done = true;
|
||||
} else if (rawText.charAt(i - 1) == '\\') {
|
||||
// semicolon was escaped so continue
|
||||
i++;
|
||||
} else {
|
||||
// found a match
|
||||
if (matches == null) {
|
||||
matches = new ArrayList(3); // lazy init
|
||||
}
|
||||
var element:String = unescapeBackslash(rawText.substring(start, i));
|
||||
if (trim) {
|
||||
element = StringUtil.trim(element);
|
||||
}
|
||||
matches.addElement(element);
|
||||
i++;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matches == null || matches.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return toStringArray(matches);
|
||||
}
|
||||
|
||||
public static function matchSinglePrefixedField(prefix:String, rawText:String, endChar:String, trim:Boolean ):String
|
||||
{
|
||||
var matches:Array = matchPrefixedField(prefix, rawText, endChar, trim);
|
||||
return matches == null ? null : matches[0];
|
||||
}
|
||||
|
||||
public static function toStringArray(strings:ArrayList):Array {
|
||||
var size:int = strings.size();
|
||||
var result:Array = new Array(size);
|
||||
for (var j:int = 0; j < size; j++) {
|
||||
result[j] = String(strings.elementAt(j));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* <p>Parses an "sms:" URI result, which specifies a number to SMS and optional
|
||||
* "via" number. See <a href="http://gbiv.com/protocols/uri/drafts/draft-antti-gsm-sms-url-04.txt">
|
||||
* the IETF draft</a> on this.</p>
|
||||
*
|
||||
* <p>This actually also parses URIs starting with "mms:", "smsto:", "mmsto:", "SMSTO:", and
|
||||
* "MMSTO:", and treats them all the same way, and effectively converts them to an "sms:" URI
|
||||
* for purposes of forwarding to the platform.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class SMSMMSResultParser extends ResultParser {
|
||||
|
||||
public function SMSMMSResultParser() {
|
||||
}
|
||||
|
||||
public static function parse(result:Result):SMSParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null) {
|
||||
return null;
|
||||
}
|
||||
var prefixLength:int;
|
||||
if (Utils.startsWith(rawText,"sms:") || Utils.startsWith(rawText,"SMS:") ||
|
||||
Utils.startsWith(rawText,"mms:") || Utils.startsWith(rawText,"MMS:")) {
|
||||
prefixLength = 4;
|
||||
} else if (Utils.startsWith(rawText,"smsto:") || Utils.startsWith(rawText,"SMSTO:") ||
|
||||
Utils.startsWith(rawText,"mmsto:") || Utils.startsWith(rawText,"MMSTO:")) {
|
||||
prefixLength = 6;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check up front if this is a URI syntax string with query arguments
|
||||
var nameValuePairs:HashTable = parseNameValuePairs(rawText);
|
||||
var subject:String = null;
|
||||
var body:String = null;
|
||||
var querySyntax:Boolean = false;
|
||||
if (nameValuePairs != null && !nameValuePairs.isEmpty()) {
|
||||
subject = String(nameValuePairs._get("subject"));
|
||||
body = String( nameValuePairs._get("body"));
|
||||
querySyntax = true;
|
||||
}
|
||||
|
||||
// Drop sms, query portion
|
||||
var queryStart:int = rawText.indexOf('?', prefixLength);
|
||||
var smsURIWithoutQuery:String;
|
||||
// If it's not query syntax, the question mark is part of the subject or message
|
||||
if (queryStart < 0 || !querySyntax) {
|
||||
smsURIWithoutQuery = rawText.substring(prefixLength);
|
||||
} else {
|
||||
smsURIWithoutQuery = rawText.substring(prefixLength, queryStart);
|
||||
}
|
||||
var numberEnd:int = smsURIWithoutQuery.indexOf(';');
|
||||
var number:String;
|
||||
var via:String;
|
||||
if (numberEnd < 0) {
|
||||
number = smsURIWithoutQuery;
|
||||
via = null;
|
||||
} else {
|
||||
number = smsURIWithoutQuery.substring(0, numberEnd);
|
||||
var maybeVia:String = smsURIWithoutQuery.substring(numberEnd + 1);
|
||||
if (Utils.startsWith(maybeVia,"via=")) {
|
||||
via = maybeVia.substring(4);
|
||||
} else {
|
||||
via = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Thanks to dominik.wild for suggesting this enhancement to support
|
||||
// smsto:number:body URIs
|
||||
if (body == null) {
|
||||
var bodyStart:int = number.indexOf(':');
|
||||
if (bodyStart >= 0) {
|
||||
body = number.substring(bodyStart + 1);
|
||||
number = number.substring(0, bodyStart);
|
||||
}
|
||||
}
|
||||
return new SMSParsedResult("sms:" + number, number, via, subject, body, null);
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,77 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class SMSParsedResult extends ParsedResult {
|
||||
|
||||
private var smsURI:String;
|
||||
private var number:String;
|
||||
private var via:String;
|
||||
private var subject:String;
|
||||
private var body:String;
|
||||
private var title:String;
|
||||
|
||||
public function SMSParsedResult(smsURI:String ,number:String ,via:String,subject:String, body:String, title:String) {
|
||||
super(ParsedResultType.SMS);
|
||||
this.smsURI = smsURI;
|
||||
this.number = number;
|
||||
this.via = via;
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public function getSMSURI():String {
|
||||
return smsURI;
|
||||
}
|
||||
|
||||
public function getNumber():String {
|
||||
return number;
|
||||
}
|
||||
|
||||
public function getVia():String {
|
||||
return via;
|
||||
}
|
||||
|
||||
public function getSubject():String {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public function getBody():String {
|
||||
return body;
|
||||
}
|
||||
|
||||
public function getTitle():String {
|
||||
return title;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
var result:StringBuilder = new StringBuilder();
|
||||
maybeAppend(number, result);
|
||||
maybeAppend(via, result);
|
||||
maybeAppend(subject, result);
|
||||
maybeAppend(body, result);
|
||||
maybeAppend(title, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class TelParsedResult extends ParsedResult {
|
||||
|
||||
private var number:String;
|
||||
private var telURI:String;
|
||||
private var title:String;
|
||||
|
||||
public function TelParsedResult(number:String, telURI:String,title:String) {
|
||||
super(ParsedResultType.TEL);
|
||||
this.number = number;
|
||||
this.telURI = telURI;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public function getNumber():String {
|
||||
return number;
|
||||
}
|
||||
|
||||
public function getTelURI():String {
|
||||
return telURI;
|
||||
}
|
||||
|
||||
public function getTitle():String {
|
||||
return title;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
var result:StringBuilder = new StringBuilder();
|
||||
maybeAppend(number, result);
|
||||
maybeAppend(title, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,46 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* Parses a "tel:" URI result, which specifies a phone number.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class TelResultParser extends ResultParser {
|
||||
|
||||
public function TelResultParser() {
|
||||
}
|
||||
|
||||
public static function parse(result:Result):TelParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null || (!Utils.startsWith(rawText,"tel:") && !Utils.startsWith(rawText,"TEL:"))) {
|
||||
return null;
|
||||
}
|
||||
// Normalize "TEL:" to "tel:"
|
||||
var telURI:String = Utils.startsWith(rawText,"TEL:") ? "tel:" + rawText.substring(4) : rawText;
|
||||
// Drop tel, query portion
|
||||
var queryStart:int = rawText.indexOf('?', 4);
|
||||
var number:String = queryStart < 0 ? rawText.substring(4) : rawText.substring(4, queryStart);
|
||||
return new TelParsedResult(number, telURI, null);
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,51 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A simple result type encapsulating a string that has no further
|
||||
* interpretation.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class TextParsedResult extends ParsedResult {
|
||||
|
||||
private var text:String;
|
||||
private var language:String;
|
||||
|
||||
public function TextParsedResult(text:String, language:String) {
|
||||
super(ParsedResultType.TEXT);
|
||||
this.text = text;
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public function getText():String {
|
||||
return text;
|
||||
}
|
||||
|
||||
public function getLanguage():String {
|
||||
return language;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class URIParsedResult extends ParsedResult {
|
||||
|
||||
private var uri:String;
|
||||
private var title:String;
|
||||
|
||||
public function URIParsedResult(uri:String,title:String) {
|
||||
super(ParsedResultType.URI);
|
||||
this.uri = massageURI(uri);
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public function getURI():String {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public function getTitle():String {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the URI contains suspicious patterns that may suggest it intends to
|
||||
* mislead the user about its true nature. At the moment this looks for the presence
|
||||
* of user/password syntax in the host/authority portion of a URI which may be used
|
||||
* in attempts to make the URI's host appear to be other than it is. Example:
|
||||
* http://yourbank.com@phisher.com This URI connects to phisher.com but may appear
|
||||
* to connect to yourbank.com at first glance.
|
||||
*/
|
||||
public function isPossiblyMaliciousURI():Boolean {
|
||||
return containsUser();
|
||||
}
|
||||
|
||||
private function containsUser():Boolean {
|
||||
// This method is likely not 100% RFC compliant yet
|
||||
var hostStart:int = uri.indexOf(':'); // we should always have scheme at this point
|
||||
hostStart++;
|
||||
// Skip slashes preceding host
|
||||
var uriLength:int = uri.length;
|
||||
while (hostStart < uriLength && uri.charAt(hostStart) == '/') {
|
||||
hostStart++;
|
||||
}
|
||||
var hostEnd:int = uri.indexOf('/', hostStart);
|
||||
if (hostEnd < 0) {
|
||||
hostEnd = uriLength;
|
||||
}
|
||||
var at:int = uri.indexOf('@', hostStart);
|
||||
return at >= hostStart && at < hostEnd;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
var result:StringBuilder = new StringBuilder();
|
||||
maybeAppend(title, result);
|
||||
maybeAppend(uri, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a string that represents a URI into something more proper, by adding or canonicalizing
|
||||
* the protocol.
|
||||
*/
|
||||
private static function massageURI(uri:String):String {
|
||||
var protocolEnd:int = uri.indexOf(':');
|
||||
if (protocolEnd < 0) {
|
||||
// No protocol, assume http
|
||||
uri = "http://" + uri;
|
||||
} else if (isColonFollowedByPortNumber(uri, protocolEnd)) {
|
||||
// Found a colon, but it looks like it is after the host, so the protocol is still missing
|
||||
uri = "http://" + uri;
|
||||
} else {
|
||||
// Lowercase protocol to avoid problems
|
||||
uri = uri.substring(0, protocolEnd).toLowerCase() + uri.substring(protocolEnd);
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
private static function isColonFollowedByPortNumber(uri:String, protocolEnd:int):Boolean {
|
||||
var nextSlash:int = uri.indexOf('/', protocolEnd + 1);
|
||||
if (nextSlash < 0) {
|
||||
nextSlash = uri.length;
|
||||
}
|
||||
if (nextSlash <= protocolEnd + 1) {
|
||||
return false;
|
||||
}
|
||||
for (var x:int = protocolEnd + 1; x < nextSlash; x++) {
|
||||
if (uri.charAt(x) < '0' || uri.charAt(x) > '9') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* Tries to parse results that are a URI of some kind.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class URIResultParser extends ResultParser {
|
||||
|
||||
public function URIResultParser() {
|
||||
}
|
||||
|
||||
public static function parse(result:Result):URIParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
// We specifically handle the odd "URL" scheme here for simplicity
|
||||
if (rawText != null && Utils.startsWith(rawText,"URL:")) {
|
||||
rawText = rawText.substring(4);
|
||||
}
|
||||
if (!isBasicallyValidURI(rawText)) {
|
||||
return null;
|
||||
}
|
||||
return new URIParsedResult(rawText, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a string is not obviously not a URI. This implements crude checks; this class does not
|
||||
* intend to strictly check URIs as its only function is to represent what is in a barcode, but, it does
|
||||
* need to know when a string is obviously not a URI.
|
||||
*/
|
||||
public static function isBasicallyValidURI(uri:String):Boolean {
|
||||
|
||||
if (uri == null || uri.indexOf(' ') >= 0 || uri.indexOf('\n') >= 0) {
|
||||
return false;
|
||||
}
|
||||
var period:int = uri.indexOf('.');
|
||||
// Look for period in a domain but followed by at least a two-char TLD
|
||||
return period < uri.length - 2 && (period >= 0 || uri.indexOf(':') >= 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*/
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* Parses the "URLTO" result format, which is of the form "URLTO:[title]:[url]".
|
||||
* This seems to be used sometimes, but I am not able to find documentation
|
||||
* on its origin or official format?
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class URLTOResultParser {
|
||||
|
||||
public function URLTOResultParser() {
|
||||
}
|
||||
|
||||
public static function parse(result:Result):URIParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null || (!Utils.startsWith(rawText,"urlto:") && !Utils.startsWith(rawText,"URLTO:"))) {
|
||||
return null;
|
||||
}
|
||||
var titleEnd:int = rawText.indexOf(':', 6);
|
||||
if (titleEnd < 0) {
|
||||
return null;
|
||||
}
|
||||
var title:String = titleEnd <= 6 ? null : rawText.substring(6, titleEnd);
|
||||
var uri:String = rawText.substring(titleEnd + 1);
|
||||
return new URIParsedResult(uri, title);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
import mx.utils.StringUtil;
|
||||
|
||||
/**
|
||||
* Parses contact information formatted according to the VCard (2.1) format. This is not a complete
|
||||
* implementation but should parse information as commonly encoded in 2D barcodes.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class VCardResultParser extends ResultParser {
|
||||
|
||||
public function VCardResultParser() {
|
||||
}
|
||||
|
||||
public static function parse(result:Result):AddressBookParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null || (Utils.startsWith(rawText,"BEGIN:VCARD")) || !Utils.endsWith(rawText,"END:VCARD")) {
|
||||
return null;
|
||||
}
|
||||
var names:Array = matchVCardPrefixedField("FN", rawText, true);
|
||||
if (names == null) {
|
||||
// If no display names found, look for regular name fields and format them
|
||||
names = matchVCardPrefixedField("N", rawText, true);
|
||||
formatNames(names);
|
||||
}
|
||||
var phoneNumbers:Array = matchVCardPrefixedField("TEL", rawText, true);
|
||||
var emails:Array = matchVCardPrefixedField("EMAIL", rawText, true);
|
||||
var note:String = matchSingleVCardPrefixedField("NOTE", rawText, false);
|
||||
var address:String = matchSingleVCardPrefixedField("ADR", rawText, true);
|
||||
address = formatAddress(address);
|
||||
var org:String = matchSingleVCardPrefixedField("ORG", rawText, true);
|
||||
var birthday:String = matchSingleVCardPrefixedField("BDAY", rawText, true);
|
||||
if (birthday != null && !isStringOfDigits(birthday, 8)) {
|
||||
return null;
|
||||
}
|
||||
var title:String = matchSingleVCardPrefixedField("TITLE", rawText, true);
|
||||
var url:String = matchSingleVCardPrefixedField("URL", rawText, true);
|
||||
return new AddressBookParsedResult(names, null, phoneNumbers, emails, note, address, org,
|
||||
birthday, title, url);
|
||||
}
|
||||
|
||||
private static function matchVCardPrefixedField(prefix:String, rawText:String, trim:Boolean):Array {
|
||||
var matches:ArrayList = null;
|
||||
var i:int = 0;
|
||||
var max:int = rawText.length;
|
||||
while (i < max) {
|
||||
i = rawText.indexOf(prefix, i);
|
||||
if (i < 0) {
|
||||
break;
|
||||
}
|
||||
if (i > 0 && rawText.charAt(i - 1) != '\n') {
|
||||
// then this didn't start a new token, we matched in the middle of something
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
i += prefix.length; // Skip past this prefix we found to start
|
||||
if (rawText.charAt(i) != ':' && rawText.charAt(i) != ';') {
|
||||
continue;
|
||||
}
|
||||
while (rawText.charAt(i) != ':') { // Skip until a colon
|
||||
i++;
|
||||
}
|
||||
i++; // skip colon
|
||||
var start:int = i; // Found the start of a match here
|
||||
i = rawText.indexOf('\n', i); // Really, ends in \r\n
|
||||
if (i < 0) {
|
||||
// No terminating end character? uh, done. Set i such that loop terminates and break
|
||||
i = max;
|
||||
} else if (i > start) {
|
||||
// found a match
|
||||
if (matches == null) {
|
||||
matches = new ArrayList(3); // lazy init
|
||||
}
|
||||
var element:String = rawText.substring(start, i);
|
||||
if (trim) {
|
||||
element = StringUtil.trim(element);
|
||||
}
|
||||
matches.addElement(element);
|
||||
i++;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (matches == null || matches.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return toStringArray(matches);
|
||||
}
|
||||
|
||||
public static function matchSingleVCardPrefixedField(prefix:String , rawText:String , trim:Boolean):String {
|
||||
var values:Array = matchVCardPrefixedField(prefix, rawText, trim);
|
||||
return values == null ? null : values[0];
|
||||
}
|
||||
|
||||
private static function formatAddress(address:String):String {
|
||||
if (address == null) {
|
||||
return null;
|
||||
}
|
||||
var length:int = address.length;
|
||||
var newAddress:StringBuilder = new StringBuilder(length);
|
||||
for (var j:int = 0; j < length; j++) {
|
||||
var c:String = address.charAt(j);
|
||||
if (c == ';') {
|
||||
newAddress.Append(' ');
|
||||
} else {
|
||||
newAddress.Append(c);
|
||||
}
|
||||
}
|
||||
return StringUtil.trim(newAddress.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats name fields of the form "Public;John;Q.;Reverend;III" into a form like
|
||||
* "Reverend John Q. Public III".
|
||||
*
|
||||
* @param names name values to format, in place
|
||||
*/
|
||||
private static function formatNames(names:Array):void {
|
||||
if (names != null) {
|
||||
for (var i:int = 0; i < names.length; i++) {
|
||||
var name:String = names[i];
|
||||
var components:Array = new Array(5);
|
||||
var start:int = 0;
|
||||
var end:int;
|
||||
var componentIndex:int = 0;
|
||||
while ((end = name.indexOf(';', start)) > 0) {
|
||||
components[componentIndex] = name.substring(start, end);
|
||||
componentIndex++;
|
||||
start = end + 1;
|
||||
}
|
||||
components[componentIndex] = name.substring(start);
|
||||
var newName:StringBuilder = new StringBuilder();
|
||||
maybeAppendComponent(components, 3, newName);
|
||||
maybeAppendComponent(components, 1, newName);
|
||||
maybeAppendComponent(components, 2, newName);
|
||||
maybeAppendComponent(components, 0, newName);
|
||||
maybeAppendComponent(components, 4, newName);
|
||||
names[i] = StringUtil.trim(newName.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function maybeAppendComponent(components:Array,i:int, newName:StringBuilder):void {
|
||||
if (components[i] != null) {
|
||||
newName.Append(' ');
|
||||
newName.Append(components[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package com.google.zxing.client.result
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Partially implements the iCalendar format's "VEVENT" format for specifying a
|
||||
* calendar event. See RFC 2445. This supports SUMMARY, DTSTART and DTEND fields.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class VEventResultParser extends ResultParser {
|
||||
|
||||
public function VEventResultParser() {
|
||||
}
|
||||
|
||||
public static function parse(result:Result):CalendarParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
if (rawText == null) {
|
||||
return null;
|
||||
}
|
||||
var vEventStart:int = rawText.indexOf("BEGIN:VEVENT");
|
||||
if (vEventStart < 0) {
|
||||
return null;
|
||||
}
|
||||
var vEventEnd:int = rawText.indexOf("END:VEVENT");
|
||||
if (vEventEnd < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var summary:String = VCardResultParser.matchSingleVCardPrefixedField("SUMMARY", rawText, true);
|
||||
var start:String = VCardResultParser.matchSingleVCardPrefixedField("DTSTART", rawText, true);
|
||||
var end:String = VCardResultParser.matchSingleVCardPrefixedField("DTEND", rawText, true);
|
||||
try {
|
||||
return new CalendarParsedResult(summary, start, end, null, null, null);
|
||||
} catch (iae:IllegalArgumentException) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.client.result.ResultParser;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
/**
|
||||
* <p>Superclass for classes encapsulating reader results encoded according
|
||||
* to the MobileTag Reader International Specification.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class AbstractMobileTagResultParser extends ResultParser {
|
||||
|
||||
public static var ACTION_DO:int = 1;
|
||||
public static var ACTION_EDIT:int = 2;
|
||||
public static var ACTION_SAVE:int = 4;
|
||||
|
||||
public static function matchDelimitedFields(rawText:String, maxItems:int):Array {
|
||||
var result:Array = new Array(maxItems);
|
||||
var item:int = 0;
|
||||
var i:int = 0;
|
||||
var max:int = rawText.length;
|
||||
while (item < maxItems && i < max) {
|
||||
var start:int = i; // Found the start of a match here
|
||||
var done:Boolean = false;
|
||||
while (!done) {
|
||||
i = rawText.indexOf('|', i);
|
||||
if (i < 0) {
|
||||
// No terminating end character? done. Set i such that loop terminates and break
|
||||
i = rawText.length;
|
||||
done = true;
|
||||
} else if (rawText.charAt(i - 1) == '\\') {
|
||||
// semicolon was escaped so continue
|
||||
i++;
|
||||
} else {
|
||||
// found a match
|
||||
if (start != i) {
|
||||
result[item] = unescapeBackslash(rawText.substring(start, i));
|
||||
}
|
||||
item++;
|
||||
i++;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item < maxItems) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function isDigits(s:String, expectedLength:int):Boolean
|
||||
{
|
||||
if (s == null) {
|
||||
return true;
|
||||
}
|
||||
if (s.length != expectedLength) {
|
||||
return false;
|
||||
}
|
||||
for (var i:int = 0; i < expectedLength; i++) {
|
||||
if (!Utils.isDigit(s.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,47 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
|
||||
import com.google.zxing.client.result.ResultParser;
|
||||
|
||||
/**
|
||||
* <p>Superclass for classes encapsulating results in the NDEF format.
|
||||
* See <a href="http://www.nfc-forum.org/specs/">http://www.nfc-forum.org/specs/</a>.</p>
|
||||
*
|
||||
* <p>This code supports a limited subset of NDEF messages, ones that are plausibly
|
||||
* useful in 2D barcode formats. This generally includes 1-record messages, no chunking,
|
||||
* "short record" syntax, no ID field.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class AbstractNDEFResultParser extends ResultParser {
|
||||
|
||||
public static function bytesToString(bytes:Array, offset:int, length:int, encoding:String):String {
|
||||
try {
|
||||
// can't do this in Actionscript
|
||||
//return new String(bytes, offset, length, encoding);
|
||||
throw new Error("Platform does not support encoding");
|
||||
} catch (uee:Error) {
|
||||
// This should only be used when 'encoding' is an encoding that must necessarily
|
||||
// be supported by the JVM, like UTF-8
|
||||
throw new Error("Platform does not support required encoding: " + uee);
|
||||
}
|
||||
throw new Error("Platform does not support encoding");
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,74 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
import com.google.zxing.client.result.ParsedResult;
|
||||
import com.google.zxing.client.result.ResultParser;
|
||||
import com.google.zxing.client.result.AddressBookParsedResult;
|
||||
|
||||
/**
|
||||
* Implements KDDI AU's address book format. See
|
||||
* <a href="http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html">
|
||||
* http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html</a>.
|
||||
* (Thanks to Yuzo for translating!)
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class AddressBookAUResultParser extends ResultParser {
|
||||
|
||||
public static function parse(result:Result):AddressBookParsedResult {
|
||||
var rawText:String = result.getText();
|
||||
// MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF
|
||||
if (rawText == null || rawText.indexOf("MEMORY") < 0 || rawText.indexOf("\r\n") < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NAME1 and NAME2 have specific uses, namely written name and pronunciation, respectively.
|
||||
// Therefore we treat them specially instead of as an array of names.
|
||||
var name:String = matchSinglePrefixedField("NAME1:", rawText, '\r', true);
|
||||
var pronunciation:String = matchSinglePrefixedField("NAME2:", rawText, '\r', true);
|
||||
|
||||
var phoneNumbers:Array = matchMultipleValuePrefix("TEL", 3, rawText, true);
|
||||
var emails:Array = matchMultipleValuePrefix("MAIL", 3, rawText, true);
|
||||
var note:String = matchSinglePrefixedField("MEMORY:", rawText, '\r', false);
|
||||
var address:String = matchSinglePrefixedField("ADD:", rawText, '\r', true);
|
||||
return new AddressBookParsedResult(maybeWrap(name), pronunciation, phoneNumbers, emails, note,
|
||||
address, null, null, null, null);
|
||||
}
|
||||
|
||||
private static function matchMultipleValuePrefix(prefix:String, max:int, rawText:String, trim:Boolean):Array {
|
||||
var values:ArrayList = null;
|
||||
for (var i:int = 1; i <= max; i++) {
|
||||
var value:String = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', trim);
|
||||
if (value == null) {
|
||||
break;
|
||||
}
|
||||
if (values == null) {
|
||||
values = new ArrayList(max); // lazy init
|
||||
}
|
||||
values.addElement(value);
|
||||
}
|
||||
if (values == null) {
|
||||
return null;
|
||||
}
|
||||
return toStringArray(values);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.result.SMSParsedResult;
|
||||
|
||||
/**
|
||||
* <p>Represents a "MMS" result encoded according to section 4.7 of the
|
||||
* MobileTag Reader International Specification.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MobileTagMMSResultParser extends AbstractMobileTagResultParser {
|
||||
|
||||
public static var SERVICE_TYPE:String = "05";
|
||||
|
||||
public static function parse(result:Result):SMSParsedResult {
|
||||
if (result.getBarcodeFormat() != BarcodeFormat.DATAMATRIX) {
|
||||
return null;
|
||||
}
|
||||
var rawText:String = result.getText();
|
||||
if (rawText.substr(0,(SERVICE_TYPE).length) != SERVICE_TYPE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var matches:Array = matchDelimitedFields(rawText.substring(2), 4);
|
||||
if (matches == null) {
|
||||
return null;
|
||||
}
|
||||
var _to:String = matches[0];
|
||||
var subject:String = matches[1];
|
||||
var body:String = matches[2];
|
||||
var title:String = matches[3];
|
||||
|
||||
return new SMSParsedResult("sms:" + _to, _to, null, subject, body, title);
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,63 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
|
||||
import com.google.zxing.client.result.ParsedResult;
|
||||
import com.google.zxing.client.result.ParsedResultType;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MobileTagRichWebParsedResult extends ParsedResult {
|
||||
|
||||
// Example: "http://www.tagserver.com/script.asp?id="
|
||||
public static var TAGSERVER_URI_PREFIX:String;// = System.getProperty("zxing.mobiletag.tagserver");
|
||||
|
||||
private var id:String;
|
||||
private var action:int;
|
||||
|
||||
public function MobileTagRichWebParsedResult(id:String, action:int, tagserver:String)
|
||||
{
|
||||
super(ParsedResultType.MOBILETAG_RICH_WEB);
|
||||
this.id = id;
|
||||
this.action = action;
|
||||
MobileTagRichWebParsedResult.TAGSERVER_URI_PREFIX = tagserver;
|
||||
}
|
||||
|
||||
public static function getTagserverURIPrefix():String {
|
||||
return MobileTagRichWebParsedResult.TAGSERVER_URI_PREFIX;
|
||||
}
|
||||
|
||||
public function getId():String {
|
||||
return id;
|
||||
}
|
||||
|
||||
public function getAction():int {
|
||||
return action;
|
||||
}
|
||||
|
||||
public function getTagserverURI():String {
|
||||
return TAGSERVER_URI_PREFIX + id;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
/**
|
||||
* <p>Represents a "rich web" result encoded according to section 5 of the
|
||||
* MobileTag Reader International Specification.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MobileTagRichWebResultParser extends AbstractMobileTagResultParser {
|
||||
|
||||
public static var SERVICE_TYPE:String = "54";
|
||||
private static var DEFAULT_ACTION:int = AbstractMobileTagResultParser.ACTION_DO;
|
||||
|
||||
public static function parse(result:Result,tagserver:String):MobileTagRichWebParsedResult {
|
||||
if (MobileTagRichWebParsedResult.TAGSERVER_URI_PREFIX == null) {
|
||||
return null;
|
||||
}
|
||||
if (result.getBarcodeFormat() != BarcodeFormat.DATAMATRIX) {
|
||||
return null;
|
||||
}
|
||||
var rawText:String = result.getText();
|
||||
if (!Utils.startsWith(rawText,SERVICE_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var length:int = rawText.length;
|
||||
if (!isDigits(rawText, length)) {
|
||||
return null;
|
||||
}
|
||||
var action:int;
|
||||
var id:String;
|
||||
if (length == 15) {
|
||||
action = DEFAULT_ACTION;
|
||||
id = rawText.substring(0, 2) + action + rawText.substring(2);
|
||||
} else if (length == 16) {
|
||||
action = rawText.charCodeAt(2) - ('0').charCodeAt(0);
|
||||
id = rawText;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new MobileTagRichWebParsedResult(id, action,tagserver);
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,55 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.result.SMSParsedResult;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* <p>Represents a "SMS" result encoded according to section 4.6 of the
|
||||
* MobileTag Reader International Specification.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MobileTagSMSResultParser extends AbstractMobileTagResultParser {
|
||||
|
||||
public static var SERVICE_TYPE:String = "03";
|
||||
|
||||
public static function parse(result:Result):SMSParsedResult {
|
||||
if (result.getBarcodeFormat() != BarcodeFormat.DATAMATRIX) {
|
||||
return null;
|
||||
}
|
||||
var rawText:String = result.getText();
|
||||
if (!Utils.startsWith(rawText,SERVICE_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var matches:Array = matchDelimitedFields(rawText.substring(2), 3);
|
||||
if (matches == null) {
|
||||
return null;
|
||||
}
|
||||
var _to:String = matches[0];
|
||||
var body:String = matches[1];
|
||||
var title:String = matches[2];
|
||||
|
||||
return new SMSParsedResult("sms:" + _to, _to, null, null, body, title);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.result.CalendarParsedResult;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* <p>Represents a "simple calendar" result encoded according to section 4.9 of the
|
||||
* MobileTag Reader International Specification.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MobileTagSimpleCalendarResultParser extends AbstractMobileTagResultParser {
|
||||
|
||||
public static var SERVICE_TYPE:String = "07";
|
||||
|
||||
public static function parse(result:Result):CalendarParsedResult {
|
||||
if (result.getBarcodeFormat() != BarcodeFormat.DATAMATRIX) {
|
||||
return null;
|
||||
}
|
||||
var rawText:String = result.getText();
|
||||
if (!Utils.startsWith(rawText,SERVICE_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var matches:Array = matchDelimitedFields(rawText.substring(2), 6);
|
||||
if (matches == null || !isDigits(matches[1], 10) || !isDigits(matches[2], 10)) {
|
||||
return null;
|
||||
}
|
||||
var summary:String = matches[0];
|
||||
var start:String = expandDateString(matches[1]);
|
||||
var end:String = expandDateString(matches[2]);
|
||||
var location:String = matches[3];
|
||||
var attendee:String = matches[4];
|
||||
var title:String = matches[5];
|
||||
|
||||
try {
|
||||
return new CalendarParsedResult(summary, start, end, location, attendee, title);
|
||||
} catch ( iae:IllegalArgumentException) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function expandDateString(date:String):String {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
// Input is of form YYMMddHHmmss, and needs to be YYYYMMdd'T'HHmmss'Z'
|
||||
return "20" + date.substring(0, 6) + 'T' + date.substring(6) + "00Z";
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,71 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.result.AddressBookParsedResult;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
/**
|
||||
* <p>Represents a "simple contact" result encoded according to section 4.8 of the
|
||||
* MobileTag Reader International Specification.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MobileTagSimpleContactResultParser extends AbstractMobileTagResultParser {
|
||||
|
||||
public static var SERVICE_TYPE:String = "02";
|
||||
|
||||
public static function parse(result:Result):AddressBookParsedResult {
|
||||
if (result.getBarcodeFormat() != BarcodeFormat.DATAMATRIX) {
|
||||
return null;
|
||||
}
|
||||
var rawText:String = result.getText();
|
||||
if (!Utils.startsWith(rawText,SERVICE_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var matches:Array = matchDelimitedFields(rawText.substring(2), 9);
|
||||
if (matches == null || !isDigits(matches[7], 8)) {
|
||||
return null;
|
||||
}
|
||||
var fullName:String = matches[0];
|
||||
var telephoneCell:String = matches[1];
|
||||
var telephone:String = matches[2];
|
||||
var email1:String = matches[3];
|
||||
var email2:String = matches[4];
|
||||
var address:String = matches[5];
|
||||
var org:String = matches[6];
|
||||
var birthday:String = matches[7];
|
||||
if (!isStringOfDigits(birthday, 8)) {
|
||||
return null;
|
||||
}
|
||||
var title:String = matches[8];
|
||||
|
||||
return new AddressBookParsedResult([fullName],
|
||||
null,
|
||||
[telephoneCell, telephone],
|
||||
[email1, email2],
|
||||
null,
|
||||
address,
|
||||
org,
|
||||
birthday,
|
||||
title,
|
||||
null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
import com.google.zxing.client.result.URIParsedResult;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
/**
|
||||
* <p>Represents a "simple web" result encoded according to section 4.11 of the
|
||||
* MobileTag Reader International Specification.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MobileTagSimpleWebResultParser extends AbstractMobileTagResultParser {
|
||||
|
||||
public static var SERVICE_TYPE:String = "04";
|
||||
private static var URI_PREFIXES:Array = [
|
||||
null,
|
||||
"http://",
|
||||
"http://www.",
|
||||
"https://",
|
||||
"https://www.",
|
||||
"rtsp://",
|
||||
];
|
||||
|
||||
public static function parse(result:Result):URIParsedResult {
|
||||
if (result.getBarcodeFormat() != BarcodeFormat.DATAMATRIX) {
|
||||
return null;
|
||||
}
|
||||
var rawText:String = result.getText();
|
||||
if (!Utils.startsWith(rawText,SERVICE_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var matches:Array = matchDelimitedFields(rawText.substring(2), 2);
|
||||
if (matches == null) {
|
||||
return null;
|
||||
}
|
||||
var uri:String = matches[0];
|
||||
var title:String = matches[1];
|
||||
|
||||
var maybePrefixChar:String = uri.charAt(2);
|
||||
if (maybePrefixChar >= '0' && maybePrefixChar <= '9') {
|
||||
var prefixIndex:int = (maybePrefixChar).charCodeAt(0) - ('0').charCodeAt(0);
|
||||
// Note that '0' is reserved
|
||||
if (prefixIndex >= 1 && prefixIndex < URI_PREFIXES.length) {
|
||||
uri = URI_PREFIXES[prefixIndex] + uri.substring(1);
|
||||
} else {
|
||||
uri = uri.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
return new URIParsedResult(uri, title);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.result.TelParsedResult;
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
|
||||
/**
|
||||
* <p>Represents a "TEL" result encoded according to section 4.4 of the
|
||||
* MobileTag Reader International Specification.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MobileTagTelResultParser extends AbstractMobileTagResultParser {
|
||||
|
||||
public static var SERVICE_TYPE:String = "01";
|
||||
|
||||
public static function parse(result:Result):TelParsedResult {
|
||||
if (result.getBarcodeFormat() != BarcodeFormat.DATAMATRIX) {
|
||||
return null;
|
||||
}
|
||||
var rawText:String = result.getText();
|
||||
if (!Utils.startsWith(rawText,SERVICE_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var matches:Array = matchDelimitedFields(rawText.substring(2), 2);
|
||||
if (matches == null) {
|
||||
return null;
|
||||
}
|
||||
var number:String = matches[0];
|
||||
var title:String = matches[1];
|
||||
|
||||
return new TelParsedResult(number, "tel:" + number, title);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>Represents a record in an NDEF message. This class only supports certain types
|
||||
* of records -- namely, non-chunked records, where ID length is omitted, and only
|
||||
* "short records".</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.Utils;
|
||||
public final class NDEFRecord {
|
||||
|
||||
private static var SUPPORTED_HEADER_MASK:int = 0x3F; // 0 0 1 1 1 111 (the bottom 6 bits matter)
|
||||
private static var SUPPORTED_HEADER:int = 0x11; // 0 0 0 1 0 001
|
||||
|
||||
public static var TEXT_WELL_KNOWN_TYPE:String = "T";
|
||||
public static var URI_WELL_KNOWN_TYPE:String = "U";
|
||||
public static var SMART_POSTER_WELL_KNOWN_TYPE:String = "Sp";
|
||||
public static var ACTION_WELL_KNOWN_TYPE:String = "act";
|
||||
|
||||
private var header:int;
|
||||
private var type:String;
|
||||
private var payload:Array;
|
||||
private var totalRecordLength:int;
|
||||
|
||||
public function NDEFRecord(header:int, type:String, payload:Array, totalRecordLength:int) {
|
||||
this.header = header;
|
||||
this.type = type;
|
||||
this.payload = payload;
|
||||
this.totalRecordLength = totalRecordLength;
|
||||
}
|
||||
|
||||
public static function readRecord(bytes:Array, offset:int):NDEFRecord {
|
||||
var header:int = bytes[offset] & 0xFF;
|
||||
// Does header match what we support in the bits we care about?
|
||||
// XOR figures out where we differ, and if any of those are in the mask, fail
|
||||
if (((header ^ SUPPORTED_HEADER) & SUPPORTED_HEADER_MASK) != 0) {
|
||||
return null;
|
||||
}
|
||||
var typeLength:int = bytes[offset + 1] & 0xFF;
|
||||
|
||||
var payloadLength:int = bytes[offset + 2] & 0xFF;
|
||||
|
||||
var type:String = AbstractNDEFResultParser.bytesToString(bytes, offset + 3, typeLength, "US-ASCII");
|
||||
|
||||
var payload:Array = new Array(payloadLength);
|
||||
Utils.arraycopy(bytes, offset + 3 + typeLength, payload, 0, payloadLength);
|
||||
|
||||
return new NDEFRecord(header, type, payload, 3 + typeLength + payloadLength);
|
||||
}
|
||||
|
||||
public function isMessageBegin():Boolean {
|
||||
return (header & 0x80) != 0;
|
||||
}
|
||||
|
||||
public function isMessageEnd():Boolean {
|
||||
return (header & 0x40) != 0;
|
||||
}
|
||||
|
||||
public function getType():String {
|
||||
return type;
|
||||
}
|
||||
|
||||
public function getPayload():Array {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public function getTotalRecordLength():int {
|
||||
return totalRecordLength;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.client.result.ParsedResultType;
|
||||
import com.google.zxing.client.result.ParsedResult;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class NDEFSmartPosterParsedResult extends ParsedResult
|
||||
{
|
||||
|
||||
public static var ACTION_UNSPECIFIED:int = -1;
|
||||
public static var ACTION_DO:int = 0;
|
||||
public static var ACTION_SAVE:int = 1;
|
||||
public static var ACTION_OPEN:int = 2;
|
||||
|
||||
private var title:String;
|
||||
private var uri:String;
|
||||
private var action:int;
|
||||
|
||||
public function NDEFSmartPosterParsedResult(action:int, uri:String, title:String) {
|
||||
super(ParsedResultType.NDEF_SMART_POSTER);
|
||||
this.action = action;
|
||||
this.uri = uri;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public function getTitle():String {
|
||||
return title;
|
||||
}
|
||||
|
||||
public function getURI():String {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public function getAction():int {
|
||||
return action;
|
||||
}
|
||||
|
||||
public override function getDisplayResult():String {
|
||||
if (title == null) {
|
||||
return uri;
|
||||
} else {
|
||||
return title + '\n' + uri;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
|
||||
/**
|
||||
* <p>Recognizes an NDEF message that encodes information according to the
|
||||
* "Smart Poster Record Type Definition" specification.</p>
|
||||
*
|
||||
* <p>This actually only supports some parts of the Smart Poster format: title,
|
||||
* URI, and action records. Icon records are not supported because the size
|
||||
* of these records are infeasibly large for barcodes. Size and type records
|
||||
* are not supported. Multiple titles are not supported.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class NDEFSmartPosterResultParser extends AbstractNDEFResultParser {
|
||||
|
||||
public static function parse(result:Result):NDEFSmartPosterParsedResult {
|
||||
var bytes:Array = result.getRawBytes();
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
}
|
||||
var headerRecord:NDEFRecord = NDEFRecord.readRecord(bytes, 0);
|
||||
// Yes, header record starts and ends a message
|
||||
if (headerRecord == null || !headerRecord.isMessageBegin() || !headerRecord.isMessageEnd()) {
|
||||
return null;
|
||||
}
|
||||
if (headerRecord.getType() != NDEFRecord.SMART_POSTER_WELL_KNOWN_TYPE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var offset:int = 0;
|
||||
var recordNumber:int = 0;
|
||||
var ndefRecord:NDEFRecord = null;
|
||||
var payload:Array = headerRecord.getPayload();
|
||||
var action:int = NDEFSmartPosterParsedResult.ACTION_UNSPECIFIED;
|
||||
var title:String = null;
|
||||
var uri:String = null;
|
||||
|
||||
while (offset < payload.length && (ndefRecord = NDEFRecord.readRecord(payload, offset)) != null) {
|
||||
if (recordNumber == 0 && !ndefRecord.isMessageBegin()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var type:String = ndefRecord.getType();
|
||||
if (NDEFRecord.TEXT_WELL_KNOWN_TYPE == type) {
|
||||
var languageText:Array = NDEFTextResultParser.decodeTextPayload(ndefRecord.getPayload());
|
||||
title = languageText[1];
|
||||
} else if (NDEFRecord.URI_WELL_KNOWN_TYPE == type) {
|
||||
uri = NDEFURIResultParser.decodeURIPayload(ndefRecord.getPayload());
|
||||
} else if (NDEFRecord.ACTION_WELL_KNOWN_TYPE == type) {
|
||||
action = ndefRecord.getPayload()[0];
|
||||
}
|
||||
recordNumber++;
|
||||
offset += ndefRecord.getTotalRecordLength();
|
||||
}
|
||||
|
||||
if (recordNumber == 0 || (ndefRecord != null && !ndefRecord.isMessageEnd())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new NDEFSmartPosterParsedResult(action, uri, title);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
import com.google.zxing.client.result.TextParsedResult;
|
||||
import com.google.zxing.Result;
|
||||
|
||||
/**
|
||||
* Recognizes an NDEF message that encodes text according to the
|
||||
* "Text Record Type Definition" specification.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class NDEFTextResultParser extends AbstractNDEFResultParser {
|
||||
|
||||
public static function parse(result:Result ):TextParsedResult {
|
||||
var bytes:Array = result.getRawBytes();
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
}
|
||||
var ndefRecord:NDEFRecord = NDEFRecord.readRecord(bytes, 0);
|
||||
if (ndefRecord == null || !ndefRecord.isMessageBegin() || !ndefRecord.isMessageEnd()) {
|
||||
return null;
|
||||
}
|
||||
if (ndefRecord.getType() != NDEFRecord.TEXT_WELL_KNOWN_TYPE) {
|
||||
return null;
|
||||
}
|
||||
var languageText:Array = decodeTextPayload(ndefRecord.getPayload());
|
||||
return new TextParsedResult(languageText[0], languageText[1]);
|
||||
}
|
||||
|
||||
public static function decodeTextPayload(payload:Array):Array {
|
||||
var statusByte:int = payload[0];
|
||||
var isUTF16:Boolean = (statusByte & 0x80) != 0;
|
||||
var languageLength:int = statusByte & 0x1F;
|
||||
// language is always ASCII-encoded:
|
||||
var language:String = bytesToString(payload, 1, languageLength, "US-ASCII");
|
||||
var encoding:String = isUTF16 ? "UTF-16" : "UTF8";
|
||||
var text:String = bytesToString(payload, 1 + languageLength, payload.length - languageLength - 1, encoding);
|
||||
return new [language, text ];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
package com.google.zxing.client.result.optional
|
||||
{
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*/
|
||||
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.result.URIParsedResult;
|
||||
|
||||
/**
|
||||
* Recognizes an NDEF message that encodes a URI according to the
|
||||
* "URI Record Type Definition" specification.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class NDEFURIResultParser extends AbstractNDEFResultParser {
|
||||
|
||||
private static var URI_PREFIXES:Array = [
|
||||
null,
|
||||
"http://www.",
|
||||
"https://www.",
|
||||
"http://",
|
||||
"https://",
|
||||
"tel:",
|
||||
"mailto:",
|
||||
"ftp://anonymous:anonymous@",
|
||||
"ftp://ftp.",
|
||||
"ftps://",
|
||||
"sftp://",
|
||||
"smb://",
|
||||
"nfs://",
|
||||
"ftp://",
|
||||
"dav://",
|
||||
"news:",
|
||||
"telnet://",
|
||||
"imap:",
|
||||
"rtsp://",
|
||||
"urn:",
|
||||
"pop:",
|
||||
"sip:",
|
||||
"sips:",
|
||||
"tftp:",
|
||||
"btspp://",
|
||||
"btl2cap://",
|
||||
"btgoep://",
|
||||
"tcpobex://",
|
||||
"irdaobex://",
|
||||
"file://",
|
||||
"urn:epc:id:",
|
||||
"urn:epc:tag:",
|
||||
"urn:epc:pat:",
|
||||
"urn:epc:raw:",
|
||||
"urn:epc:",
|
||||
"urn:nfc:",
|
||||
];
|
||||
|
||||
public static function parse(result:Result ):URIParsedResult {
|
||||
var bytes:Array = result.getRawBytes();
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
}
|
||||
var ndefRecord:NDEFRecord = NDEFRecord.readRecord(bytes, 0);
|
||||
if (ndefRecord == null || !ndefRecord.isMessageBegin() || !ndefRecord.isMessageEnd()) {
|
||||
return null;
|
||||
}
|
||||
if (ndefRecord.getType() != NDEFRecord.URI_WELL_KNOWN_TYPE) {
|
||||
return null;
|
||||
}
|
||||
var fullURI:String = decodeURIPayload(ndefRecord.getPayload());
|
||||
return new URIParsedResult(fullURI, null);
|
||||
}
|
||||
|
||||
public static function decodeURIPayload(payload:Array):String {
|
||||
var identifierCode:int = payload[0] & 0xFF;
|
||||
var prefix:String = null;
|
||||
if (identifierCode < URI_PREFIXES.length) {
|
||||
prefix = URI_PREFIXES[identifierCode];
|
||||
}
|
||||
var restOfURI:String = bytesToString(payload, 1, payload.length - 1, "UTF8");
|
||||
return prefix == null ? restOfURI : prefix + restOfURI;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,296 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
/**
|
||||
* <p>A simple, fast array of bits, represented compactly by an array of ints internally.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class BitArray
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
// TODO: I have changed these members to be public so ProGuard can inline get() and set(). Ideally
|
||||
// they'd be private and we'd use the -allowaccessmodification flag, but Dalvik rejects the
|
||||
// resulting binary at runtime on Android. If we find a solution to this, these should be changed
|
||||
// back to private.
|
||||
public var bits:Array;
|
||||
public var Size:int;
|
||||
|
||||
public function BitArray(size:int) {
|
||||
if (size < 1) {
|
||||
throw new IllegalArgumentException("common : BitArray : size must be at least 1");
|
||||
}
|
||||
this.Size = size;
|
||||
this.bits = makeArray(size);
|
||||
}
|
||||
|
||||
public function getSize():int {
|
||||
return Size;
|
||||
}
|
||||
|
||||
public function getSizeInBytes():int
|
||||
{
|
||||
return (this.Size + 7) >> 3;
|
||||
}
|
||||
|
||||
|
||||
private function ensureCapacity(size:int):void
|
||||
{
|
||||
if (size > bits.length << 5)
|
||||
{
|
||||
var newArray:Array = new Array(size);
|
||||
if (bits != null)
|
||||
{
|
||||
//System.Array.Copy(bytes, 0, newArray, 0, bytes.length);
|
||||
for (var i:int=0;i<bits.length;i++)
|
||||
{
|
||||
newArray[i] = bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
this.bits = newArray;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i bit to get
|
||||
* @return true iff bit i is set
|
||||
*/
|
||||
public function _get(i:int):Boolean {
|
||||
return (bits[i >> 5] & (1 << (i & 0x1F))) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bit i.
|
||||
*
|
||||
* @param i bit to set
|
||||
*/
|
||||
public function _set(i:int):void {
|
||||
bits[i >> 5] |= 1 << (i & 0x1F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips bit i.
|
||||
*
|
||||
* @param i bit to set
|
||||
*/
|
||||
public function flip(i:int):void {
|
||||
bits[i >> 5] ^= 1 << (i & 0x1F);
|
||||
}
|
||||
/**
|
||||
* Sets a block of 32 bits, starting at bit i.
|
||||
*
|
||||
* @param i first bit to set
|
||||
* @param newBits the new value of the next 32 bits. Note again that the least-significant bit
|
||||
* corresponds to bit i, the next-least-significant to i+1, and so on.
|
||||
*/
|
||||
public function setBulk(i:int, newBits:int):void {
|
||||
bits[i >> 5] = newBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all bits (sets to false).
|
||||
*/
|
||||
public function clear():void {
|
||||
var max:int = bits.length;
|
||||
for (var i:int = 0; i < max; i++) {
|
||||
bits[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Efficient method to check if a range of bits is set, or not set.
|
||||
*
|
||||
* @param start start of range, inclusive.
|
||||
* @param end end of range, exclusive
|
||||
* @param value if true, checks that bits in range are set, otherwise checks that they are not set
|
||||
* @return true iff all bits are set or not set in range, according to value argument
|
||||
* @throws IllegalArgumentException if end is less than or equal to start
|
||||
*/
|
||||
public function isRange(start:int, end:int, value:Boolean):Boolean {
|
||||
if (end < start) {
|
||||
throw new IllegalArgumentException("common : BitArray isRange : end before start");
|
||||
}
|
||||
if (end == start) {
|
||||
return true; // empty range matches
|
||||
}
|
||||
end--; // will be easier to treat this as the last actually set bit -- inclusive
|
||||
var firstInt:int = start >> 5;
|
||||
var lastInt:int = end >> 5;
|
||||
for (var i:int = firstInt; i <= lastInt; i++) {
|
||||
var firstBit:int = i > firstInt ? 0 : start & 0x1F;
|
||||
var lastBit:int = i < lastInt ? 31 : end & 0x1F;
|
||||
var mask:int;
|
||||
if (firstBit == 0 && lastBit == 31) {
|
||||
mask = -1;
|
||||
} else {
|
||||
mask = 0;
|
||||
for (var j:int = firstBit; j <= lastBit; j++) {
|
||||
mask |= 1 << j;
|
||||
}
|
||||
}
|
||||
|
||||
// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
|
||||
// equals the mask, or we're looking for 0s and the masked portion is not all 0s
|
||||
if ((bits[i] & mask) != (value ? mask : 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return underlying array of ints. The first element holds the first 32 bits, and the least
|
||||
* significant bit is bit 0.
|
||||
*/
|
||||
public function getBitArray():Array {
|
||||
return bits;
|
||||
}
|
||||
|
||||
private function setBitArray(a:Array):void {
|
||||
bits = a;
|
||||
}
|
||||
public function setSize(siz:int):void {
|
||||
Size = siz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses all bits in the array.
|
||||
*/
|
||||
public function reverse():void {
|
||||
var newBits:Array = makeArray(Size);
|
||||
var max:int = Size;
|
||||
for (var i:int = 0; i < max; i++) { newBits[i] = 0; }//Flex : makew
|
||||
var size:int = this.Size;
|
||||
for (var ii:int = 0; ii < size; ii++) {
|
||||
if (this._get(size - ii - 1)) {
|
||||
newBits[ii >> 5] |= 1 << (ii & 0x1F);
|
||||
}
|
||||
}
|
||||
bits = newBits;
|
||||
}
|
||||
|
||||
private static function makeArray(size:int):Array {
|
||||
var arraySize:int = size >> 5;
|
||||
if ((size & 0x1F) != 0) {
|
||||
arraySize++;
|
||||
}
|
||||
return new Array(arraySize);
|
||||
}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
var result:StringBuilder = new StringBuilder(this.Size);
|
||||
for (var i:int = 0; i < this.Size; i++)
|
||||
{
|
||||
if ((i & 0x07) == 0)
|
||||
{
|
||||
result.Append(' ');
|
||||
}
|
||||
result.Append(_get(i) ? 'X' : '.');
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
public function appendBit(bit:Boolean):void
|
||||
{
|
||||
this.ensureCapacity(this.Size + 1);
|
||||
if (bit)
|
||||
{
|
||||
this.bits[this.Size >> 5] |= (1 << (this.Size & 0x1F));
|
||||
}
|
||||
this.Size++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the least-significant bits, from value, in order from most-significant to
|
||||
* least-significant. For example, appending 6 bits from 0x000001E will append the bits
|
||||
* 0, 1, 1, 1, 1, 0 in that order.
|
||||
*/
|
||||
public function appendBits(value:int, numBits:int):void {
|
||||
if (numBits < 0 || numBits > 32) {
|
||||
throw new IllegalArgumentException("Num bits must be between 0 and 32");
|
||||
}
|
||||
this.ensureCapacity(this.Size + numBits);
|
||||
for (var numBitsLeft:int = numBits; numBitsLeft > 0; numBitsLeft--) {
|
||||
appendBit(((value >> (numBitsLeft - 1)) & 0x01) == 1);
|
||||
}
|
||||
}
|
||||
|
||||
public function appendBitArray(other:BitArray):void {
|
||||
var otherSize:int = other.getSize();
|
||||
this.ensureCapacity(this.Size + otherSize);
|
||||
for (var i:int = 0; i < otherSize; i++) {
|
||||
appendBit(other._get(i));
|
||||
}
|
||||
}
|
||||
|
||||
public function xor(other:BitArray):void {
|
||||
if (bits.length != other.bits.length) {
|
||||
throw new IllegalArgumentException("Sizes don't match");
|
||||
}
|
||||
for (var i:int = 0; i < bits.length; i++) {
|
||||
// The last byte could be incomplete (i.e. not have 8 bits in
|
||||
// it) but there is no problem since 0 XOR 0 == 0.
|
||||
bits[i] ^= other.bits[i];
|
||||
}
|
||||
}
|
||||
/*
|
||||
private static function makeArray(size:int):Array {
|
||||
return new Array((size + 31) >> 5);
|
||||
}
|
||||
*
|
||||
/*
|
||||
public function toString():String {
|
||||
var result:StringBuffer = new StringBuffer(size);
|
||||
for (var i:int = 0; i < size; i++) {
|
||||
if ((i & 0x07) == 0) {
|
||||
result.append(' ');
|
||||
}
|
||||
result.append(get(i) ? 'X' : '.');
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @param bitOffset first bit to start writing
|
||||
* @param array array to write into. Bytes are written most-significant byte first. This is the opposite
|
||||
* of the internal representation, which is exposed by {@link #getBitArray()}
|
||||
* @param offset position in array to start writing
|
||||
* @param numBytes how many bytes to write
|
||||
*/
|
||||
public function toBytes(bitOffset:int, array:Array, offset:int, numBytes:int):void
|
||||
{
|
||||
for (var i:int = 0; i < numBytes; i++) {
|
||||
var theByte:int = 0;
|
||||
for (var j:int = 0; j < 8; j++) {
|
||||
if (_get(bitOffset)) {
|
||||
theByte |= 1 << (7 - j);
|
||||
}
|
||||
bitOffset++;
|
||||
}
|
||||
array[offset + i] = theByte;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,337 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
/**
|
||||
* <p>Represents a 2D matrix of bits. In function arguments below, and throughout the common
|
||||
* module, x is the column position, and y is the row position. The ordering is always x, y.
|
||||
* The origin is at the top-left.</p>
|
||||
*
|
||||
* <p>Internally the bits are represented in a 1-D array of 32-bit ints. However, each row begins
|
||||
* with a new int. This is done intentionally so that we can copy out a row into a BitArray very
|
||||
* efficiently.</p>
|
||||
*
|
||||
* <p>The ordering of bits is row-major. Within each int, the least significant bits are used first,
|
||||
* meaning they represent lower x values. This is compatible with BitArray's implementation.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public class BitMatrix
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
public var width:int;
|
||||
public var height:int;
|
||||
public var rowSize:int;
|
||||
public var bits:Array;
|
||||
|
||||
|
||||
public function BitMatrix(width:int, o:Object= null)
|
||||
{
|
||||
var height:int;
|
||||
if (o == null)
|
||||
{
|
||||
height = width;
|
||||
}
|
||||
else if (o is int)
|
||||
{
|
||||
height = (o as int);
|
||||
}
|
||||
|
||||
if (width < 1 || height < 1)
|
||||
{
|
||||
throw new IllegalArgumentException("common : BitMatrix : Both dimensions must be greater than 0");
|
||||
}
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.rowSize = (width+31) >> 5;
|
||||
bits = new Array(rowSize * height);
|
||||
// initialize the array
|
||||
for (var i:int=0;i<bits.length;i++) { bits[i] = 0; }
|
||||
|
||||
}
|
||||
/**
|
||||
* <p>Gets the requested bit, where true means black.</p>
|
||||
*
|
||||
* @param x The horizontal component (i.e. which column)
|
||||
* @param y The vertical component (i.e. which row)
|
||||
* @return value of given bit in matrix
|
||||
*/
|
||||
public function _get(x:int, y:int):Boolean {
|
||||
var offset:int = y * rowSize + (x >> 5);
|
||||
return ((bits[offset] >>> (x & 0x1f)) & 1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the given bit to true.</p>
|
||||
*
|
||||
* @param x The horizontal component (i.e. which column)
|
||||
* @param y The vertical component (i.e. which row)
|
||||
*/
|
||||
public function _set(x:int, y:int):void {
|
||||
var offset:int = y * rowSize + (x >> 5);
|
||||
bits[offset] |= 1 << (x & 0x1f);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Flips the given bit.</p>
|
||||
*
|
||||
* @param x The horizontal component (i.e. which column)
|
||||
* @param y The vertical component (i.e. which row)
|
||||
*/
|
||||
public function flip(x:int, y:int):void {
|
||||
var offset:int = y * rowSize + (x >> 5);
|
||||
bits[offset] ^= 1 << (x & 0x1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all bits (sets to false).
|
||||
*/
|
||||
public function clear():void {
|
||||
var max:int = bits.length;
|
||||
for (var i:int = 0; i < max; i++) {
|
||||
bits[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets a square region of the bit matrix to true.</p>
|
||||
*
|
||||
* @param left The horizontal position to begin at (inclusive)
|
||||
* @param top The vertical position to begin at (inclusive)
|
||||
* @param width The width of the region
|
||||
* @param height The height of the region
|
||||
*/
|
||||
public function setRegion(left:int,top:int, width:int, height:int):void {
|
||||
if (top < 0 || left < 0) {
|
||||
throw new IllegalArgumentException("Common : BitMatrix : setRegion : Left and top must be nonnegative");
|
||||
}
|
||||
if (height < 1 || width < 1) {
|
||||
throw new IllegalArgumentException("Common : BitMatrix : setRegion : Height and width must be at least 1");
|
||||
}
|
||||
var right:int = left + width;
|
||||
var bottom:int = top + height;
|
||||
if (bottom > this.height || right > this.width) {
|
||||
throw new IllegalArgumentException("Common : BitMatrix : setRegion : The region must fit inside the matrix");
|
||||
}
|
||||
for (var y:int = top; y < bottom; y++) {
|
||||
var offset:int = y * rowSize;
|
||||
for (var x:int = left; x < right; x++) {
|
||||
bits[offset + (x >> 5)] |= 1 << (x & 0x1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A fast method to retrieve one row of data from the matrix as a BitArray.
|
||||
*
|
||||
* @param y The row to retrieve
|
||||
* @param row An optional caller-allocated BitArray, will be allocated if null or too small
|
||||
* @return The resulting BitArray - this reference should always be used even when passing
|
||||
* your own row
|
||||
*/
|
||||
public function getRow(y:int, row:BitArray ):BitArray {
|
||||
if (row == null || row.getSize() < width) {
|
||||
row = new BitArray(width);
|
||||
}
|
||||
var offset:int = y * rowSize;
|
||||
for (var x:int = 0; x < rowSize; x++) {
|
||||
row.setBulk(x << 5, bits[offset + x]);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
public function getTopLeftOnBit():Array {
|
||||
var bitsOffset:int = 0;
|
||||
while (bitsOffset < bits.length && bits[bitsOffset] == 0) {
|
||||
bitsOffset++;
|
||||
}
|
||||
if (bitsOffset == bits.length) {
|
||||
return null;
|
||||
}
|
||||
var y:int = bitsOffset / rowSize;
|
||||
var x:int = (bitsOffset % rowSize) << 5;
|
||||
|
||||
var theBits:int = bits[bitsOffset];
|
||||
var bit:int = 0;
|
||||
while ((theBits << (31-bit)) == 0) {
|
||||
bit++;
|
||||
}
|
||||
x += bit;
|
||||
return [x, y];
|
||||
}
|
||||
/**
|
||||
* @return The width of the matrix
|
||||
*/
|
||||
public function getWidth():int {
|
||||
return width;
|
||||
}
|
||||
|
||||
public function getBottomRightOnBit():Array {
|
||||
var bitsOffset:int = bits.length - 1;
|
||||
while (bitsOffset >= 0 && bits[bitsOffset] == 0) {
|
||||
bitsOffset--;
|
||||
}
|
||||
if (bitsOffset < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var y:int = bitsOffset / rowSize;
|
||||
var x:int = (bitsOffset % rowSize) << 5;
|
||||
|
||||
var theBits:int = bits[bitsOffset];
|
||||
var bit:int = 31;
|
||||
while ((theBits >>> bit) == 0) {
|
||||
bit--;
|
||||
}
|
||||
x += bit;
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return The height of the matrix
|
||||
*/
|
||||
public function getHeight():int {
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
public function equals(o:Object):Boolean {
|
||||
if (!(o is BitMatrix)) {
|
||||
return false;
|
||||
}
|
||||
var other:BitMatrix = BitMatrix(o);
|
||||
if (width != other.width || height != other.height ||
|
||||
rowSize != other.rowSize || bits.length != other.bits.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i:int = 0; i < bits.length; i++) {
|
||||
if (bits[i] != other.bits[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function hashCode():int {
|
||||
var hash:int = width;
|
||||
hash = 31 * hash + width;
|
||||
hash = 31 * hash + height;
|
||||
hash = 31 * hash + rowSize;
|
||||
for (var i:int = 0; i < bits.length; i++) {
|
||||
hash = 31 * hash + bits[i];
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is useful in detecting the enclosing rectangle of a 'pure' barcode.
|
||||
*
|
||||
* @return {left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white
|
||||
*/
|
||||
public function getEnclosingRectangle():Array
|
||||
{
|
||||
var left:int = this.width;
|
||||
var top:int = this.height;
|
||||
var right:int = -1;
|
||||
var bottom:int = -1;
|
||||
var bit:int;
|
||||
|
||||
for (var y:int = 0; y < this.height; y++) {
|
||||
for (var x32:int = 0; x32 < rowSize; x32++) {
|
||||
var theBits:int = bits[y * rowSize + x32];
|
||||
if (theBits != 0) {
|
||||
if (y < top) {
|
||||
top = y;
|
||||
}
|
||||
if (y > bottom) {
|
||||
bottom = y;
|
||||
}
|
||||
if (x32 * 32 < left) {
|
||||
bit = 0;
|
||||
while ((theBits << (31 - bit)) == 0) {
|
||||
bit++;
|
||||
}
|
||||
if ((x32 * 32 + bit) < left) {
|
||||
left = x32 * 32 + bit;
|
||||
}
|
||||
}
|
||||
if (x32 * 32 + 31 > right) {
|
||||
bit = 31;
|
||||
while ((theBits >>> bit) == 0) {
|
||||
bit--;
|
||||
}
|
||||
if ((x32 * 32 + bit) > right) {
|
||||
right = x32 * 32 + bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var width:int = right - left;
|
||||
var height:int = bottom - top;
|
||||
|
||||
if (width < 0 || height < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [left, top, width, height];
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
var result:StringBuilder = new StringBuilder(height * (width + 1));
|
||||
for (var y:int = 0; y < height; y++) {
|
||||
for (var x:int = 0; x < width; x++) {
|
||||
result.Append(_get(x, y) ? "X " : " ");
|
||||
}
|
||||
result.Append('\n');
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
public function toString2():String {
|
||||
var totalbits:int = 0;
|
||||
var result:StringBuilder = new StringBuilder(height * (width + 1));
|
||||
for (var y:int = 0; y < height; y++) {
|
||||
for (var x:int = 0; x < width; x++) {
|
||||
result.Append(_get(x, y) ? "1" : "0");
|
||||
if (_get(x, y)) { totalbits++;}
|
||||
}
|
||||
}
|
||||
result.Append("\nsize:"+(this.width*this.height));
|
||||
result.Append("\ntotalbits:"+totalbits);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public function fromByteArray(width:int,height:int,arr:Array):void
|
||||
{
|
||||
this.bits = arr;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.rowSize = (width+31) >> 5;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.common
|
||||
{
|
||||
/// <summary> A class which wraps a 2D array of bytes. The default usage is signed. If you want to use it as a
|
||||
/// unsigned container, it's up to you to do byteValue & 0xff at each location.
|
||||
/// *
|
||||
/// JAVAPORT: I'm not happy about the argument ordering throughout the file, as I always like to have
|
||||
/// the horizontal component first, but this is for compatibility with the C++ code. The original
|
||||
/// code was a 2D array of ints, but since it only ever gets assigned -1, 0, and 1, I'm going to use
|
||||
/// less memory and go with bytes.
|
||||
/// *
|
||||
/// </summary>
|
||||
/// <author> dswitkin@google.com (Daniel Switkin)
|
||||
///
|
||||
/// </author>
|
||||
public class BitSource
|
||||
{
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
private var bytes:Array;
|
||||
private var byteOffset:int;
|
||||
private var bitOffset:int;
|
||||
|
||||
/**
|
||||
* @param bytes bytes from which this will read bits. Bits will be read from the first byte first.
|
||||
* Bits are read within a byte from most-significant to least-significant bit.
|
||||
*/
|
||||
public function BitSource( bytes:Array) {
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}.
|
||||
*/
|
||||
public function getByteOffset():int {
|
||||
return byteOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param numBits number of bits to read
|
||||
* @return int representing the bits read. The bits will appear as the least-significant
|
||||
* bits of the int
|
||||
* @throws IllegalArgumentException if numBits isn't in [1,32]
|
||||
*/
|
||||
public function readBits(numBits:int):int
|
||||
{
|
||||
if (numBits < 1 || numBits > 32)
|
||||
{
|
||||
throw new IllegalArgumentException("BitSource : numBits out of range");
|
||||
}
|
||||
|
||||
var result:int = 0;
|
||||
|
||||
// First, read remainder from current byte
|
||||
if (bitOffset > 0) {
|
||||
var bitsLeft:int = 8 - bitOffset;
|
||||
var toRead:int = numBits < bitsLeft ? numBits : bitsLeft;
|
||||
var bitsToNotRead:int = bitsLeft - toRead;
|
||||
var mask:int = (0xFF >> (8 - toRead)) << bitsToNotRead;
|
||||
result = (bytes[byteOffset] & mask) >> bitsToNotRead;
|
||||
numBits -= toRead;
|
||||
bitOffset += toRead;
|
||||
if (bitOffset == 8) {
|
||||
bitOffset = 0;
|
||||
byteOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
// Next read whole bytes
|
||||
if (numBits > 0) {
|
||||
while (numBits >= 8) {
|
||||
result = (result << 8) | (bytes[byteOffset] & 0xFF);
|
||||
byteOffset++;
|
||||
numBits -= 8;
|
||||
}
|
||||
|
||||
// Finally read a partial byte
|
||||
if (numBits > 0) {
|
||||
var bitsToNotRead2:int = 8 - numBits;
|
||||
var mask2:int = (0xFF >> bitsToNotRead2) << bitsToNotRead2;
|
||||
result = (result << numBits) | ((bytes[byteOffset] & mask2) >> bitsToNotRead2);
|
||||
bitOffset += numBits;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of bits that can be read successfully
|
||||
*/
|
||||
public function available():int {
|
||||
var bits:int = 8 * (bytes.length - byteOffset) - bitOffset;
|
||||
return bits;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* Copyright 2008 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.common
|
||||
{
|
||||
/**
|
||||
* A class which wraps a 2D array of bytes. The default usage is signed. If you want to use it as a
|
||||
* unsigned container, it's up to you to do byteValue & 0xff at each location.
|
||||
*
|
||||
* JAVAPORT: The original code was a 2D array of ints, but since it only ever gets assigned
|
||||
* -1, 0, and 1, I'm going to use less memory and go with bytes.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public class ByteMatrix
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.StringBuilder;
|
||||
private var bytes:Array;
|
||||
private var Height:int;
|
||||
private var Width:int;
|
||||
|
||||
|
||||
public function ByteMatrix(height:int, width:int ) {
|
||||
bytes = new Array(height);
|
||||
for (var i:int = 0; i < height; i++) {
|
||||
bytes[i] = new Array(width);
|
||||
}
|
||||
this.Height = height;
|
||||
this.Width = width;
|
||||
}
|
||||
|
||||
public function height():int
|
||||
{
|
||||
return Height;
|
||||
}
|
||||
|
||||
public function width():int
|
||||
{
|
||||
return Width;
|
||||
}
|
||||
|
||||
public function _get(x:int, y:int):int
|
||||
{
|
||||
return bytes[y][x];
|
||||
}
|
||||
|
||||
public function getArray():Array
|
||||
{
|
||||
return bytes;
|
||||
}
|
||||
|
||||
//public function _set(y:int,x:int, value:int)
|
||||
//{
|
||||
// bytes[y][x] = value;
|
||||
//}
|
||||
|
||||
public function _set(x:int, y:int, value:Object ):void
|
||||
{
|
||||
if (value is int)
|
||||
{
|
||||
bytes[y][x] = value as int;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Error('ByteMatrix : _set : unknown type of value');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function clear(value:int):void
|
||||
{
|
||||
for (var y:int = 0; y < Height; ++y)
|
||||
{
|
||||
for (var x:int = 0; x < Width; ++x)
|
||||
{
|
||||
bytes[y][x] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function sum():int
|
||||
{
|
||||
var result:int = 0;
|
||||
for (var y:int = 0; y < Height; ++y)
|
||||
{
|
||||
for (var x:int = 0; x < Width; ++x)
|
||||
{
|
||||
result += bytes[y][x];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
var result:StringBuilder = new StringBuilder();
|
||||
for (var y:int = 0; y < Height; ++y)
|
||||
{
|
||||
for (var x:int = 0; x < Width; ++x)
|
||||
{
|
||||
switch (bytes[y][x])
|
||||
{
|
||||
case 0:
|
||||
result.Append("0");
|
||||
break;
|
||||
case 1:
|
||||
result.Append("1");
|
||||
break;
|
||||
default:
|
||||
result.Append(".");
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.Append('\n');
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
public function toString2():String
|
||||
{
|
||||
var result:StringBuilder = new StringBuilder();
|
||||
for (var y:int = 0; y < Height; ++y)
|
||||
{
|
||||
for (var x:int = 0; x < Width; ++x)
|
||||
{
|
||||
switch (bytes[y][x])
|
||||
{
|
||||
case 0:
|
||||
result.Append("0");
|
||||
break;
|
||||
case 1:
|
||||
result.Append("1");
|
||||
break;
|
||||
default:
|
||||
result.Append("_");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Copyright 2008 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.common
|
||||
{
|
||||
/**
|
||||
* Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1
|
||||
* of ISO 18004.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class CharacterSetECI extends ECI
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.HashTable;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
private static var VALUE_TO_ECI:HashTable;
|
||||
private static var NAME_TO_ECI:HashTable;
|
||||
|
||||
private static function initialize():void {
|
||||
VALUE_TO_ECI = new HashTable(29);
|
||||
NAME_TO_ECI = new HashTable(29);
|
||||
// TODO figure out if these values are even right!
|
||||
addCharacterSet(0, "Cp437");
|
||||
addCharacterSet(1, ["ISO8859_1", "ISO-8859-1"]);
|
||||
addCharacterSet(2, "Cp437");
|
||||
addCharacterSet(3, ["ISO8859_1", "ISO-8859-1"]);
|
||||
addCharacterSet(4, "ISO8859_2");
|
||||
addCharacterSet(5, "ISO8859_3");
|
||||
addCharacterSet(6, "ISO8859_4");
|
||||
addCharacterSet(7, "ISO8859_5");
|
||||
addCharacterSet(8, "ISO8859_6");
|
||||
addCharacterSet(9, "ISO8859_7");
|
||||
addCharacterSet(10, "ISO8859_8");
|
||||
addCharacterSet(11, "ISO8859_9");
|
||||
addCharacterSet(12, "ISO8859_10");
|
||||
addCharacterSet(13, "ISO8859_11");
|
||||
addCharacterSet(15, "ISO8859_13");
|
||||
addCharacterSet(16, "ISO8859_14");
|
||||
addCharacterSet(17, "ISO8859_15");
|
||||
addCharacterSet(18, "ISO8859_16");
|
||||
addCharacterSet(20, ["SJIS", "Shift_JIS"]);
|
||||
}
|
||||
|
||||
private var encodingName:String;
|
||||
|
||||
public function CharacterSetECI(value:int, encodingName:String) {
|
||||
super(value);
|
||||
this.encodingName = encodingName;
|
||||
}
|
||||
|
||||
public function getEncodingName():String {
|
||||
return encodingName;
|
||||
}
|
||||
|
||||
private static function addCharacterSet(value:int, encodingNames:Object):void
|
||||
{
|
||||
var eci:CharacterSetECI;
|
||||
if (encodingNames is String)
|
||||
{
|
||||
eci = new CharacterSetECI(value, encodingNames as String);
|
||||
VALUE_TO_ECI._put(value, eci);
|
||||
NAME_TO_ECI._put(encodingNames as String, eci);
|
||||
}
|
||||
else if (encodingNames is Array)
|
||||
{
|
||||
eci = new CharacterSetECI(value, encodingNames[0]);
|
||||
VALUE_TO_ECI._put(value, eci);
|
||||
for (var i:int = 0; i < encodingNames.length; i++) { NAME_TO_ECI._put(encodingNames[i], eci);}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value character set ECI value
|
||||
* @return {@link CharacterSetECI} representing ECI of given value, or null if it is legal but
|
||||
* unsupported
|
||||
* @throws IllegalArgumentException if ECI value is invalid
|
||||
*/
|
||||
public static function getCharacterSetECIByValue(value:int):CharacterSetECI {
|
||||
if (VALUE_TO_ECI == null)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
if (value < 0 || value >= 900) {
|
||||
throw new IllegalArgumentException("COMMON : CharacterSetECI : getCharacterSetECIByValue : Bad ECI value: " + value);
|
||||
}
|
||||
return VALUE_TO_ECI.getValueByKey(value) as CharacterSetECI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name character set ECI encoding name
|
||||
* @return {@link CharacterSetECI} representing ECI for character encoding, or null if it is legal
|
||||
* but unsupported
|
||||
*/
|
||||
public static function getCharacterSetECIByName(name:String ):CharacterSetECI {
|
||||
if (NAME_TO_ECI == null) {
|
||||
initialize();
|
||||
}
|
||||
return (NAME_TO_ECI.getValueByKey(name) as CharacterSetECI);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
/**
|
||||
* <p>This is basically a substitute for <code>java.util.Collections</code>, which is not
|
||||
* present in MIDP 2.0 / CLDC 1.1.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class Collections
|
||||
{
|
||||
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
|
||||
public function Collections()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts its argument (destructively) using insert sort; in the context of this package
|
||||
* insertion sort is simple and efficient given its relatively small inputs.
|
||||
*
|
||||
* @param vector vector to sort
|
||||
* @param comparator comparator to define sort ordering
|
||||
*/
|
||||
public static function insertionSort( vector:ArrayList, comparator:Comparator ):void
|
||||
{
|
||||
var max:int = vector.Count;
|
||||
for (var i:int = 1; i < max; i++)
|
||||
{
|
||||
var valueA:Object = vector[i];
|
||||
var j:int = i - 1;
|
||||
var valueB:Object;
|
||||
while (j >= 0 && comparator.compare((valueB = vector[j]), valueA) > 0)
|
||||
{
|
||||
vector[j + 1] = valueB;
|
||||
j--;
|
||||
}
|
||||
vector[j + 1] = valueA;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
/**
|
||||
* This is merely a clone of <code>Comparator</code> since it is not available in
|
||||
* CLDC 1.1 / MIDP 2.0.
|
||||
*/
|
||||
public interface Comparator
|
||||
{
|
||||
|
||||
function compare(o1:Object, o2:Object):int;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
import mx.controls.List;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
import com.google.zxing.common.flexdatatypes.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Encapsulates the result of decoding a matrix of bits. This typically
|
||||
* applies to 2D barcode formats. For now it contains the raw bytes obtained,
|
||||
* as well as a String interpretation of those bytes, if applicable.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/ public class DecoderResult
|
||||
{
|
||||
|
||||
private var rawBytes:Array;
|
||||
private var text:String ;
|
||||
private var byteSegments:ArrayList;
|
||||
private var ecLevel:String;
|
||||
|
||||
public function DecoderResult(rawBytes:Array, text:String, byteSegments:ArrayList, ecLevel:String)
|
||||
{
|
||||
if (rawBytes == null && text == null)
|
||||
{
|
||||
throw new IllegalArgumentException("common : DecoderResult : Constructor : rawBytes array contains no data and text == null");
|
||||
}
|
||||
this.rawBytes = rawBytes;
|
||||
this.text = text;
|
||||
this.byteSegments = byteSegments;
|
||||
this.ecLevel = ecLevel
|
||||
}
|
||||
|
||||
public function getRawBytes():Array {
|
||||
return this.rawBytes;
|
||||
}
|
||||
|
||||
public function getText():String {
|
||||
return text;
|
||||
}
|
||||
|
||||
public function getByteSegments():ArrayList
|
||||
{
|
||||
return byteSegments;
|
||||
}
|
||||
|
||||
public function getECLevel():String
|
||||
{
|
||||
return ecLevel;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
|
||||
import com.google.zxing.NotFoundException;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class DefaultGridSampler extends GridSampler
|
||||
{
|
||||
|
||||
|
||||
|
||||
override public function sampleGrid2(image:BitMatrix,
|
||||
dimensionX:int,
|
||||
dimensionY:int,
|
||||
p1ToX:Number,
|
||||
p1ToY:Number,
|
||||
p2ToX:Number, p2ToY:Number,
|
||||
p3ToX:Number, p3ToY:Number,
|
||||
p4ToX:Number, p4ToY:Number,
|
||||
p1FromX:Number, p1FromY:Number,
|
||||
p2FromX:Number, p2FromY:Number,
|
||||
p3FromX:Number, p3FromY:Number,
|
||||
p4FromX:Number, p4FromY:Number):BitMatrix
|
||||
{
|
||||
var transform:PerspectiveTransform = PerspectiveTransform.quadrilateralToQuadrilateral(
|
||||
p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
|
||||
p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
|
||||
return sampleGrid(image, dimensionX, dimensionY, transform);
|
||||
}
|
||||
|
||||
public override function sampleGrid(image:BitMatrix ,
|
||||
dimensionX:int,
|
||||
dimensionY:int,
|
||||
transform:PerspectiveTransform):BitMatrix {
|
||||
if (dimensionX <= 0 || dimensionY <= 0) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
var bits:BitMatrix = new BitMatrix(dimensionX, dimensionY);
|
||||
var points:Array = new Array(dimensionX << 1);
|
||||
for (var y:int = 0; y < dimensionY; y++) {
|
||||
var max:int = points.length;
|
||||
var iValue:Number = Number(y + 0.5);
|
||||
for (var x:int = 0; x < max; x += 2) {
|
||||
points[x] = Number(int(x >> 1) + 0.5);
|
||||
points[x + 1] = iValue;
|
||||
}
|
||||
transform.transformPoints(points);
|
||||
// Quick check to see if points transformed to something inside the image;
|
||||
// sufficient to check the endpoints
|
||||
checkAndNudgePoints(image, points);
|
||||
try {
|
||||
for (x = 0; x < max; x += 2) {
|
||||
if (image._get(int(points[x]), int( points[x + 1]))) {
|
||||
// Black(-ish) pixel
|
||||
bits._set(x >> 1, y);
|
||||
}
|
||||
}
|
||||
} catch (aioobe:Error) {
|
||||
// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
|
||||
// transform gets "twisted" such that it maps a straight line of points to a set of points
|
||||
// whose endpoints are in bounds, but others are not. There is probably some mathematical
|
||||
// way to detect this about the transformation that I don't know yet.
|
||||
// This results in an ugly runtime exception despite our clever checks above -- can't have
|
||||
// that. We could check each point's coordinates but that feels duplicative. We settle for
|
||||
// catching and wrapping ArrayIndexOutOfBoundsException.
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
import com.google.zxing.ResultPoint;
|
||||
|
||||
/**
|
||||
* <p>Encapsulates the result of detecting a barcode in an image. This includes the raw
|
||||
* matrix of black/white pixels corresponding to the barcode, and possibly points of interest
|
||||
* in the image, like the location of finder patterns or corners of the barcode in the image.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class DetectorResult
|
||||
{
|
||||
private var bits:BitMatrix;
|
||||
private var points:Array;
|
||||
|
||||
public function DetectorResult( bits:BitMatrix, points:Array ) {
|
||||
this.bits = bits;
|
||||
this.points = points;
|
||||
|
||||
}
|
||||
|
||||
public function getBits():BitMatrix {
|
||||
return bits;
|
||||
}
|
||||
|
||||
public function getPoints():Array {
|
||||
return points;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright 2008 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.common
|
||||
{
|
||||
/**
|
||||
* Superclass of classes encapsulating types ECIs, according to "Extended Channel Interpretations"
|
||||
* 5.3 of ISO 18004.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class ECI
|
||||
{
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
|
||||
private var value:int;
|
||||
|
||||
public function ECI( value:int) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public function getValue():int {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value ECI value
|
||||
* @return {@link ECI} representing ECI of given value, or null if it is legal but unsupported
|
||||
* @throws IllegalArgumentException if ECI value is invalid
|
||||
*/
|
||||
|
||||
public static function getECIByValue(value:int ):ECI {
|
||||
if (value < 0 || value > 999999) {
|
||||
throw new IllegalArgumentException("Bad ECI value: " + value);
|
||||
}
|
||||
if (value < 900) { // Character set ECIs use 000000 - 000899
|
||||
return CharacterSetECI.getCharacterSetECIByValue(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* 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.common
|
||||
{
|
||||
|
||||
import com.google.zxing.Binarizer;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
import com.google.zxing.ReaderException;
|
||||
|
||||
/**
|
||||
* This Binarizer implementation uses the old ZXing global histogram approach. It is suitable
|
||||
* for low-end mobile devices which don't have enough CPU or memory to use a local thresholding
|
||||
* algorithm. However, because it picks a global black point, it cannot handle difficult shadows
|
||||
* and gradients.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class GlobalHistogramBinarizer extends Binarizer {
|
||||
|
||||
|
||||
private static var LUMINANCE_BITS:int = 5;
|
||||
private static var LUMINANCE_SHIFT:int = 8 - LUMINANCE_BITS;
|
||||
private static var LUMINANCE_BUCKETS:int = 1 << LUMINANCE_BITS;
|
||||
|
||||
private var luminances:Array = null;
|
||||
private var buckets:Array = null;
|
||||
|
||||
public function GlobalHistogramBinarizer(source:LuminanceSource ) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
// Applies simple sharpening to the row data to improve performance of the 1D Readers.
|
||||
public override function getBlackRow(y:int , row:BitArray ):BitArray {
|
||||
|
||||
var source:LuminanceSource = getLuminanceSource();
|
||||
var width:int = source.getWidth();
|
||||
if (row == null || row.getSize() < width) {
|
||||
row = new BitArray(width);
|
||||
} else {
|
||||
row.clear();
|
||||
}
|
||||
|
||||
initArrays(width);
|
||||
var _localLuminances:Array = source.getRow(y, luminances);
|
||||
var localBuckets:Array = buckets;
|
||||
for (var x2:int = 0; x2 < width; x2++)
|
||||
{
|
||||
var pixel:int = _localLuminances[x2] & 0xff;
|
||||
localBuckets[pixel >> LUMINANCE_SHIFT]++;
|
||||
}
|
||||
|
||||
var blackPoint:int = estimateBlackPoint(localBuckets);
|
||||
|
||||
var left:int = _localLuminances[0] & 0xff;
|
||||
var center:int = _localLuminances[1] & 0xff;
|
||||
for (var x:int = 1; x < width - 1; x++)
|
||||
{
|
||||
var right:int = _localLuminances[x + 1] & 0xff;
|
||||
// A simple -1 4 -1 box filter with a weight of 2.
|
||||
var luminance:int = ((center << 2) - left - right) >> 1;
|
||||
if (luminance < blackPoint) {
|
||||
row._set(x);
|
||||
}
|
||||
left = center;
|
||||
center = right;
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
// Does not sharpen the data, as this call is intended to only be used by 2D Readers.
|
||||
public override function getBlackMatrix():BitMatrix
|
||||
{
|
||||
var source:LuminanceSource = getLuminanceSource();
|
||||
var width:int = source.getWidth();
|
||||
var height:int = source.getHeight();
|
||||
var matrix:BitMatrix = new BitMatrix(width, height);
|
||||
|
||||
// Quickly calculates the histogram by sampling four rows from the image. This proved to be
|
||||
// more robust on the blackbox tests than sampling a diagonal as we used to do.
|
||||
initArrays(width);
|
||||
var _localLuminances:Array;
|
||||
var localBuckets:Array = buckets;//assign empty array
|
||||
for (var y2:int = 1; y2 < 5; y2++)
|
||||
{
|
||||
var row:int = int(height * y2 / 5);
|
||||
_localLuminances = source.getRow(row, luminances);
|
||||
var right:int = int((width << 2) / 5);
|
||||
for (var x:int = int(width / 5); x < right; x++)
|
||||
{
|
||||
var pixel:int = _localLuminances[x] & 0xff;
|
||||
var index:int = Math.floor(pixel >> LUMINANCE_SHIFT);
|
||||
localBuckets[index]++;
|
||||
}
|
||||
}
|
||||
|
||||
var blackPoint:int = estimateBlackPoint(localBuckets);
|
||||
|
||||
// We delay reading the entire image luminance until the black point estimation succeeds.
|
||||
// Although we end up reading four rows twice, it is consistent with our motto of
|
||||
// "fail quickly" which is necessary for continuous scanning.
|
||||
_localLuminances = source.getMatrix();
|
||||
for (var y:int = 0; y < height; y++)
|
||||
{
|
||||
var offset:int = y * width;
|
||||
for (var x2:int = 0; x2< width; x2++)
|
||||
{
|
||||
var pixel2:int = _localLuminances[offset + x2] & 0xff;
|
||||
if (pixel2 < blackPoint)
|
||||
{
|
||||
matrix._set(x2, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public override function createBinarizer(source:LuminanceSource):Binarizer {
|
||||
return new GlobalHistogramBinarizer(source);
|
||||
}
|
||||
|
||||
private function initArrays(luminanceSize:int):void {
|
||||
if (luminances == null || luminances.length < luminanceSize)
|
||||
{
|
||||
luminances = new Array(luminanceSize);
|
||||
}
|
||||
for (var i:int=0;i<luminances.length;i++) { luminances[i]=0;}
|
||||
|
||||
if (buckets == null)
|
||||
{
|
||||
buckets = new Array(LUMINANCE_BUCKETS);
|
||||
}
|
||||
for (var j:int=0;j<buckets.length;j++) { buckets[j]=0;}
|
||||
}
|
||||
|
||||
private static function estimateBlackPoint(buckets:Array):int {
|
||||
// Find the tallest peak in the histogram.
|
||||
var numBuckets:int = buckets.length;
|
||||
var maxBucketCount:int = 0;
|
||||
var firstPeak:int = 0;
|
||||
var firstPeakSize:int = 0;
|
||||
for (var x:int = 0; x < numBuckets; x++) {
|
||||
if (buckets[x] > firstPeakSize) {
|
||||
firstPeak = x;
|
||||
firstPeakSize = buckets[x];
|
||||
}
|
||||
if (buckets[x] > maxBucketCount) {
|
||||
maxBucketCount = buckets[x];
|
||||
}
|
||||
}
|
||||
|
||||
// Find the second-tallest peak which is somewhat far from the tallest peak.
|
||||
var secondPeak:int = 0;
|
||||
var secondPeakScore:int = 0;
|
||||
for (var x2:int = 0; x2 < numBuckets; x2++) {
|
||||
var distanceToBiggest:int = x2 - firstPeak;
|
||||
// Encourage more distant second peaks by multiplying by square of distance.
|
||||
var score:int = buckets[x2] * distanceToBiggest * distanceToBiggest;
|
||||
if (score > secondPeakScore) {
|
||||
secondPeak = x2;
|
||||
secondPeakScore = score;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure firstPeak corresponds to the black peak.
|
||||
if (firstPeak > secondPeak) {
|
||||
var temp:int = firstPeak;
|
||||
firstPeak = secondPeak;
|
||||
secondPeak = temp;
|
||||
}
|
||||
|
||||
// If there is too little contrast in the image to pick a meaningful black point, throw rather
|
||||
// than waste time trying to decode the image, and risk false positives.
|
||||
// TODO: It might be worth comparing the brightest and darkest pixels seen, rather than the
|
||||
// two peaks, to determine the contrast.
|
||||
if (secondPeak - firstPeak <= numBuckets >> 4) {
|
||||
throw new ReaderException("GlobalHistogramBinarizer : estimateBlackPoint");
|
||||
}
|
||||
|
||||
// Find a valley between them that is low and closer to the white peak.
|
||||
var bestValley:int = secondPeak - 1;
|
||||
var bestValleyScore:int = -1;
|
||||
for (var x3:int = secondPeak - 1; x3 > firstPeak; x3--) {
|
||||
var fromFirst:int = x3 - firstPeak;
|
||||
var score2:int = fromFirst * fromFirst * (secondPeak - x3) * (maxBucketCount - buckets[x3]);
|
||||
if (score2 > bestValleyScore) {
|
||||
bestValley = x3;
|
||||
bestValleyScore = score2;
|
||||
}
|
||||
}
|
||||
|
||||
return bestValley << LUMINANCE_SHIFT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,237 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
/**
|
||||
* Implementations of this class can, given locations of finder patterns for a QR code in an
|
||||
* image, sample the right points in the image to reconstruct the QR code, accounting for
|
||||
* perspective distortion. It is abstracted since it is relatively expensive and should be allowed
|
||||
* to take advantage of platform-specific optimized implementations, like Sun's Java Advanced
|
||||
* Imaging library, but which may not be available in other environments such as J2ME, and vice
|
||||
* versa.
|
||||
*
|
||||
* The implementation used can be controlled by calling {@link #setGridSampler(GridSampler)}
|
||||
* with an instance of a class which implements this interface.
|
||||
*
|
||||
* @author Sean Owen
|
||||
*
|
||||
*/
|
||||
import com.google.zxing.ReaderException;
|
||||
import com.google.zxing.common.flexdatatypes.IllegalArgumentException;
|
||||
import com.google.zxing.NotFoundException;
|
||||
|
||||
public class GridSampler
|
||||
{
|
||||
|
||||
private static var gridSampler:GridSampler = new GridSampler();
|
||||
|
||||
/**
|
||||
* Sets the implementation of {@link GridSampler} used by the library. One global
|
||||
* instance is stored, which may sound problematic. But, the implementation provided
|
||||
* ought to be appropriate for the entire platform, and all uses of this library
|
||||
* in the whole lifetime of the JVM. For instance, an Android activity can swap in
|
||||
* an implementation that takes advantage of native platform libraries.
|
||||
*
|
||||
* @param newGridSampler The platform-specific object to install.
|
||||
*/
|
||||
public static function setGridSampler(newGridSampler:GridSampler):void {
|
||||
if (newGridSampler == null) {
|
||||
throw new IllegalArgumentException("common : GridSampler : setGridSampler");;
|
||||
}
|
||||
gridSampler = newGridSampler;
|
||||
}
|
||||
/**
|
||||
* @return the current implementation of {@link GridSampler}
|
||||
*/
|
||||
|
||||
|
||||
public static function getGridSamplerInstance():GridSampler
|
||||
{
|
||||
return gridSampler;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Samples an image for a square matrix of bits of the given dimension. This is used to extract
|
||||
* the black/white modules of a 2D barcode like a QR Code found in an image. Because this barcode
|
||||
* may be rotated or perspective-distorted, the caller supplies four points in the source image
|
||||
* that define known points in the barcode, so that the image may be sampled appropriately.</p>
|
||||
*
|
||||
* <p>The last eight "from" parameters are four X/Y coordinate pairs of locations of points in
|
||||
* the image that define some significant points in the image to be sample. For example,
|
||||
* these may be the location of finder pattern in a QR Code.</p>
|
||||
*
|
||||
* <p>The first eight "to" parameters are four X/Y coordinate pairs measured in the destination
|
||||
* {@link BitMatrix}, from the top left, where the known points in the image given by the "from"
|
||||
* parameters map to.</p>
|
||||
*
|
||||
* <p>These 16 parameters define the transformation needed to sample the image.</p>
|
||||
*
|
||||
* @param image image to sample
|
||||
* @param dimension width/height of {@link BitMatrix} to sample from iamge
|
||||
* @return {@link BitMatrix} representing a grid of points sampled from the image within a region
|
||||
* defined by the "from" parameters
|
||||
* @throws ReaderException if image can't be sampled, for example, if the transformation defined
|
||||
* by the given points is invalid or results in sampling outside the image boundaries
|
||||
*/
|
||||
|
||||
public function sampleGrid(image:BitMatrix ,
|
||||
dimensionX:int,
|
||||
dimensionY:int,
|
||||
transform:PerspectiveTransform):BitMatrix
|
||||
{
|
||||
// originally in DefaultGridSampler
|
||||
if (dimensionX <= 0 || dimensionY <= 0) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
var bits:BitMatrix = new BitMatrix(dimensionX, dimensionY);
|
||||
var points:Array = new Array(dimensionX << 1);
|
||||
for (var y:int = 0; y < dimensionY; y++) {
|
||||
var max:int = points.length;
|
||||
var iValue:Number = Number(y + 0.5);
|
||||
for (var x:int = 0; x < max; x += 2) {
|
||||
points[x] = Number((x >> 1) + 0.5);
|
||||
points[x + 1] = iValue;
|
||||
}
|
||||
transform.transformPoints(points);
|
||||
// Quick check to see if points transformed to something inside the image;
|
||||
// sufficient to check the endpoints
|
||||
checkAndNudgePoints(image, points);
|
||||
try {
|
||||
for (x = 0; x < max; x += 2) {
|
||||
if (image._get(int(points[x]), int( points[x + 1]))) {
|
||||
// Black(-ish) pixel
|
||||
bits._set(x >> 1, y);
|
||||
}
|
||||
}
|
||||
} catch (aioobe:RangeError) {
|
||||
// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
|
||||
// transform gets "twisted" such that it maps a straight line of points to a set of points
|
||||
// whose endpoints are in bounds, but others are not. There is probably some mathematical
|
||||
// way to detect this about the transformation that I don't know yet.
|
||||
// This results in an ugly runtime exception despite our clever checks above -- can't have
|
||||
// that. We could check each point's coordinates but that feels duplicative. We settle for
|
||||
// catching and wrapping ArrayIndexOutOfBoundsException.
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
public function sampleGrid2(image:BitMatrix,
|
||||
dimensionX:int,
|
||||
dimensionY:int,
|
||||
p1ToX:Number,
|
||||
p1ToY:Number,
|
||||
p2ToX:Number, p2ToY:Number,
|
||||
p3ToX:Number, p3ToY:Number,
|
||||
p4ToX:Number, p4ToY:Number,
|
||||
p1FromX:Number, p1FromY:Number,
|
||||
p2FromX:Number, p2FromY:Number,
|
||||
p3FromX:Number, p3FromY:Number,
|
||||
p4FromX:Number, p4FromY:Number):BitMatrix
|
||||
{
|
||||
var transform:PerspectiveTransform = PerspectiveTransform.quadrilateralToQuadrilateral(
|
||||
p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
|
||||
p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
|
||||
return sampleGrid(image, dimensionX, dimensionY, transform);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks a set of points that have been transformed to sample points on an image against
|
||||
* the image's dimensions to see if the point are even within the image.</p>
|
||||
*
|
||||
* <p>This method will actually "nudge" the endpoints back onto the image if they are found to be
|
||||
* barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder
|
||||
* patterns in an image where the QR Code runs all the way to the image border.</p>
|
||||
*
|
||||
* <p>For efficiency, the method will check points from either end of the line until one is found
|
||||
* to be within the image. Because the set of points are assumed to be linear, this is valid.</p>
|
||||
*
|
||||
* @param image image into which the points should map
|
||||
* @param points actual points in x1,y1,...,xn,yn form
|
||||
* @throws ReaderException if an endpoint is lies outside the image boundaries
|
||||
*/
|
||||
public static function checkAndNudgePoints(image:BitMatrix, points:Array):void
|
||||
{
|
||||
var width:int = image.getWidth();
|
||||
var height:int = image.getHeight();
|
||||
// Check and nudge points from start until we see some that are OK:
|
||||
var nudged:Boolean = true;
|
||||
for (var offset:int = 0; offset < points.length && nudged; offset += 2)
|
||||
{
|
||||
var x:int = int(points[offset]);
|
||||
var y:int = int(points[offset + 1]);
|
||||
if (x < -1 || x > width || y < -1 || y > height)
|
||||
{
|
||||
throw new ReaderException("common : GridSampler : checkAndNudgePoints : point out of range ("+x+""+y+") max:"+width+" - "+height);
|
||||
}
|
||||
nudged = false;
|
||||
if (x == -1)
|
||||
{
|
||||
points[offset] = 0;
|
||||
nudged = true;
|
||||
}
|
||||
else if (x == width)
|
||||
{
|
||||
points[offset] = width - 1;
|
||||
nudged = true;
|
||||
}
|
||||
if (y == -1)
|
||||
{
|
||||
points[offset + 1] = 0;
|
||||
nudged = true;
|
||||
}
|
||||
else if (y == height)
|
||||
{
|
||||
points[offset + 1] = height - 1;
|
||||
nudged = true;
|
||||
}
|
||||
}
|
||||
// Check and nudge points from end:
|
||||
nudged = true;
|
||||
for (var offset1:int = points.length - 2; offset >= 0 && nudged; offset -= 2)
|
||||
{
|
||||
var x1:int = int(points[offset1]);
|
||||
var y1:int = int(points[offset1 + 1]);
|
||||
if (x1 < -1 || x1 > width || y1 < -1 || y1 > height)
|
||||
{
|
||||
throw new ReaderException("common : GridSampler : checkAndNudgePoints : out of bounds");
|
||||
}
|
||||
nudged = false;
|
||||
if (x1 == -1)
|
||||
{
|
||||
points[offset1] = 0;
|
||||
nudged = true;
|
||||
}
|
||||
else if (x1 == width)
|
||||
{
|
||||
points[offset1] = width - 1;
|
||||
nudged = true;
|
||||
}
|
||||
if (y1 == -1)
|
||||
{
|
||||
points[offset1 + 1] = 0;
|
||||
nudged = true;
|
||||
}
|
||||
else if (y1 == height)
|
||||
{
|
||||
points[offset1 + 1] = height - 1;
|
||||
nudged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
* 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.common
|
||||
{
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements a local thresholding algorithm, which while slower than the
|
||||
* GlobalHistogramBinarizer, is fairly efficient for what it does. It is designed for
|
||||
* high frequency images of barcodes with black data on white backgrounds. For this application,
|
||||
* it does a much better job than a global blackpoint with severe shadows and gradients.
|
||||
* However it tends to produce artifacts on lower frequency images and is therefore not
|
||||
* a good general purpose binarizer for uses outside ZXing.
|
||||
*
|
||||
* NOTE: This class is still experimental and may not be ready for prime time yet.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
import com.google.zxing.Binarizer;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
|
||||
public class HybridBinarizer extends GlobalHistogramBinarizer {
|
||||
|
||||
// This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.
|
||||
// So this is the smallest dimension in each axis we can accept.
|
||||
private static var MINIMUM_DIMENSION:int = 40;
|
||||
private var matrix:BitMatrix = null;
|
||||
|
||||
public function HybridBinarizer(source:LuminanceSource) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
public override function getBlackMatrix():BitMatrix
|
||||
{
|
||||
binarizeEntireImage();
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public override function createBinarizer(source:LuminanceSource):Binarizer
|
||||
{
|
||||
return new HybridBinarizer(source);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the final BitMatrix once for all requests. This could be called once from the
|
||||
// constructor instead, but there are some advantages to doing it lazily, such as making
|
||||
// profiling easier, and not doing heavy lifting when callers don't expect it.
|
||||
private function binarizeEntireImage():void {
|
||||
if (matrix == null) {
|
||||
var source:LuminanceSource = getLuminanceSource();
|
||||
if (source.getWidth() >= MINIMUM_DIMENSION && source.getHeight() >= MINIMUM_DIMENSION)
|
||||
{
|
||||
var luminances:Array = source.getMatrix();
|
||||
var width:int = source.getWidth();
|
||||
var height:int = source.getHeight();
|
||||
var subWidth:int = width >> 3;
|
||||
if ((width & 0x07) != 0) {
|
||||
subWidth++;
|
||||
}
|
||||
var subHeight:int = height >> 3;
|
||||
if ((height & 0x07) != 0) {
|
||||
subHeight++;
|
||||
}
|
||||
var blackPoints:Array = calculateBlackPoints(luminances, subWidth, subHeight, width, height);
|
||||
|
||||
matrix = new BitMatrix(width, height);
|
||||
calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, matrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the image is too small, fall back to the global histogram approach.
|
||||
matrix = super.getBlackMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For each 8x8 block in the image, calculate the average black point using a 5x5 grid
|
||||
// of the blocks around it. Also handles the corner cases, but will ignore up to 7 pixels
|
||||
// on the right edge and 7 pixels at the bottom of the image if the overall dimsions are not
|
||||
// multiples of eight. In practice, leaving those pixels white does not seem to be a problem.
|
||||
private static function calculateThresholdForBlock(luminances:Array , subWidth:int , subHeight:int ,
|
||||
width:int, height:int , blackPoints:Array , matrix:BitMatrix ):void {
|
||||
for (var y:int = 0; y < subHeight; y++) {
|
||||
var yoffset:int = y << 3;
|
||||
if ((yoffset + 8) >= height) {
|
||||
yoffset = height - 8;
|
||||
}
|
||||
for (var x:int = 0; x < subWidth; x++) {
|
||||
var xoffset:int = x << 3;
|
||||
if ((xoffset + 8) >= width) {
|
||||
xoffset = width - 8;
|
||||
}
|
||||
var left:int = x > 1 ? x : 2;
|
||||
left = left < subWidth - 2 ? left : subWidth - 3;
|
||||
var top:int = y > 1 ? y : 2;
|
||||
top = top < subHeight - 2 ? top : subHeight - 3;
|
||||
var sum:int = 0;
|
||||
for (var z:int = -2; z <= 2; z++) {
|
||||
var blackRow:Array = blackPoints[top + z];
|
||||
sum += blackRow[left - 2];
|
||||
sum += blackRow[left - 1];
|
||||
sum += blackRow[left];
|
||||
sum += blackRow[left + 1];
|
||||
sum += blackRow[left + 2];
|
||||
}
|
||||
var average:int = int(sum / 25);
|
||||
threshold8x8Block(luminances, xoffset, yoffset, average, width, matrix);
|
||||
}
|
||||
} }
|
||||
|
||||
// Applies a single threshold to an 8x8 block of pixels.
|
||||
private static function threshold8x8Block(luminances:Array , xoffset:int , yoffset:int , threshold:int ,
|
||||
stride:int , matrix:BitMatrix ):void {
|
||||
for (var y:int = 0; y < 8; y++) {
|
||||
var offset:int = (yoffset + y) * stride + xoffset;
|
||||
for (var x:int = 0; x < 8; x++) {
|
||||
var pixel:int = luminances[offset + x] & 0xff;
|
||||
if (pixel < threshold) {
|
||||
matrix._set(xoffset + x, yoffset + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates a single black point for each 8x8 block of pixels and saves it away.
|
||||
private static function calculateBlackPoints(luminances:Array, subWidth:int, subHeight:int,
|
||||
width:int, height:int):Array {
|
||||
var blackPoints:Array = new Array(subHeight);
|
||||
for(var i:int=0;i<blackPoints.length;i++) { blackPoints[i]=new Array(subWidth);for(var j:int=0;j<subWidth;j++){blackPoints[i][j]=0; }}
|
||||
for (var y:int = 0; y < subHeight; y++) {
|
||||
var yoffset:int = y << 3;
|
||||
if ((yoffset + 8) >= height) {
|
||||
yoffset = height - 8;
|
||||
}
|
||||
for (var x:int = 0; x < subWidth; x++) {
|
||||
var xoffset:int = x << 3;
|
||||
if ((xoffset + 8) >= width) {
|
||||
xoffset = width - 8;
|
||||
}
|
||||
var sum:int = 0;
|
||||
var min:int = 255;
|
||||
var max:int = 0;
|
||||
for (var yy:int = 0; yy < 8; yy++) {
|
||||
var offset:int = (yoffset + yy) * width + xoffset;
|
||||
for (var xx:int = 0; xx < 8; xx++) {
|
||||
var pixel:int = luminances[offset + xx] & 0xff;
|
||||
sum += pixel;
|
||||
if (pixel < min) {
|
||||
min = pixel;
|
||||
}
|
||||
if (pixel > max) {
|
||||
max = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the contrast is inadequate, use half the minimum, so that this block will be
|
||||
// treated as part of the white background, but won't drag down neighboring blocks
|
||||
// too much.
|
||||
var average:int;
|
||||
if (max - min > 24) {
|
||||
average = sum >> 6;
|
||||
} else {
|
||||
// When min == max == 0, let average be 1 so all is black
|
||||
average = max == 0 ? 1 : min >> 1;
|
||||
}
|
||||
blackPoints[y][x] = average;
|
||||
}
|
||||
}
|
||||
return blackPoints;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* 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.common
|
||||
{
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements a local thresholding algorithm, which while slower than the
|
||||
* GlobalHistogramBinarizer, is fairly efficient for what it does. It is designed for
|
||||
* high frequency images of barcodes with black data on white backgrounds. For this application,
|
||||
* it does a much better job than a global blackpoint with severe shadows and gradients.
|
||||
* However it tends to produce artifacts on lower frequency images and is therefore not
|
||||
* a good general purpose binarizer for uses outside ZXing.
|
||||
*
|
||||
* NOTE: This class is still experimental and may not be ready for prime time yet.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
import com.google.zxing.Binarizer;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
|
||||
public final class LocalBlockBinarizer extends Binarizer {
|
||||
|
||||
|
||||
private var matrix:BitMatrix = null;
|
||||
|
||||
public function LocalBlockBinarizer(source:LuminanceSource) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
// TODO: Consider a different strategy for 1D Readers.
|
||||
public override function getBlackRow(y:int , row:BitArray ):BitArray {
|
||||
binarizeEntireImage();
|
||||
return matrix.getRow(y, row);
|
||||
}
|
||||
|
||||
// TODO: If getBlackRow() calculates its own values, removing sharpening here.
|
||||
public override function getBlackMatrix():BitMatrix {
|
||||
binarizeEntireImage();
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public override function createBinarizer(source:LuminanceSource ):Binarizer {
|
||||
return new LocalBlockBinarizer(source);
|
||||
}
|
||||
|
||||
// Calculates the final BitMatrix once for all requests. This could be called once from the
|
||||
// constructor instead, but there are some advantages to doing it lazily, such as making
|
||||
// profiling easier, and not doing heavy lifting when callers don't expect it.
|
||||
private function binarizeEntireImage():void {
|
||||
if (matrix == null) {
|
||||
var source:LuminanceSource = getLuminanceSource();
|
||||
var luminances:Array = source.getMatrix();
|
||||
var width:int = source.getWidth();
|
||||
var height:int = source.getHeight();
|
||||
sharpenRow(luminances, width, height);
|
||||
|
||||
var subWidth:int = width >> 3;
|
||||
var subHeight:int = height >> 3;
|
||||
var blackPoints:Array = calculateBlackPoints(luminances, subWidth, subHeight, width);
|
||||
|
||||
matrix = new BitMatrix(width, height);
|
||||
calculateThresholdForBlock(luminances, subWidth, subHeight, width, blackPoints, matrix);
|
||||
}
|
||||
}
|
||||
|
||||
// For each 8x8 block in the image, calculate the average black point using a 5x5 grid
|
||||
// of the blocks around it. Also handles the corner cases, but will ignore up to 7 pixels
|
||||
// on the right edge and 7 pixels at the bottom of the image if the overall dimsions are not
|
||||
// multiples of eight. In practice, leaving those pixels white does not seem to be a problem.
|
||||
private static function calculateThresholdForBlock(luminances:Array , subWidth:int , subHeight:int ,
|
||||
stride:int , blackPoints:Array , matrix:BitMatrix ):void {
|
||||
for (var y:int = 0; y < subHeight; y++) {
|
||||
for (var x:int = 0; x < subWidth; x++) {
|
||||
var left:int = (x > 1) ? x : 2;
|
||||
left = (left < subWidth - 2) ? left : subWidth - 3;
|
||||
var top:int = (y > 1) ? y : 2;
|
||||
top = (top < subHeight - 2) ? top : subHeight - 3;
|
||||
var sum:int = 0;
|
||||
for (var z:int = -2; z <= 2; z++) {
|
||||
sum += blackPoints[top + z][left - 2];
|
||||
sum += blackPoints[top + z][left - 1];
|
||||
sum += blackPoints[top + z][left];
|
||||
sum += blackPoints[top + z][left + 1];
|
||||
sum += blackPoints[top + z][left + 2];
|
||||
}
|
||||
var average:int = sum / 25;
|
||||
threshold8x8Block(luminances, x << 3, y << 3, average, stride, matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Applies a single threshold to an 8x8 block of pixels.
|
||||
private static function threshold8x8Block(luminances:Array , xoffset:int , yoffset:int , threshold:int ,
|
||||
stride:int , matrix:BitMatrix ):void {
|
||||
for (var y:int = 0; y < 8; y++) {
|
||||
var offset:int = (yoffset + y) * stride + xoffset;
|
||||
for (var x:int = 0; x < 8; x++) {
|
||||
var pixel:int = luminances[offset + x] & 0xff;
|
||||
if (pixel < threshold) {
|
||||
matrix._set(xoffset + x, yoffset + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates a single black point for each 8x8 block of pixels and saves it away.
|
||||
private static function calculateBlackPoints(luminances:Array, subWidth:int, subHeight:int,
|
||||
stride:int):Array {
|
||||
//int[][] blackPoints = new int[subHeight][subWidth];
|
||||
var blackPoints:Array = new Array();
|
||||
for (var y:int = 0; y < subHeight; y++) {
|
||||
for (var x:int = 0; x < subWidth; x++) {
|
||||
var sum:int = 0;
|
||||
var min:int = 255;
|
||||
var max:int = 0;
|
||||
for (var yy:int = 0; yy < 8; yy++) {
|
||||
var offset:int = ((y << 3) + yy) * stride + (x << 3);
|
||||
for (var xx:int = 0; xx < 8; xx++) {
|
||||
var pixel:int = luminances[offset + xx] & 0xff;
|
||||
sum += pixel;
|
||||
if (pixel < min) {
|
||||
min = pixel;
|
||||
}
|
||||
if (pixel > max) {
|
||||
max = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the contrast is inadequate, use half the minimum, so that this block will be
|
||||
// treated as part of the white background, but won't drag down neighboring blocks
|
||||
// too much.
|
||||
var average:int = (max - min > 24) ? (sum >> 6) : (min >> 1);
|
||||
blackPoints[y][x] = average;
|
||||
}
|
||||
}
|
||||
return blackPoints;
|
||||
}
|
||||
|
||||
// Applies a simple -1 4 -1 box filter with a weight of 2 to each row.
|
||||
private static function sharpenRow(luminances:Array, width:int, height:int):void {
|
||||
for (var y:int = 0; y < height; y++) {
|
||||
var offset:int = y * width;
|
||||
var left:int = luminances[offset] & 0xff;
|
||||
var center:int = luminances[offset + 1] & 0xff;
|
||||
for (var x:int = 1; x < width - 1; x++) {
|
||||
var right:int = luminances[offset + x + 1] & 0xff;
|
||||
var pixel:int = ((center << 2) - left - right) >> 1;
|
||||
// Must clamp values to 0..255 so they will fit in a byte.
|
||||
if (pixel > 255) {
|
||||
pixel = 255;
|
||||
} else if (pixel < 0) {
|
||||
pixel = 0;
|
||||
}
|
||||
luminances[offset + x] = pixel;
|
||||
left = center;
|
||||
center = right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 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.common
|
||||
{
|
||||
/**
|
||||
* <p>This class implements a perspective transform in two dimensions. Given four source and four
|
||||
* destination points, it will compute the transformation implied between them. The code is based
|
||||
* directly upon section 3.4.2 of George Wolberg's "Digital Image Warping"; see pages 54-56.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public class PerspectiveTransform
|
||||
{
|
||||
private var a11:Number;
|
||||
private var a12:Number;
|
||||
private var a13:Number;
|
||||
private var a21:Number;
|
||||
private var a22:Number;
|
||||
private var a23:Number;
|
||||
private var a31:Number;
|
||||
private var a32:Number;
|
||||
private var a33:Number;
|
||||
|
||||
public function PerspectiveTransform( a11:Number, a21:Number,a31:Number, a12:Number, a22:Number, a32:Number, a13:Number, a23:Number, a33:Number)
|
||||
{
|
||||
this.a11 = a11;
|
||||
this.a12 = a12;
|
||||
this.a13 = a13;
|
||||
this.a21 = a21;
|
||||
this.a22 = a22;
|
||||
this.a23 = a23;
|
||||
this.a31 = a31;
|
||||
this.a32 = a32;
|
||||
this.a33 = a33;
|
||||
}
|
||||
|
||||
public static function quadrilateralToQuadrilateral(x0:Number,y0:Number,x1:Number,y1:Number,x2:Number,y2:Number,x3:Number,y3:Number,x0p:Number,y0p:Number,x1p:Number,y1p:Number,x2p:Number, y2p:Number,x3p:Number,y3p:Number):PerspectiveTransform
|
||||
{
|
||||
|
||||
var qToS:PerspectiveTransform = quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);
|
||||
var sToQ:PerspectiveTransform = squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);
|
||||
return sToQ.times(qToS);
|
||||
}
|
||||
public function transformPoints(points:Array):Array
|
||||
{
|
||||
var max:int = points.length;
|
||||
var a11:Number = this.a11;
|
||||
var a12:Number = this.a12;
|
||||
var a13:Number = this.a13;
|
||||
var a21:Number = this.a21;
|
||||
var a22:Number = this.a22;
|
||||
var a23:Number = this.a23;
|
||||
var a31:Number = this.a31;
|
||||
var a32:Number = this.a32;
|
||||
var a33:Number = this.a33;
|
||||
for (var i:int = 0; i < max; i += 2)
|
||||
{
|
||||
var x:Number = points[i];
|
||||
var y:Number = points[i + 1];
|
||||
var denominator:Number = a13 * x + a23 * y + a33;
|
||||
points[i] = (a11 * x + a21 * y + a31) / denominator;
|
||||
points[i + 1] = (a12 * x + a22 * y + a32) / denominator;
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
public static function squareToQuadrilateral(x0:Number,y0:Number,x1:Number,y1:Number,x2:Number,y2:Number,x3:Number,y3:Number):PerspectiveTransform
|
||||
{
|
||||
var dy2:Number = y3 - y2;
|
||||
var dy3:Number = y0 - y1 + y2 - y3;
|
||||
if (dy2 == 0 && dy3 == 0)
|
||||
{
|
||||
return new PerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
var dx1:Number = x1 - x2;
|
||||
var dx2:Number = x3 - x2;
|
||||
var dx3:Number = x0 - x1 + x2 - x3;
|
||||
var dy1:Number = y1 - y2;
|
||||
var denominator:Number = dx1 * dy2 - dx2 * dy1;
|
||||
var a13:Number = (dx3 * dy2 - dx2 * dy3) / denominator;
|
||||
var a23:Number = (dx1 * dy3 - dx3 * dy1) / denominator;
|
||||
return new PerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0, a13, a23, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static function quadrilateralToSquare(x0:Number,y0:Number,x1:Number,y1:Number,x2:Number,y2:Number,x3:Number,y3:Number):PerspectiveTransform
|
||||
{
|
||||
// Here, the adjoint serves as the inverse:
|
||||
return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();
|
||||
}
|
||||
|
||||
public function buildAdjoint():PerspectiveTransform
|
||||
{
|
||||
// Adjoint is the transpose of the cofactor matrix:
|
||||
return new PerspectiveTransform(a22 * a33 - a23 * a32,
|
||||
a23 * a31 - a21 * a33,
|
||||
a21 * a32 - a22 * a31,
|
||||
a13 * a32 - a12 * a33,
|
||||
a11 * a33 - a13 * a31,
|
||||
a12 * a31 - a11 * a32,
|
||||
a12 * a23 - a13 * a22,
|
||||
a13 * a21 - a11 * a23,
|
||||
a11 * a22 - a12 * a21);
|
||||
}
|
||||
|
||||
private function times(other:PerspectiveTransform ):PerspectiveTransform
|
||||
{
|
||||
return new PerspectiveTransform(a11 * other.a11 + a21 * other.a12 + a31 * other.a13,
|
||||
a11 * other.a21 + a21 * other.a22 + a31 * other.a23,
|
||||
a11 * other.a31 + a21 * other.a32 + a31 * other.a33,
|
||||
a12 * other.a11 + a22 * other.a12 + a32 * other.a13,
|
||||
a12 * other.a21 + a22 * other.a22 + a32 * other.a23,
|
||||
a12 * other.a31 + a22 * other.a32 + a32 * other.a33,
|
||||
a13 * other.a11 + a23 * other.a12 + a33 * other.a13,
|
||||
a13 * other.a21 + a23 * other.a22 + a33 * other.a23,
|
||||
a13 * other.a31 + a23 * other.a32 + a33 * other.a33);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,217 +0,0 @@
|
|||
/*
|
||||
* 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.common.detector
|
||||
{
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.ReaderException;
|
||||
|
||||
/**
|
||||
* <p>A somewhat generic detector that looks for a barcode-like rectangular region within an image.
|
||||
* It looks within a mostly white region of an image for a region of black and white, but mostly
|
||||
* black. It returns the four corners of the region, as best it can determine.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class MonochromeRectangleDetector
|
||||
{
|
||||
|
||||
private static var MAX_MODULES:int = 32;
|
||||
|
||||
private var image:BitMatrix;
|
||||
|
||||
public function MonochromeRectangleDetector(image:BitMatrix)
|
||||
{
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Detects a rectangular region of black and white -- mostly black -- with a region of mostly
|
||||
* white, in an image.</p>
|
||||
*
|
||||
* @return {@link ResultPoint}[] describing the corners of the rectangular region. The first and
|
||||
* last points are opposed on the diagonal, as are the second and third. The first point will be
|
||||
* the topmost point and the last, the bottommost. The second point will be leftmost and the
|
||||
* third, the rightmost
|
||||
* @throws ReaderException if no Data Matrix Code can be found
|
||||
*/
|
||||
public function detect():Array
|
||||
{
|
||||
var height:int = image.getHeight();
|
||||
var width:int = image.getWidth();
|
||||
var halfHeight:int = height >> 1;
|
||||
var halfWidth:int = width >> 1;
|
||||
var deltaY:int = Math.max(1, height / (MAX_MODULES << 3));
|
||||
var deltaX:int = Math.max(1, width / (MAX_MODULES << 3));
|
||||
|
||||
var top:int = 0;
|
||||
var bottom:int = height;
|
||||
var left:int = 0;
|
||||
var right:int = width;
|
||||
var pointA:ResultPoint = findCornerFromCenter(halfWidth, 0, left, right,
|
||||
halfHeight, -deltaY, top, bottom, halfWidth >> 1);
|
||||
top = int(pointA.getY() - 1);
|
||||
var pointB:ResultPoint = findCornerFromCenter(halfWidth, -deltaX, left, right,
|
||||
halfHeight, 0, top, bottom, halfHeight >> 1);
|
||||
left = int(pointB.getX() - 1);
|
||||
var pointC:ResultPoint = findCornerFromCenter(halfWidth, deltaX, left, right,
|
||||
halfHeight, 0, top, bottom, halfHeight >> 1);
|
||||
right = int(pointC.getX() + 1);
|
||||
var pointD:ResultPoint = findCornerFromCenter(halfWidth, 0, left, right,
|
||||
halfHeight, deltaY, top, bottom, halfWidth >> 1);
|
||||
bottom = int(pointD.getY() + 1);
|
||||
|
||||
// Go try to find point A again with better information -- might have been off at first.
|
||||
pointA = findCornerFromCenter(halfWidth, 0, left, right,
|
||||
halfHeight, -deltaY, top, bottom, halfWidth >> 2);
|
||||
|
||||
return [pointA, pointB, pointC, pointD ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to locate a corner of the barcode by scanning up, down, left or right from a center
|
||||
* point which should be within the barcode.
|
||||
*
|
||||
* @param centerX center's x component (horizontal)
|
||||
* @param deltaX same as deltaY but change in x per step instead
|
||||
* @param left minimum value of x
|
||||
* @param right maximum value of x
|
||||
* @param centerY center's y component (vertical)
|
||||
* @param deltaY change in y per step. If scanning up this is negative; down, positive;
|
||||
* left or right, 0
|
||||
* @param top minimum value of y to search through (meaningless when di == 0)
|
||||
* @param bottom maximum value of y
|
||||
* @param maxWhiteRun maximum run of white pixels that can still be considered to be within
|
||||
* the barcode
|
||||
* @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found
|
||||
* @throws com.google.zxing.ReaderException if such a point cannot be found
|
||||
*/
|
||||
private function findCornerFromCenter(centerX:int, deltaX:int, left:int, right:int,
|
||||
centerY:int, deltaY:int, top:int, bottom:int, maxWhiteRun:int):ResultPoint
|
||||
{
|
||||
var lastRange:Array = null;
|
||||
for (var y:int = centerY, x:int = centerX;
|
||||
y < bottom && y >= top && x < right && x >= left;
|
||||
y += deltaY, x += deltaX) {
|
||||
var range:Array;
|
||||
if (deltaX == 0) {
|
||||
// horizontal slices, up and down
|
||||
range = blackWhiteRange(y, maxWhiteRun, left, right, true);
|
||||
} else {
|
||||
// vertical slices, left and right
|
||||
range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);
|
||||
}
|
||||
if (range == null) {
|
||||
if (lastRange == null) {
|
||||
throw new ReaderException("MonochromeRectangleDetector : findCornerFromCenter : range and lastRange null");
|
||||
}
|
||||
// lastRange was found
|
||||
if (deltaX == 0) {
|
||||
var lastY:int = y - deltaY;
|
||||
if (lastRange[0] < centerX) {
|
||||
if (lastRange[1] > centerX) {
|
||||
// straddle, choose one or the other based on direction
|
||||
return new ResultPoint(deltaY > 0 ? lastRange[0] : lastRange[1], lastY);
|
||||
}
|
||||
return new ResultPoint(lastRange[0], lastY);
|
||||
} else {
|
||||
return new ResultPoint(lastRange[1], lastY);
|
||||
}
|
||||
} else {
|
||||
var lastX:int = x - deltaX;
|
||||
if (lastRange[0] < centerY) {
|
||||
if (lastRange[1] > centerY) {
|
||||
return new ResultPoint(lastX, deltaX < 0 ? lastRange[0] : lastRange[1]);
|
||||
}
|
||||
return new ResultPoint(lastX, lastRange[0]);
|
||||
} else {
|
||||
return new ResultPoint(lastX, lastRange[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastRange = range;
|
||||
}
|
||||
throw new ReaderException("MonochromeRectangleDetector : findCornerFromCenter :generic error");
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the start and end of a region of pixels, either horizontally or vertically, that could
|
||||
* be part of a Data Matrix barcode.
|
||||
*
|
||||
* @param fixedDimension if scanning horizontally, this is the row (the fixed vertical location)
|
||||
* where we are scanning. If scanning vertically it's the colummn, the fixed horizontal location
|
||||
* @param maxWhiteRun largest run of white pixels that can still be considered part of the
|
||||
* barcode region
|
||||
* @param minDim minimum pixel location, horizontally or vertically, to consider
|
||||
* @param maxDim maximum pixel location, horizontally or vertically, to consider
|
||||
* @param horizontal if true, we're scanning left-right, instead of up-down
|
||||
* @return int[] with start and end of found range, or null if no such range is found
|
||||
* (e.g. only white was found)
|
||||
*/
|
||||
private function blackWhiteRange(fixedDimension:int, maxWhiteRun:int, minDim:int, maxDim:int,
|
||||
horizontal:Boolean):Array
|
||||
{
|
||||
|
||||
var center:int = (minDim + maxDim) >> 1;
|
||||
|
||||
// Scan left/up first
|
||||
var start:int = center;
|
||||
var condition:Boolean;
|
||||
var whiteRunStart:int;
|
||||
while (start >= minDim) {
|
||||
if (horizontal ? image._get(start, fixedDimension) : image._get(fixedDimension, start)) {
|
||||
start--;
|
||||
} else {
|
||||
whiteRunStart = start;
|
||||
|
||||
do {
|
||||
start--;
|
||||
condition = (horizontal ? image._get(start, fixedDimension) : image._get(fixedDimension, start));
|
||||
} while ((start >= minDim )&& !condition);
|
||||
var whiteRunSize:int = whiteRunStart - start;
|
||||
if (start < minDim || whiteRunSize > maxWhiteRun) {
|
||||
start = whiteRunStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
start++;
|
||||
|
||||
// Then try right/down
|
||||
var end:int = center;
|
||||
while (end < maxDim) {
|
||||
if (horizontal ? image._get(end, fixedDimension) : image._get(fixedDimension, end)) {
|
||||
end++;
|
||||
} else {
|
||||
whiteRunStart = end;
|
||||
do {
|
||||
end++;
|
||||
condition = horizontal ? image._get(end, fixedDimension) : image._get(fixedDimension, end);
|
||||
} while (end < maxDim && !condition );
|
||||
var whiteRunSize2:int = end - whiteRunStart;
|
||||
if (end >= maxDim || whiteRunSize2 > maxWhiteRun) {
|
||||
end = whiteRunStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
end--;
|
||||
|
||||
return end > start ? [start, end] : null;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,354 +0,0 @@
|
|||
/*
|
||||
* Copyright 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.common.detector
|
||||
{
|
||||
|
||||
import com.google.zxing.NotFoundException;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Detects a candidate barcode-like rectangular region within an image. It
|
||||
* starts around the center of the image, increases the size of the candidate
|
||||
* region until it finds a white rectangular region. By keeping track of the
|
||||
* last black points it encountered, it determines the corners of the barcode.
|
||||
* </p>
|
||||
*
|
||||
* @author David Olivier
|
||||
*/
|
||||
public final class WhiteRectangleDetector
|
||||
{
|
||||
|
||||
private static var INIT_SIZE:int = 30;
|
||||
private static var CORR:int = 1;
|
||||
|
||||
private var image:BitMatrix ;
|
||||
private var height:int;
|
||||
private var width:int;
|
||||
private var leftInit:int;
|
||||
private var rightInit:int;
|
||||
private var downInit:int;
|
||||
private var upInit:int;
|
||||
|
||||
/**
|
||||
* @throws NotFoundException if image is too small
|
||||
*/
|
||||
public function WhiteRectangleDetector(image:BitMatrix , initSize:int=-1, x:int=-1, y:int=-1)
|
||||
{
|
||||
if ((initSize==-1)&&( x==-1)&&( y==-1))
|
||||
{
|
||||
this.image = image;
|
||||
height = image.getHeight();
|
||||
width = image.getWidth();
|
||||
leftInit = (width - INIT_SIZE) >> 1;
|
||||
rightInit = (width + INIT_SIZE) >> 1;
|
||||
upInit = (height - INIT_SIZE) >> 1;
|
||||
downInit = (height + INIT_SIZE) >> 1;
|
||||
if (upInit < 0 || leftInit < 0 || downInit >= height || rightInit >= width) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.image = image;
|
||||
height = image.getHeight();
|
||||
width = image.getWidth();
|
||||
var halfsize:int = initSize >> 1;
|
||||
leftInit = x - halfsize;
|
||||
rightInit = x + halfsize;
|
||||
upInit = y - halfsize;
|
||||
downInit = y + halfsize;
|
||||
if (upInit < 0 || leftInit < 0 || downInit >= height || rightInit >= width) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Detects a candidate barcode-like rectangular region within an image. It
|
||||
* starts around the center of the image, increases the size of the candidate
|
||||
* region until it finds a white rectangular region.
|
||||
* </p>
|
||||
*
|
||||
* @return {@link ResultPoint}[] describing the corners of the rectangular
|
||||
* region. The first and last points are opposed on the diagonal, as
|
||||
* are the second and third. The first point will be the topmost
|
||||
* point and the last, the bottommost. The second point will be
|
||||
* leftmost and the third, the rightmost
|
||||
* @throws NotFoundException if no Data Matrix Code can be found
|
||||
*/
|
||||
public function detect():Array {
|
||||
|
||||
var left:int = leftInit;
|
||||
var right:int = rightInit;
|
||||
var up:int = upInit;
|
||||
var down:int = downInit;
|
||||
var sizeExceeded:Boolean = false;
|
||||
var aBlackPointFoundOnBorder:Boolean = true;
|
||||
var atLeastOneBlackPointFoundOnBorder:Boolean = false;
|
||||
|
||||
while (aBlackPointFoundOnBorder) {
|
||||
|
||||
aBlackPointFoundOnBorder = false;
|
||||
|
||||
// .....
|
||||
// . |
|
||||
// .....
|
||||
var rightBorderNotWhite:Boolean = true;
|
||||
while (rightBorderNotWhite && right < width) {
|
||||
rightBorderNotWhite = containsBlackPoint(up, down, right, false);
|
||||
if (rightBorderNotWhite) {
|
||||
right++;
|
||||
aBlackPointFoundOnBorder = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (right >= width) {
|
||||
sizeExceeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// .....
|
||||
// . .
|
||||
// .___.
|
||||
var bottomBorderNotWhite:Boolean = true;
|
||||
while (bottomBorderNotWhite && down < height) {
|
||||
bottomBorderNotWhite = containsBlackPoint(left, right, down, true);
|
||||
if (bottomBorderNotWhite) {
|
||||
down++;
|
||||
aBlackPointFoundOnBorder = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (down >= height) {
|
||||
sizeExceeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// .....
|
||||
// | .
|
||||
// .....
|
||||
var leftBorderNotWhite:Boolean = true;
|
||||
while (leftBorderNotWhite && left >= 0) {
|
||||
leftBorderNotWhite = containsBlackPoint(up, down, left, false);
|
||||
if (leftBorderNotWhite) {
|
||||
left--;
|
||||
aBlackPointFoundOnBorder = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (left < 0) {
|
||||
sizeExceeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// .___.
|
||||
// . .
|
||||
// .....
|
||||
var topBorderNotWhite:Boolean = true;
|
||||
while (topBorderNotWhite && up >= 0) {
|
||||
topBorderNotWhite = containsBlackPoint(left, right, up, true);
|
||||
if (topBorderNotWhite) {
|
||||
up--;
|
||||
aBlackPointFoundOnBorder = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (up < 0) {
|
||||
sizeExceeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (aBlackPointFoundOnBorder) {
|
||||
atLeastOneBlackPointFoundOnBorder = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
|
||||
|
||||
var maxSize:int = right - left;
|
||||
|
||||
var z:ResultPoint = null;
|
||||
for (var i:int = 1; i < maxSize; i++)
|
||||
{
|
||||
z = getBlackPointOnSegment(left, down - i, left + i, down);
|
||||
|
||||
if (z != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (z == null) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
var t:ResultPoint = null;
|
||||
//go down right
|
||||
for (var i4:int = 1; i4 < maxSize; i4++) {
|
||||
t = getBlackPointOnSegment(left, up + i4, left + i4, up);
|
||||
if (t != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t == null) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
var x:ResultPoint = null;
|
||||
//go down left
|
||||
for (var i5:int = 1; i5 < maxSize; i5++) {
|
||||
x = getBlackPointOnSegment(right, up + i5, right - i5, up);
|
||||
if (x != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x == null) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
var y:ResultPoint = null;
|
||||
//go up left
|
||||
for (i = 1; i < maxSize; i++) {
|
||||
y = getBlackPointOnSegment(right, down - i, right - i, down);
|
||||
if (y != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (y == null) {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
|
||||
return centerEdges(y, z, x, t);
|
||||
|
||||
} else {
|
||||
throw NotFoundException.getNotFoundInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends up being a bit faster than Math.round(). This merely rounds its
|
||||
* argument to the nearest int, where x.5 rounds up.
|
||||
*/
|
||||
private static function round(d:Number):int {
|
||||
return (int) (d + 0.5);
|
||||
}
|
||||
|
||||
private function getBlackPointOnSegment(aX:Number, aY:Number, bX:Number, bY:Number):ResultPoint {
|
||||
var dist:int = distanceL2(aX, aY, bX, bY);
|
||||
var xStep:Number = (bX - aX) / dist;
|
||||
var yStep:Number = (bY - aY) / dist;
|
||||
|
||||
for (var i:int = 0; i < dist; i++) {
|
||||
var x:int = round(aX + i * xStep);
|
||||
var y:int = round(aY + i * yStep);
|
||||
if (image._get(x, y)) {
|
||||
return new ResultPoint(x, y);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function distanceL2(aX:Number, aY:Number, bX:Number, bY:Number):int {
|
||||
var xDiff:Number = aX - bX;
|
||||
var yDiff:Number = aY - bY;
|
||||
return round(Math.sqrt(xDiff * xDiff + yDiff * yDiff));
|
||||
}
|
||||
|
||||
/**
|
||||
* recenters the points of a constant distance towards the center
|
||||
*
|
||||
* @param y bottom most point
|
||||
* @param z left most point
|
||||
* @param x right most point
|
||||
* @param t top most point
|
||||
* @return {@link ResultPoint}[] describing the corners of the rectangular
|
||||
* region. The first and last points are opposed on the diagonal, as
|
||||
* are the second and third. The first point will be the topmost
|
||||
* point and the last, the bottommost. The second point will be
|
||||
* leftmost and the third, the rightmost
|
||||
*/
|
||||
private function centerEdges(y:ResultPoint , z:ResultPoint,
|
||||
x:ResultPoint, t:ResultPoint):Array {
|
||||
|
||||
//
|
||||
// t t
|
||||
// z x
|
||||
// x OR z
|
||||
// y y
|
||||
//
|
||||
|
||||
var yi:Number = y.getX();
|
||||
var yj:Number = y.getY();
|
||||
var zi:Number = z.getX();
|
||||
var zj:Number = z.getY();
|
||||
var xi:Number = x.getX();
|
||||
var xj:Number = x.getY();
|
||||
var ti:Number = t.getX();
|
||||
var tj:Number = t.getY();
|
||||
|
||||
if (yi < width / 2) {
|
||||
return [
|
||||
new ResultPoint(ti - CORR, tj + CORR),
|
||||
new ResultPoint(zi + CORR, zj + CORR),
|
||||
new ResultPoint(xi - CORR, xj - CORR),
|
||||
new ResultPoint(yi + CORR, yj - CORR)];
|
||||
} else {
|
||||
return [
|
||||
new ResultPoint(ti + CORR, tj + CORR),
|
||||
new ResultPoint(zi + CORR, zj - CORR),
|
||||
new ResultPoint(xi - CORR, xj + CORR),
|
||||
new ResultPoint(yi - CORR, yj - CORR)];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a segment contains a black point
|
||||
*
|
||||
* @param a min value of the scanned coordinate
|
||||
* @param b max value of the scanned coordinate
|
||||
* @param fixed value of fixed coordinate
|
||||
* @param horizontal set to true if scan must be horizontal, false if vertical
|
||||
* @return true if a black point has been found, else false.
|
||||
*/
|
||||
private function containsBlackPoint(a:int, b:int, fixed:int, horizontal:Boolean):Boolean {
|
||||
|
||||
if (horizontal) {
|
||||
for (var x:int = a; x <= b; x++) {
|
||||
if (image._get(x, fixed)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var y:int = a; y <= b; y++) {
|
||||
if (image._get(fixed, y)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.common.flexdatatypes
|
||||
{
|
||||
// these comparators should reside in the classes but that didn's work for some reason.
|
||||
import com.google.zxing.datamatrix.detector.ResultPointsAndTransitionsComparator;
|
||||
import com.google.zxing.qrcode.detector.CenterComparator;
|
||||
import com.google.zxing.qrcode.detector.FurthestFromAverageComparator;
|
||||
|
||||
|
||||
public class ArrayList
|
||||
{
|
||||
private var _array:Array;
|
||||
public function ArrayList(siz:int=0)
|
||||
{
|
||||
this._array = new Array(siz);
|
||||
}
|
||||
public function get Capacity():int
|
||||
{
|
||||
return this._array.length;
|
||||
}
|
||||
|
||||
public function getObjectByIndex(index:int):Object
|
||||
{
|
||||
var obj:Object = this._array[index];
|
||||
return obj;
|
||||
}
|
||||
|
||||
public function setObjectByIndex(index:int,obj:Object):void
|
||||
{
|
||||
this._array[index] = obj;
|
||||
}
|
||||
|
||||
|
||||
public function Contains(o:Object):Boolean
|
||||
{
|
||||
if (this._array.indexOf(o) != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function set Capacity(cap:int):void
|
||||
{
|
||||
// not needed;
|
||||
}
|
||||
|
||||
public function AddRange(itemsToAdd:Array):void
|
||||
{
|
||||
// add this number of items
|
||||
var len:int = this._array.length;
|
||||
for (var i:int=0;i<itemsToAdd.length;i++)
|
||||
{
|
||||
this._array.push(new Object());
|
||||
}
|
||||
}
|
||||
|
||||
public function indexOf(o:Object):int
|
||||
{
|
||||
return this._array.indexOf(o);
|
||||
}
|
||||
|
||||
public function removeElementAt(index:int):void
|
||||
{
|
||||
var newArray:Array = new Array();
|
||||
for(var i:int=0;i<this._array.length;i++)
|
||||
{
|
||||
if (i != index) { newArray.push(this._array[i]); }
|
||||
}
|
||||
this._array = newArray;
|
||||
}
|
||||
|
||||
public function setElementAt(elem:Object, index:int):void
|
||||
{
|
||||
this._array[index] = elem;
|
||||
}
|
||||
|
||||
// limit size of array
|
||||
public function setSize(size:int):void
|
||||
{
|
||||
var newArray:Array = new Array();
|
||||
if (this._array.length > size)
|
||||
{
|
||||
for (var i:int=0;i<size;i++)
|
||||
{
|
||||
newArray[i] = this._array[i]; // bas : fixed .push
|
||||
}
|
||||
this._array = newArray;
|
||||
}
|
||||
}
|
||||
|
||||
public function RemoveRange(newSize:int,itemsToRemove:int):void
|
||||
{
|
||||
// remove the items
|
||||
var tmpAr:Object;
|
||||
for (var i:int=0;i<itemsToRemove;i++)
|
||||
{
|
||||
// remove the item with this index
|
||||
tmpAr = this._array.pop();
|
||||
}
|
||||
}
|
||||
|
||||
public function get Count():int
|
||||
{
|
||||
return this._array.length;
|
||||
}
|
||||
|
||||
public function Add(item:Object):void
|
||||
{
|
||||
|
||||
this._array.push(item);
|
||||
}
|
||||
|
||||
public function addElement(item:Object):void
|
||||
{
|
||||
this.Add(item);
|
||||
}
|
||||
|
||||
public function get length():int
|
||||
{
|
||||
return this._array.length;
|
||||
}
|
||||
|
||||
public function sort_ResultPointsAndTransitionsComparator():void
|
||||
{
|
||||
this._array.sort(ResultPointsAndTransitionsComparator.compare);
|
||||
//this._array.sort(args);
|
||||
}
|
||||
|
||||
public function sort_CenterComparator(average:Number):void
|
||||
{
|
||||
CenterComparator.setAverage(average);
|
||||
this._array.sort(CenterComparator.compare);
|
||||
}
|
||||
|
||||
public function sort_FurthestFromAverageComparator(average:Number):void
|
||||
{
|
||||
FurthestFromAverageComparator.setAverage(average);
|
||||
this._array.sort(FurthestFromAverageComparator.compare);
|
||||
}
|
||||
|
||||
public function size():int
|
||||
{
|
||||
return this._array.length;
|
||||
}
|
||||
|
||||
public function elementAt(index:int):Object
|
||||
{
|
||||
return this._array[index];
|
||||
}
|
||||
|
||||
public function isEmpty():Boolean
|
||||
{
|
||||
if (this._array.length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function clearAll():void
|
||||
{
|
||||
this._array = new Array();
|
||||
}
|
||||
|
||||
public function elements():Array
|
||||
{
|
||||
return this._array;
|
||||
}
|
||||
|
||||
public function lastElement():Object
|
||||
{
|
||||
return this._array[this._array.length-1]; // bas : fixed this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.common.flexdatatypes
|
||||
{
|
||||
public class Enumeration
|
||||
{
|
||||
private var _arr:Array;
|
||||
|
||||
public function isEmpty():Boolean
|
||||
{
|
||||
return this.getSize()==0?true:false;
|
||||
}
|
||||
|
||||
public function getSize():int
|
||||
{
|
||||
return this._arr.length;
|
||||
}
|
||||
|
||||
public function Enumeration(arr:Array)
|
||||
{
|
||||
this._arr = arr;
|
||||
}
|
||||
|
||||
public function hasMoreElement():Boolean
|
||||
{
|
||||
return (!this.isEmpty());
|
||||
}
|
||||
|
||||
public function nextElement():Object
|
||||
{
|
||||
return this._arr.shift();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.common.flexdatatypes
|
||||
{
|
||||
public class HashTable
|
||||
{
|
||||
private var _arr:Array;
|
||||
|
||||
public function isEmpty():Boolean
|
||||
{
|
||||
return this.getSize()==0?true:false;
|
||||
}
|
||||
|
||||
public function getSize():int
|
||||
{
|
||||
return this._arr.length;
|
||||
}
|
||||
|
||||
public function getIndexOf(key:Object):int
|
||||
{
|
||||
for (var i:String in this._arr)
|
||||
{
|
||||
if (this._arr[i][0] == key)
|
||||
{
|
||||
return (i as int);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public function getValueByIndex(index:int):Object
|
||||
{
|
||||
return this._arr[index][1];
|
||||
}
|
||||
|
||||
public function getKeyByIndex(index:int):Object
|
||||
{
|
||||
return this._arr[index][0];
|
||||
}
|
||||
|
||||
public function HashTable(siz:int=0)
|
||||
{
|
||||
this._arr = new Array(siz);
|
||||
}
|
||||
|
||||
public function Add(key:Object, value:Object):void
|
||||
{
|
||||
var ta:Array = new Array(2);
|
||||
ta[0] = key;
|
||||
ta[1] = value;
|
||||
this._arr[this._arr.length] = ta;
|
||||
}
|
||||
|
||||
public function _put(k:Object,v:Object):void
|
||||
{
|
||||
this.Add(k,v);
|
||||
}
|
||||
|
||||
public function ContainsKey(key:Object):Boolean
|
||||
{
|
||||
//for (var i:int=0;i<this._arr.length;i++)
|
||||
for (var i:String in this._arr)
|
||||
{
|
||||
if (this._arr[i][0] == key) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getValuesByKey(key:Object):ArrayList
|
||||
{
|
||||
var al:ArrayList = new ArrayList();
|
||||
//for (var i:int=0;i<this._arr.length;i++)
|
||||
for (var i:String in this._arr)
|
||||
{
|
||||
if (this._arr[i][0] == key)
|
||||
{
|
||||
al.Add(this._arr[i][1]);
|
||||
}
|
||||
}
|
||||
return al;
|
||||
}
|
||||
|
||||
public function _get(key:Object):Object
|
||||
{
|
||||
return this.getValueByKey(key);
|
||||
}
|
||||
|
||||
public function getValueByKey(key:Object):Object
|
||||
{
|
||||
var al:ArrayList = new ArrayList();
|
||||
//for (var i:int=0;i<this._arr.length;i++)
|
||||
for (var i:String in this._arr)
|
||||
{
|
||||
if (this._arr[i][0] == key)
|
||||
{
|
||||
return this._arr[i][1];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setValue(key:Object,value:Object):void
|
||||
{
|
||||
//for (var i:int=0;i<this._arr.length;i++)
|
||||
for (var i:String in this._arr)
|
||||
{
|
||||
if (this._arr[i][0] == key)
|
||||
{
|
||||
this._arr[i][1] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getKeyByValue(value:Object):int
|
||||
{
|
||||
//for (var i:int=0;i<this._arr.length;i++)
|
||||
for (var i:String in this._arr)
|
||||
{
|
||||
if (this._arr[i][1] == value)
|
||||
{
|
||||
return this._arr[i][0];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function containsKey(key:Object):Boolean
|
||||
{
|
||||
//for (var i:int=0;i<this._arr.length;i++)
|
||||
for (var i:String in this._arr)
|
||||
{
|
||||
if (this._arr[i][0] == key)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function keys():Array
|
||||
{
|
||||
var result:Array = new Array(this._arr.length);
|
||||
//for (var i:int=0;i<this._arr.length;i++)
|
||||
for (var i:String in this._arr)
|
||||
{
|
||||
result[i] = this._arr[i][0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.common.flexdatatypes
|
||||
{
|
||||
public class IllegalArgumentException extends Error
|
||||
{
|
||||
public function IllegalArgumentException(message:String="")
|
||||
{
|
||||
super("IllegalArgumentException"+message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.common.flexdatatypes
|
||||
{
|
||||
import com.google.zxing.ReaderException;
|
||||
|
||||
public class StringBuilder
|
||||
{
|
||||
public var _string:String = "";
|
||||
|
||||
public function StringBuilder(ignore:int=0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function charAt(index:int):String
|
||||
{
|
||||
return this._string.charAt(index);
|
||||
}
|
||||
|
||||
|
||||
public function setCharAt(index:int, char:String):void
|
||||
{
|
||||
var temp:Array = this._string.split("");
|
||||
temp[index] = char.charAt(0);
|
||||
this._string = temp.join("");
|
||||
}
|
||||
|
||||
public function setLength(l:int):void
|
||||
{
|
||||
if (l == 0)
|
||||
{
|
||||
this._string = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
this._string = this._string.substr(0,l);
|
||||
}
|
||||
}
|
||||
|
||||
public function Append(o:Object,startIndex:int=-1,count:int=-1):void
|
||||
{
|
||||
if (startIndex == -1)
|
||||
{
|
||||
if (o is Array)
|
||||
{
|
||||
this._string = this._string + (o as Array).join("");
|
||||
}
|
||||
else if (o is String)
|
||||
{
|
||||
this._string = this._string + o;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._string = this._string + o.toString();
|
||||
}
|
||||
}
|
||||
else if (count == -1)
|
||||
{
|
||||
this._string = this._string + (o.toString()).substr(startIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._string = this._string + (o.toString()).substr(startIndex,count);
|
||||
}
|
||||
}
|
||||
|
||||
public function ToString():String
|
||||
{
|
||||
return this._string;
|
||||
}
|
||||
|
||||
public function get length():int
|
||||
{
|
||||
return this._string.length;
|
||||
}
|
||||
|
||||
public function set length(size:int):void
|
||||
{
|
||||
if (size==0) { this._string = "";}
|
||||
else
|
||||
{
|
||||
throw new ReaderException("size can ony be set to 0");
|
||||
}
|
||||
}
|
||||
public function Insert (pos:int,o:Object):void
|
||||
{
|
||||
if (pos == 0)
|
||||
{
|
||||
this._string = o.toString() + this._string;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ReaderException('pos not supported yet');
|
||||
}
|
||||
}
|
||||
|
||||
public function Remove(startIndex:int,length:int):void
|
||||
{
|
||||
|
||||
var leftPart:String = "";
|
||||
var rightPart:String = "";
|
||||
if (startIndex > 0) { leftPart = this._string.substring(0,startIndex); }
|
||||
if ((startIndex+length) < this._string.length)
|
||||
{ rightPart = this._string.substr(startIndex+length); }
|
||||
this._string = leftPart + rightPart;
|
||||
}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
return this._string;
|
||||
}
|
||||
|
||||
public function toHexString():String
|
||||
{
|
||||
var r:String="";
|
||||
var e:int=this._string.length;
|
||||
var c:int=0;
|
||||
var h:String;
|
||||
while(c<e){
|
||||
h=this._string.charCodeAt(c++).toString(16);
|
||||
while(h.length<3) h="0"+h;
|
||||
r+=h;
|
||||
}
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
public function deleteCharAt(index:int):void
|
||||
{
|
||||
var temp:Array = this._string.split("");
|
||||
var result:String = "";
|
||||
for(var i:int=0;i<temp.length;i++)
|
||||
{
|
||||
if (i!=index){result = result + (temp[i] as String); }
|
||||
}
|
||||
this._string = result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.common.flexdatatypes
|
||||
{
|
||||
public class Utils
|
||||
{
|
||||
public function Utils()
|
||||
{
|
||||
}
|
||||
|
||||
public static function startsWith(text:String, subtext:String):Boolean
|
||||
{
|
||||
if (text.substr(0,subtext.length) == subtext) { return true; }
|
||||
return false;
|
||||
}
|
||||
public static function endsWith(text:String, subtext:String):Boolean
|
||||
{
|
||||
if (text.substr(text.length-subtext.length) == subtext) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function isDigit(s:String):Boolean
|
||||
{
|
||||
return !isNaN(Number(s));
|
||||
}
|
||||
|
||||
public static function arraycopy(source:Array, sourceoffset:int, target:Array, targetoffset:int, length:int):void
|
||||
{
|
||||
for (var i:int=sourceoffset;i<(sourceoffset+length);i++)
|
||||
{
|
||||
target[targetoffset++] = source[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue