first commit
This commit is contained in:
commit
ed37b7ba01
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.vs
|
||||||
|
DataMatrix.net/bin
|
||||||
|
DataMatrix.net/obj
|
||||||
25
DataMatrix.net.sln
Normal file
25
DataMatrix.net.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.14.36414.22 d17.14
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataMatrix.net", "DataMatrix.net\DataMatrix.net.csproj", "{360B7A7C-0D9D-42FA-850E-BA87CAF0F60A}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{360B7A7C-0D9D-42FA-850E-BA87CAF0F60A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{360B7A7C-0D9D-42FA-850E-BA87CAF0F60A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{360B7A7C-0D9D-42FA-850E-BA87CAF0F60A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{360B7A7C-0D9D-42FA-850E-BA87CAF0F60A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {21728DFC-EB10-4117-B50A-250B02AF7DFE}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
45
DataMatrix.net/C40TextState.cs
Normal file
45
DataMatrix.net/C40TextState.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal struct C40TextState
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
internal int Shift { get; set; }
|
||||||
|
|
||||||
|
internal bool UpperShift { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
18
DataMatrix.net/DataMatrix.net.csproj
Normal file
18
DataMatrix.net/DataMatrix.net.csproj
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
|
||||||
|
<PackageId>DataMatrix.net</PackageId>
|
||||||
|
<Authors>Michael Faschinger</Authors>
|
||||||
|
<Version>0.5.0</Version>
|
||||||
|
<PackageProjectUrl>https://github.com/xas/DataMatrix.NET</PackageProjectUrl>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
57
DataMatrix.net/DmtxBestLine.cs
Normal file
57
DataMatrix.net/DmtxBestLine.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal struct DmtxBestLine
|
||||||
|
{
|
||||||
|
internal int Angle { get; set; }
|
||||||
|
|
||||||
|
internal int HOffset { get; set; }
|
||||||
|
|
||||||
|
internal int Mag { get; set; }
|
||||||
|
|
||||||
|
internal int StepBeg { get; set; }
|
||||||
|
|
||||||
|
internal int StepPos { get; set; }
|
||||||
|
|
||||||
|
internal int StepNeg { get; set; }
|
||||||
|
|
||||||
|
internal int DistSq { get; set; }
|
||||||
|
|
||||||
|
internal double Devn { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc LocBeg { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc LocPos { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc LocNeg { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
314
DataMatrix.net/DmtxBresLine.cs
Normal file
314
DataMatrix.net/DmtxBresLine.cs
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal struct DmtxBresLine
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
int _xStep;
|
||||||
|
int _yStep;
|
||||||
|
int _xDelta;
|
||||||
|
int _yDelta;
|
||||||
|
bool _steep;
|
||||||
|
int _xOut;
|
||||||
|
int _yOut;
|
||||||
|
int _travel;
|
||||||
|
int _outward;
|
||||||
|
int _error;
|
||||||
|
DmtxPixelLoc _loc;
|
||||||
|
DmtxPixelLoc _loc0;
|
||||||
|
DmtxPixelLoc _loc1;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
internal DmtxBresLine(DmtxBresLine orig)
|
||||||
|
{
|
||||||
|
this._error = orig._error;
|
||||||
|
this._loc = new DmtxPixelLoc { X = orig._loc.X, Y = orig._loc.Y };
|
||||||
|
this._loc0 = new DmtxPixelLoc { X = orig._loc0.X, Y = orig._loc0.Y };
|
||||||
|
this._loc1 = new DmtxPixelLoc { X = orig._loc1.X, Y = orig._loc1.Y };
|
||||||
|
this._outward = orig._outward;
|
||||||
|
this._steep = orig._steep;
|
||||||
|
this._travel = orig._travel;
|
||||||
|
this._xDelta = orig._xDelta;
|
||||||
|
this._xOut = orig._xOut;
|
||||||
|
this._xStep = orig._xStep;
|
||||||
|
this._yDelta = orig._yDelta;
|
||||||
|
this._yOut = orig._yOut;
|
||||||
|
this._yStep = orig._yStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DmtxBresLine(DmtxPixelLoc loc0, DmtxPixelLoc loc1, DmtxPixelLoc locInside)
|
||||||
|
{
|
||||||
|
int cp;
|
||||||
|
DmtxPixelLoc locBeg, locEnd;
|
||||||
|
|
||||||
|
|
||||||
|
/* Values that stay the same after initialization */
|
||||||
|
this._loc0 = loc0;
|
||||||
|
this._loc1 = loc1;
|
||||||
|
this._xStep = (loc0.X < loc1.X) ? +1 : -1;
|
||||||
|
this._yStep = (loc0.Y < loc1.Y) ? +1 : -1;
|
||||||
|
this._xDelta = Math.Abs(loc1.X - loc0.X);
|
||||||
|
this._yDelta = Math.Abs(loc1.Y - loc0.Y);
|
||||||
|
this._steep = (this._yDelta > this._xDelta);
|
||||||
|
|
||||||
|
/* Take cross product to determine outward step */
|
||||||
|
if (this._steep)
|
||||||
|
{
|
||||||
|
/* Point first vector up to get correct sign */
|
||||||
|
if (loc0.Y < loc1.Y)
|
||||||
|
{
|
||||||
|
locBeg = loc0;
|
||||||
|
locEnd = loc1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
locBeg = loc1;
|
||||||
|
locEnd = loc0;
|
||||||
|
}
|
||||||
|
cp = (((locEnd.X - locBeg.X) * (locInside.Y - locEnd.Y)) -
|
||||||
|
((locEnd.Y - locBeg.Y) * (locInside.X - locEnd.X)));
|
||||||
|
|
||||||
|
this._xOut = (cp > 0) ? +1 : -1;
|
||||||
|
this._yOut = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Point first vector left to get correct sign */
|
||||||
|
if (loc0.X > loc1.X)
|
||||||
|
{
|
||||||
|
locBeg = loc0;
|
||||||
|
locEnd = loc1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
locBeg = loc1;
|
||||||
|
locEnd = loc0;
|
||||||
|
}
|
||||||
|
cp = (((locEnd.X - locBeg.X) * (locInside.Y - locEnd.Y)) -
|
||||||
|
((locEnd.Y - locBeg.Y) * (locInside.X - locEnd.X)));
|
||||||
|
|
||||||
|
this._xOut = 0;
|
||||||
|
this._yOut = (cp > 0) ? +1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Values that change while stepping through line */
|
||||||
|
this._loc = loc0;
|
||||||
|
this._travel = 0;
|
||||||
|
this._outward = 0;
|
||||||
|
this._error = (this._steep) ? this._yDelta / 2 : this._xDelta / 2;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
internal bool GetStep(DmtxPixelLoc target, ref int travel, ref int outward)
|
||||||
|
{
|
||||||
|
/* Determine necessary step along and outward from Bresenham line */
|
||||||
|
if (this._steep)
|
||||||
|
{
|
||||||
|
travel = (this._yStep > 0) ? target.Y - this._loc.Y : this._loc.Y - target.Y;
|
||||||
|
Step(travel, 0);
|
||||||
|
outward = (this._xOut > 0) ? target.X - this._loc.X : this._loc.X - target.X;
|
||||||
|
if (this._yOut != 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Invald yOut value for bresline step!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
travel = (this._xStep > 0) ? target.X - this._loc.X : this._loc.X - target.X;
|
||||||
|
Step(travel, 0);
|
||||||
|
outward = (this._yOut > 0) ? target.Y - this._loc.Y : this._loc.Y - target.Y;
|
||||||
|
if (this._xOut != 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Invald xOut value for bresline step!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal bool Step(int travel, int outward)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (Math.Abs(travel) >= 2)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid value for 'travel' in BaseLineStep!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform forward step */
|
||||||
|
if (travel > 0)
|
||||||
|
{
|
||||||
|
this._travel++;
|
||||||
|
if (this._steep)
|
||||||
|
{
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y + this._yStep };
|
||||||
|
this._error -= this._xDelta;
|
||||||
|
if (this._error < 0)
|
||||||
|
{
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xStep, Y = this._loc.Y };
|
||||||
|
this._error += this._yDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xStep, Y = this._loc.Y };
|
||||||
|
this._error -= this._yDelta;
|
||||||
|
if (this._error < 0)
|
||||||
|
{
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y + this._yStep };
|
||||||
|
this._error += this._xDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (travel < 0)
|
||||||
|
{
|
||||||
|
this._travel--;
|
||||||
|
if (this._steep)
|
||||||
|
{
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y - this._yStep };
|
||||||
|
this._error += this._xDelta;
|
||||||
|
if (this.Error >= this.YDelta)
|
||||||
|
{
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X - this._xStep, Y = this._loc.Y };
|
||||||
|
this._error -= this._yDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X - this._xStep, Y = this._loc.Y };
|
||||||
|
this._error += this._yDelta;
|
||||||
|
if (this._error >= this._xDelta)
|
||||||
|
{
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y - this._yStep };
|
||||||
|
this._error -= this._xDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < outward; i++)
|
||||||
|
{
|
||||||
|
/* Outward steps */
|
||||||
|
this._outward++;
|
||||||
|
this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xOut, Y = this._loc.Y + this._yOut };
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
internal int XStep
|
||||||
|
{
|
||||||
|
get { return _xStep; }
|
||||||
|
set { _xStep = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int YStep
|
||||||
|
{
|
||||||
|
get { return _yStep; }
|
||||||
|
set { _yStep = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int XDelta
|
||||||
|
{
|
||||||
|
get { return _xDelta; }
|
||||||
|
set { _xDelta = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int YDelta
|
||||||
|
{
|
||||||
|
get { return _yDelta; }
|
||||||
|
set { _yDelta = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool Steep
|
||||||
|
{
|
||||||
|
get { return _steep; }
|
||||||
|
set { _steep = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int XOut
|
||||||
|
{
|
||||||
|
get { return _xOut; }
|
||||||
|
set { _xOut = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int YOut
|
||||||
|
{
|
||||||
|
get { return _yOut; }
|
||||||
|
set { _yOut = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int Travel
|
||||||
|
{
|
||||||
|
get { return _travel; }
|
||||||
|
set { _travel = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int Outward
|
||||||
|
{
|
||||||
|
get { return _outward; }
|
||||||
|
set { _outward = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int Error
|
||||||
|
{
|
||||||
|
get { return _error; }
|
||||||
|
set { _error = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DmtxPixelLoc Loc
|
||||||
|
{
|
||||||
|
get { return _loc; }
|
||||||
|
set { _loc = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal DmtxPixelLoc Loc0
|
||||||
|
{
|
||||||
|
get { return _loc0; }
|
||||||
|
set { _loc0 = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DmtxPixelLoc Loc1
|
||||||
|
{
|
||||||
|
get { return _loc1; }
|
||||||
|
set { _loc1 = value; }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
77
DataMatrix.net/DmtxChannel.cs
Normal file
77
DataMatrix.net/DmtxChannel.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal class DmtxChannel
|
||||||
|
{
|
||||||
|
byte[] _encodedWords;
|
||||||
|
|
||||||
|
internal byte[] Input { get; set; }
|
||||||
|
|
||||||
|
internal DmtxScheme EncScheme { get; set; }
|
||||||
|
|
||||||
|
internal DmtxChannelStatus Invalid { get; set; }
|
||||||
|
|
||||||
|
internal int InputIndex { get; set; }
|
||||||
|
|
||||||
|
internal int EncodedLength { get; set; }
|
||||||
|
|
||||||
|
internal int CurrentLength { get; set; }
|
||||||
|
|
||||||
|
internal int FirstCodeWord { get; set; }
|
||||||
|
|
||||||
|
internal byte[] EncodedWords
|
||||||
|
{
|
||||||
|
get { return this._encodedWords ?? (this._encodedWords = new byte[1558]); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DmtxChannelGroup
|
||||||
|
{
|
||||||
|
DmtxChannel[] _channels;
|
||||||
|
|
||||||
|
internal DmtxChannel[] Channels
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_channels == null)
|
||||||
|
{
|
||||||
|
_channels = new DmtxChannel[6];
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
_channels[i] = new DmtxChannel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _channels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
309
DataMatrix.net/DmtxCommon.cs
Normal file
309
DataMatrix.net/DmtxCommon.cs
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal static class DmtxCommon
|
||||||
|
{
|
||||||
|
internal static void GenReedSolEcc(DmtxMessage message, DmtxSymbolSize sizeIdx)
|
||||||
|
{
|
||||||
|
byte[] g = new byte[69];
|
||||||
|
byte[] b = new byte[68];
|
||||||
|
|
||||||
|
int symbolDataWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx);
|
||||||
|
int symbolErrorWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolErrorWords, sizeIdx);
|
||||||
|
int symbolTotalWords = symbolDataWords + symbolErrorWords;
|
||||||
|
int blockErrorWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribBlockErrorWords, sizeIdx);
|
||||||
|
int step = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribInterleavedBlocks, sizeIdx);
|
||||||
|
if (blockErrorWords != symbolErrorWords / step)
|
||||||
|
{
|
||||||
|
throw new Exception("Error generation reed solomon error correction");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int gI = 0; gI < g.Length; gI++)
|
||||||
|
{
|
||||||
|
g[gI] = 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate ECC polynomia
|
||||||
|
for (int i = 1; i <= blockErrorWords; i++)
|
||||||
|
{
|
||||||
|
for (int j = i - 1; j >= 0; j--)
|
||||||
|
{
|
||||||
|
g[j] = GfDoublify(g[j], i); // g[j] *= 2**i
|
||||||
|
if (j > 0)
|
||||||
|
g[j] = GfSum(g[j], g[j - 1]); // g[j] += g[j-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate error codeword array
|
||||||
|
for (int block = 0; block < step; block++)
|
||||||
|
{
|
||||||
|
for (int bI = 0; bI < b.Length; bI++)
|
||||||
|
{
|
||||||
|
b[bI] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = block; i < symbolDataWords; i += step)
|
||||||
|
{
|
||||||
|
int val = GfSum(b[blockErrorWords - 1], message.Code[i]);
|
||||||
|
for (int j = blockErrorWords - 1; j > 0; j--)
|
||||||
|
{
|
||||||
|
b[j] = GfSum(b[j - 1], GfProduct(g[j], val));
|
||||||
|
}
|
||||||
|
b[0] = GfProduct(g[0], val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int blockDataWords = GetBlockDataSize(sizeIdx, block);
|
||||||
|
int bIndex = blockErrorWords;
|
||||||
|
|
||||||
|
for (int i = block + (step * blockDataWords); i < symbolTotalWords; i += step)
|
||||||
|
{
|
||||||
|
message.Code[i] = b[--bIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bIndex != 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Error generation error correction code!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte GfProduct(byte a, int b)
|
||||||
|
{
|
||||||
|
if (a == 0 || b == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (byte)DmtxConstants.aLogVal[(DmtxConstants.logVal[a] + DmtxConstants.logVal[b]) % 255];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte GfSum(byte a, byte b)
|
||||||
|
{
|
||||||
|
return (byte)(a ^ b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte GfDoublify(byte a, int b)
|
||||||
|
{
|
||||||
|
if (a == 0) /* XXX this is right, right? */
|
||||||
|
return 0;
|
||||||
|
if (b == 0)
|
||||||
|
return a; /* XXX this is right, right? */
|
||||||
|
|
||||||
|
return (byte)DmtxConstants.aLogVal[(DmtxConstants.logVal[a] + b) % 255];
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int GetSymbolAttribute(DmtxSymAttribute attribute, DmtxSymbolSize sizeIdx)
|
||||||
|
{
|
||||||
|
if (sizeIdx < 0 || (int)sizeIdx >= DmtxConstants.DmtxSymbolSquareCount + DmtxConstants.DmtxSymbolRectCount)
|
||||||
|
return DmtxConstants.DmtxUndefined;
|
||||||
|
|
||||||
|
switch (attribute)
|
||||||
|
{
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribSymbolRows:
|
||||||
|
return DmtxConstants.SymbolRows[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribSymbolCols:
|
||||||
|
return DmtxConstants.SymbolCols[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribDataRegionRows:
|
||||||
|
return DmtxConstants.DataRegionRows[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribDataRegionCols:
|
||||||
|
return DmtxConstants.DataRegionCols[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribHorizDataRegions:
|
||||||
|
return DmtxConstants.HorizDataRegions[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribVertDataRegions:
|
||||||
|
return ((int)sizeIdx < DmtxConstants.DmtxSymbolSquareCount) ? DmtxConstants.HorizDataRegions[(int)sizeIdx] : 1;
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribMappingMatrixRows:
|
||||||
|
return DmtxConstants.DataRegionRows[(int)sizeIdx] *
|
||||||
|
GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribVertDataRegions, sizeIdx);
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribMappingMatrixCols:
|
||||||
|
return DmtxConstants.DataRegionCols[(int)sizeIdx] * DmtxConstants.HorizDataRegions[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribInterleavedBlocks:
|
||||||
|
return DmtxConstants.InterleavedBlocks[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribBlockErrorWords:
|
||||||
|
return DmtxConstants.BlockErrorWords[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribBlockMaxCorrectable:
|
||||||
|
return DmtxConstants.BlockMaxCorrectable[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribSymbolDataWords:
|
||||||
|
return DmtxConstants.SymbolDataWords[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribSymbolErrorWords:
|
||||||
|
return DmtxConstants.BlockErrorWords[(int)sizeIdx] * DmtxConstants.InterleavedBlocks[(int)sizeIdx];
|
||||||
|
case DmtxSymAttribute.DmtxSymAttribSymbolMaxCorrectable:
|
||||||
|
return DmtxConstants.BlockMaxCorrectable[(int)sizeIdx] * DmtxConstants.InterleavedBlocks[(int)sizeIdx];
|
||||||
|
}
|
||||||
|
return DmtxConstants.DmtxUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int GetBlockDataSize(DmtxSymbolSize sizeIdx, int blockIdx)
|
||||||
|
{
|
||||||
|
int symbolDataWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx);
|
||||||
|
int interleavedBlocks = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribInterleavedBlocks, sizeIdx);
|
||||||
|
int count = symbolDataWords / interleavedBlocks;
|
||||||
|
|
||||||
|
if (symbolDataWords < 1 || interleavedBlocks < 1)
|
||||||
|
return DmtxConstants.DmtxUndefined;
|
||||||
|
|
||||||
|
return (sizeIdx == DmtxSymbolSize.DmtxSymbol144x144 && blockIdx < 8) ? count + 1 : count;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static DmtxSymbolSize FindCorrectSymbolSize(int dataWords, DmtxSymbolSize sizeIdxRequest)
|
||||||
|
{
|
||||||
|
DmtxSymbolSize sizeIdx;
|
||||||
|
if (dataWords <= 0)
|
||||||
|
{
|
||||||
|
return DmtxSymbolSize.DmtxSymbolShapeAuto;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolSquareAuto || sizeIdxRequest == DmtxSymbolSize.DmtxSymbolRectAuto)
|
||||||
|
{
|
||||||
|
DmtxSymbolSize idxBeg;
|
||||||
|
DmtxSymbolSize idxEnd;
|
||||||
|
if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolSquareAuto)
|
||||||
|
{
|
||||||
|
idxBeg = 0;
|
||||||
|
idxEnd = (DmtxSymbolSize)DmtxConstants.DmtxSymbolSquareCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idxBeg = (DmtxSymbolSize)DmtxConstants.DmtxSymbolSquareCount;
|
||||||
|
idxEnd = (DmtxSymbolSize)(DmtxConstants.DmtxSymbolSquareCount + DmtxConstants.DmtxSymbolRectCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (sizeIdx = idxBeg; sizeIdx < idxEnd; sizeIdx++)
|
||||||
|
{
|
||||||
|
if (GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx) >= dataWords)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeIdx == idxEnd)
|
||||||
|
{
|
||||||
|
return DmtxSymbolSize.DmtxSymbolShapeAuto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sizeIdx = sizeIdxRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataWords > GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx))
|
||||||
|
{
|
||||||
|
return DmtxSymbolSize.DmtxSymbolShapeAuto;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizeIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int GetBitsPerPixel(DmtxPackOrder pack)
|
||||||
|
{
|
||||||
|
switch (pack)
|
||||||
|
{
|
||||||
|
case DmtxPackOrder.DmtxPack1bppK:
|
||||||
|
return 1;
|
||||||
|
case DmtxPackOrder.DmtxPack8bppK:
|
||||||
|
return 8;
|
||||||
|
case DmtxPackOrder.DmtxPack16bppRGB:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppRGBX:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppXRGB:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppBGR:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppBGRX:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppXBGR:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppYCbCr:
|
||||||
|
return 16;
|
||||||
|
case DmtxPackOrder.DmtxPack24bppRGB:
|
||||||
|
case DmtxPackOrder.DmtxPack24bppBGR:
|
||||||
|
case DmtxPackOrder.DmtxPack24bppYCbCr:
|
||||||
|
return 24;
|
||||||
|
case DmtxPackOrder.DmtxPack32bppRGBX:
|
||||||
|
case DmtxPackOrder.DmtxPack32bppXRGB:
|
||||||
|
case DmtxPackOrder.DmtxPack32bppBGRX:
|
||||||
|
case DmtxPackOrder.DmtxPack32bppXBGR:
|
||||||
|
case DmtxPackOrder.DmtxPack32bppCMYK:
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DmtxConstants.DmtxUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static T Min<T>(T x, T y) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
return x.CompareTo(y) < 0 ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static T Max<T>(T x, T y) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
return x.CompareTo(y) < 0 ? y : x;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool DecodeCheckErrors(byte[] code, int codeIndex, DmtxSymbolSize sizeIdx, int fix)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[255];
|
||||||
|
|
||||||
|
int interleavedBlocks = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribInterleavedBlocks, sizeIdx);
|
||||||
|
int blockErrorWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribBlockErrorWords, sizeIdx);
|
||||||
|
|
||||||
|
const int fixedErr = 0;
|
||||||
|
int fixedErrSum = 0;
|
||||||
|
for (int i = 0; i < interleavedBlocks; i++)
|
||||||
|
{
|
||||||
|
int blockTotalWords = blockErrorWords + GetBlockDataSize(sizeIdx, i);
|
||||||
|
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < blockTotalWords; j++)
|
||||||
|
data[j] = code[j * interleavedBlocks + i];
|
||||||
|
|
||||||
|
fixedErrSum += fixedErr;
|
||||||
|
|
||||||
|
for (j = 0; j < blockTotalWords; j++)
|
||||||
|
code[j * interleavedBlocks + i] = data[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fix != DmtxConstants.DmtxUndefined && fix >= 0 && fix < fixedErrSum)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static double RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle)
|
||||||
|
{
|
||||||
|
DmtxVector2 vA = (c0 - c1);
|
||||||
|
DmtxVector2 vB = (c2 - c1);
|
||||||
|
vA.Norm();
|
||||||
|
vB.Norm();
|
||||||
|
|
||||||
|
DmtxMatrix3 m = DmtxMatrix3.Rotate(angle);
|
||||||
|
vB *= m;
|
||||||
|
|
||||||
|
return vA.Dot(vB);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
363
DataMatrix.net/DmtxConstants.cs
Normal file
363
DataMatrix.net/DmtxConstants.cs
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal static class DmtxConstants
|
||||||
|
{
|
||||||
|
internal static readonly double DmtxAlmostZero = 0.000001;
|
||||||
|
|
||||||
|
internal static readonly int DmtxModuleOff = 0x00;
|
||||||
|
internal static readonly int DmtxModuleOnRed = 0x01;
|
||||||
|
internal static readonly int DmtxModuleOnGreen = 0x02;
|
||||||
|
internal static readonly int DmtxModuleOnBlue = 0x04;
|
||||||
|
internal static readonly int DmtxModuleOnRGB = 0x07; /* OnRed | OnGreen | OnBlue */
|
||||||
|
internal static readonly int DmtxModuleOn = 0x07;
|
||||||
|
internal static readonly int DmtxModuleUnsure = 0x08;
|
||||||
|
internal static readonly int DmtxModuleAssigned = 0x10;
|
||||||
|
internal static readonly int DmtxModuleVisited = 0x20;
|
||||||
|
internal static readonly int DmtxModuleData = 0x40;
|
||||||
|
|
||||||
|
internal static readonly byte DmtxCharAsciiPad = 129;
|
||||||
|
internal static readonly byte DmtxCharAsciiUpperShift = 235;
|
||||||
|
internal static readonly byte DmtxCharTripletShift1 = 0;
|
||||||
|
internal static readonly byte DmtxCharTripletShift2 = 1;
|
||||||
|
internal static readonly byte DmtxCharTripletShift3 = 2;
|
||||||
|
internal static readonly byte DmtxCharFNC1 = 232;
|
||||||
|
internal static readonly byte DmtxCharStructuredAppend = 233;
|
||||||
|
internal static readonly byte DmtxChar05Macro = 236;
|
||||||
|
internal static readonly byte DmtxChar06Macro = 237;
|
||||||
|
|
||||||
|
internal static readonly int DmtxC40TextBasicSet = 0;
|
||||||
|
internal static readonly int DmtxC40TextShift1 = 1;
|
||||||
|
internal static readonly int DmtxC40TextShift2 = 2;
|
||||||
|
internal static readonly int DmtxC40TextShift3 = 3;
|
||||||
|
|
||||||
|
internal static readonly int DmtxCharTripletUnlatch = 254;
|
||||||
|
internal static readonly int DmtxCharEdifactUnlatch = 31;
|
||||||
|
|
||||||
|
internal static readonly byte DmtxCharC40Latch = 230;
|
||||||
|
internal static readonly byte DmtxCharTextLatch = 239;
|
||||||
|
internal static readonly byte DmtxCharX12Latch = 238;
|
||||||
|
internal static readonly byte DmtxCharEdifactLatch = 240;
|
||||||
|
internal static readonly byte DmtxCharBase256Latch = 231;
|
||||||
|
|
||||||
|
internal static readonly int[] SymbolRows = new int[] { 10, 12, 14, 16, 18, 20, 22, 24, 26,
|
||||||
|
32, 36, 40, 44, 48, 52,
|
||||||
|
64, 72, 80, 88, 96, 104,
|
||||||
|
120, 132, 144,
|
||||||
|
8, 8, 12, 12, 16, 16 };
|
||||||
|
|
||||||
|
internal static readonly int[] SymbolCols = new int[] { 10, 12, 14, 16, 18, 20, 22, 24, 26,
|
||||||
|
32, 36, 40, 44, 48, 52,
|
||||||
|
64, 72, 80, 88, 96, 104,
|
||||||
|
120, 132, 144,
|
||||||
|
18, 32, 26, 36, 36, 48 };
|
||||||
|
|
||||||
|
internal static readonly int[] DataRegionRows = new int[] { 8, 10, 12, 14, 16, 18, 20, 22, 24,
|
||||||
|
14, 16, 18, 20, 22, 24,
|
||||||
|
14, 16, 18, 20, 22, 24,
|
||||||
|
18, 20, 22,
|
||||||
|
6, 6, 10, 10, 14, 14 };
|
||||||
|
|
||||||
|
internal static readonly int[] DataRegionCols = new int[] { 8, 10, 12, 14, 16, 18, 20, 22, 24,
|
||||||
|
14, 16, 18, 20, 22, 24,
|
||||||
|
14, 16, 18, 20, 22, 24,
|
||||||
|
18, 20, 22,
|
||||||
|
16, 14, 24, 16, 16, 22 };
|
||||||
|
|
||||||
|
internal static readonly int[] HorizDataRegions = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
2, 2, 2, 2, 2, 2,
|
||||||
|
4, 4, 4, 4, 4, 4,
|
||||||
|
6, 6, 6,
|
||||||
|
1, 2, 1, 2, 2, 2 };
|
||||||
|
|
||||||
|
internal static readonly int[] InterleavedBlocks = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 2,
|
||||||
|
2, 4, 4, 4, 4, 6,
|
||||||
|
6, 8, 10,
|
||||||
|
1, 1, 1, 1, 1, 1 };
|
||||||
|
|
||||||
|
internal static readonly int[] SymbolDataWords = new int[] { 3, 5, 8, 12, 18, 22, 30, 36, 44,
|
||||||
|
62, 86, 114, 144, 174, 204,
|
||||||
|
280, 368, 456, 576, 696, 816,
|
||||||
|
1050, 1304, 1558,
|
||||||
|
5, 10, 16, 22, 32, 49 };
|
||||||
|
|
||||||
|
internal static readonly int[] BlockErrorWords = new int[] { 5, 7, 10, 12, 14, 18, 20, 24, 28,
|
||||||
|
36, 42, 48, 56, 68, 42,
|
||||||
|
56, 36, 48, 56, 68, 56,
|
||||||
|
68, 62, 62,
|
||||||
|
7, 11, 14, 18, 24, 28 };
|
||||||
|
|
||||||
|
internal static readonly int[] BlockMaxCorrectable = new int[] { 2, 3, 5, 6, 7, 9, 10, 12, 14,
|
||||||
|
18, 21, 24, 28, 34, 21,
|
||||||
|
28, 18, 24, 28, 34, 28,
|
||||||
|
34, 31, 31,
|
||||||
|
3, 5, 7, 9, 12, 14 };
|
||||||
|
internal static readonly int DmtxSymbolSquareCount = 24;
|
||||||
|
internal static readonly int DmtxSymbolRectCount = 6;
|
||||||
|
internal static readonly int DmtxUndefined = -1;
|
||||||
|
|
||||||
|
internal static readonly int[] DmtxPatternX = new int[] { -1, 0, 1, 1, 1, 0, -1, -1 };
|
||||||
|
internal static readonly int[] DmtxPatternY = new int[] { -1, -1, -1, 0, 1, 1, 1, 0 };
|
||||||
|
internal static readonly DmtxPointFlow DmtxBlankEdge = new DmtxPointFlow() { Plane = 0, Arrive = 0, Depart = 0, Mag = DmtxConstants.DmtxUndefined, Loc = new DmtxPixelLoc() { X = -1, Y = -1 } };
|
||||||
|
|
||||||
|
internal static readonly int DmtxHoughRes = 180;
|
||||||
|
internal static readonly int DmtxNeighborNone = 8;
|
||||||
|
|
||||||
|
internal static readonly int[] rHvX =
|
||||||
|
{ 256, 256, 256, 256, 255, 255, 255, 254, 254, 253, 252, 251, 250, 249, 248,
|
||||||
|
247, 246, 245, 243, 242, 241, 239, 237, 236, 234, 232, 230, 228, 226, 224,
|
||||||
|
222, 219, 217, 215, 212, 210, 207, 204, 202, 199, 196, 193, 190, 187, 184,
|
||||||
|
181, 178, 175, 171, 168, 165, 161, 158, 154, 150, 147, 143, 139, 136, 132,
|
||||||
|
128, 124, 120, 116, 112, 108, 104, 100, 96, 92, 88, 83, 79, 75, 71,
|
||||||
|
66, 62, 58, 53, 49, 44, 40, 36, 31, 27, 22, 18, 13, 9, 4,
|
||||||
|
0, -4, -9, -13, -18, -22, -27, -31, -36, -40, -44, -49, -53, -58, -62,
|
||||||
|
-66, -71, -75, -79, -83, -88, -92, -96, -100, -104, -108, -112, -116, -120, -124,
|
||||||
|
-128, -132, -136, -139, -143, -147, -150, -154, -158, -161, -165, -168, -171, -175, -178,
|
||||||
|
-181, -184, -187, -190, -193, -196, -199, -202, -204, -207, -210, -212, -215, -217, -219,
|
||||||
|
-222, -224, -226, -228, -230, -232, -234, -236, -237, -239, -241, -242, -243, -245, -246,
|
||||||
|
-247, -248, -249, -250, -251, -252, -253, -254, -254, -255, -255, -255, -256, -256, -256 };
|
||||||
|
|
||||||
|
internal static readonly int[] rHvY =
|
||||||
|
{ 0, 4, 9, 13, 18, 22, 27, 31, 36, 40, 44, 49, 53, 58, 62,
|
||||||
|
66, 71, 75, 79, 83, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
|
||||||
|
128, 132, 136, 139, 143, 147, 150, 154, 158, 161, 165, 168, 171, 175, 178,
|
||||||
|
181, 184, 187, 190, 193, 196, 199, 202, 204, 207, 210, 212, 215, 217, 219,
|
||||||
|
222, 224, 226, 228, 230, 232, 234, 236, 237, 239, 241, 242, 243, 245, 246,
|
||||||
|
247, 248, 249, 250, 251, 252, 253, 254, 254, 255, 255, 255, 256, 256, 256,
|
||||||
|
256, 256, 256, 256, 255, 255, 255, 254, 254, 253, 252, 251, 250, 249, 248,
|
||||||
|
247, 246, 245, 243, 242, 241, 239, 237, 236, 234, 232, 230, 228, 226, 224,
|
||||||
|
222, 219, 217, 215, 212, 210, 207, 204, 202, 199, 196, 193, 190, 187, 184,
|
||||||
|
181, 178, 175, 171, 168, 165, 161, 158, 154, 150, 147, 143, 139, 136, 132,
|
||||||
|
128, 124, 120, 116, 112, 108, 104, 100, 96, 92, 88, 83, 79, 75, 71,
|
||||||
|
66, 62, 58, 53, 49, 44, 40, 36, 31, 27, 22, 18, 13, 9, 4 };
|
||||||
|
|
||||||
|
internal static readonly int[] aLogVal =
|
||||||
|
{ 1, 2, 4, 8, 16, 32, 64, 128, 45, 90, 180, 69, 138, 57, 114, 228,
|
||||||
|
229, 231, 227, 235, 251, 219, 155, 27, 54, 108, 216, 157, 23, 46, 92, 184,
|
||||||
|
93, 186, 89, 178, 73, 146, 9, 18, 36, 72, 144, 13, 26, 52, 104, 208,
|
||||||
|
141, 55, 110, 220, 149, 7, 14, 28, 56, 112, 224, 237, 247, 195, 171, 123,
|
||||||
|
246, 193, 175, 115, 230, 225, 239, 243, 203, 187, 91, 182, 65, 130, 41, 82,
|
||||||
|
164, 101, 202, 185, 95, 190, 81, 162, 105, 210, 137, 63, 126, 252, 213, 135,
|
||||||
|
35, 70, 140, 53, 106, 212, 133, 39, 78, 156, 21, 42, 84, 168, 125, 250,
|
||||||
|
217, 159, 19, 38, 76, 152, 29, 58, 116, 232, 253, 215, 131, 43, 86, 172,
|
||||||
|
117, 234, 249, 223, 147, 11, 22, 44, 88, 176, 77, 154, 25, 50, 100, 200,
|
||||||
|
189, 87, 174, 113, 226, 233, 255, 211, 139, 59, 118, 236, 245, 199, 163, 107,
|
||||||
|
214, 129, 47, 94, 188, 85, 170, 121, 242, 201, 191, 83, 166, 97, 194, 169,
|
||||||
|
127, 254, 209, 143, 51, 102, 204, 181, 71, 142, 49, 98, 196, 165, 103, 206,
|
||||||
|
177, 79, 158, 17, 34, 68, 136, 61, 122, 244, 197, 167, 99, 198, 161, 111,
|
||||||
|
222, 145, 15, 30, 60, 120, 240, 205, 183, 67, 134, 33, 66, 132, 37, 74,
|
||||||
|
148, 5, 10, 20, 40, 80, 160, 109, 218, 153, 31, 62, 124, 248, 221, 151,
|
||||||
|
3, 6, 12, 24, 48, 96, 192, 173, 119, 238, 241, 207, 179, 75, 150, 1 };
|
||||||
|
|
||||||
|
internal static readonly int[] logVal =
|
||||||
|
{-255, 255, 1, 240, 2, 225, 241, 53, 3, 38, 226, 133, 242, 43, 54, 210,
|
||||||
|
4, 195, 39, 114, 227, 106, 134, 28, 243, 140, 44, 23, 55, 118, 211, 234,
|
||||||
|
5, 219, 196, 96, 40, 222, 115, 103, 228, 78, 107, 125, 135, 8, 29, 162,
|
||||||
|
244, 186, 141, 180, 45, 99, 24, 49, 56, 13, 119, 153, 212, 199, 235, 91,
|
||||||
|
6, 76, 220, 217, 197, 11, 97, 184, 41, 36, 223, 253, 116, 138, 104, 193,
|
||||||
|
229, 86, 79, 171, 108, 165, 126, 145, 136, 34, 9, 74, 30, 32, 163, 84,
|
||||||
|
245, 173, 187, 204, 142, 81, 181, 190, 46, 88, 100, 159, 25, 231, 50, 207,
|
||||||
|
57, 147, 14, 67, 120, 128, 154, 248, 213, 167, 200, 63, 236, 110, 92, 176,
|
||||||
|
7, 161, 77, 124, 221, 102, 218, 95, 198, 90, 12, 152, 98, 48, 185, 179,
|
||||||
|
42, 209, 37, 132, 224, 52, 254, 239, 117, 233, 139, 22, 105, 27, 194, 113,
|
||||||
|
230, 206, 87, 158, 80, 189, 172, 203, 109, 175, 166, 62, 127, 247, 146, 66,
|
||||||
|
137, 192, 35, 252, 10, 183, 75, 216, 31, 83, 33, 73, 164, 144, 85, 170,
|
||||||
|
246, 65, 174, 61, 188, 202, 205, 157, 143, 169, 82, 72, 182, 215, 191, 251,
|
||||||
|
47, 178, 89, 151, 101, 94, 160, 123, 26, 112, 232, 21, 51, 238, 208, 131,
|
||||||
|
58, 69, 148, 18, 15, 16, 68, 17, 121, 149, 129, 19, 155, 59, 249, 70,
|
||||||
|
214, 250, 168, 71, 201, 156, 64, 60, 237, 130, 111, 20, 93, 122, 177, 150 };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DmtxFormat
|
||||||
|
{
|
||||||
|
Matrix,
|
||||||
|
Mosaic,
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DmtxSymAttribute
|
||||||
|
{
|
||||||
|
DmtxSymAttribSymbolRows,
|
||||||
|
DmtxSymAttribSymbolCols,
|
||||||
|
DmtxSymAttribDataRegionRows,
|
||||||
|
DmtxSymAttribDataRegionCols,
|
||||||
|
DmtxSymAttribHorizDataRegions,
|
||||||
|
DmtxSymAttribVertDataRegions,
|
||||||
|
DmtxSymAttribMappingMatrixRows,
|
||||||
|
DmtxSymAttribMappingMatrixCols,
|
||||||
|
DmtxSymAttribInterleavedBlocks,
|
||||||
|
DmtxSymAttribBlockErrorWords,
|
||||||
|
DmtxSymAttribBlockMaxCorrectable,
|
||||||
|
DmtxSymAttribSymbolDataWords,
|
||||||
|
DmtxSymAttribSymbolErrorWords,
|
||||||
|
DmtxSymAttribSymbolMaxCorrectable
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DmtxSymbolSize
|
||||||
|
{
|
||||||
|
DmtxSymbolRectAuto = -3,
|
||||||
|
DmtxSymbolSquareAuto = -2,
|
||||||
|
DmtxSymbolShapeAuto = -1,
|
||||||
|
DmtxSymbol10x10 = 0,
|
||||||
|
DmtxSymbol12x12,
|
||||||
|
DmtxSymbol14x14,
|
||||||
|
DmtxSymbol16x16,
|
||||||
|
DmtxSymbol18x18,
|
||||||
|
DmtxSymbol20x20,
|
||||||
|
DmtxSymbol22x22,
|
||||||
|
DmtxSymbol24x24,
|
||||||
|
DmtxSymbol26x26,
|
||||||
|
DmtxSymbol32x32,
|
||||||
|
DmtxSymbol36x36,
|
||||||
|
DmtxSymbol40x40,
|
||||||
|
DmtxSymbol44x44,
|
||||||
|
DmtxSymbol48x48,
|
||||||
|
DmtxSymbol52x52,
|
||||||
|
DmtxSymbol64x64,
|
||||||
|
DmtxSymbol72x72,
|
||||||
|
DmtxSymbol80x80,
|
||||||
|
DmtxSymbol88x88,
|
||||||
|
DmtxSymbol96x96,
|
||||||
|
DmtxSymbol104x104,
|
||||||
|
DmtxSymbol120x120,
|
||||||
|
DmtxSymbol132x132,
|
||||||
|
DmtxSymbol144x144,
|
||||||
|
DmtxSymbol8x18,
|
||||||
|
DmtxSymbol8x32,
|
||||||
|
DmtxSymbol12x26,
|
||||||
|
DmtxSymbol12x36,
|
||||||
|
DmtxSymbol16x36,
|
||||||
|
DmtxSymbol16x48
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DmtxFlip
|
||||||
|
{
|
||||||
|
DmtxFlipNone = 0x00,
|
||||||
|
DmtxFlipX = 0x01 << 0,
|
||||||
|
DmtxFlipY = 0x01 << 1
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DmtxPackOrder
|
||||||
|
{
|
||||||
|
/* Custom format */
|
||||||
|
DmtxPackCustom = 100,
|
||||||
|
/* 1 bpp */
|
||||||
|
DmtxPack1bppK = 200,
|
||||||
|
/* 8 bpp grayscale */
|
||||||
|
DmtxPack8bppK = 300,
|
||||||
|
/* 16 bpp formats */
|
||||||
|
DmtxPack16bppRGB = 400,
|
||||||
|
DmtxPack16bppRGBX,
|
||||||
|
DmtxPack16bppXRGB,
|
||||||
|
DmtxPack16bppBGR,
|
||||||
|
DmtxPack16bppBGRX,
|
||||||
|
DmtxPack16bppXBGR,
|
||||||
|
DmtxPack16bppYCbCr,
|
||||||
|
/* 24 bpp formats */
|
||||||
|
DmtxPack24bppRGB = 500,
|
||||||
|
DmtxPack24bppBGR,
|
||||||
|
DmtxPack24bppYCbCr,
|
||||||
|
/* 32 bpp formats */
|
||||||
|
DmtxPack32bppRGBX = 600,
|
||||||
|
DmtxPack32bppXRGB,
|
||||||
|
DmtxPack32bppBGRX,
|
||||||
|
DmtxPack32bppXBGR,
|
||||||
|
DmtxPack32bppCMYK
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DmtxRange
|
||||||
|
{
|
||||||
|
DmtxRangeGood,
|
||||||
|
DmtxRangeBad,
|
||||||
|
DmtxRangeEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DmtxDirection
|
||||||
|
{
|
||||||
|
DmtxDirNone = 0x00,
|
||||||
|
DmtxDirUp = 0x01 << 0,
|
||||||
|
DmtxDirLeft = 0x01 << 1,
|
||||||
|
DmtxDirDown = 0x01 << 2,
|
||||||
|
DmtxDirRight = 0x01 << 3,
|
||||||
|
DmtxDirHorizontal = DmtxDirLeft | DmtxDirRight,
|
||||||
|
DmtxDirVertical = DmtxDirUp | DmtxDirDown,
|
||||||
|
DmtxDirRightUp = DmtxDirRight | DmtxDirUp,
|
||||||
|
DmtxDirLeftDown = DmtxDirLeft | DmtxDirDown
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DmtxScheme
|
||||||
|
{
|
||||||
|
DmtxSchemeAutoFast = -2,
|
||||||
|
DmtxSchemeAutoBest = -1,
|
||||||
|
DmtxSchemeAscii = 0,
|
||||||
|
DmtxSchemeC40,
|
||||||
|
DmtxSchemeText,
|
||||||
|
DmtxSchemeX12,
|
||||||
|
DmtxSchemeEdifact,
|
||||||
|
DmtxSchemeBase256,
|
||||||
|
DmtxSchemeAsciiGS1
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DmtxMaskBit
|
||||||
|
{
|
||||||
|
DmtxMaskBit8 = 0x01 << 0,
|
||||||
|
DmtxMaskBit7 = 0x01 << 1,
|
||||||
|
DmtxMaskBit6 = 0x01 << 2,
|
||||||
|
DmtxMaskBit5 = 0x01 << 3,
|
||||||
|
DmtxMaskBit4 = 0x01 << 4,
|
||||||
|
DmtxMaskBit3 = 0x01 << 5,
|
||||||
|
DmtxMaskBit2 = 0x01 << 6,
|
||||||
|
DmtxMaskBit1 = 0x01 << 7
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum DmtxEdge
|
||||||
|
{
|
||||||
|
DmtxEdgeTop = 0x01 << 0,
|
||||||
|
DmtxEdgeBottom = 0x01 << 1,
|
||||||
|
DmtxEdgeLeft = 0x01 << 2,
|
||||||
|
DmtxEdgeRight = 0x01 << 3
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DmtxChannelStatus
|
||||||
|
{
|
||||||
|
DmtxChannelValid = 0x00,
|
||||||
|
DmtxChannelUnsupportedChar = 0x01 << 0,
|
||||||
|
DmtxChannelCannotUnlatch = 0x01 << 1
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DmtxUnlatch
|
||||||
|
{
|
||||||
|
Explicit,
|
||||||
|
Implicit
|
||||||
|
}
|
||||||
|
}
|
||||||
2236
DataMatrix.net/DmtxDecode.cs
Normal file
2236
DataMatrix.net/DmtxDecode.cs
Normal file
File diff suppressed because it is too large
Load Diff
1679
DataMatrix.net/DmtxEncode.cs
Normal file
1679
DataMatrix.net/DmtxEncode.cs
Normal file
File diff suppressed because it is too large
Load Diff
81
DataMatrix.net/DmtxFollow.cs
Normal file
81
DataMatrix.net/DmtxFollow.cs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal struct DmtxFollow
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
int _ptrIndex;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
internal int PtrIndex
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_ptrIndex = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal byte CurrentPtr
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Ptr[_ptrIndex];
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.Ptr[_ptrIndex] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal byte[] Ptr { get; set; }
|
||||||
|
|
||||||
|
internal byte Neighbor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Ptr[_ptrIndex];
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.Ptr[_ptrIndex] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int Step { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc Loc { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
269
DataMatrix.net/DmtxImage.cs
Normal file
269
DataMatrix.net/DmtxImage.cs
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal class DmtxImage
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
int _rowPadBytes;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
internal DmtxImage(byte[] pxl, int width, int height, DmtxPackOrder pack)
|
||||||
|
{
|
||||||
|
this.BitsPerChannel = new int[4];
|
||||||
|
this.ChannelStart = new int[4];
|
||||||
|
if (pxl == null || width < 1 || height < 1)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Cannot create image of size null");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Pxl = pxl;
|
||||||
|
this.Width = width;
|
||||||
|
this.Height = height;
|
||||||
|
this.PixelPacking = pack;
|
||||||
|
this.BitsPerPixel = DmtxCommon.GetBitsPerPixel(pack);
|
||||||
|
this.BytesPerPixel = this.BitsPerPixel / 8;
|
||||||
|
this._rowPadBytes = 0;
|
||||||
|
this.RowSizeBytes = this.Width * this.BytesPerPixel + this._rowPadBytes;
|
||||||
|
this.ImageFlip = DmtxFlip.DmtxFlipNone;
|
||||||
|
|
||||||
|
/* Leave channelStart[] and bitsPerChannel[] with zeros from calloc */
|
||||||
|
this.ChannelCount = 0;
|
||||||
|
|
||||||
|
switch (pack)
|
||||||
|
{
|
||||||
|
case DmtxPackOrder.DmtxPackCustom:
|
||||||
|
break;
|
||||||
|
case DmtxPackOrder.DmtxPack1bppK:
|
||||||
|
throw new ArgumentException("Cannot create image: not supported pack order!");
|
||||||
|
case DmtxPackOrder.DmtxPack8bppK:
|
||||||
|
SetChannel(0, 8);
|
||||||
|
break;
|
||||||
|
case DmtxPackOrder.DmtxPack16bppRGB:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppBGR:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppYCbCr:
|
||||||
|
SetChannel(0, 5);
|
||||||
|
SetChannel(5, 5);
|
||||||
|
SetChannel(10, 5);
|
||||||
|
break;
|
||||||
|
case DmtxPackOrder.DmtxPack24bppRGB:
|
||||||
|
case DmtxPackOrder.DmtxPack24bppBGR:
|
||||||
|
case DmtxPackOrder.DmtxPack24bppYCbCr:
|
||||||
|
case DmtxPackOrder.DmtxPack32bppRGBX:
|
||||||
|
case DmtxPackOrder.DmtxPack32bppBGRX:
|
||||||
|
SetChannel(0, 8);
|
||||||
|
SetChannel(8, 8);
|
||||||
|
SetChannel(16, 8);
|
||||||
|
break;
|
||||||
|
case DmtxPackOrder.DmtxPack16bppRGBX:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppBGRX:
|
||||||
|
SetChannel(0, 5);
|
||||||
|
SetChannel(5, 5);
|
||||||
|
SetChannel(10, 5);
|
||||||
|
break;
|
||||||
|
case DmtxPackOrder.DmtxPack16bppXRGB:
|
||||||
|
case DmtxPackOrder.DmtxPack16bppXBGR:
|
||||||
|
SetChannel(1, 5);
|
||||||
|
SetChannel(6, 5);
|
||||||
|
SetChannel(11, 5);
|
||||||
|
break;
|
||||||
|
case DmtxPackOrder.DmtxPack32bppXRGB:
|
||||||
|
case DmtxPackOrder.DmtxPack32bppXBGR:
|
||||||
|
SetChannel(8, 8);
|
||||||
|
SetChannel(16, 8);
|
||||||
|
SetChannel(24, 8);
|
||||||
|
break;
|
||||||
|
case DmtxPackOrder.DmtxPack32bppCMYK:
|
||||||
|
SetChannel(0, 8);
|
||||||
|
SetChannel(8, 8);
|
||||||
|
SetChannel(16, 8);
|
||||||
|
SetChannel(24, 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException("Cannot create image: Invalid Pack Order");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
internal bool SetChannel(int channelStart, int bitsPerChannel)
|
||||||
|
{
|
||||||
|
if (this.ChannelCount >= 4) /* IMAGE_MAX_CHANNEL */
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* New channel extends beyond pixel data */
|
||||||
|
|
||||||
|
this.BitsPerChannel[this.ChannelCount] = bitsPerChannel;
|
||||||
|
this.ChannelStart[this.ChannelCount] = channelStart;
|
||||||
|
(this.ChannelCount)++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int GetByteOffset(int x, int y)
|
||||||
|
{
|
||||||
|
if (this.ImageFlip == DmtxFlip.DmtxFlipX)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("DmtxFlipX is not an option!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ContainsInt(0, x, y))
|
||||||
|
return DmtxConstants.DmtxUndefined;
|
||||||
|
|
||||||
|
if (this.ImageFlip == DmtxFlip.DmtxFlipY)
|
||||||
|
return (y * this.RowSizeBytes + x * this.BytesPerPixel);
|
||||||
|
|
||||||
|
return ((this.Height - y - 1) * this.RowSizeBytes + x * this.BytesPerPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool GetPixelValue(int x, int y, int channel, ref int value)
|
||||||
|
{
|
||||||
|
if (channel >= this.ChannelCount)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Channel greater than channel count!");
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = GetByteOffset(x, y);
|
||||||
|
if (offset == DmtxConstants.DmtxUndefined)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (this.BitsPerChannel[channel])
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if (this.ChannelStart[channel] % 8 != 0 || this.BitsPerPixel % 8 != 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Error getting pixel value");
|
||||||
|
}
|
||||||
|
value = this.Pxl[offset + channel];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool SetPixelValue(int x, int y, int channel, byte value)
|
||||||
|
{
|
||||||
|
if (channel >= this.ChannelCount)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Channel greater than channel count!");
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = GetByteOffset(x, y);
|
||||||
|
if (offset == DmtxConstants.DmtxUndefined)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (this.BitsPerChannel[channel])
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if (this.ChannelStart[channel] % 8 != 0 || this.BitsPerPixel % 8 != 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Error getting pixel value");
|
||||||
|
}
|
||||||
|
this.Pxl[offset + channel] = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool ContainsInt(int margin, int x, int y)
|
||||||
|
{
|
||||||
|
if (x - margin >= 0 && x + margin < this.Width &&
|
||||||
|
y - margin >= 0 && y + margin < this.Height)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool ContainsFloat(double x, double y)
|
||||||
|
{
|
||||||
|
if (x >= 0.0 && x < this.Width && y >= 0.0 && y < this.Height)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
internal int Width { get; set; }
|
||||||
|
|
||||||
|
internal int Height { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPackOrder PixelPacking { get; set; }
|
||||||
|
|
||||||
|
internal int BitsPerPixel { get; set; }
|
||||||
|
|
||||||
|
internal int BytesPerPixel { get; set; }
|
||||||
|
|
||||||
|
internal int RowPadBytes
|
||||||
|
{
|
||||||
|
get { return _rowPadBytes; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_rowPadBytes = value;
|
||||||
|
this.RowSizeBytes = this.Width * (this.BitsPerPixel / 8) + this._rowPadBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int RowSizeBytes { get; set; }
|
||||||
|
|
||||||
|
internal DmtxFlip ImageFlip { get; set; }
|
||||||
|
|
||||||
|
internal int ChannelCount { get; set; }
|
||||||
|
|
||||||
|
internal int[] ChannelStart { get; set; }
|
||||||
|
|
||||||
|
internal int[] BitsPerChannel { get; set; }
|
||||||
|
|
||||||
|
internal byte[] Pxl { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
154
DataMatrix.net/DmtxImageDecoder.cs
Normal file
154
DataMatrix.net/DmtxImageDecoder.cs
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
public class DmtxImageDecoder
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// returns a list of all decoded DataMatrix codes in the image provided
|
||||||
|
/// </summary>
|
||||||
|
public List<string> DecodeImage(Bitmap image)
|
||||||
|
{
|
||||||
|
return DecodeImage(image, int.MaxValue, TimeSpan.MaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns a list of all decoded DataMatrix codes in the image provided
|
||||||
|
/// that can be found in the given time span
|
||||||
|
/// </summary>
|
||||||
|
public List<string> DecodeImage(Bitmap image, TimeSpan timeSpan)
|
||||||
|
{
|
||||||
|
return DecodeImage(image, int.MaxValue, timeSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns a list of all decoded DataMatrix codes in the image provided
|
||||||
|
/// </summary>
|
||||||
|
public List<string> DecodeImageMosaic(Bitmap image)
|
||||||
|
{
|
||||||
|
return DecodeImageMosaic(image, int.MaxValue, TimeSpan.MaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns a list of DataMatrix codes in the image provided that can be
|
||||||
|
/// found in the given time span, but no more than maxResultCount codes
|
||||||
|
/// (useful, if you e.g. expect only one code to be in the image)
|
||||||
|
/// </summary>
|
||||||
|
public List<string> DecodeImageMosaic(Bitmap image, int maxResultCount, TimeSpan timeOut)
|
||||||
|
{
|
||||||
|
return DecodeImage(image, maxResultCount, timeOut, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns a list of all decoded DataMatrix codes in the image provided
|
||||||
|
/// that can be found in the given time span
|
||||||
|
/// </summary>
|
||||||
|
public List<string> DecodeImageMosaic(Bitmap image, TimeSpan timeSpan)
|
||||||
|
{
|
||||||
|
return DecodeImage(image, int.MaxValue, timeSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns a list of DataMatrix codes in the image provided that can be
|
||||||
|
/// found in the given time span, but no more than maxResultCount codes
|
||||||
|
/// (useful, if you e.g. expect only one code to be in the image)
|
||||||
|
/// </summary>
|
||||||
|
public List<string> DecodeImage(Bitmap image, int maxResultCount, TimeSpan timeOut)
|
||||||
|
{
|
||||||
|
return DecodeImage(image, maxResultCount, timeOut, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<string> DecodeImage(Bitmap image, int maxResultCount, TimeSpan timeOut, bool isMosaic)
|
||||||
|
{
|
||||||
|
List<string> result = new List<string>();
|
||||||
|
int stride;
|
||||||
|
byte[] rawImg = ImageToByteArray(image, out stride);
|
||||||
|
DmtxImage dmtxImg = new DmtxImage(rawImg, image.Width, image.Height, DmtxPackOrder.DmtxPack24bppRGB);
|
||||||
|
dmtxImg.RowPadBytes = stride % 3;
|
||||||
|
DmtxDecode decode = new DmtxDecode(dmtxImg, 1);
|
||||||
|
Stopwatch stopWatch = new Stopwatch();
|
||||||
|
stopWatch.Start();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (stopWatch.Elapsed > timeOut)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DmtxRegion region = decode.RegionFindNext(timeOut);
|
||||||
|
if (region != null)
|
||||||
|
{
|
||||||
|
DmtxMessage msg = isMosaic ? decode.MosaicRegion(region, -1) : decode.MatrixRegion(region, -1);
|
||||||
|
string message = Encoding.ASCII.GetString(msg.Output, 0, msg.Output.Length);
|
||||||
|
message = message.Substring(0, message.IndexOf('\0'));
|
||||||
|
if (!result.Contains(message))
|
||||||
|
{
|
||||||
|
result.Add(message);
|
||||||
|
if (result.Count >= maxResultCount)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private byte[] ImageToByteArray(Bitmap b, out int stride)
|
||||||
|
{
|
||||||
|
Rectangle rect = new Rectangle(0, 0, b.Width, b.Height);
|
||||||
|
BitmapData bd = b.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] pxl = new byte[bd.Stride * b.Height];
|
||||||
|
Marshal.Copy(bd.Scan0, pxl, 0, bd.Stride * b.Height);
|
||||||
|
stride = bd.Stride;
|
||||||
|
return pxl;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
b.UnlockBits(bd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
318
DataMatrix.net/DmtxImageEncoder.cs
Normal file
318
DataMatrix.net/DmtxImageEncoder.cs
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
public class DmtxImageEncoder
|
||||||
|
{
|
||||||
|
public static readonly int DefaultDotSize = 5;
|
||||||
|
public static readonly int DefaultMargin = 10;
|
||||||
|
public static readonly Color DefaultBackColor = Color.White;
|
||||||
|
public static readonly Color DefaultForeColor = Color.Black;
|
||||||
|
|
||||||
|
public Bitmap EncodeImageMosaic(string val)
|
||||||
|
{
|
||||||
|
return EncodeImageMosaic(val, DefaultDotSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap EncodeImageMosaic(string val, int dotSize)
|
||||||
|
{
|
||||||
|
return EncodeImageMosaic(val, dotSize, DefaultMargin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap EncodeImageMosaic(string val, int dotSize, int margin)
|
||||||
|
{
|
||||||
|
DmtxImageEncoderOptions options = new DmtxImageEncoderOptions {MarginSize = margin, ModuleSize = dotSize};
|
||||||
|
return EncodeImageMosaic(val, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap EncodeImageMosaic(string val, DmtxImageEncoderOptions options)
|
||||||
|
{
|
||||||
|
return EncodeImage(val, options, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap EncodeImage(string val, DmtxImageEncoderOptions options, bool isMosaic)
|
||||||
|
{
|
||||||
|
DmtxEncode encode = new DmtxEncode
|
||||||
|
{
|
||||||
|
ModuleSize = options.ModuleSize,
|
||||||
|
MarginSize = options.MarginSize,
|
||||||
|
SizeIdxRequest = options.SizeIdx
|
||||||
|
};
|
||||||
|
byte[] valAsByteArray = GetRawDataAndSetEncoding(val, options, encode);
|
||||||
|
if (isMosaic)
|
||||||
|
{
|
||||||
|
encode.EncodeDataMosaic(valAsByteArray);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
encode.EncodeDataMatrix(options.ForeColor, options.BackColor, valAsByteArray);
|
||||||
|
}
|
||||||
|
return CopyDataToBitmap(encode.Image.Pxl, encode.Image.Width, encode.Image.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] GetRawDataAndSetEncoding(string code, DmtxImageEncoderOptions options, DmtxEncode encode)
|
||||||
|
{
|
||||||
|
byte[] result = options.Encoding.GetBytes(code);
|
||||||
|
encode.Scheme = options.Scheme;
|
||||||
|
if (options.Scheme == DmtxScheme.DmtxSchemeAsciiGS1)
|
||||||
|
{
|
||||||
|
List<byte> prefixedRawData = new List<byte>(new[] { (byte)232 });
|
||||||
|
prefixedRawData.AddRange(result);
|
||||||
|
result = prefixedRawData.ToArray();
|
||||||
|
encode.Scheme = DmtxScheme.DmtxSchemeAscii;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap EncodeImage(string val)
|
||||||
|
{
|
||||||
|
return EncodeImage(val, DefaultDotSize, DefaultMargin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap EncodeImage(string val, int dotSize)
|
||||||
|
{
|
||||||
|
return EncodeImage(val, dotSize, DefaultMargin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap EncodeImage(string val, int dotSize, int margin)
|
||||||
|
{
|
||||||
|
DmtxImageEncoderOptions options = new DmtxImageEncoderOptions {MarginSize = margin, ModuleSize = dotSize};
|
||||||
|
return EncodeImage(val, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap EncodeImage(string val, DmtxImageEncoderOptions options)
|
||||||
|
{
|
||||||
|
return EncodeImage(val, options, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EncodeSvgImage(string val)
|
||||||
|
{
|
||||||
|
return EncodeSvgImage(val, DefaultDotSize, DefaultMargin, DefaultForeColor, DefaultBackColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EncodeSvgImage(string val, int dotSize)
|
||||||
|
{
|
||||||
|
return EncodeSvgImage(val, dotSize, DefaultMargin, DefaultForeColor, DefaultBackColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EncodeSvgImage(string val, int dotSize, int margin)
|
||||||
|
{
|
||||||
|
return EncodeSvgImage(val, dotSize, margin, DefaultForeColor, DefaultBackColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EncodeSvgImage(string val, int dotSize, int margin, Color foreColor, Color backColor)
|
||||||
|
{
|
||||||
|
DmtxImageEncoderOptions options = new DmtxImageEncoderOptions
|
||||||
|
{
|
||||||
|
ModuleSize = dotSize,
|
||||||
|
MarginSize = margin,
|
||||||
|
ForeColor = foreColor,
|
||||||
|
BackColor = backColor
|
||||||
|
};
|
||||||
|
return EncodeSvgImage(val, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool[,] EncodeRawData(string val)
|
||||||
|
{
|
||||||
|
return EncodeRawData(val, new DmtxImageEncoderOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool[,] EncodeRawData(string val, DmtxImageEncoderOptions options)
|
||||||
|
{
|
||||||
|
DmtxEncode encode = new DmtxEncode
|
||||||
|
{
|
||||||
|
ModuleSize = 1,
|
||||||
|
MarginSize = 0,
|
||||||
|
SizeIdxRequest = options.SizeIdx,
|
||||||
|
Scheme = options.Scheme
|
||||||
|
};
|
||||||
|
|
||||||
|
byte[] valAsByteArray = GetRawDataAndSetEncoding(val, options, encode);
|
||||||
|
|
||||||
|
encode.EncodeDataMatrixRaw(valAsByteArray);
|
||||||
|
|
||||||
|
return encode.RawData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EncodeSvgImage(string val, DmtxImageEncoderOptions options)
|
||||||
|
{
|
||||||
|
DmtxEncode encode = new DmtxEncode
|
||||||
|
{
|
||||||
|
ModuleSize = options.ModuleSize,
|
||||||
|
MarginSize = options.MarginSize,
|
||||||
|
SizeIdxRequest = options.SizeIdx,
|
||||||
|
Scheme = options.Scheme
|
||||||
|
};
|
||||||
|
|
||||||
|
byte[] valAsByteArray = GetRawDataAndSetEncoding(val, options, encode);
|
||||||
|
|
||||||
|
encode.EncodeDataMatrix(options.ForeColor, options.BackColor, valAsByteArray);
|
||||||
|
|
||||||
|
return EncodeSvgFile(encode, "", options.ModuleSize, options.MarginSize, options.ForeColor, options.BackColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Bitmap CopyDataToBitmap(byte[] data, int width, int height)
|
||||||
|
{
|
||||||
|
data = InsertPaddingBytes(data, width, height, 24);
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(width, height);
|
||||||
|
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
|
||||||
|
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
|
||||||
|
bmp.UnlockBits(bmpData);
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] InsertPaddingBytes(byte[] data, int width, int height, int bitsPerPixel)
|
||||||
|
{
|
||||||
|
int paddedWidth = 4 * ((width * bitsPerPixel + 31) / 32);
|
||||||
|
int padding = paddedWidth - 3 * width;
|
||||||
|
if (padding == 0)
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
byte[] newData = new byte[paddedWidth * height];
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < width; j++)
|
||||||
|
{
|
||||||
|
newData[i * paddedWidth + 3 * j] = data[3 * (i * width + j)];
|
||||||
|
newData[i * paddedWidth + 3 * j + 1] = data[3 * (i * width + j) + 1];
|
||||||
|
newData[i * paddedWidth + 3 * j + 2] = data[3 * (i * width + j) + 2];
|
||||||
|
}
|
||||||
|
for (int k = 0; k < padding; k++)
|
||||||
|
{
|
||||||
|
newData[i * paddedWidth + 3 * k] = 255;
|
||||||
|
newData[i * paddedWidth + 3 * k + 1] = 255;
|
||||||
|
newData[i * paddedWidth + 3 * k + 2] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NumberFormatInfo _dotFormatProvider;
|
||||||
|
|
||||||
|
internal string EncodeSvgFile(DmtxEncode enc, string format, int moduleSize, int margin, Color foreColor, Color backColor)
|
||||||
|
{
|
||||||
|
bool defineOnly = false;
|
||||||
|
string idString = null;
|
||||||
|
string style;
|
||||||
|
string outputString = "";
|
||||||
|
|
||||||
|
if (_dotFormatProvider == null)
|
||||||
|
{
|
||||||
|
_dotFormatProvider = new NumberFormatInfo {NumberDecimalSeparator = "."};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == "svg:")
|
||||||
|
{
|
||||||
|
defineOnly = true;
|
||||||
|
idString = format.Substring(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(idString))
|
||||||
|
{
|
||||||
|
idString = "dmtx_0001";
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = 2 * enc.MarginSize + (enc.Region.SymbolCols * enc.ModuleSize);
|
||||||
|
int height = 2 * enc.MarginSize + (enc.Region.SymbolRows * enc.ModuleSize);
|
||||||
|
|
||||||
|
int symbolCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolCols, enc.Region.SizeIdx);
|
||||||
|
int symbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, enc.Region.SizeIdx);
|
||||||
|
|
||||||
|
/* Print SVG Header */
|
||||||
|
if (!defineOnly)
|
||||||
|
{
|
||||||
|
outputString += string.Format(
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
|
||||||
|
"<!-- Created with DataMatrix.net (http://datamatrixnet.sourceforge.net/) -->\n" +
|
||||||
|
"<svg\n" +
|
||||||
|
"xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +
|
||||||
|
"xmlns=\"http://www.w3.org/2000/svg\"\n" +
|
||||||
|
"xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" +
|
||||||
|
"version=\"1.0\"\n" +
|
||||||
|
"width=\"{0}\"\n" +
|
||||||
|
"height=\"{1}\"\n" +
|
||||||
|
"id=\"svg2\">\n" +
|
||||||
|
"<defs>\n" +
|
||||||
|
"<symbol id=\"{2}\">\n" +
|
||||||
|
" <desc>Layout:{0}x%{1} Symbol:{3}x{4} Data Matrix</desc>\n", width, height, idString, symbolCols, symbolRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backColor != Color.White)
|
||||||
|
{
|
||||||
|
style = string.Format("style=\"fill:#{0}{1}{2};fill-opacity:{3};stroke:none\" ",
|
||||||
|
backColor.R.ToString("X2"), backColor.G.ToString("X2"), backColor.B.ToString("X2"), ((double)backColor.A / (double)byte.MaxValue).ToString("0.##", _dotFormatProvider));
|
||||||
|
outputString += string.Format(" <rect width=\"{0}\" height=\"{1}\" x=\"0\" y=\"0\" {2}/>\n",
|
||||||
|
width, height, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write Data Matrix ON modules */
|
||||||
|
for (int row = 0; row < enc.Region.SymbolRows; row++)
|
||||||
|
{
|
||||||
|
int rowInv = enc.Region.SymbolRows - row - 1;
|
||||||
|
for (int col = 0; col < enc.Region.SymbolCols; col++)
|
||||||
|
{
|
||||||
|
int module = enc.Message.SymbolModuleStatus(enc.Region.SizeIdx, row, col);
|
||||||
|
style = string.Format("style=\"fill:#{0}{1}{2};fill-opacity:{3};stroke:none\" ",
|
||||||
|
foreColor.R.ToString("X2"), foreColor.G.ToString("X2"), foreColor.B.ToString("X2"), ((double)foreColor.A / (double)byte.MaxValue).ToString("0.##", _dotFormatProvider));
|
||||||
|
|
||||||
|
if ((module & DmtxConstants.DmtxModuleOn) != 0)
|
||||||
|
{
|
||||||
|
outputString += string.Format(" <rect width=\"{0}\" height=\"{1}\" x=\"{2}\" y=\"{3}\" {4}/>\n",
|
||||||
|
moduleSize, moduleSize,
|
||||||
|
col * moduleSize + margin,
|
||||||
|
rowInv * moduleSize + margin, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputString += " </symbol>\n";
|
||||||
|
|
||||||
|
/* Close SVG document */
|
||||||
|
if (!defineOnly)
|
||||||
|
{
|
||||||
|
outputString += string.Format("</defs>\n" +
|
||||||
|
"<use xlink:href=\"#{0}\" x='0' y='0' style=\"fill:#000000;fill-opacity:1;stroke:none\" />\n" +
|
||||||
|
"\n</svg>\n", idString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
DataMatrix.net/DmtxImageEncoderOptions.cs
Normal file
73
DataMatrix.net/DmtxImageEncoderOptions.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
public class DmtxImageEncoderOptions
|
||||||
|
{
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public DmtxImageEncoderOptions()
|
||||||
|
{
|
||||||
|
BackColor = Color.White;
|
||||||
|
ForeColor = Color.Black;
|
||||||
|
SizeIdx = DmtxSymbolSize.DmtxSymbolSquareAuto;
|
||||||
|
Scheme = DmtxScheme.DmtxSchemeAscii;
|
||||||
|
ModuleSize = 5;
|
||||||
|
MarginSize = 10;
|
||||||
|
Encoding = Encoding.ASCII;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public int MarginSize { get; set; }
|
||||||
|
|
||||||
|
public int ModuleSize { get; set; }
|
||||||
|
|
||||||
|
public DmtxScheme Scheme { get; set; }
|
||||||
|
|
||||||
|
public DmtxSymbolSize SizeIdx { get; set; }
|
||||||
|
|
||||||
|
public Color ForeColor { get; set; }
|
||||||
|
|
||||||
|
public Color BackColor { get; set; }
|
||||||
|
|
||||||
|
public Encoding Encoding { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
249
DataMatrix.net/DmtxMatrix3.cs
Normal file
249
DataMatrix.net/DmtxMatrix3.cs
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal class DmtxMatrix3
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
double[,] _data;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
DmtxMatrix3()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// copy constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="src">the matrix to copy</param>
|
||||||
|
internal DmtxMatrix3(DmtxMatrix3 src)
|
||||||
|
{
|
||||||
|
_data = new[,] { { src[0, 0], src[0, 1], src[0, 2] }, { src[1, 0], src[1, 1], src[1, 2] }, { src[2, 0], src[2, 1], src[2, 2] } };
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region internal Static Methods
|
||||||
|
/// <summary>
|
||||||
|
/// creates a 3x3 identitiy matrix:<para />
|
||||||
|
/// 1 0 0<para />
|
||||||
|
/// 0 1 0<para />
|
||||||
|
/// 0 0 1
|
||||||
|
/// </summary>
|
||||||
|
internal static DmtxMatrix3 Identity()
|
||||||
|
{
|
||||||
|
return Translate(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// generates a 3x3 translate transformation matrix
|
||||||
|
/// 1 0 0<para />
|
||||||
|
/// 0 1 0<para />
|
||||||
|
/// tx ty 1
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tx"></param>
|
||||||
|
/// <param name="ty"></param>
|
||||||
|
internal static DmtxMatrix3 Translate(double tx, double ty)
|
||||||
|
{
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3 {_data = new[,] {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {tx, ty, 1.0}}};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// generates a 3x3 rotate transformation matrix
|
||||||
|
/// cos(angle) sin(angle) 0<para />
|
||||||
|
/// -sin(angle) cos(angle) 0<para />
|
||||||
|
/// 0 0 1
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="angle"></param>
|
||||||
|
internal static DmtxMatrix3 Rotate(double angle)
|
||||||
|
{
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3 { _data = new[,] {
|
||||||
|
{Math.Cos(angle), Math.Sin(angle), 0.0},
|
||||||
|
{-Math.Sin(angle), Math.Cos(angle), 0.0}, {0, 0, 1.0} }};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// generates a 3x3 scale transformation matrix
|
||||||
|
/// sx 0 0<para />
|
||||||
|
/// 0 sy 0<para />
|
||||||
|
/// 0 0 1
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sx"></param>
|
||||||
|
/// <param name="sy"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static DmtxMatrix3 Scale(double sx, double sy)
|
||||||
|
{
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3 {_data = new[,] {{sx, 0.0, 0.0}, {0.0, sy, 0.0}, {0, 0, 1.0}}};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// generates a 3x3 shear transformation matrix
|
||||||
|
/// 0 shx 0<para />
|
||||||
|
/// shy 0 0<para />
|
||||||
|
/// 0 0 1
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static DmtxMatrix3 Shear(double shx, double shy)
|
||||||
|
{
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3 {_data = new[,] {{1.0, shy, 0.0}, {shx, 1.0, 0.0}, {0, 0, 1.0}}};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// generates a 3x3 top line skew transformation matrix
|
||||||
|
/// b1/b0 0 (b1-b0)/(sz * b0)<para />
|
||||||
|
/// 0 sz/b0 0<para />
|
||||||
|
/// 0 0 1
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static DmtxMatrix3 LineSkewTop(double b0, double b1, double sz)
|
||||||
|
{
|
||||||
|
if (b0 < DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("b0 must be larger than zero in top line skew transformation");
|
||||||
|
}
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3
|
||||||
|
{_data = new[,] {{b1/b0, 0.0, (b1 - b0)/(sz*b0)}, {0.0, sz/b0, 0.0}, {0, 0, 1.0}}};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// generates a 3x3 top line skew transformation matrix (inverse)
|
||||||
|
/// b0/b1 0 (b0-b1)/(sz * b1)<para />
|
||||||
|
/// 0 b0/sz 0<para />
|
||||||
|
/// 0 0 1
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static DmtxMatrix3 LineSkewTopInv(double b0, double b1, double sz)
|
||||||
|
{
|
||||||
|
if (b1 < DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("b1 must be larger than zero in top line skew transformation (inverse)");
|
||||||
|
}
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3
|
||||||
|
{_data = new[,] {{b0/b1, 0.0, (b0 - b1)/(sz*b1)}, {0.0, b0/sz, 0.0}, {0, 0, 1.0}}};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// generates a 3x3 side line skew transformation matrix (inverse)
|
||||||
|
/// sz/b0 0 0<para />
|
||||||
|
/// 0 b1/b0 (b1-b0)/(sz*b0)<para />
|
||||||
|
/// 0 0 1
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static DmtxMatrix3 LineSkewSide(double b0, double b1, double sz)
|
||||||
|
{
|
||||||
|
if (b0 < DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("b0 must be larger than zero in side line skew transformation (inverse)");
|
||||||
|
}
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3
|
||||||
|
{_data = new[,] {{sz/b0, 0.0, 0.0}, {0.0, b1/b0, (b1 - b0)/(sz*b0)}, {0, 0, 1.0}}};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// generates a 3x3 side line skew transformation matrix (inverse)
|
||||||
|
/// b0/sz 0 0<para />
|
||||||
|
/// 0 b0/b1 (b0 - b1) / (sz * b1)<para />
|
||||||
|
/// 0 0 1
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static DmtxMatrix3 LineSkewSideInv(double b0, double b1, double sz)
|
||||||
|
{
|
||||||
|
if (b1 < DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("b1 must be larger than zero in top line skew transformation (inverse)");
|
||||||
|
}
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3
|
||||||
|
{_data = new[,] {{b0/sz, 0.0, 0.0}, {0.0, b0/b1, (b0 - b1)/(sz*b1)}, {0, 0, 1.0}}};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DmtxMatrix3 operator *(DmtxMatrix3 m1, DmtxMatrix3 m2)
|
||||||
|
{
|
||||||
|
DmtxMatrix3 result = new DmtxMatrix3 {_data = new[,] {{0.0, 0, 0}, {0, 0, 0}, {0, 0, 0}}};
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
result[i, j] += m1[i, k] * m2[k, j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DmtxVector2 operator *(DmtxVector2 vector, DmtxMatrix3 matrix)
|
||||||
|
{
|
||||||
|
double w = Math.Abs(vector.X * matrix[0, 2] + vector.Y * matrix[1, 2] + matrix[2, 2]);
|
||||||
|
if (w <= DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Multiplication of vector and matrix resulted in invalid result");
|
||||||
|
}
|
||||||
|
DmtxVector2 result = new DmtxVector2((vector.X*matrix[0,0] + vector.Y * matrix[1,0] + matrix[2,0])/w,
|
||||||
|
(vector.X * matrix[0,1] + vector.Y * matrix[1,1] + matrix[2,1])/w);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("{0}\t{1}\t{2}\n{3}\t{4}\t{5}\n{6}\t{7}\t{8}\n", _data[0, 0], _data[0, 1], _data[0, 2], _data[1, 0], _data[1, 1], _data[1, 2], _data[2, 0], _data[2, 1], _data[2, 2]);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
internal double this[int i, int j]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _data[i, j];
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_data[i, j] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
554
DataMatrix.net/DmtxMessage.cs
Normal file
554
DataMatrix.net/DmtxMessage.cs
Normal file
@ -0,0 +1,554 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal class DmtxMessage
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
int _outputIdx; /* Internal index used to store output progress */
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
internal DmtxMessage(DmtxSymbolSize sizeIdx, DmtxFormat symbolFormat)
|
||||||
|
{
|
||||||
|
if (symbolFormat != DmtxFormat.Matrix && symbolFormat != DmtxFormat.Mosaic)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Only DmtxFormats Matrix and Mosaic are currently supported");
|
||||||
|
}
|
||||||
|
int mappingRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixRows, sizeIdx);
|
||||||
|
int mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, sizeIdx);
|
||||||
|
|
||||||
|
this.Array = new byte[mappingCols * mappingRows];
|
||||||
|
|
||||||
|
int codeSize = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx) + DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolErrorWords, sizeIdx);
|
||||||
|
this.Code = new byte[codeSize];
|
||||||
|
|
||||||
|
this.Output = new byte[10 * codeSize];
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
internal void DecodeDataStream(DmtxSymbolSize sizeIdx, byte[] outputStart)
|
||||||
|
{
|
||||||
|
bool macro = false;
|
||||||
|
|
||||||
|
this.Output = outputStart ?? this.Output;
|
||||||
|
this._outputIdx = 0;
|
||||||
|
|
||||||
|
byte[] ptr = this.Code;
|
||||||
|
int dataEndIndex = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx);
|
||||||
|
|
||||||
|
/* Print macro header if first codeword triggers it */
|
||||||
|
if (ptr[0] == DmtxConstants.DmtxChar05Macro || ptr[0] == DmtxConstants.DmtxChar06Macro)
|
||||||
|
{
|
||||||
|
PushOutputMacroHeader(ptr[0]);
|
||||||
|
macro = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int codeIter = 0; codeIter < dataEndIndex; )
|
||||||
|
{
|
||||||
|
|
||||||
|
DmtxScheme encScheme = GetEncodationScheme(this.Code[codeIter]);
|
||||||
|
if (encScheme != DmtxScheme.DmtxSchemeAscii)
|
||||||
|
codeIter++;
|
||||||
|
|
||||||
|
switch (encScheme)
|
||||||
|
{
|
||||||
|
case DmtxScheme.DmtxSchemeAscii:
|
||||||
|
codeIter = DecodeSchemeAscii(codeIter, dataEndIndex);
|
||||||
|
break;
|
||||||
|
case DmtxScheme.DmtxSchemeC40:
|
||||||
|
case DmtxScheme.DmtxSchemeText:
|
||||||
|
codeIter = DecodeSchemeC40Text(codeIter, dataEndIndex, encScheme);
|
||||||
|
break;
|
||||||
|
case DmtxScheme.DmtxSchemeX12:
|
||||||
|
codeIter = DecodeSchemeX12(codeIter, dataEndIndex);
|
||||||
|
break;
|
||||||
|
case DmtxScheme.DmtxSchemeEdifact:
|
||||||
|
codeIter = DecodeSchemeEdifact(codeIter, dataEndIndex);
|
||||||
|
break;
|
||||||
|
case DmtxScheme.DmtxSchemeBase256:
|
||||||
|
codeIter = DecodeSchemeBase256(codeIter, dataEndIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print macro trailer if required */
|
||||||
|
if (macro)
|
||||||
|
{
|
||||||
|
PushOutputMacroTrailer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PushOutputMacroHeader(byte macroType)
|
||||||
|
{
|
||||||
|
PushOutputWord((byte)'[');
|
||||||
|
PushOutputWord((byte)')');
|
||||||
|
PushOutputWord((byte)'>');
|
||||||
|
PushOutputWord(30); /* ASCII RS */
|
||||||
|
PushOutputWord((byte)'0');
|
||||||
|
|
||||||
|
if (macroType == DmtxConstants.DmtxChar05Macro)
|
||||||
|
{
|
||||||
|
PushOutputWord((byte)'5');
|
||||||
|
}
|
||||||
|
else if (macroType == DmtxConstants.DmtxChar06Macro)
|
||||||
|
{
|
||||||
|
PushOutputWord((byte)'6');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Macro Header only supported for char05 and char06");
|
||||||
|
}
|
||||||
|
|
||||||
|
PushOutputWord(29); /* ASCII GS */
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushOutputMacroTrailer()
|
||||||
|
{
|
||||||
|
PushOutputWord(30); /* ASCII RS */
|
||||||
|
PushOutputWord(4); /* ASCII EOT */
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushOutputWord(byte value)
|
||||||
|
{
|
||||||
|
this.Output[this._outputIdx++] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DmtxScheme GetEncodationScheme(byte val)
|
||||||
|
{
|
||||||
|
if (val == DmtxConstants.DmtxCharC40Latch)
|
||||||
|
{
|
||||||
|
return DmtxScheme.DmtxSchemeC40;
|
||||||
|
}
|
||||||
|
if (val == DmtxConstants.DmtxCharBase256Latch)
|
||||||
|
{
|
||||||
|
return DmtxScheme.DmtxSchemeBase256;
|
||||||
|
}
|
||||||
|
if (val == DmtxConstants.DmtxCharEdifactLatch)
|
||||||
|
{
|
||||||
|
return DmtxScheme.DmtxSchemeEdifact;
|
||||||
|
}
|
||||||
|
if (val == DmtxConstants.DmtxCharTextLatch)
|
||||||
|
{
|
||||||
|
return DmtxScheme.DmtxSchemeText;
|
||||||
|
}
|
||||||
|
if (val == DmtxConstants.DmtxCharX12Latch)
|
||||||
|
{
|
||||||
|
return DmtxScheme.DmtxSchemeX12;
|
||||||
|
}
|
||||||
|
return DmtxScheme.DmtxSchemeAscii;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DecodeSchemeAscii(int startIndex, int endIndex)
|
||||||
|
{
|
||||||
|
bool upperShift = false;
|
||||||
|
|
||||||
|
while (startIndex < endIndex)
|
||||||
|
{
|
||||||
|
|
||||||
|
byte codeword = this.Code[startIndex];
|
||||||
|
|
||||||
|
if (GetEncodationScheme(this.Code[startIndex]) != DmtxScheme.DmtxSchemeAscii)
|
||||||
|
return startIndex;
|
||||||
|
|
||||||
|
startIndex++;
|
||||||
|
|
||||||
|
if (upperShift)
|
||||||
|
{
|
||||||
|
PushOutputWord((byte)(codeword + 127));
|
||||||
|
upperShift = false;
|
||||||
|
}
|
||||||
|
else if (codeword == DmtxConstants.DmtxCharAsciiUpperShift)
|
||||||
|
{
|
||||||
|
upperShift = true;
|
||||||
|
}
|
||||||
|
else if (codeword == DmtxConstants.DmtxCharAsciiPad)
|
||||||
|
{
|
||||||
|
this.PadCount = endIndex - startIndex;
|
||||||
|
return endIndex;
|
||||||
|
}
|
||||||
|
else if (codeword <= 128)
|
||||||
|
{
|
||||||
|
PushOutputWord((byte)(codeword - 1));
|
||||||
|
}
|
||||||
|
else if (codeword <= 229)
|
||||||
|
{
|
||||||
|
byte digits = (byte)(codeword - 130);
|
||||||
|
PushOutputWord((byte)(digits / 10 + '0'));
|
||||||
|
PushOutputWord((byte)(digits - (digits / 10) * 10 + '0'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DecodeSchemeC40Text(int startIndex, int endIndex, DmtxScheme encScheme)
|
||||||
|
{
|
||||||
|
int[] c40Values = new int[3];
|
||||||
|
C40TextState state = new C40TextState {Shift = DmtxConstants.DmtxC40TextBasicSet, UpperShift = false};
|
||||||
|
|
||||||
|
|
||||||
|
if (!(encScheme == DmtxScheme.DmtxSchemeC40 || encScheme == DmtxScheme.DmtxSchemeText))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid scheme selected for decodind!");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (startIndex < endIndex)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* FIXME Also check that ptr+1 is safe to access */
|
||||||
|
int packed = (this.Code[startIndex] << 8) | this.Code[startIndex + 1];
|
||||||
|
c40Values[0] = ((packed - 1) / 1600);
|
||||||
|
c40Values[1] = ((packed - 1) / 40) % 40;
|
||||||
|
c40Values[2] = (packed - 1) % 40;
|
||||||
|
startIndex += 2;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (state.Shift == DmtxConstants.DmtxC40TextBasicSet)
|
||||||
|
{ /* Basic set */
|
||||||
|
if (c40Values[i] <= 2)
|
||||||
|
{
|
||||||
|
state.Shift = c40Values[i] + 1;
|
||||||
|
}
|
||||||
|
else if (c40Values[i] == 3)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, ' ');
|
||||||
|
}
|
||||||
|
else if (c40Values[i] <= 13)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] - 13 + '9'); /* 0-9 */
|
||||||
|
}
|
||||||
|
else if (c40Values[i] <= 39)
|
||||||
|
{
|
||||||
|
if (encScheme == DmtxScheme.DmtxSchemeC40)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] - 39 + 'Z'); /* A-Z */
|
||||||
|
}
|
||||||
|
else if (encScheme == DmtxScheme.DmtxSchemeText)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] - 39 + 'z'); /* a-z */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state.Shift == DmtxConstants.DmtxC40TextShift1)
|
||||||
|
{ /* Shift 1 set */
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i]); /* ASCII 0 - 31 */
|
||||||
|
}
|
||||||
|
else if (state.Shift == DmtxConstants.DmtxC40TextShift2)
|
||||||
|
{ /* Shift 2 set */
|
||||||
|
if (c40Values[i] <= 14)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] + 33); /* ASCII 33 - 47 */
|
||||||
|
}
|
||||||
|
else if (c40Values[i] <= 21)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] + 43); /* ASCII 58 - 64 */
|
||||||
|
}
|
||||||
|
else if (c40Values[i] <= 26)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] + 69); /* ASCII 91 - 95 */
|
||||||
|
}
|
||||||
|
else if (c40Values[i] == 27)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, 0x1d); /* FNC1 -- XXX depends on position? */
|
||||||
|
}
|
||||||
|
else if (c40Values[i] == 30)
|
||||||
|
{
|
||||||
|
state.UpperShift = true;
|
||||||
|
state.Shift = DmtxConstants.DmtxC40TextBasicSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state.Shift == DmtxConstants.DmtxC40TextShift3)
|
||||||
|
{ /* Shift 3 set */
|
||||||
|
if (encScheme == DmtxScheme.DmtxSchemeC40)
|
||||||
|
{
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] + 96);
|
||||||
|
}
|
||||||
|
else if (encScheme == DmtxScheme.DmtxSchemeText)
|
||||||
|
{
|
||||||
|
if (c40Values[i] == 0)
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] + 96);
|
||||||
|
else if (c40Values[i] <= 26)
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] - 26 + 'Z'); /* A-Z */
|
||||||
|
else
|
||||||
|
PushOutputC40TextWord(ref state, c40Values[i] - 31 + 127); /* { | } ~ DEL */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlatch if codeword 254 follows 2 codewords in C40/Text encodation */
|
||||||
|
if (this.Code[startIndex] == DmtxConstants.DmtxCharTripletUnlatch)
|
||||||
|
return startIndex + 1;
|
||||||
|
|
||||||
|
/* Unlatch is implied if only one codeword remains */
|
||||||
|
if (endIndex - startIndex == 1)
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushOutputC40TextWord(ref C40TextState state, int value)
|
||||||
|
{
|
||||||
|
if (!(value >= 0 && value < 256))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid value: Exceeds range for conversion to byte");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Output[this._outputIdx] = (byte)value;
|
||||||
|
|
||||||
|
if (state.UpperShift)
|
||||||
|
{
|
||||||
|
if (!(value >= 0 && value < 256))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid value: Exceeds range for conversion to upper case character");
|
||||||
|
}
|
||||||
|
this.Output[this._outputIdx] += 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._outputIdx++;
|
||||||
|
|
||||||
|
state.Shift = DmtxConstants.DmtxC40TextBasicSet;
|
||||||
|
state.UpperShift = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DecodeSchemeX12(int startIndex, int endIndex)
|
||||||
|
{
|
||||||
|
int[] x12Values = new int[3];
|
||||||
|
|
||||||
|
while (startIndex < endIndex)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* FIXME Also check that ptr+1 is safe to access */
|
||||||
|
int packed = (this.Code[startIndex] << 8) | this.Code[startIndex + 1];
|
||||||
|
x12Values[0] = ((packed - 1) / 1600);
|
||||||
|
x12Values[1] = ((packed - 1) / 40) % 40;
|
||||||
|
x12Values[2] = (packed - 1) % 40;
|
||||||
|
startIndex += 2;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (x12Values[i] == 0)
|
||||||
|
PushOutputWord(13);
|
||||||
|
else if (x12Values[i] == 1)
|
||||||
|
PushOutputWord(42);
|
||||||
|
else if (x12Values[i] == 2)
|
||||||
|
PushOutputWord(62);
|
||||||
|
else if (x12Values[i] == 3)
|
||||||
|
PushOutputWord(32);
|
||||||
|
else if (x12Values[i] <= 13)
|
||||||
|
PushOutputWord((byte)(x12Values[i] + 44));
|
||||||
|
else if (x12Values[i] <= 90)
|
||||||
|
PushOutputWord((byte)(x12Values[i] + 51));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlatch if codeword 254 follows 2 codewords in C40/Text encodation */
|
||||||
|
if (this.Code[startIndex] == DmtxConstants.DmtxCharTripletUnlatch)
|
||||||
|
return startIndex + 1;
|
||||||
|
|
||||||
|
/* Unlatch is implied if only one codeword remains */
|
||||||
|
if (endIndex - startIndex == 1)
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DecodeSchemeEdifact(int startIndex, int endIndex)
|
||||||
|
{
|
||||||
|
byte[] unpacked = new byte[4];
|
||||||
|
|
||||||
|
while (startIndex < endIndex)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* FIXME Also check that ptr+2 is safe to access -- shouldn't be a
|
||||||
|
problem because I'm guessing you can guarantee there will always
|
||||||
|
be at least 3 error codewords */
|
||||||
|
unpacked[0] = (byte)((this.Code[startIndex] & 0xfc) >> 2);
|
||||||
|
unpacked[1] = (byte)((this.Code[startIndex] & 0x03) << 4 | (this.Code[startIndex + 1] & 0xf0) >> 4);
|
||||||
|
unpacked[2] = (byte)((this.Code[startIndex + 1] & 0x0f) << 2 | (this.Code[startIndex + 2] & 0xc0) >> 6);
|
||||||
|
unpacked[3] = (byte)(this.Code[startIndex + 2] & 0x3f);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Advance input ptr (4th value comes from already-read 3rd byte) */
|
||||||
|
if (i < 3)
|
||||||
|
startIndex++;
|
||||||
|
|
||||||
|
/* Test for unlatch condition */
|
||||||
|
if (unpacked[i] == DmtxConstants.DmtxCharEdifactUnlatch)
|
||||||
|
{
|
||||||
|
if (this.Output[_outputIdx] != 0)
|
||||||
|
{/* XXX dirty why? */
|
||||||
|
throw new Exception("Error decoding edifact scheme");
|
||||||
|
}
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
PushOutputWord((byte)(unpacked[i] ^ (((unpacked[i] & 0x20) ^ 0x20) << 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlatch is implied if fewer than 3 codewords remain */
|
||||||
|
if (endIndex - startIndex < 3)
|
||||||
|
{
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DecodeSchemeBase256(int startIndex, int endIndex)
|
||||||
|
{
|
||||||
|
int tempEndIndex;
|
||||||
|
|
||||||
|
/* Find positional index used for unrandomizing */
|
||||||
|
int idx = startIndex + 1;
|
||||||
|
|
||||||
|
int d0 = UnRandomize255State(this.Code[startIndex++], idx++);
|
||||||
|
if (d0 == 0)
|
||||||
|
{
|
||||||
|
tempEndIndex = endIndex;
|
||||||
|
}
|
||||||
|
else if (d0 <= 249)
|
||||||
|
{
|
||||||
|
tempEndIndex = startIndex + d0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int d1 = UnRandomize255State(this.Code[startIndex++], idx++);
|
||||||
|
tempEndIndex = startIndex + (d0 - 249) * 250 + d1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempEndIndex > endIndex)
|
||||||
|
{
|
||||||
|
throw new Exception("Error decoding scheme base 256");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (startIndex < tempEndIndex)
|
||||||
|
{
|
||||||
|
PushOutputWord(UnRandomize255State(this.Code[startIndex++], idx++));
|
||||||
|
}
|
||||||
|
|
||||||
|
return startIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static byte UnRandomize255State(byte value, int idx)
|
||||||
|
{
|
||||||
|
int pseudoRandom = ((149 * idx) % 255) + 1;
|
||||||
|
int tmp = value - pseudoRandom;
|
||||||
|
if (tmp < 0)
|
||||||
|
tmp += 256;
|
||||||
|
|
||||||
|
if (tmp < 0 || tmp >= 256)
|
||||||
|
{
|
||||||
|
throw new Exception("Error unrandomizing 255 state");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte)tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int SymbolModuleStatus(DmtxSymbolSize sizeIdx, int symbolRow, int symbolCol)
|
||||||
|
{
|
||||||
|
int dataRegionRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribDataRegionRows, sizeIdx);
|
||||||
|
int dataRegionCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribDataRegionCols, sizeIdx);
|
||||||
|
int symbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, sizeIdx);
|
||||||
|
int mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, sizeIdx);
|
||||||
|
|
||||||
|
int symbolRowReverse = symbolRows - symbolRow - 1;
|
||||||
|
int mappingRow = symbolRowReverse - 1 - 2 * (symbolRowReverse / (dataRegionRows + 2));
|
||||||
|
int mappingCol = symbolCol - 1 - 2 * (symbolCol / (dataRegionCols + 2));
|
||||||
|
|
||||||
|
/* Solid portion of alignment patterns */
|
||||||
|
if (symbolRow % (dataRegionRows + 2) == 0 || symbolCol % (dataRegionCols + 2) == 0)
|
||||||
|
{
|
||||||
|
return (DmtxConstants.DmtxModuleOnRGB | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0)); // check if unary not is correct
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Horinzontal calibration bars */
|
||||||
|
if ((symbolRow + 1) % (dataRegionRows + 2) == 0)
|
||||||
|
{
|
||||||
|
return (((symbolCol & 0x01) != 0) ? 0 : DmtxConstants.DmtxModuleOnRGB) | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vertical calibration bars */
|
||||||
|
if ((symbolCol + 1) % (dataRegionCols + 2) == 0)
|
||||||
|
{
|
||||||
|
return (((symbolRow & 0x01) != 0) ? 0 : DmtxConstants.DmtxModuleOnRGB) | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data modules */
|
||||||
|
return (this.Array[mappingRow * mappingCols + mappingCol] | DmtxConstants.DmtxModuleData);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
internal int PadCount { get; set; }
|
||||||
|
|
||||||
|
internal byte[] Array { get; set; }
|
||||||
|
|
||||||
|
internal byte[] Code { get; set; }
|
||||||
|
|
||||||
|
internal byte[] Output { get; set; }
|
||||||
|
|
||||||
|
internal int ArraySize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Array.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int CodeSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Code.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int OutputSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.Output.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
56
DataMatrix.net/DmtxMultiplet.cs
Normal file
56
DataMatrix.net/DmtxMultiplet.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal struct DmtxTriplet
|
||||||
|
{
|
||||||
|
byte[] _value;
|
||||||
|
|
||||||
|
internal byte[] Value
|
||||||
|
{
|
||||||
|
get { return this._value ?? (this._value = new byte[3]); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct DmtxQuadruplet
|
||||||
|
* @brief DmtxQuadruplet
|
||||||
|
*/
|
||||||
|
internal struct DmtxQuadruplet
|
||||||
|
{
|
||||||
|
byte[] _value;
|
||||||
|
|
||||||
|
internal byte[] Value
|
||||||
|
{
|
||||||
|
get { return this._value ?? (this._value = new byte[4]); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
DataMatrix.net/DmtxPixelLoc.cs
Normal file
47
DataMatrix.net/DmtxPixelLoc.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal struct DmtxPixelLoc
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
internal int X { get; set; }
|
||||||
|
|
||||||
|
internal int Y { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
49
DataMatrix.net/DmtxPointFlow.cs
Normal file
49
DataMatrix.net/DmtxPointFlow.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal class DmtxPointFlow
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
internal int Plane { get; set; }
|
||||||
|
|
||||||
|
internal int Arrive { get; set; }
|
||||||
|
|
||||||
|
internal int Depart { get; set; }
|
||||||
|
|
||||||
|
internal int Mag { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc Loc { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
67
DataMatrix.net/DmtxRay2.cs
Normal file
67
DataMatrix.net/DmtxRay2.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal class DmtxRay2
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
DmtxVector2 _p;
|
||||||
|
DmtxVector2 _v;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
internal DmtxVector2 P
|
||||||
|
{
|
||||||
|
get { return this._p ?? (this._p = new DmtxVector2()); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DmtxVector2 V
|
||||||
|
{
|
||||||
|
get { return this._v ?? (this._v = new DmtxVector2()); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_v = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal double TMin { get; set; }
|
||||||
|
|
||||||
|
internal double TMax { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
161
DataMatrix.net/DmtxRegion.cs
Normal file
161
DataMatrix.net/DmtxRegion.cs
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal class DmtxRegion
|
||||||
|
{
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
internal DmtxRegion()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DmtxRegion(DmtxRegion src)
|
||||||
|
{
|
||||||
|
this.BottomAngle = src.BottomAngle;
|
||||||
|
this.BottomKnown = src.BottomKnown;
|
||||||
|
this.BottomLine = src.BottomLine;
|
||||||
|
this.BottomLoc = src.BottomLoc;
|
||||||
|
this.BoundMax = src.BoundMax;
|
||||||
|
this.BoundMin = src.BoundMin;
|
||||||
|
this.FinalNeg = src.FinalNeg;
|
||||||
|
this.FinalPos = src.FinalPos;
|
||||||
|
this.Fit2Raw = new DmtxMatrix3(src.Fit2Raw);
|
||||||
|
this.FlowBegin = src.FlowBegin;
|
||||||
|
this.JumpToNeg = src.JumpToNeg;
|
||||||
|
this.JumpToPos = src.JumpToPos;
|
||||||
|
this.LeftAngle = src.LeftAngle;
|
||||||
|
this.LeftKnown = src.LeftKnown;
|
||||||
|
this.LeftLine = src.LeftLine;
|
||||||
|
this.LeftLoc = src.LeftLoc;
|
||||||
|
this.LocR = src.LocR;
|
||||||
|
this.LocT = src.LocT;
|
||||||
|
this.MappingCols = src.MappingCols;
|
||||||
|
this.MappingRows = src.MappingRows;
|
||||||
|
this.OffColor = src.OffColor;
|
||||||
|
this.OnColor = src.OnColor;
|
||||||
|
this.Polarity = src.Polarity;
|
||||||
|
this.Raw2Fit = new DmtxMatrix3(src.Raw2Fit);
|
||||||
|
this.RightAngle = src.RightAngle;
|
||||||
|
this.RightKnown = src.RightKnown;
|
||||||
|
this.RightLoc = src.RightLoc;
|
||||||
|
this.SizeIdx = src.SizeIdx;
|
||||||
|
this.StepR = src.StepR;
|
||||||
|
this.StepsTotal = src.StepsTotal;
|
||||||
|
this.StepT = src.StepT;
|
||||||
|
this.SymbolCols = src.SymbolCols;
|
||||||
|
this.SymbolRows = src.SymbolRows;
|
||||||
|
this.TopAngle = src.TopAngle;
|
||||||
|
this.TopKnown = src.TopKnown;
|
||||||
|
this.TopLoc = src.TopLoc;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
internal int JumpToPos { get; set; }
|
||||||
|
|
||||||
|
internal int JumpToNeg { get; set; }
|
||||||
|
|
||||||
|
internal int StepsTotal { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc FinalPos { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc FinalNeg { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc BoundMin { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc BoundMax { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPointFlow FlowBegin { get; set; }
|
||||||
|
|
||||||
|
internal int Polarity { get; set; }
|
||||||
|
|
||||||
|
internal int StepR { get; set; }
|
||||||
|
|
||||||
|
internal int StepT { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc LocR { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc LocT { get; set; }
|
||||||
|
|
||||||
|
internal int LeftKnown { get; set; }
|
||||||
|
|
||||||
|
internal int LeftAngle { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc LeftLoc { get; set; }
|
||||||
|
|
||||||
|
internal DmtxBestLine LeftLine { get; set; }
|
||||||
|
|
||||||
|
internal int BottomKnown { get; set; }
|
||||||
|
|
||||||
|
internal int BottomAngle { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc BottomLoc { get; set; }
|
||||||
|
|
||||||
|
internal DmtxBestLine BottomLine { get; set; }
|
||||||
|
|
||||||
|
internal int TopKnown { get; set; }
|
||||||
|
|
||||||
|
internal int TopAngle { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc TopLoc { get; set; }
|
||||||
|
|
||||||
|
internal int RightKnown { get; set; }
|
||||||
|
|
||||||
|
internal int RightAngle { get; set; }
|
||||||
|
|
||||||
|
internal DmtxPixelLoc RightLoc { get; set; }
|
||||||
|
|
||||||
|
internal int OnColor { get; set; }
|
||||||
|
|
||||||
|
internal int OffColor { get; set; }
|
||||||
|
|
||||||
|
internal DmtxSymbolSize SizeIdx { get; set; }
|
||||||
|
|
||||||
|
internal int SymbolRows { get; set; }
|
||||||
|
|
||||||
|
internal int SymbolCols { get; set; }
|
||||||
|
|
||||||
|
internal int MappingRows { get; set; }
|
||||||
|
|
||||||
|
internal int MappingCols { get; set; }
|
||||||
|
|
||||||
|
internal DmtxMatrix3 Raw2Fit { get; set; }
|
||||||
|
|
||||||
|
internal DmtxMatrix3 Fit2Raw { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
369
DataMatrix.net/DmtxScanGrid.cs
Normal file
369
DataMatrix.net/DmtxScanGrid.cs
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal struct DmtxScanGrid
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
int _minExtent;
|
||||||
|
int _maxExtent;
|
||||||
|
int _xOffset;
|
||||||
|
int _yOffset;
|
||||||
|
int _xMin;
|
||||||
|
int _xMax;
|
||||||
|
int _yMin;
|
||||||
|
int _yMax;
|
||||||
|
|
||||||
|
int _total;
|
||||||
|
int _extent;
|
||||||
|
int _jumpSize;
|
||||||
|
int _pixelTotal;
|
||||||
|
int _startPos;
|
||||||
|
|
||||||
|
int _pixelCount;
|
||||||
|
int _xCenter;
|
||||||
|
int _yCenter;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
internal DmtxScanGrid(DmtxDecode dec)
|
||||||
|
{
|
||||||
|
int smallestFeature = dec.ScanGap;
|
||||||
|
this._xMin = dec.XMin;
|
||||||
|
this._xMax = dec.XMax;
|
||||||
|
this._yMin = dec.YMin;
|
||||||
|
this._yMax = dec.YMax;
|
||||||
|
|
||||||
|
/* Values that get set once */
|
||||||
|
int xExtent = this._xMax - this._xMin;
|
||||||
|
int yExtent = this._yMax - this._yMin;
|
||||||
|
int maxExtent = (xExtent > yExtent) ? xExtent : yExtent;
|
||||||
|
|
||||||
|
if (maxExtent < 1)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid max extent for Scan Grid: Must be greater than 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
int extent = 1;
|
||||||
|
this._minExtent = extent;
|
||||||
|
for (; extent < maxExtent; extent = ((extent + 1) * 2) - 1)
|
||||||
|
{
|
||||||
|
if (extent <= smallestFeature)
|
||||||
|
{
|
||||||
|
_minExtent = extent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._maxExtent = extent ;
|
||||||
|
|
||||||
|
this._xOffset = (this._xMin + this._xMax - this._maxExtent) / 2;
|
||||||
|
this._yOffset = (this._yMin + this._yMax - this._maxExtent) / 2;
|
||||||
|
|
||||||
|
/* Values that get reset for every level */
|
||||||
|
this._total = 1;
|
||||||
|
this._extent = this._maxExtent;
|
||||||
|
|
||||||
|
this._jumpSize = this._extent + 1;
|
||||||
|
this._pixelTotal = 2 * this._extent - 1;
|
||||||
|
this._startPos = this._extent / 2;
|
||||||
|
this._pixelCount = 0;
|
||||||
|
this._xCenter = this._yCenter = this._startPos;
|
||||||
|
|
||||||
|
SetDerivedFields();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
internal DmtxRange PopGridLocation(ref DmtxPixelLoc loc)
|
||||||
|
{
|
||||||
|
DmtxRange locStatus;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
locStatus = GetGridCoordinates(ref loc);
|
||||||
|
|
||||||
|
/* Always leave grid pointing at next available location */
|
||||||
|
this._pixelCount++;
|
||||||
|
|
||||||
|
} while (locStatus == DmtxRange.DmtxRangeBad);
|
||||||
|
|
||||||
|
return locStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DmtxRange GetGridCoordinates(ref DmtxPixelLoc locRef)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Initially pixelCount may fall beyond acceptable limits. Update grid
|
||||||
|
* state before testing coordinates */
|
||||||
|
|
||||||
|
/* Jump to next cross pattern horizontally if current column is done */
|
||||||
|
if (this._pixelCount >= this._pixelTotal)
|
||||||
|
{
|
||||||
|
this._pixelCount = 0;
|
||||||
|
this._xCenter += this._jumpSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jump to next cross pattern vertically if current row is done */
|
||||||
|
if (this._xCenter > this._maxExtent)
|
||||||
|
{
|
||||||
|
this._xCenter = this._startPos;
|
||||||
|
this._yCenter += this._jumpSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment level when vertical step goes too far */
|
||||||
|
if (this._yCenter > this._maxExtent)
|
||||||
|
{
|
||||||
|
this._total *= 4;
|
||||||
|
this._extent /= 2;
|
||||||
|
SetDerivedFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._extent == 0 || this._extent < this._minExtent)
|
||||||
|
{
|
||||||
|
locRef.X = locRef.Y = -1;
|
||||||
|
return DmtxRange.DmtxRangeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = this._pixelCount;
|
||||||
|
|
||||||
|
if (count >= this._pixelTotal)
|
||||||
|
{
|
||||||
|
throw new Exception("Scangrid is beyong image limits!");
|
||||||
|
}
|
||||||
|
|
||||||
|
DmtxPixelLoc loc = new DmtxPixelLoc();
|
||||||
|
if (count == this._pixelTotal - 1)
|
||||||
|
{
|
||||||
|
/* center pixel */
|
||||||
|
loc.X = this._xCenter;
|
||||||
|
loc.Y = this._yCenter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int half = this._pixelTotal / 2;
|
||||||
|
int quarter = half / 2;
|
||||||
|
|
||||||
|
/* horizontal portion */
|
||||||
|
if (count < half)
|
||||||
|
{
|
||||||
|
loc.X = this._xCenter + ((count < quarter) ? (count - quarter) : (half - count));
|
||||||
|
loc.Y = this._yCenter;
|
||||||
|
}
|
||||||
|
/* vertical portion */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count -= half;
|
||||||
|
loc.X = this._xCenter;
|
||||||
|
loc.Y = this._yCenter + ((count < quarter) ? (count - quarter) : (half - count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loc.X += this._xOffset;
|
||||||
|
loc.Y += this._yOffset;
|
||||||
|
|
||||||
|
locRef.X = loc.X;
|
||||||
|
locRef.Y = loc.Y;
|
||||||
|
|
||||||
|
if (loc.X < this._xMin || loc.X > this._xMax ||
|
||||||
|
loc.Y < this._yMin || loc.Y > this._yMax)
|
||||||
|
{
|
||||||
|
return DmtxRange.DmtxRangeBad;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DmtxRange.DmtxRangeGood;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update derived fields based on current state
|
||||||
|
/// </summary>
|
||||||
|
private void SetDerivedFields()
|
||||||
|
{
|
||||||
|
this._jumpSize = this._extent + 1;
|
||||||
|
this._pixelTotal = 2 * this._extent - 1;
|
||||||
|
this._startPos = this._extent / 2;
|
||||||
|
this._pixelCount = 0;
|
||||||
|
this._xCenter = this._yCenter = this._startPos;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
/// <summary>
|
||||||
|
/// Smallest cross size used in scan
|
||||||
|
/// </summary>
|
||||||
|
internal int MinExtent
|
||||||
|
{
|
||||||
|
get { return _minExtent; }
|
||||||
|
set { _minExtent = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Size of bounding grid region (2^N - 1)
|
||||||
|
/// </summary>
|
||||||
|
internal int MaxExtent
|
||||||
|
{
|
||||||
|
get { return _maxExtent; }
|
||||||
|
set { _maxExtent = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to obtain image X coordinate
|
||||||
|
/// </summary>
|
||||||
|
internal int XOffset
|
||||||
|
{
|
||||||
|
get { return _xOffset; }
|
||||||
|
set { _xOffset = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to obtain image Y coordinate
|
||||||
|
/// </summary>
|
||||||
|
internal int YOffset
|
||||||
|
{
|
||||||
|
get { return _yOffset; }
|
||||||
|
set { _yOffset = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Minimum X in image coordinate system
|
||||||
|
/// </summary>
|
||||||
|
internal int XMin
|
||||||
|
{
|
||||||
|
get { return _xMin; }
|
||||||
|
set { _xMin = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum X in image coordinate system
|
||||||
|
/// </summary>
|
||||||
|
internal int XMax
|
||||||
|
{
|
||||||
|
get { return _xMax; }
|
||||||
|
set { _xMax = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Minimum Y in image coordinate system
|
||||||
|
/// </summary>
|
||||||
|
internal int YMin
|
||||||
|
{
|
||||||
|
get { return _yMin; }
|
||||||
|
set { _yMin = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum Y in image coordinate system
|
||||||
|
/// </summary>
|
||||||
|
internal int YMax
|
||||||
|
{
|
||||||
|
get { return _yMax; }
|
||||||
|
set { _yMax = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total number of crosses at this size
|
||||||
|
/// </summary>
|
||||||
|
internal int Total
|
||||||
|
{
|
||||||
|
get { return _total; }
|
||||||
|
set { _total = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Length/width of cross in pixels
|
||||||
|
/// </summary>
|
||||||
|
internal int Extent
|
||||||
|
{
|
||||||
|
get { return _extent; }
|
||||||
|
set { _extent = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Distance in pixels between cross centers
|
||||||
|
/// </summary>
|
||||||
|
internal int JumpSize
|
||||||
|
{
|
||||||
|
get { return _jumpSize; }
|
||||||
|
set { _jumpSize = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total pixel count within an individual cross path
|
||||||
|
/// </summary>
|
||||||
|
internal int PixelTotal
|
||||||
|
{
|
||||||
|
get { return _pixelTotal; }
|
||||||
|
set { _pixelTotal = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// X and Y coordinate of first cross center in pattern
|
||||||
|
/// </summary>
|
||||||
|
internal int StartPos
|
||||||
|
{
|
||||||
|
get { return _startPos; }
|
||||||
|
set { _startPos = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Progress (pixel count) within current cross pattern
|
||||||
|
/// </summary>
|
||||||
|
internal int PixelCount
|
||||||
|
{
|
||||||
|
get { return _pixelCount; }
|
||||||
|
set { _pixelCount = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// X center of current cross pattern
|
||||||
|
/// </summary>
|
||||||
|
internal int XCenter
|
||||||
|
{
|
||||||
|
get { return _xCenter; }
|
||||||
|
set { _xCenter = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Y center of current cross pattern
|
||||||
|
/// </summary>
|
||||||
|
internal int YCenter
|
||||||
|
{
|
||||||
|
get { return _yCenter; }
|
||||||
|
set { _yCenter = value; }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
152
DataMatrix.net/DmtxVector2.cs
Normal file
152
DataMatrix.net/DmtxVector2.cs
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
DataMatrix.Net
|
||||||
|
|
||||||
|
DataMatrix.Net - .net library for decoding DataMatrix codes.
|
||||||
|
Copyright (C) 2009/2010 Michael Faschinger
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
You can also redistribute and/or modify it under the terms of the
|
||||||
|
GNU Lesser General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3.0 of the License or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License or the GNU Lesser General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License and the GNU Lesser General Public License along with this
|
||||||
|
library; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact: Michael Faschinger - michfasch@gmx.at
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DataMatrix.net
|
||||||
|
{
|
||||||
|
internal class DmtxVector2
|
||||||
|
{
|
||||||
|
#region Constructors
|
||||||
|
internal DmtxVector2()
|
||||||
|
{
|
||||||
|
this.X = 0.0;
|
||||||
|
this.Y = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DmtxVector2(double x, double y)
|
||||||
|
{
|
||||||
|
this.X = x;
|
||||||
|
this.Y = y;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Operators
|
||||||
|
public static DmtxVector2 operator +(DmtxVector2 v1, DmtxVector2 v2)
|
||||||
|
{
|
||||||
|
DmtxVector2 result = new DmtxVector2(v1.X, v1.Y);
|
||||||
|
result.X += v2.X;
|
||||||
|
result.Y += v2.Y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DmtxVector2 operator -(DmtxVector2 v1, DmtxVector2 v2)
|
||||||
|
{
|
||||||
|
DmtxVector2 result = new DmtxVector2(v1.X, v1.Y);
|
||||||
|
result.X -= v2.X;
|
||||||
|
result.Y -= v2.Y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DmtxVector2 operator *(DmtxVector2 v1, double factor)
|
||||||
|
{
|
||||||
|
return new DmtxVector2(v1.X * factor, v1.Y * factor);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
internal double Cross(DmtxVector2 v2)
|
||||||
|
{
|
||||||
|
return (this.X * v2.Y - this.Y * v2.X);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal double Norm()
|
||||||
|
{
|
||||||
|
double mag = Mag();
|
||||||
|
if (mag <= DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
return -1.0; // FIXXXME: This doesn't look clean, as noted in original dmtx source
|
||||||
|
}
|
||||||
|
this.X /= mag;
|
||||||
|
this.Y /= mag;
|
||||||
|
return mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal double Dot(DmtxVector2 v2)
|
||||||
|
{
|
||||||
|
return Math.Sqrt(this.X * v2.X + this.Y * v2.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal double Mag()
|
||||||
|
{
|
||||||
|
return Math.Sqrt(this.X * this.X + this.Y * this.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal double DistanceFromRay2(DmtxRay2 ray)
|
||||||
|
{
|
||||||
|
if (Math.Abs(1.0 - ray.V.Mag()) > DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("DistanceFromRay2: The ray's V vector must be a unit vector");
|
||||||
|
}
|
||||||
|
return ray.V.Cross(this - ray.P);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal double DistanceAlongRay2(DmtxRay2 ray)
|
||||||
|
{
|
||||||
|
if (Math.Abs(1.0 - ray.V.Mag()) > DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("DistanceAlongRay2: The ray's V vector must be a unit vector");
|
||||||
|
}
|
||||||
|
return (this - ray.P).Dot(ray.V);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool Intersect(DmtxRay2 p0, DmtxRay2 p1)
|
||||||
|
{
|
||||||
|
double denominator = p1.V.Cross(p0.V);
|
||||||
|
if (Math.Abs(denominator) < DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
double numerator = p1.V.Cross(p1.P - p0.P);
|
||||||
|
return PointAlongRay2(p0, numerator / denominator);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool PointAlongRay2(DmtxRay2 ray, double t)
|
||||||
|
{
|
||||||
|
if (Math.Abs(1.0 - ray.V.Mag()) > DmtxConstants.DmtxAlmostZero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("PointAlongRay: The ray's V vector must be a unit vector");
|
||||||
|
}
|
||||||
|
DmtxVector2 tmp = new DmtxVector2(ray.V.X * t, ray.V.Y * t);
|
||||||
|
this.X = ray.P.X + tmp.X;
|
||||||
|
this.Y = ray.P.Y + tmp.Y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
internal double X { get; set; }
|
||||||
|
|
||||||
|
internal double Y { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user