mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-27 03:33:25 +08:00
添加项目文件。
This commit is contained in:
95
zxing.core/xx/datamatrix/encoder/ASCIIEncoder.cs
Normal file
95
zxing.core/xx/datamatrix/encoder/ASCIIEncoder.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal sealed class ASCIIEncoder : Encoder
|
||||
{
|
||||
public int EncodingMode
|
||||
{
|
||||
get { return Encodation.ASCII; }
|
||||
}
|
||||
|
||||
public void encode(EncoderContext context)
|
||||
{
|
||||
//step B
|
||||
int n = HighLevelEncoder.determineConsecutiveDigitCount(context.Message, context.Pos);
|
||||
if (n >= 2)
|
||||
{
|
||||
context.writeCodeword(encodeASCIIDigits(context.Message[context.Pos],
|
||||
context.Message[context.Pos + 1]));
|
||||
context.Pos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
char c = context.CurrentChar;
|
||||
int newMode = HighLevelEncoder.lookAheadTest(context.Message, context.Pos, EncodingMode);
|
||||
if (newMode != EncodingMode)
|
||||
{
|
||||
switch (newMode)
|
||||
{
|
||||
case Encodation.BASE256:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_BASE256);
|
||||
context.signalEncoderChange(Encodation.BASE256);
|
||||
return;
|
||||
case Encodation.C40:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_C40);
|
||||
context.signalEncoderChange(Encodation.C40);
|
||||
return;
|
||||
case Encodation.X12:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_ANSIX12);
|
||||
context.signalEncoderChange(Encodation.X12);
|
||||
break;
|
||||
case Encodation.TEXT:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_TEXT);
|
||||
context.signalEncoderChange(Encodation.TEXT);
|
||||
break;
|
||||
case Encodation.EDIFACT:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_EDIFACT);
|
||||
context.signalEncoderChange(Encodation.EDIFACT);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Illegal mode: " + newMode);
|
||||
}
|
||||
}
|
||||
else if (HighLevelEncoder.isExtendedASCII(c))
|
||||
{
|
||||
context.writeCodeword(HighLevelEncoder.UPPER_SHIFT);
|
||||
context.writeCodeword((char)(c - 128 + 1));
|
||||
context.Pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.writeCodeword((char)(c + 1));
|
||||
context.Pos++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static char encodeASCIIDigits(char digit1, char digit2)
|
||||
{
|
||||
if (HighLevelEncoder.isDigit(digit1) && HighLevelEncoder.isDigit(digit2))
|
||||
{
|
||||
int num = (digit1 - 48) * 10 + (digit2 - 48);
|
||||
return (char)(num + 130);
|
||||
}
|
||||
throw new ArgumentException("not digits: " + digit1 + digit2);
|
||||
}
|
||||
}
|
||||
}
|
||||
90
zxing.core/xx/datamatrix/encoder/Base256Encoder.cs
Normal file
90
zxing.core/xx/datamatrix/encoder/Base256Encoder.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal sealed class Base256Encoder : Encoder
|
||||
{
|
||||
public int EncodingMode
|
||||
{
|
||||
get { return Encodation.BASE256; }
|
||||
}
|
||||
|
||||
public void encode(EncoderContext context)
|
||||
{
|
||||
var buffer = new StringBuilder();
|
||||
buffer.Append('\u0000'); //Initialize length field
|
||||
while (context.HasMoreCharacters)
|
||||
{
|
||||
char c = context.CurrentChar;
|
||||
buffer.Append(c);
|
||||
|
||||
context.Pos++;
|
||||
|
||||
int newMode = HighLevelEncoder.lookAheadTest(context.Message, context.Pos, EncodingMode);
|
||||
if (newMode != EncodingMode)
|
||||
{
|
||||
context.signalEncoderChange(newMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
int dataCount = buffer.Length - 1;
|
||||
const int lengthFieldSize = 1;
|
||||
int currentSize = context.CodewordCount + dataCount + lengthFieldSize;
|
||||
context.updateSymbolInfo(currentSize);
|
||||
bool mustPad = (context.SymbolInfo.dataCapacity - currentSize) > 0;
|
||||
if (context.HasMoreCharacters || mustPad)
|
||||
{
|
||||
if (dataCount <= 249)
|
||||
{
|
||||
buffer[0] = (char)dataCount;
|
||||
}
|
||||
else if (dataCount > 249 && dataCount <= 1555)
|
||||
{
|
||||
buffer[0] = (char)((dataCount / 250) + 249);
|
||||
buffer.Insert(1, new [] { (char)(dataCount % 250) });
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Message length not in valid ranges: " + dataCount);
|
||||
}
|
||||
}
|
||||
{
|
||||
var c = buffer.Length;
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
context.writeCodeword(randomize255State(
|
||||
buffer[i], context.CodewordCount + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static char randomize255State(char ch, int codewordPosition)
|
||||
{
|
||||
int pseudoRandom = ((149 * codewordPosition) % 255) + 1;
|
||||
int tempVariable = ch + pseudoRandom;
|
||||
if (tempVariable <= 255)
|
||||
{
|
||||
return (char)tempVariable;
|
||||
}
|
||||
return (char)(tempVariable - 256);
|
||||
}
|
||||
}
|
||||
}
|
||||
223
zxing.core/xx/datamatrix/encoder/C40Encoder.cs
Normal file
223
zxing.core/xx/datamatrix/encoder/C40Encoder.cs
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal class C40Encoder : Encoder
|
||||
{
|
||||
virtual public int EncodingMode
|
||||
{
|
||||
get { return Encodation.C40; }
|
||||
}
|
||||
|
||||
virtual public void encode(EncoderContext context)
|
||||
{
|
||||
//step C
|
||||
var buffer = new StringBuilder();
|
||||
while (context.HasMoreCharacters)
|
||||
{
|
||||
char c = context.CurrentChar;
|
||||
context.Pos++;
|
||||
|
||||
int lastCharSize = encodeChar(c, buffer);
|
||||
|
||||
int unwritten = (buffer.Length / 3) * 2;
|
||||
|
||||
int curCodewordCount = context.CodewordCount + unwritten;
|
||||
context.updateSymbolInfo(curCodewordCount);
|
||||
int available = context.SymbolInfo.dataCapacity - curCodewordCount;
|
||||
|
||||
if (!context.HasMoreCharacters)
|
||||
{
|
||||
//Avoid having a single C40 value in the last triplet
|
||||
var removed = new StringBuilder();
|
||||
if ((buffer.Length % 3) == 2)
|
||||
{
|
||||
if (available < 2 || available > 2)
|
||||
{
|
||||
lastCharSize = backtrackOneCharacter(context, buffer, removed,
|
||||
lastCharSize);
|
||||
}
|
||||
}
|
||||
while ((buffer.Length % 3) == 1
|
||||
&& ((lastCharSize <= 3 && available != 1) || lastCharSize > 3))
|
||||
{
|
||||
lastCharSize = backtrackOneCharacter(context, buffer, removed, lastCharSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int count = buffer.Length;
|
||||
if ((count % 3) == 0)
|
||||
{
|
||||
int newMode = HighLevelEncoder.lookAheadTest(context.Message, context.Pos, EncodingMode);
|
||||
if (newMode != EncodingMode)
|
||||
{
|
||||
context.signalEncoderChange(newMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
handleEOD(context, buffer);
|
||||
}
|
||||
|
||||
private int backtrackOneCharacter(EncoderContext context,
|
||||
StringBuilder buffer, StringBuilder removed, int lastCharSize)
|
||||
{
|
||||
int count = buffer.Length;
|
||||
buffer.Remove(count - lastCharSize, lastCharSize);
|
||||
context.Pos--;
|
||||
char c = context.CurrentChar;
|
||||
lastCharSize = encodeChar(c, removed);
|
||||
context.resetSymbolInfo(); //Deal with possible reduction in symbol size
|
||||
return lastCharSize;
|
||||
}
|
||||
|
||||
internal static void writeNextTriplet(EncoderContext context, StringBuilder buffer)
|
||||
{
|
||||
context.writeCodewords(encodeToCodewords(buffer, 0));
|
||||
buffer.Remove(0, 3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle "end of data" situations
|
||||
/// </summary>
|
||||
/// <param name="context">the encoder context</param>
|
||||
/// <param name="buffer">the buffer with the remaining encoded characters</param>
|
||||
virtual protected void handleEOD(EncoderContext context, StringBuilder buffer)
|
||||
{
|
||||
int unwritten = (buffer.Length / 3) * 2;
|
||||
int rest = buffer.Length % 3;
|
||||
|
||||
int curCodewordCount = context.CodewordCount + unwritten;
|
||||
context.updateSymbolInfo(curCodewordCount);
|
||||
int available = context.SymbolInfo.dataCapacity - curCodewordCount;
|
||||
|
||||
if (rest == 2)
|
||||
{
|
||||
buffer.Append('\u0000'); //Shift 1
|
||||
while (buffer.Length >= 3)
|
||||
{
|
||||
writeNextTriplet(context, buffer);
|
||||
}
|
||||
if (context.HasMoreCharacters)
|
||||
{
|
||||
context.writeCodeword(HighLevelEncoder.C40_UNLATCH);
|
||||
}
|
||||
}
|
||||
else if (available == 1 && rest == 1)
|
||||
{
|
||||
while (buffer.Length >= 3)
|
||||
{
|
||||
writeNextTriplet(context, buffer);
|
||||
}
|
||||
if (context.HasMoreCharacters)
|
||||
{
|
||||
context.writeCodeword(HighLevelEncoder.C40_UNLATCH);
|
||||
}
|
||||
// else no unlatch
|
||||
context.Pos--;
|
||||
}
|
||||
else if (rest == 0)
|
||||
{
|
||||
while (buffer.Length >= 3)
|
||||
{
|
||||
writeNextTriplet(context, buffer);
|
||||
}
|
||||
if (available > 0 || context.HasMoreCharacters)
|
||||
{
|
||||
context.writeCodeword(HighLevelEncoder.C40_UNLATCH);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Unexpected case. Please report!");
|
||||
}
|
||||
context.signalEncoderChange(Encodation.ASCII);
|
||||
}
|
||||
|
||||
virtual protected int encodeChar(char c, StringBuilder sb)
|
||||
{
|
||||
if (c == ' ')
|
||||
{
|
||||
sb.Append('\u0003');
|
||||
return 1;
|
||||
}
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
sb.Append((char)(c - 48 + 4));
|
||||
return 1;
|
||||
}
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
sb.Append((char)(c - 65 + 14));
|
||||
return 1;
|
||||
}
|
||||
if (c >= '\u0000' && c <= '\u001f')
|
||||
{
|
||||
sb.Append('\u0000'); //Shift 1 Set
|
||||
sb.Append(c);
|
||||
return 2;
|
||||
}
|
||||
if (c >= '!' && c <= '/')
|
||||
{
|
||||
sb.Append('\u0001'); //Shift 2 Set
|
||||
sb.Append((char)(c - 33));
|
||||
return 2;
|
||||
}
|
||||
if (c >= ':' && c <= '@')
|
||||
{
|
||||
sb.Append('\u0001'); //Shift 2 Set
|
||||
sb.Append((char)(c - 58 + 15));
|
||||
return 2;
|
||||
}
|
||||
if (c >= '[' && c <= '_')
|
||||
{
|
||||
sb.Append('\u0001'); //Shift 2 Set
|
||||
sb.Append((char)(c - 91 + 22));
|
||||
return 2;
|
||||
}
|
||||
if (c >= '\u0060' && c <= '\u007f')
|
||||
{
|
||||
sb.Append('\u0002'); //Shift 3 Set
|
||||
sb.Append((char)(c - 96));
|
||||
return 2;
|
||||
}
|
||||
if (c >= '\u0080')
|
||||
{
|
||||
sb.Append("\u0001\u001e"); //Shift 2, Upper Shift
|
||||
int len = 2;
|
||||
len += encodeChar((char)(c - 128), sb);
|
||||
return len;
|
||||
}
|
||||
throw new InvalidOperationException("Illegal character: " + c);
|
||||
}
|
||||
|
||||
private static String encodeToCodewords(StringBuilder sb, int startPos)
|
||||
{
|
||||
char c1 = sb[startPos];
|
||||
char c2 = sb[startPos + 1];
|
||||
char c3 = sb[startPos + 2];
|
||||
int v = (1600 * c1) + (40 * c2) + c3 + 1;
|
||||
char cw1 = (char)(v / 256);
|
||||
char cw2 = (char)(v % 256);
|
||||
return new String(new char[] { cw1, cw2 });
|
||||
}
|
||||
}
|
||||
}
|
||||
36
zxing.core/xx/datamatrix/encoder/DataMatrixSymbolInfo144.cs
Normal file
36
zxing.core/xx/datamatrix/encoder/DataMatrixSymbolInfo144.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2006 Jeremias Maerki
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal sealed class DataMatrixSymbolInfo144 : SymbolInfo
|
||||
{
|
||||
public DataMatrixSymbolInfo144()
|
||||
: base(false, 1558, 620, 22, 22, 36, -1, 62)
|
||||
{
|
||||
}
|
||||
|
||||
public override int getInterleavedBlockCount()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
public override int getDataLengthForInterleavedBlock(int index)
|
||||
{
|
||||
return (index <= 8) ? 156 : 155;
|
||||
}
|
||||
}
|
||||
}
|
||||
139
zxing.core/xx/datamatrix/encoder/DatamatrixEncodingOptions.cs
Normal file
139
zxing.core/xx/datamatrix/encoder/DatamatrixEncodingOptions.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2013 ZXing.Net authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
using ZXing.Common;
|
||||
using ZXing.Datamatrix.Encoder;
|
||||
|
||||
namespace ZXing.Datamatrix
|
||||
{
|
||||
/// <summary>
|
||||
/// The class holds the available options for the DatamatrixWriter
|
||||
/// </summary>
|
||||
public class DatamatrixEncodingOptions : EncodingOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the matrix shape for Data Matrix
|
||||
/// </summary>
|
||||
public SymbolShapeHint? SymbolShape
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Hints.ContainsKey(EncodeHintType.DATA_MATRIX_SHAPE))
|
||||
{
|
||||
return (SymbolShapeHint)Hints[EncodeHintType.DATA_MATRIX_SHAPE];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
if (Hints.ContainsKey(EncodeHintType.DATA_MATRIX_SHAPE))
|
||||
Hints.Remove(EncodeHintType.DATA_MATRIX_SHAPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Hints[EncodeHintType.DATA_MATRIX_SHAPE] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a minimum barcode size
|
||||
/// </summary>
|
||||
public Dimension MinSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Hints.ContainsKey(EncodeHintType.MIN_SIZE))
|
||||
{
|
||||
return (Dimension)Hints[EncodeHintType.MIN_SIZE];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
if (Hints.ContainsKey(EncodeHintType.MIN_SIZE))
|
||||
Hints.Remove(EncodeHintType.MIN_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Hints[EncodeHintType.MIN_SIZE] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a maximum barcode size
|
||||
/// </summary>
|
||||
public Dimension MaxSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Hints.ContainsKey(EncodeHintType.MAX_SIZE))
|
||||
{
|
||||
return (Dimension)Hints[EncodeHintType.MAX_SIZE];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
if (Hints.ContainsKey(EncodeHintType.MAX_SIZE))
|
||||
Hints.Remove(EncodeHintType.MAX_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Hints[EncodeHintType.MAX_SIZE] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the default encodation
|
||||
/// Make sure that the content fits into the encodation value, otherwise there will be an exception thrown.
|
||||
/// standard value: Encodation.ASCII
|
||||
/// </summary>
|
||||
public int? DefaultEncodation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Hints.ContainsKey(EncodeHintType.DATA_MATRIX_DEFAULT_ENCODATION))
|
||||
{
|
||||
return (int)Hints[EncodeHintType.DATA_MATRIX_DEFAULT_ENCODATION];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
if (Hints.ContainsKey(EncodeHintType.DATA_MATRIX_DEFAULT_ENCODATION))
|
||||
Hints.Remove(EncodeHintType.DATA_MATRIX_DEFAULT_ENCODATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
Hints[EncodeHintType.DATA_MATRIX_DEFAULT_ENCODATION] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
222
zxing.core/xx/datamatrix/encoder/DefaultPlacement.cs
Normal file
222
zxing.core/xx/datamatrix/encoder/DefaultPlacement.cs
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright 2006 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Symbol Character Placement Program. Adapted from Annex M.1 in ISO/IEC 16022:2000(E).
|
||||
/// </summary>
|
||||
public class DefaultPlacement
|
||||
{
|
||||
private readonly String codewords;
|
||||
private readonly int numrows;
|
||||
private readonly int numcols;
|
||||
private readonly byte[] bits;
|
||||
|
||||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
/// <param name="codewords">the codewords to place</param>
|
||||
/// <param name="numcols">the number of columns</param>
|
||||
/// <param name="numrows">the number of rows</param>
|
||||
public DefaultPlacement(String codewords, int numcols, int numrows)
|
||||
{
|
||||
this.codewords = codewords;
|
||||
this.numcols = numcols;
|
||||
this.numrows = numrows;
|
||||
this.bits = new byte[numcols * numrows];
|
||||
SupportClass.Fill(this.bits, (byte)2); //Initialize with "not set" value
|
||||
}
|
||||
|
||||
public int Numrows
|
||||
{
|
||||
get { return numrows; }
|
||||
}
|
||||
|
||||
public int Numcols
|
||||
{
|
||||
get { return numcols; }
|
||||
}
|
||||
|
||||
public byte[] Bits
|
||||
{
|
||||
get { return bits; }
|
||||
}
|
||||
|
||||
public bool getBit(int col, int row)
|
||||
{
|
||||
return bits[row * numcols + col] == 1;
|
||||
}
|
||||
|
||||
public void setBit(int col, int row, bool bit)
|
||||
{
|
||||
bits[row * numcols + col] = bit ? (byte)1 : (byte)0;
|
||||
}
|
||||
|
||||
public bool hasBit(int col, int row)
|
||||
{
|
||||
return bits[row * numcols + col] < 2;
|
||||
}
|
||||
|
||||
public void place()
|
||||
{
|
||||
int pos = 0;
|
||||
int row = 4;
|
||||
int col = 0;
|
||||
|
||||
do
|
||||
{
|
||||
/* repeatedly first check for one of the special corner cases, then... */
|
||||
if ((row == numrows) && (col == 0))
|
||||
{
|
||||
corner1(pos++);
|
||||
}
|
||||
if ((row == numrows - 2) && (col == 0) && ((numcols % 4) != 0))
|
||||
{
|
||||
corner2(pos++);
|
||||
}
|
||||
if ((row == numrows - 2) && (col == 0) && (numcols % 8 == 4))
|
||||
{
|
||||
corner3(pos++);
|
||||
}
|
||||
if ((row == numrows + 4) && (col == 2) && ((numcols % 8) == 0))
|
||||
{
|
||||
corner4(pos++);
|
||||
}
|
||||
/* sweep upward diagonally, inserting successive characters... */
|
||||
do
|
||||
{
|
||||
if ((row < numrows) && (col >= 0) && !hasBit(col, row))
|
||||
{
|
||||
utah(row, col, pos++);
|
||||
}
|
||||
row -= 2;
|
||||
col += 2;
|
||||
} while (row >= 0 && (col < numcols));
|
||||
row++;
|
||||
col += 3;
|
||||
|
||||
/* and then sweep downward diagonally, inserting successive characters, ... */
|
||||
do
|
||||
{
|
||||
if ((row >= 0) && (col < numcols) && !hasBit(col, row))
|
||||
{
|
||||
utah(row, col, pos++);
|
||||
}
|
||||
row += 2;
|
||||
col -= 2;
|
||||
} while ((row < numrows) && (col >= 0));
|
||||
row += 3;
|
||||
col++;
|
||||
|
||||
/* ...until the entire array is scanned */
|
||||
} while ((row < numrows) || (col < numcols));
|
||||
|
||||
/* Lastly, if the lower righthand corner is untouched, fill in fixed pattern */
|
||||
if (!hasBit(numcols - 1, numrows - 1))
|
||||
{
|
||||
setBit(numcols - 1, numrows - 1, true);
|
||||
setBit(numcols - 2, numrows - 2, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void module(int row, int col, int pos, int bit)
|
||||
{
|
||||
if (row < 0)
|
||||
{
|
||||
row += numrows;
|
||||
col += 4 - ((numrows + 4) % 8);
|
||||
}
|
||||
if (col < 0)
|
||||
{
|
||||
col += numcols;
|
||||
row += 4 - ((numcols + 4) % 8);
|
||||
}
|
||||
// Note the conversion:
|
||||
int v = codewords[pos];
|
||||
v &= 1 << (8 - bit);
|
||||
setBit(col, row, v != 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Places the 8 bits of a utah-shaped symbol character in ECC200.
|
||||
/// </summary>
|
||||
/// <param name="row">The row.</param>
|
||||
/// <param name="col">The col.</param>
|
||||
/// <param name="pos">character position</param>
|
||||
private void utah(int row, int col, int pos)
|
||||
{
|
||||
module(row - 2, col - 2, pos, 1);
|
||||
module(row - 2, col - 1, pos, 2);
|
||||
module(row - 1, col - 2, pos, 3);
|
||||
module(row - 1, col - 1, pos, 4);
|
||||
module(row - 1, col, pos, 5);
|
||||
module(row, col - 2, pos, 6);
|
||||
module(row, col - 1, pos, 7);
|
||||
module(row, col, pos, 8);
|
||||
}
|
||||
|
||||
private void corner1(int pos)
|
||||
{
|
||||
module(numrows - 1, 0, pos, 1);
|
||||
module(numrows - 1, 1, pos, 2);
|
||||
module(numrows - 1, 2, pos, 3);
|
||||
module(0, numcols - 2, pos, 4);
|
||||
module(0, numcols - 1, pos, 5);
|
||||
module(1, numcols - 1, pos, 6);
|
||||
module(2, numcols - 1, pos, 7);
|
||||
module(3, numcols - 1, pos, 8);
|
||||
}
|
||||
|
||||
private void corner2(int pos)
|
||||
{
|
||||
module(numrows - 3, 0, pos, 1);
|
||||
module(numrows - 2, 0, pos, 2);
|
||||
module(numrows - 1, 0, pos, 3);
|
||||
module(0, numcols - 4, pos, 4);
|
||||
module(0, numcols - 3, pos, 5);
|
||||
module(0, numcols - 2, pos, 6);
|
||||
module(0, numcols - 1, pos, 7);
|
||||
module(1, numcols - 1, pos, 8);
|
||||
}
|
||||
|
||||
private void corner3(int pos)
|
||||
{
|
||||
module(numrows - 3, 0, pos, 1);
|
||||
module(numrows - 2, 0, pos, 2);
|
||||
module(numrows - 1, 0, pos, 3);
|
||||
module(0, numcols - 2, pos, 4);
|
||||
module(0, numcols - 1, pos, 5);
|
||||
module(1, numcols - 1, pos, 6);
|
||||
module(2, numcols - 1, pos, 7);
|
||||
module(3, numcols - 1, pos, 8);
|
||||
}
|
||||
|
||||
private void corner4(int pos)
|
||||
{
|
||||
module(numrows - 1, 0, pos, 1);
|
||||
module(numrows - 1, numcols - 1, pos, 2);
|
||||
module(0, numcols - 3, pos, 3);
|
||||
module(0, numcols - 2, pos, 4);
|
||||
module(0, numcols - 1, pos, 5);
|
||||
module(1, numcols - 3, pos, 6);
|
||||
module(1, numcols - 2, pos, 7);
|
||||
module(1, numcols - 1, pos, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
165
zxing.core/xx/datamatrix/encoder/EdifactEncoder.cs
Normal file
165
zxing.core/xx/datamatrix/encoder/EdifactEncoder.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal sealed class EdifactEncoder : Encoder
|
||||
{
|
||||
public int EncodingMode
|
||||
{
|
||||
get { return Encodation.EDIFACT; }
|
||||
}
|
||||
|
||||
public void encode(EncoderContext context)
|
||||
{
|
||||
//step F
|
||||
var buffer = new StringBuilder();
|
||||
while (context.HasMoreCharacters)
|
||||
{
|
||||
char c = context.CurrentChar;
|
||||
encodeChar(c, buffer);
|
||||
context.Pos++;
|
||||
|
||||
int count = buffer.Length;
|
||||
if (count >= 4)
|
||||
{
|
||||
context.writeCodewords(encodeToCodewords(buffer, 0));
|
||||
buffer.Remove(0, 4);
|
||||
|
||||
int newMode = HighLevelEncoder.lookAheadTest(context.Message, context.Pos, EncodingMode);
|
||||
if (newMode != EncodingMode)
|
||||
{
|
||||
context.signalEncoderChange(Encodation.ASCII);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer.Append((char)31); //Unlatch
|
||||
handleEOD(context, buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle "end of data" situations
|
||||
/// </summary>
|
||||
/// <param name="context">the encoder context</param>
|
||||
/// <param name="buffer">the buffer with the remaining encoded characters</param>
|
||||
private static void handleEOD(EncoderContext context, StringBuilder buffer)
|
||||
{
|
||||
try
|
||||
{
|
||||
int count = buffer.Length;
|
||||
if (count == 0)
|
||||
{
|
||||
return; //Already finished
|
||||
}
|
||||
if (count == 1)
|
||||
{
|
||||
//Only an unlatch at the end
|
||||
context.updateSymbolInfo();
|
||||
int available = context.SymbolInfo.dataCapacity - context.CodewordCount;
|
||||
int remaining = context.RemainingCharacters;
|
||||
if (remaining == 0 && available <= 2)
|
||||
{
|
||||
return; //No unlatch
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 4)
|
||||
{
|
||||
throw new InvalidOperationException("Count must not exceed 4");
|
||||
}
|
||||
int restChars = count - 1;
|
||||
String encoded = encodeToCodewords(buffer, 0);
|
||||
bool endOfSymbolReached = !context.HasMoreCharacters;
|
||||
bool restInAscii = endOfSymbolReached && restChars <= 2;
|
||||
|
||||
if (restChars <= 2)
|
||||
{
|
||||
context.updateSymbolInfo(context.CodewordCount + restChars);
|
||||
int available = context.SymbolInfo.dataCapacity - context.CodewordCount;
|
||||
if (available >= 3)
|
||||
{
|
||||
restInAscii = false;
|
||||
context.updateSymbolInfo(context.CodewordCount + encoded.Length);
|
||||
//available = context.symbolInfo.dataCapacity - context.getCodewordCount();
|
||||
}
|
||||
}
|
||||
|
||||
if (restInAscii)
|
||||
{
|
||||
context.resetSymbolInfo();
|
||||
context.Pos -= restChars;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.writeCodewords(encoded);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
context.signalEncoderChange(Encodation.ASCII);
|
||||
}
|
||||
}
|
||||
|
||||
private static void encodeChar(char c, StringBuilder sb)
|
||||
{
|
||||
if (c >= ' ' && c <= '?')
|
||||
{
|
||||
sb.Append(c);
|
||||
}
|
||||
else if (c >= '@' && c <= '^')
|
||||
{
|
||||
sb.Append((char)(c - 64));
|
||||
}
|
||||
else
|
||||
{
|
||||
HighLevelEncoder.illegalCharacter(c);
|
||||
}
|
||||
}
|
||||
|
||||
private static String encodeToCodewords(StringBuilder sb, int startPos)
|
||||
{
|
||||
int len = sb.Length - startPos;
|
||||
if (len == 0)
|
||||
{
|
||||
throw new InvalidOperationException("StringBuilder must not be empty");
|
||||
}
|
||||
char c1 = sb[startPos];
|
||||
char c2 = len >= 2 ? sb[startPos + 1] : (char)0;
|
||||
char c3 = len >= 3 ? sb[startPos + 2] : (char)0;
|
||||
char c4 = len >= 4 ? sb[startPos + 3] : (char)0;
|
||||
|
||||
int v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4;
|
||||
char cw1 = (char)((v >> 16) & 255);
|
||||
char cw2 = (char)((v >> 8) & 255);
|
||||
char cw3 = (char)(v & 255);
|
||||
var res = new StringBuilder(3);
|
||||
res.Append(cw1);
|
||||
if (len >= 2)
|
||||
{
|
||||
res.Append(cw2);
|
||||
}
|
||||
if (len >= 3)
|
||||
{
|
||||
res.Append(cw3);
|
||||
}
|
||||
return res.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
31
zxing.core/xx/datamatrix/encoder/Encodation.cs
Normal file
31
zxing.core/xx/datamatrix/encoder/Encodation.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2013
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration for encodation types
|
||||
/// </summary>
|
||||
public sealed class Encodation
|
||||
{
|
||||
public const int ASCII = 0;
|
||||
public const int C40 = 1;
|
||||
public const int TEXT = 2;
|
||||
public const int X12 = 3;
|
||||
public const int EDIFACT = 4;
|
||||
public const int BASE256 = 5;
|
||||
}
|
||||
}
|
||||
25
zxing.core/xx/datamatrix/encoder/Encoder.cs
Normal file
25
zxing.core/xx/datamatrix/encoder/Encoder.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal interface Encoder
|
||||
{
|
||||
int EncodingMode { get; }
|
||||
|
||||
void encode(EncoderContext context);
|
||||
}
|
||||
}
|
||||
186
zxing.core/xx/datamatrix/encoder/EncoderContext.cs
Normal file
186
zxing.core/xx/datamatrix/encoder/EncoderContext.cs
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal sealed class EncoderContext
|
||||
{
|
||||
private readonly String msg;
|
||||
private SymbolShapeHint shape;
|
||||
private Dimension minSize;
|
||||
private Dimension maxSize;
|
||||
private readonly StringBuilder codewords;
|
||||
private int pos;
|
||||
private int newEncoding;
|
||||
private SymbolInfo symbolInfo;
|
||||
private int skipAtEnd;
|
||||
private static readonly Encoding encoding;
|
||||
|
||||
static EncoderContext()
|
||||
{
|
||||
#if !(WindowsCE || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE)
|
||||
encoding = Encoding.GetEncoding("ISO-8859-1");
|
||||
#elif WindowsCE
|
||||
try
|
||||
{
|
||||
encoding = Encoding.GetEncoding("ISO-8859-1");
|
||||
}
|
||||
catch (PlatformNotSupportedException)
|
||||
{
|
||||
encoding = Encoding.GetEncoding(1252);
|
||||
}
|
||||
#else
|
||||
// not fully correct but what else
|
||||
encoding = Encoding.GetEncoding("UTF-8");
|
||||
#endif
|
||||
}
|
||||
|
||||
public EncoderContext(String msg)
|
||||
{
|
||||
//From this point on Strings are not Unicode anymore!
|
||||
var msgBinary = encoding.GetBytes(msg);
|
||||
var sb = new StringBuilder(msgBinary.Length);
|
||||
var c = msgBinary.Length;
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
// TODO: does it works in .Net the same way?
|
||||
var ch = (char)(msgBinary[i] & 0xff);
|
||||
if (ch == '?' && msg[i] != '?')
|
||||
{
|
||||
throw new ArgumentException("Message contains characters outside " + encoding.WebName + " encoding.");
|
||||
}
|
||||
sb.Append(ch);
|
||||
}
|
||||
this.msg = sb.ToString(); //Not Unicode here!
|
||||
shape = SymbolShapeHint.FORCE_NONE;
|
||||
this.codewords = new StringBuilder(msg.Length);
|
||||
newEncoding = -1;
|
||||
}
|
||||
|
||||
public void setSymbolShape(SymbolShapeHint shape)
|
||||
{
|
||||
this.shape = shape;
|
||||
}
|
||||
|
||||
public void setSizeConstraints(Dimension minSize, Dimension maxSize)
|
||||
{
|
||||
this.minSize = minSize;
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
public void setSkipAtEnd(int count)
|
||||
{
|
||||
this.skipAtEnd = count;
|
||||
}
|
||||
|
||||
public char CurrentChar
|
||||
{
|
||||
get { return msg[pos]; }
|
||||
}
|
||||
|
||||
public char Current
|
||||
{
|
||||
get { return msg[pos]; }
|
||||
}
|
||||
|
||||
public void writeCodewords(String codewords)
|
||||
{
|
||||
this.codewords.Append(codewords);
|
||||
}
|
||||
|
||||
public void writeCodeword(char codeword)
|
||||
{
|
||||
this.codewords.Append(codeword);
|
||||
}
|
||||
|
||||
public int CodewordCount
|
||||
{
|
||||
get { return this.codewords.Length; }
|
||||
}
|
||||
|
||||
public void signalEncoderChange(int encoding)
|
||||
{
|
||||
this.newEncoding = encoding;
|
||||
}
|
||||
|
||||
public void resetEncoderSignal()
|
||||
{
|
||||
this.newEncoding = -1;
|
||||
}
|
||||
|
||||
public bool HasMoreCharacters
|
||||
{
|
||||
get { return pos < TotalMessageCharCount; }
|
||||
}
|
||||
|
||||
private int TotalMessageCharCount
|
||||
{
|
||||
get { return msg.Length - skipAtEnd; }
|
||||
}
|
||||
|
||||
public int RemainingCharacters
|
||||
{
|
||||
get { return TotalMessageCharCount - pos; }
|
||||
}
|
||||
|
||||
public void updateSymbolInfo()
|
||||
{
|
||||
updateSymbolInfo(CodewordCount);
|
||||
}
|
||||
|
||||
public void updateSymbolInfo(int len)
|
||||
{
|
||||
if (this.symbolInfo == null || len > this.symbolInfo.dataCapacity)
|
||||
{
|
||||
this.symbolInfo = SymbolInfo.lookup(len, shape, minSize, maxSize, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetSymbolInfo()
|
||||
{
|
||||
this.symbolInfo = null;
|
||||
}
|
||||
|
||||
public int Pos
|
||||
{
|
||||
get { return pos; }
|
||||
set { pos = value; }
|
||||
}
|
||||
|
||||
public StringBuilder Codewords
|
||||
{
|
||||
get { return codewords; }
|
||||
}
|
||||
|
||||
public SymbolInfo SymbolInfo
|
||||
{
|
||||
get { return symbolInfo; }
|
||||
}
|
||||
|
||||
public int NewEncoding
|
||||
{
|
||||
get { return newEncoding; }
|
||||
}
|
||||
|
||||
public String Message
|
||||
{
|
||||
get { return msg; }
|
||||
}
|
||||
}
|
||||
}
|
||||
283
zxing.core/xx/datamatrix/encoder/ErrorCorrection.cs
Normal file
283
zxing.core/xx/datamatrix/encoder/ErrorCorrection.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright 2006 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Error Correction Code for ECC200.
|
||||
/// </summary>
|
||||
public static class ErrorCorrection
|
||||
{
|
||||
/// <summary>
|
||||
/// Lookup table which factors to use for which number of error correction codewords.
|
||||
/// See FACTORS.
|
||||
/// </summary>
|
||||
private static readonly int[] FACTOR_SETS
|
||||
= { 5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68 };
|
||||
|
||||
/// <summary>
|
||||
/// Precomputed polynomial factors for ECC 200.
|
||||
/// </summary>
|
||||
private static readonly int[][] FACTORS = {
|
||||
new[] {228, 48, 15, 111, 62},
|
||||
new[] {23, 68, 144, 134, 240, 92, 254},
|
||||
new[] {28, 24, 185, 166, 223, 248, 116, 255, 110, 61},
|
||||
new[] {175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120},
|
||||
new[] {41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242},
|
||||
new[] {156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185}
|
||||
,
|
||||
new[]
|
||||
{
|
||||
83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254,
|
||||
225,
|
||||
48, 90, 188
|
||||
},
|
||||
new[]
|
||||
{
|
||||
15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79,
|
||||
108,
|
||||
82, 27, 174, 186, 172
|
||||
},
|
||||
new[]
|
||||
{
|
||||
52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21
|
||||
, 5
|
||||
, 172,
|
||||
254, 124, 12, 181, 184, 96, 50, 193
|
||||
},
|
||||
new[]
|
||||
{
|
||||
211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34,
|
||||
249,
|
||||
121,
|
||||
17, 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255
|
||||
},
|
||||
new[]
|
||||
{
|
||||
245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220,
|
||||
251, 80, 182,
|
||||
229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59
|
||||
,
|
||||
25,
|
||||
225, 98, 81, 112
|
||||
},
|
||||
new[]
|
||||
{
|
||||
77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133,
|
||||
242
|
||||
, 8,
|
||||
175, 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57,
|
||||
54,
|
||||
101,
|
||||
248, 202, 69, 50, 150, 177, 226, 5, 9, 5
|
||||
},
|
||||
new[]
|
||||
{
|
||||
245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205,
|
||||
188,
|
||||
237, 87,
|
||||
191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100
|
||||
,
|
||||
66, 138,
|
||||
186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253
|
||||
,
|
||||
225, 19
|
||||
},
|
||||
new[]
|
||||
{
|
||||
175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192
|
||||
,
|
||||
215, 235,
|
||||
150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117,
|
||||
203,
|
||||
29, 232,
|
||||
144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127,
|
||||
67,
|
||||
247, 28,
|
||||
155, 43, 203, 107, 233, 53, 143, 46
|
||||
},
|
||||
new[]
|
||||
{
|
||||
242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143,
|
||||
108,
|
||||
196, 37,
|
||||
185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175,
|
||||
64
|
||||
, 114, 71,
|
||||
161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163
|
||||
,
|
||||
31,
|
||||
176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204
|
||||
},
|
||||
new[]
|
||||
{
|
||||
220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36
|
||||
,
|
||||
73, 127,
|
||||
213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15,
|
||||
160,
|
||||
227, 236,
|
||||
66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231,
|
||||
136,
|
||||
223, 239,
|
||||
181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153,
|
||||
132, 63,
|
||||
96, 103, 82, 186
|
||||
}
|
||||
};
|
||||
|
||||
private const int MODULO_VALUE = 0x12D;
|
||||
|
||||
private static readonly int[] LOG;
|
||||
private static readonly int[] ALOG;
|
||||
|
||||
static ErrorCorrection()
|
||||
{
|
||||
//Create log and antilog table
|
||||
LOG = new int[256];
|
||||
ALOG = new int[255];
|
||||
|
||||
int p = 1;
|
||||
for (int i = 0; i < 255; i++)
|
||||
{
|
||||
ALOG[i] = p;
|
||||
LOG[p] = i;
|
||||
p <<= 1;
|
||||
if (p >= 256)
|
||||
{
|
||||
p ^= MODULO_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the ECC200 error correction for an encoded message.
|
||||
/// </summary>
|
||||
/// <param name="codewords">The codewords.</param>
|
||||
/// <param name="symbolInfo">information about the symbol to be encoded</param>
|
||||
/// <returns>the codewords with interleaved error correction.</returns>
|
||||
public static String encodeECC200(String codewords, SymbolInfo symbolInfo)
|
||||
{
|
||||
if (codewords.Length != symbolInfo.dataCapacity)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"The number of codewords does not match the selected symbol");
|
||||
}
|
||||
var sb = new StringBuilder(symbolInfo.dataCapacity + symbolInfo.errorCodewords);
|
||||
sb.Append(codewords);
|
||||
int blockCount = symbolInfo.getInterleavedBlockCount();
|
||||
if (blockCount == 1)
|
||||
{
|
||||
String ecc = createECCBlock(codewords, symbolInfo.errorCodewords);
|
||||
sb.Append(ecc);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Length = sb.Capacity;
|
||||
int[] dataSizes = new int[blockCount];
|
||||
int[] errorSizes = new int[blockCount];
|
||||
int[] startPos = new int[blockCount];
|
||||
for (int i = 0; i < blockCount; i++)
|
||||
{
|
||||
dataSizes[i] = symbolInfo.getDataLengthForInterleavedBlock(i + 1);
|
||||
errorSizes[i] = symbolInfo.getErrorLengthForInterleavedBlock(i + 1);
|
||||
startPos[i] = 0;
|
||||
if (i > 0)
|
||||
{
|
||||
startPos[i] = startPos[i - 1] + dataSizes[i];
|
||||
}
|
||||
}
|
||||
for (int block = 0; block < blockCount; block++)
|
||||
{
|
||||
var temp = new StringBuilder(dataSizes[block]);
|
||||
for (int d = block; d < symbolInfo.dataCapacity; d += blockCount)
|
||||
{
|
||||
temp.Append(codewords[d]);
|
||||
}
|
||||
String ecc = createECCBlock(temp.ToString(), errorSizes[block]);
|
||||
int pos = 0;
|
||||
for (int e = block; e < errorSizes[block] * blockCount; e += blockCount)
|
||||
{
|
||||
sb[symbolInfo.dataCapacity + e] = ecc[pos++];
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
|
||||
}
|
||||
|
||||
private static String createECCBlock(String codewords, int numECWords)
|
||||
{
|
||||
return createECCBlock(codewords, 0, codewords.Length, numECWords);
|
||||
}
|
||||
|
||||
private static String createECCBlock(String codewords, int start, int len, int numECWords)
|
||||
{
|
||||
int table = -1;
|
||||
for (int i = 0; i < FACTOR_SETS.Length; i++)
|
||||
{
|
||||
if (FACTOR_SETS[i] == numECWords)
|
||||
{
|
||||
table = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (table < 0)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Illegal number of error correction codewords specified: " + numECWords);
|
||||
}
|
||||
int[] poly = FACTORS[table];
|
||||
char[] ecc = new char[numECWords];
|
||||
for (int i = 0; i < numECWords; i++)
|
||||
{
|
||||
ecc[i] = (char)0;
|
||||
}
|
||||
for (int i = start; i < start + len; i++)
|
||||
{
|
||||
int m = ecc[numECWords - 1] ^ codewords[i];
|
||||
for (int k = numECWords - 1; k > 0; k--)
|
||||
{
|
||||
if (m != 0 && poly[k] != 0)
|
||||
{
|
||||
ecc[k] = (char)(ecc[k - 1] ^ ALOG[(LOG[m] + LOG[poly[k]]) % 255]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecc[k] = ecc[k - 1];
|
||||
}
|
||||
}
|
||||
if (m != 0 && poly[0] != 0)
|
||||
{
|
||||
ecc[0] = (char)ALOG[(LOG[m] + LOG[poly[0]]) % 255];
|
||||
}
|
||||
else
|
||||
{
|
||||
ecc[0] = (char)0;
|
||||
}
|
||||
}
|
||||
char[] eccReversed = new char[numECWords];
|
||||
for (int i = 0; i < numECWords; i++)
|
||||
{
|
||||
eccReversed[i] = ecc[numECWords - i - 1];
|
||||
}
|
||||
return new String(eccReversed);
|
||||
}
|
||||
}
|
||||
}
|
||||
537
zxing.core/xx/datamatrix/encoder/HighLevelEncoder.cs
Normal file
537
zxing.core/xx/datamatrix/encoder/HighLevelEncoder.cs
Normal file
@@ -0,0 +1,537 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
/// <summary>
|
||||
/// DataMatrix ECC 200 data encoder following the algorithm described in ISO/IEC 16022:200(E) in
|
||||
/// annex S.
|
||||
/// </summary>
|
||||
internal static class HighLevelEncoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Padding character
|
||||
/// </summary>
|
||||
public const char PAD = (char)129;
|
||||
/// <summary>
|
||||
/// mode latch to C40 encodation mode
|
||||
/// </summary>
|
||||
public const char LATCH_TO_C40 = (char)230;
|
||||
/// <summary>
|
||||
/// mode latch to Base 256 encodation mode
|
||||
/// </summary>
|
||||
public const char LATCH_TO_BASE256 = (char)231;
|
||||
/// <summary>
|
||||
/// FNC1 Codeword
|
||||
/// </summary>
|
||||
public const char FNC1 = (char)232;
|
||||
/// <summary>
|
||||
/// Structured Append Codeword
|
||||
/// </summary>
|
||||
public const char STRUCTURED_APPEND = (char)233;
|
||||
/// <summary>
|
||||
/// Reader Programming
|
||||
/// </summary>
|
||||
public const char READER_PROGRAMMING = (char)234;
|
||||
/// <summary>
|
||||
/// Upper Shift
|
||||
/// </summary>
|
||||
public const char UPPER_SHIFT = (char)235;
|
||||
/// <summary>
|
||||
/// 05 Macro
|
||||
/// </summary>
|
||||
public const char MACRO_05 = (char)236;
|
||||
/// <summary>
|
||||
/// 06 Macro
|
||||
/// </summary>
|
||||
public const char MACRO_06 = (char)237;
|
||||
/// <summary>
|
||||
/// mode latch to ANSI X.12 encodation mode
|
||||
/// </summary>
|
||||
public const char LATCH_TO_ANSIX12 = (char)238;
|
||||
/// <summary>
|
||||
/// mode latch to Text encodation mode
|
||||
/// </summary>
|
||||
public const char LATCH_TO_TEXT = (char)239;
|
||||
/// <summary>
|
||||
/// mode latch to EDIFACT encodation mode
|
||||
/// </summary>
|
||||
public const char LATCH_TO_EDIFACT = (char)240;
|
||||
/// <summary>
|
||||
/// ECI character (Extended Channel Interpretation)
|
||||
/// </summary>
|
||||
public const char ECI = (char)241;
|
||||
|
||||
/// <summary>
|
||||
/// Unlatch from C40 encodation
|
||||
/// </summary>
|
||||
public const char C40_UNLATCH = (char)254;
|
||||
/// <summary>
|
||||
/// Unlatch from X12 encodation
|
||||
/// </summary>
|
||||
public const char X12_UNLATCH = (char)254;
|
||||
|
||||
/// <summary>
|
||||
/// 05 Macro header
|
||||
/// </summary>
|
||||
public const String MACRO_05_HEADER = "[)>\u001E05\u001D";
|
||||
/// <summary>
|
||||
/// 06 Macro header
|
||||
/// </summary>
|
||||
public const String MACRO_06_HEADER = "[)>\u001E06\u001D";
|
||||
/// <summary>
|
||||
/// Macro trailer
|
||||
/// </summary>
|
||||
public const String MACRO_TRAILER = "\u001E\u0004";
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Converts the message to a byte array using the default encoding (cp437) as defined by the
|
||||
/// specification
|
||||
/// </summary>
|
||||
/// <param name="msg">the message</param>
|
||||
/// <returns>the byte array of the message</returns>
|
||||
public static byte[] getBytesForMessage(String msg)
|
||||
{
|
||||
return Encoding.GetEncoding("CP437").GetBytes(msg); //See 4.4.3 and annex B of ISO/IEC 15438:2001(E)
|
||||
}
|
||||
*/
|
||||
|
||||
private static char randomize253State(char ch, int codewordPosition)
|
||||
{
|
||||
int pseudoRandom = ((149 * codewordPosition) % 253) + 1;
|
||||
int tempVariable = ch + pseudoRandom;
|
||||
return tempVariable <= 254 ? (char)tempVariable : (char)(tempVariable - 254);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs message encoding of a DataMatrix message using the algorithm described in annex P
|
||||
/// of ISO/IEC 16022:2000(E).
|
||||
/// </summary>
|
||||
/// <param name="msg">the message</param>
|
||||
/// <returns>the encoded message (the char values range from 0 to 255)</returns>
|
||||
public static String encodeHighLevel(String msg)
|
||||
{
|
||||
return encodeHighLevel(msg, SymbolShapeHint.FORCE_NONE, null, null, Encodation.ASCII);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs message encoding of a DataMatrix message using the algorithm described in annex P
|
||||
/// of ISO/IEC 16022:2000(E).
|
||||
/// </summary>
|
||||
/// <param name="msg">the message</param>
|
||||
/// <param name="shape">requested shape. May be {@code SymbolShapeHint.FORCE_NONE},{@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}.</param>
|
||||
/// <param name="minSize">the minimum symbol size constraint or null for no constraint</param>
|
||||
/// <param name="maxSize">the maximum symbol size constraint or null for no constraint</param>
|
||||
/// <returns>the encoded message (the char values range from 0 to 255)</returns>
|
||||
public static String encodeHighLevel(String msg,
|
||||
SymbolShapeHint shape,
|
||||
Dimension minSize,
|
||||
Dimension maxSize,
|
||||
int defaultEncodation)
|
||||
{
|
||||
//the codewords 0..255 are encoded as Unicode characters
|
||||
Encoder[] encoders =
|
||||
{
|
||||
new ASCIIEncoder(), new C40Encoder(), new TextEncoder(),
|
||||
new X12Encoder(), new EdifactEncoder(), new Base256Encoder()
|
||||
};
|
||||
|
||||
var context = new EncoderContext(msg);
|
||||
context.setSymbolShape(shape);
|
||||
context.setSizeConstraints(minSize, maxSize);
|
||||
|
||||
if (msg.StartsWith(MACRO_05_HEADER) && msg.EndsWith(MACRO_TRAILER))
|
||||
{
|
||||
context.writeCodeword(MACRO_05);
|
||||
context.setSkipAtEnd(2);
|
||||
context.Pos += MACRO_05_HEADER.Length;
|
||||
}
|
||||
else if (msg.StartsWith(MACRO_06_HEADER) && msg.EndsWith(MACRO_TRAILER))
|
||||
{
|
||||
context.writeCodeword(MACRO_06);
|
||||
context.setSkipAtEnd(2);
|
||||
context.Pos += MACRO_06_HEADER.Length;
|
||||
}
|
||||
|
||||
int encodingMode = defaultEncodation; //Default mode
|
||||
switch (encodingMode)
|
||||
{
|
||||
case Encodation.BASE256:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_BASE256);
|
||||
break;
|
||||
case Encodation.C40:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_C40);
|
||||
break;
|
||||
case Encodation.X12:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_ANSIX12);
|
||||
break;
|
||||
case Encodation.TEXT:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_TEXT);
|
||||
break;
|
||||
case Encodation.EDIFACT:
|
||||
context.writeCodeword(HighLevelEncoder.LATCH_TO_EDIFACT);
|
||||
break;
|
||||
case Encodation.ASCII:
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Illegal mode: " + encodingMode);
|
||||
}
|
||||
while (context.HasMoreCharacters)
|
||||
{
|
||||
encoders[encodingMode].encode(context);
|
||||
if (context.NewEncoding >= 0)
|
||||
{
|
||||
encodingMode = context.NewEncoding;
|
||||
context.resetEncoderSignal();
|
||||
}
|
||||
}
|
||||
int len = context.Codewords.Length;
|
||||
context.updateSymbolInfo();
|
||||
int capacity = context.SymbolInfo.dataCapacity;
|
||||
if (len < capacity)
|
||||
{
|
||||
if (encodingMode != Encodation.ASCII && encodingMode != Encodation.BASE256)
|
||||
{
|
||||
context.writeCodeword('\u00fe'); //Unlatch (254)
|
||||
}
|
||||
}
|
||||
//Padding
|
||||
StringBuilder codewords = context.Codewords;
|
||||
if (codewords.Length < capacity)
|
||||
{
|
||||
codewords.Append(PAD);
|
||||
}
|
||||
while (codewords.Length < capacity)
|
||||
{
|
||||
codewords.Append(randomize253State(PAD, codewords.Length + 1));
|
||||
}
|
||||
|
||||
return context.Codewords.ToString();
|
||||
}
|
||||
|
||||
internal static int lookAheadTest(String msg, int startpos, int currentMode)
|
||||
{
|
||||
if (startpos >= msg.Length)
|
||||
{
|
||||
return currentMode;
|
||||
}
|
||||
float[] charCounts;
|
||||
//step J
|
||||
if (currentMode == Encodation.ASCII)
|
||||
{
|
||||
charCounts = new [] { 0, 1, 1, 1, 1, 1.25f };
|
||||
}
|
||||
else
|
||||
{
|
||||
charCounts = new [] { 1, 2, 2, 2, 2, 2.25f };
|
||||
charCounts[currentMode] = 0;
|
||||
}
|
||||
|
||||
int charsProcessed = 0;
|
||||
while (true)
|
||||
{
|
||||
//step K
|
||||
if ((startpos + charsProcessed) == msg.Length)
|
||||
{
|
||||
var min = Int32.MaxValue;
|
||||
var mins = new byte[6];
|
||||
var intCharCounts = new int[6];
|
||||
min = findMinimums(charCounts, intCharCounts, min, mins);
|
||||
var minCount = getMinimumCount(mins);
|
||||
|
||||
if (intCharCounts[Encodation.ASCII] == min)
|
||||
{
|
||||
return Encodation.ASCII;
|
||||
}
|
||||
if (minCount == 1 && mins[Encodation.BASE256] > 0)
|
||||
{
|
||||
return Encodation.BASE256;
|
||||
}
|
||||
if (minCount == 1 && mins[Encodation.EDIFACT] > 0)
|
||||
{
|
||||
return Encodation.EDIFACT;
|
||||
}
|
||||
if (minCount == 1 && mins[Encodation.TEXT] > 0)
|
||||
{
|
||||
return Encodation.TEXT;
|
||||
}
|
||||
if (minCount == 1 && mins[Encodation.X12] > 0)
|
||||
{
|
||||
return Encodation.X12;
|
||||
}
|
||||
return Encodation.C40;
|
||||
}
|
||||
|
||||
char c = msg[startpos + charsProcessed];
|
||||
charsProcessed++;
|
||||
|
||||
//step L
|
||||
if (isDigit(c))
|
||||
{
|
||||
charCounts[Encodation.ASCII] += 0.5f;
|
||||
}
|
||||
else if (isExtendedASCII(c))
|
||||
{
|
||||
charCounts[Encodation.ASCII] = (int)Math.Ceiling(charCounts[Encodation.ASCII]);
|
||||
charCounts[Encodation.ASCII] += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
charCounts[Encodation.ASCII] = (int)Math.Ceiling(charCounts[Encodation.ASCII]);
|
||||
charCounts[Encodation.ASCII]++;
|
||||
}
|
||||
|
||||
//step M
|
||||
if (isNativeC40(c))
|
||||
{
|
||||
charCounts[Encodation.C40] += 2.0f / 3.0f;
|
||||
}
|
||||
else if (isExtendedASCII(c))
|
||||
{
|
||||
charCounts[Encodation.C40] += 8.0f / 3.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
charCounts[Encodation.C40] += 4.0f / 3.0f;
|
||||
}
|
||||
|
||||
//step N
|
||||
if (isNativeText(c))
|
||||
{
|
||||
charCounts[Encodation.TEXT] += 2.0f / 3.0f;
|
||||
}
|
||||
else if (isExtendedASCII(c))
|
||||
{
|
||||
charCounts[Encodation.TEXT] += 8.0f / 3.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
charCounts[Encodation.TEXT] += 4.0f / 3.0f;
|
||||
}
|
||||
|
||||
//step O
|
||||
if (isNativeX12(c))
|
||||
{
|
||||
charCounts[Encodation.X12] += 2.0f / 3.0f;
|
||||
}
|
||||
else if (isExtendedASCII(c))
|
||||
{
|
||||
charCounts[Encodation.X12] += 13.0f / 3.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
charCounts[Encodation.X12] += 10.0f / 3.0f;
|
||||
}
|
||||
|
||||
//step P
|
||||
if (isNativeEDIFACT(c))
|
||||
{
|
||||
charCounts[Encodation.EDIFACT] += 3.0f / 4.0f;
|
||||
}
|
||||
else if (isExtendedASCII(c))
|
||||
{
|
||||
charCounts[Encodation.EDIFACT] += 17.0f / 4.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
charCounts[Encodation.EDIFACT] += 13.0f / 4.0f;
|
||||
}
|
||||
|
||||
// step Q
|
||||
if (isSpecialB256(c))
|
||||
{
|
||||
charCounts[Encodation.BASE256] += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
charCounts[Encodation.BASE256]++;
|
||||
}
|
||||
|
||||
//step R
|
||||
if (charsProcessed >= 4)
|
||||
{
|
||||
var intCharCounts = new int[6];
|
||||
var mins = new byte[6];
|
||||
findMinimums(charCounts, intCharCounts, Int32.MaxValue, mins);
|
||||
int minCount = getMinimumCount(mins);
|
||||
|
||||
if (intCharCounts[Encodation.ASCII] < intCharCounts[Encodation.BASE256]
|
||||
&& intCharCounts[Encodation.ASCII] < intCharCounts[Encodation.C40]
|
||||
&& intCharCounts[Encodation.ASCII] < intCharCounts[Encodation.TEXT]
|
||||
&& intCharCounts[Encodation.ASCII] < intCharCounts[Encodation.X12]
|
||||
&& intCharCounts[Encodation.ASCII] < intCharCounts[Encodation.EDIFACT])
|
||||
{
|
||||
return Encodation.ASCII;
|
||||
}
|
||||
if (intCharCounts[Encodation.BASE256] < intCharCounts[Encodation.ASCII]
|
||||
|| (mins[Encodation.C40] + mins[Encodation.TEXT] + mins[Encodation.X12] + mins[Encodation.EDIFACT]) == 0)
|
||||
{
|
||||
return Encodation.BASE256;
|
||||
}
|
||||
if (minCount == 1 && mins[Encodation.EDIFACT] > 0)
|
||||
{
|
||||
return Encodation.EDIFACT;
|
||||
}
|
||||
if (minCount == 1 && mins[Encodation.TEXT] > 0)
|
||||
{
|
||||
return Encodation.TEXT;
|
||||
}
|
||||
if (minCount == 1 && mins[Encodation.X12] > 0)
|
||||
{
|
||||
return Encodation.X12;
|
||||
}
|
||||
if (intCharCounts[Encodation.C40] + 1 < intCharCounts[Encodation.ASCII]
|
||||
&& intCharCounts[Encodation.C40] + 1 < intCharCounts[Encodation.BASE256]
|
||||
&& intCharCounts[Encodation.C40] + 1 < intCharCounts[Encodation.EDIFACT]
|
||||
&& intCharCounts[Encodation.C40] + 1 < intCharCounts[Encodation.TEXT])
|
||||
{
|
||||
if (intCharCounts[Encodation.C40] < intCharCounts[Encodation.X12])
|
||||
{
|
||||
return Encodation.C40;
|
||||
}
|
||||
if (intCharCounts[Encodation.C40] == intCharCounts[Encodation.X12])
|
||||
{
|
||||
int p = startpos + charsProcessed + 1;
|
||||
while (p < msg.Length)
|
||||
{
|
||||
char tc = msg[p];
|
||||
if (isX12TermSep(tc))
|
||||
{
|
||||
return Encodation.X12;
|
||||
}
|
||||
if (!isNativeX12(tc))
|
||||
{
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return Encodation.C40;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int findMinimums(float[] charCounts, int[] intCharCounts, int min, byte[] mins)
|
||||
{
|
||||
SupportClass.Fill(mins, (byte)0);
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
intCharCounts[i] = (int)Math.Ceiling(charCounts[i]);
|
||||
int current = intCharCounts[i];
|
||||
if (min > current)
|
||||
{
|
||||
min = current;
|
||||
SupportClass.Fill(mins, (byte)0);
|
||||
}
|
||||
if (min == current)
|
||||
{
|
||||
mins[i]++;
|
||||
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
private static int getMinimumCount(byte[] mins)
|
||||
{
|
||||
int minCount = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
minCount += mins[i];
|
||||
}
|
||||
return minCount;
|
||||
}
|
||||
|
||||
internal static bool isDigit(char ch)
|
||||
{
|
||||
return ch >= '0' && ch <= '9';
|
||||
}
|
||||
|
||||
internal static bool isExtendedASCII(char ch)
|
||||
{
|
||||
return ch >= 128 && ch <= 255;
|
||||
}
|
||||
|
||||
internal static bool isNativeC40(char ch)
|
||||
{
|
||||
return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z');
|
||||
}
|
||||
|
||||
internal static bool isNativeText(char ch)
|
||||
{
|
||||
return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z');
|
||||
}
|
||||
|
||||
internal static bool isNativeX12(char ch)
|
||||
{
|
||||
return isX12TermSep(ch) || (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z');
|
||||
}
|
||||
|
||||
internal static bool isX12TermSep(char ch)
|
||||
{
|
||||
return (ch == '\r') //CR
|
||||
|| (ch == '*')
|
||||
|| (ch == '>');
|
||||
}
|
||||
|
||||
internal static bool isNativeEDIFACT(char ch)
|
||||
{
|
||||
return ch >= ' ' && ch <= '^';
|
||||
}
|
||||
|
||||
internal static bool isSpecialB256(char ch)
|
||||
{
|
||||
return false; //TODO NOT IMPLEMENTED YET!!!
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the number of consecutive characters that are encodable using numeric compaction.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message</param>
|
||||
/// <param name="startpos">the start position within the message</param>
|
||||
/// <returns>the requested character count</returns>
|
||||
public static int determineConsecutiveDigitCount(String msg, int startpos)
|
||||
{
|
||||
int count = 0;
|
||||
int len = msg.Length;
|
||||
int idx = startpos;
|
||||
if (idx < len)
|
||||
{
|
||||
char ch = msg[idx];
|
||||
while (isDigit(ch) && idx < len)
|
||||
{
|
||||
count++;
|
||||
idx++;
|
||||
if (idx < len)
|
||||
{
|
||||
ch = msg[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
internal static void illegalCharacter(char c)
|
||||
{
|
||||
throw new ArgumentException(String.Format("Illegal character: {0} (0x{1:X})", c, (int)c));
|
||||
}
|
||||
}
|
||||
}
|
||||
258
zxing.core/xx/datamatrix/encoder/SymbolInfo.cs
Normal file
258
zxing.core/xx/datamatrix/encoder/SymbolInfo.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2006 Jeremias Maerki
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Symbol info table for DataMatrix.
|
||||
/// </summary>
|
||||
public class SymbolInfo
|
||||
{
|
||||
internal static readonly SymbolInfo[] PROD_SYMBOLS = {
|
||||
new SymbolInfo(false, 3, 5, 8, 8, 1),
|
||||
new SymbolInfo(false, 5, 7, 10, 10, 1),
|
||||
/*rect*/new SymbolInfo(true, 5, 7, 16, 6, 1),
|
||||
new SymbolInfo(false, 8, 10, 12, 12, 1),
|
||||
/*rect*/new SymbolInfo(true, 10, 11, 14, 6, 2),
|
||||
new SymbolInfo(false, 12, 12, 14, 14, 1),
|
||||
/*rect*/new SymbolInfo(true, 16, 14, 24, 10, 1),
|
||||
|
||||
new SymbolInfo(false, 18, 14, 16, 16, 1),
|
||||
new SymbolInfo(false, 22, 18, 18, 18, 1),
|
||||
/*rect*/new SymbolInfo(true, 22, 18, 16, 10, 2),
|
||||
new SymbolInfo(false, 30, 20, 20, 20, 1),
|
||||
/*rect*/new SymbolInfo(true, 32, 24, 16, 14, 2),
|
||||
new SymbolInfo(false, 36, 24, 22, 22, 1),
|
||||
new SymbolInfo(false, 44, 28, 24, 24, 1),
|
||||
/*rect*/new SymbolInfo(true, 49, 28, 22, 14, 2),
|
||||
|
||||
new SymbolInfo(false, 62, 36, 14, 14, 4),
|
||||
new SymbolInfo(false, 86, 42, 16, 16, 4),
|
||||
new SymbolInfo(false, 114, 48, 18, 18, 4),
|
||||
new SymbolInfo(false, 144, 56, 20, 20, 4),
|
||||
new SymbolInfo(false, 174, 68, 22, 22, 4),
|
||||
|
||||
new SymbolInfo(false, 204, 84, 24, 24, 4, 102, 42),
|
||||
new SymbolInfo(false, 280, 112, 14, 14, 16, 140, 56),
|
||||
new SymbolInfo(false, 368, 144, 16, 16, 16, 92, 36),
|
||||
new SymbolInfo(false, 456, 192, 18, 18, 16, 114, 48),
|
||||
new SymbolInfo(false, 576, 224, 20, 20, 16, 144, 56),
|
||||
new SymbolInfo(false, 696, 272, 22, 22, 16, 174, 68),
|
||||
new SymbolInfo(false, 816, 336, 24, 24, 16, 136, 56),
|
||||
new SymbolInfo(false, 1050, 408, 18, 18, 36, 175, 68),
|
||||
new SymbolInfo(false, 1304, 496, 20, 20, 36, 163, 62),
|
||||
new DataMatrixSymbolInfo144(),
|
||||
};
|
||||
|
||||
private static SymbolInfo[] symbols = PROD_SYMBOLS;
|
||||
|
||||
/**
|
||||
* Overrides the symbol info set used by this class. Used for testing purposes.
|
||||
*
|
||||
* @param override the symbol info set to use
|
||||
*/
|
||||
public static void overrideSymbolSet(SymbolInfo[] @override)
|
||||
{
|
||||
symbols = @override;
|
||||
}
|
||||
|
||||
private readonly bool rectangular;
|
||||
internal readonly int dataCapacity;
|
||||
internal readonly int errorCodewords;
|
||||
public readonly int matrixWidth;
|
||||
public readonly int matrixHeight;
|
||||
private readonly int dataRegions;
|
||||
private readonly int rsBlockData;
|
||||
private readonly int rsBlockError;
|
||||
|
||||
public SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords,
|
||||
int matrixWidth, int matrixHeight, int dataRegions)
|
||||
: this(rectangular, dataCapacity, errorCodewords, matrixWidth, matrixHeight, dataRegions,
|
||||
dataCapacity, errorCodewords)
|
||||
{
|
||||
}
|
||||
|
||||
internal SymbolInfo(bool rectangular, int dataCapacity, int errorCodewords,
|
||||
int matrixWidth, int matrixHeight, int dataRegions,
|
||||
int rsBlockData, int rsBlockError)
|
||||
{
|
||||
this.rectangular = rectangular;
|
||||
this.dataCapacity = dataCapacity;
|
||||
this.errorCodewords = errorCodewords;
|
||||
this.matrixWidth = matrixWidth;
|
||||
this.matrixHeight = matrixHeight;
|
||||
this.dataRegions = dataRegions;
|
||||
this.rsBlockData = rsBlockData;
|
||||
this.rsBlockError = rsBlockError;
|
||||
}
|
||||
|
||||
public static SymbolInfo lookup(int dataCodewords)
|
||||
{
|
||||
return lookup(dataCodewords, SymbolShapeHint.FORCE_NONE, true);
|
||||
}
|
||||
|
||||
public static SymbolInfo lookup(int dataCodewords, SymbolShapeHint shape)
|
||||
{
|
||||
return lookup(dataCodewords, shape, true);
|
||||
}
|
||||
|
||||
public static SymbolInfo lookup(int dataCodewords, bool allowRectangular, bool fail)
|
||||
{
|
||||
SymbolShapeHint shape = allowRectangular
|
||||
? SymbolShapeHint.FORCE_NONE : SymbolShapeHint.FORCE_SQUARE;
|
||||
return lookup(dataCodewords, shape, fail);
|
||||
}
|
||||
|
||||
private static SymbolInfo lookup(int dataCodewords, SymbolShapeHint shape, bool fail)
|
||||
{
|
||||
return lookup(dataCodewords, shape, null, null, fail);
|
||||
}
|
||||
|
||||
public static SymbolInfo lookup(int dataCodewords,
|
||||
SymbolShapeHint shape,
|
||||
Dimension minSize,
|
||||
Dimension maxSize,
|
||||
bool fail)
|
||||
{
|
||||
foreach (SymbolInfo symbol in symbols)
|
||||
{
|
||||
if (shape == SymbolShapeHint.FORCE_SQUARE && symbol.rectangular)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (shape == SymbolShapeHint.FORCE_RECTANGLE && !symbol.rectangular)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (minSize != null
|
||||
&& (symbol.getSymbolWidth() < minSize.Width
|
||||
|| symbol.getSymbolHeight() < minSize.Height))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (maxSize != null
|
||||
&& (symbol.getSymbolWidth() > maxSize.Width
|
||||
|| symbol.getSymbolHeight() > maxSize.Height))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (dataCodewords <= symbol.dataCapacity)
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
if (fail)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Can't find a symbol arrangement that matches the message. Data codewords: "
|
||||
+ dataCodewords);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
int getHorizontalDataRegions()
|
||||
{
|
||||
switch (dataRegions)
|
||||
{
|
||||
case 1:
|
||||
return 1;
|
||||
case 2:
|
||||
return 2;
|
||||
case 4:
|
||||
return 2;
|
||||
case 16:
|
||||
return 4;
|
||||
case 36:
|
||||
return 6;
|
||||
default:
|
||||
throw new InvalidOperationException("Cannot handle this number of data regions");
|
||||
}
|
||||
}
|
||||
|
||||
int getVerticalDataRegions()
|
||||
{
|
||||
switch (dataRegions)
|
||||
{
|
||||
case 1:
|
||||
return 1;
|
||||
case 2:
|
||||
return 1;
|
||||
case 4:
|
||||
return 2;
|
||||
case 16:
|
||||
return 4;
|
||||
case 36:
|
||||
return 6;
|
||||
default:
|
||||
throw new InvalidOperationException("Cannot handle this number of data regions");
|
||||
}
|
||||
}
|
||||
|
||||
public int getSymbolDataWidth()
|
||||
{
|
||||
return getHorizontalDataRegions() * matrixWidth;
|
||||
}
|
||||
|
||||
public int getSymbolDataHeight()
|
||||
{
|
||||
return getVerticalDataRegions() * matrixHeight;
|
||||
}
|
||||
|
||||
public int getSymbolWidth()
|
||||
{
|
||||
return getSymbolDataWidth() + (getHorizontalDataRegions() * 2);
|
||||
}
|
||||
|
||||
public int getSymbolHeight()
|
||||
{
|
||||
return getSymbolDataHeight() + (getVerticalDataRegions() * 2);
|
||||
}
|
||||
|
||||
public int getCodewordCount()
|
||||
{
|
||||
return dataCapacity + errorCodewords;
|
||||
}
|
||||
|
||||
virtual public int getInterleavedBlockCount()
|
||||
{
|
||||
return dataCapacity / rsBlockData;
|
||||
}
|
||||
|
||||
virtual public int getDataLengthForInterleavedBlock(int index)
|
||||
{
|
||||
return rsBlockData;
|
||||
}
|
||||
|
||||
public int getErrorLengthForInterleavedBlock(int index)
|
||||
{
|
||||
return rsBlockError;
|
||||
}
|
||||
|
||||
public override String ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(rectangular ? "Rectangular Symbol:" : "Square Symbol:");
|
||||
sb.Append(" data region ").Append(matrixWidth).Append('x').Append(matrixHeight);
|
||||
sb.Append(", symbol size ").Append(getSymbolWidth()).Append('x').Append(getSymbolHeight());
|
||||
sb.Append(", symbol data size ").Append(getSymbolDataWidth()).Append('x').Append(getSymbolDataHeight());
|
||||
sb.Append(", codewords ").Append(dataCapacity).Append('+').Append(errorCodewords);
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
29
zxing.core/xx/datamatrix/encoder/SymbolShapeHint.cs
Normal file
29
zxing.core/xx/datamatrix/encoder/SymbolShapeHint.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration for DataMatrix symbol shape hint. It can be used to force square or rectangular
|
||||
/// symbols.
|
||||
/// </summary>
|
||||
public enum SymbolShapeHint
|
||||
{
|
||||
FORCE_NONE,
|
||||
FORCE_SQUARE,
|
||||
FORCE_RECTANGLE,
|
||||
}
|
||||
}
|
||||
98
zxing.core/xx/datamatrix/encoder/TextEncoder.cs
Normal file
98
zxing.core/xx/datamatrix/encoder/TextEncoder.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal sealed class TextEncoder : C40Encoder
|
||||
{
|
||||
override public int EncodingMode
|
||||
{
|
||||
get { return Encodation.TEXT; }
|
||||
}
|
||||
|
||||
override protected int encodeChar(char c, StringBuilder sb)
|
||||
{
|
||||
if (c == ' ')
|
||||
{
|
||||
sb.Append('\u0003');
|
||||
return 1;
|
||||
}
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
sb.Append((char)(c - 48 + 4));
|
||||
return 1;
|
||||
}
|
||||
if (c >= 'a' && c <= 'z')
|
||||
{
|
||||
sb.Append((char)(c - 97 + 14));
|
||||
return 1;
|
||||
}
|
||||
if (c >= '\u0000' && c <= '\u001f')
|
||||
{
|
||||
sb.Append('\u0000'); //Shift 1 Set
|
||||
sb.Append(c);
|
||||
return 2;
|
||||
}
|
||||
if (c >= '!' && c <= '/')
|
||||
{
|
||||
sb.Append('\u0001'); //Shift 2 Set
|
||||
sb.Append((char)(c - 33));
|
||||
return 2;
|
||||
}
|
||||
if (c >= ':' && c <= '@')
|
||||
{
|
||||
sb.Append('\u0001'); //Shift 2 Set
|
||||
sb.Append((char)(c - 58 + 15));
|
||||
return 2;
|
||||
}
|
||||
if (c >= '[' && c <= '_')
|
||||
{
|
||||
sb.Append('\u0001'); //Shift 2 Set
|
||||
sb.Append((char)(c - 91 + 22));
|
||||
return 2;
|
||||
}
|
||||
if (c == '\u0060')
|
||||
{
|
||||
sb.Append('\u0002'); //Shift 3 Set
|
||||
sb.Append((char)(c - 96));
|
||||
return 2;
|
||||
}
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
sb.Append('\u0002'); //Shift 3 Set
|
||||
sb.Append((char)(c - 65 + 1));
|
||||
return 2;
|
||||
}
|
||||
if (c >= '{' && c <= '\u007f')
|
||||
{
|
||||
sb.Append('\u0002'); //Shift 3 Set
|
||||
sb.Append((char)(c - 123 + 27));
|
||||
return 2;
|
||||
}
|
||||
if (c >= '\u0080')
|
||||
{
|
||||
sb.Append("\u0001\u001e"); //Shift 2, Upper Shift
|
||||
int len = 2;
|
||||
len += encodeChar((char)(c - 128), sb);
|
||||
return len;
|
||||
}
|
||||
HighLevelEncoder.illegalCharacter(c);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
102
zxing.core/xx/datamatrix/encoder/X12Encoder.cs
Normal file
102
zxing.core/xx/datamatrix/encoder/X12Encoder.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2006-2007 Jeremias Maerki.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Text;
|
||||
|
||||
namespace ZXing.Datamatrix.Encoder
|
||||
{
|
||||
internal sealed class X12Encoder : C40Encoder
|
||||
{
|
||||
public override int EncodingMode
|
||||
{
|
||||
get { return Encodation.X12; }
|
||||
}
|
||||
|
||||
public override void encode(EncoderContext context)
|
||||
{
|
||||
//step C
|
||||
var buffer = new StringBuilder();
|
||||
int currentMode = EncodingMode;
|
||||
while (context.HasMoreCharacters)
|
||||
{
|
||||
char c = context.CurrentChar;
|
||||
context.Pos++;
|
||||
|
||||
encodeChar(c, buffer);
|
||||
|
||||
int count = buffer.Length;
|
||||
if ((count%3) == 0)
|
||||
{
|
||||
writeNextTriplet(context, buffer);
|
||||
|
||||
int newMode = HighLevelEncoder.lookAheadTest(context.Message, context.Pos, currentMode);
|
||||
if (newMode != currentMode)
|
||||
{
|
||||
context.signalEncoderChange(newMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
handleEOD(context, buffer);
|
||||
}
|
||||
|
||||
protected override int encodeChar(char c, StringBuilder sb)
|
||||
{
|
||||
if (c == '\r')
|
||||
{
|
||||
sb.Append('\u0000');
|
||||
}
|
||||
else if (c == '*')
|
||||
{
|
||||
sb.Append('\u0001');
|
||||
}
|
||||
else if (c == '>')
|
||||
{
|
||||
sb.Append('\u0002');
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
sb.Append('\u0003');
|
||||
}
|
||||
else if (c >= '0' && c <= '9')
|
||||
{
|
||||
sb.Append((char) (c - 48 + 4));
|
||||
}
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
sb.Append((char) (c - 65 + 14));
|
||||
}
|
||||
else
|
||||
{
|
||||
HighLevelEncoder.illegalCharacter(c);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected override void handleEOD(EncoderContext context, StringBuilder buffer)
|
||||
{
|
||||
context.updateSymbolInfo();
|
||||
int available = context.SymbolInfo.dataCapacity - context.CodewordCount;
|
||||
int count = buffer.Length;
|
||||
context.Pos -= count;
|
||||
if (context.RemainingCharacters > 1 || available > 1 ||
|
||||
context.RemainingCharacters != available)
|
||||
context.writeCodeword(HighLevelEncoder.X12_UNLATCH);
|
||||
if (context.NewEncoding < 0)
|
||||
context.signalEncoderChange(Encodation.ASCII);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user