hints)
- {
- if (String.IsNullOrEmpty(contents))
- {
- throw new ArgumentException("Found empty contents", contents);
- }
-
- if (format != BarcodeFormat.DATA_MATRIX)
- {
- throw new ArgumentException("Can only encode DATA_MATRIX, but got " + format);
- }
-
- if (width < 0 || height < 0)
- {
- throw new ArgumentException("Requested dimensions are too small: " + width + 'x' + height);
- }
-
- // Try to get force shape & min / max size
- var shape = SymbolShapeHint.FORCE_NONE;
- var defaultEncodation = Encodation.ASCII;
- var minSize = new Dimension(width, height);
- Dimension maxSize = null;
- if (hints != null)
- {
- var requestedShape = hints.ContainsKey(EncodeHintType.DATA_MATRIX_SHAPE) ? (SymbolShapeHint?)hints[EncodeHintType.DATA_MATRIX_SHAPE] : null;
- if (requestedShape != null)
- {
- shape = requestedShape.Value;
- }
- var requestedMinSize = hints.ContainsKey(EncodeHintType.MIN_SIZE) ? (Dimension)hints[EncodeHintType.MIN_SIZE] : null;
- if (requestedMinSize != null)
- {
- minSize = requestedMinSize;
- }
- var requestedMaxSize = hints.ContainsKey(EncodeHintType.MAX_SIZE) ? (Dimension)hints[EncodeHintType.MAX_SIZE] : null;
- if (requestedMaxSize != null)
- {
- maxSize = requestedMaxSize;
- }
- var requestedDefaultEncodation = hints.ContainsKey(EncodeHintType.DATA_MATRIX_DEFAULT_ENCODATION) ? (int?)hints[EncodeHintType.DATA_MATRIX_DEFAULT_ENCODATION] : (int?)null;
- if (requestedDefaultEncodation != null)
- {
- defaultEncodation = requestedDefaultEncodation.Value;
- }
- }
-
-
- //1. step: Data encodation
- String encoded = HighLevelEncoder.encodeHighLevel(contents, shape, minSize, maxSize, defaultEncodation);
-
- SymbolInfo symbolInfo = SymbolInfo.lookup(encoded.Length, shape, minSize, maxSize, true);
-
- //2. step: ECC generation
- String codewords = ErrorCorrection.encodeECC200(encoded, symbolInfo);
-
- //3. step: Module placement in Matrix
- var placement =
- new DefaultPlacement(codewords, symbolInfo.getSymbolDataWidth(), symbolInfo.getSymbolDataHeight());
- placement.place();
-
- //4. step: low-level encoding
- return encodeLowLevel(placement, symbolInfo);
- }
-
- ///
- /// Encode the given symbol info to a bit matrix.
- ///
- /// The DataMatrix placement.
- /// The symbol info to encode.
- /// The bit matrix generated.
- private static BitMatrix encodeLowLevel(DefaultPlacement placement, SymbolInfo symbolInfo)
- {
- int symbolWidth = symbolInfo.getSymbolDataWidth();
- int symbolHeight = symbolInfo.getSymbolDataHeight();
-
- var matrix = new ByteMatrix(symbolInfo.getSymbolWidth(), symbolInfo.getSymbolHeight());
-
- int matrixY = 0;
-
- for (int y = 0; y < symbolHeight; y++)
- {
- // Fill the top edge with alternate 0 / 1
- int matrixX;
- if ((y % symbolInfo.matrixHeight) == 0)
- {
- matrixX = 0;
- for (int x = 0; x < symbolInfo.getSymbolWidth(); x++)
- {
- matrix.set(matrixX, matrixY, (x % 2) == 0);
- matrixX++;
- }
- matrixY++;
- }
- matrixX = 0;
- for (int x = 0; x < symbolWidth; x++)
- {
- // Fill the right edge with full 1
- if ((x % symbolInfo.matrixWidth) == 0)
- {
- matrix.set(matrixX, matrixY, true);
- matrixX++;
- }
- matrix.set(matrixX, matrixY, placement.getBit(x, y));
- matrixX++;
- // Fill the right edge with alternate 0 / 1
- if ((x % symbolInfo.matrixWidth) == symbolInfo.matrixWidth - 1)
- {
- matrix.set(matrixX, matrixY, (y % 2) == 0);
- matrixX++;
- }
- }
- matrixY++;
- // Fill the bottom edge with full 1
- if ((y % symbolInfo.matrixHeight) == symbolInfo.matrixHeight - 1)
- {
- matrixX = 0;
- for (int x = 0; x < symbolInfo.getSymbolWidth(); x++)
- {
- matrix.set(matrixX, matrixY, true);
- matrixX++;
- }
- matrixY++;
- }
- }
-
- return convertByteMatrixToBitMatrix(matrix);
- }
-
- ///
- /// Convert the ByteMatrix to BitMatrix.
- ///
- /// The input matrix.
- /// The output matrix.
- private static BitMatrix convertByteMatrixToBitMatrix(ByteMatrix matrix)
- {
- int matrixWidgth = matrix.Width;
- int matrixHeight = matrix.Height;
-
- var output = new BitMatrix(matrixWidgth, matrixHeight);
- output.clear();
- for (int i = 0; i < matrixWidgth; i++)
- {
- for (int j = 0; j < matrixHeight; j++)
- {
- // Zero is white in the bytematrix
- if (matrix[i, j] == 1)
- {
- output[i, j] = true;
- }
- }
- }
-
- return output;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/decoder/BitMatrixParser.cs b/zxing.core/xx/datamatrix/decoder/BitMatrixParser.cs
deleted file mode 100644
index ce5e496..0000000
--- a/zxing.core/xx/datamatrix/decoder/BitMatrixParser.cs
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright 2007 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-
-using ZXing.Common;
-
-namespace ZXing.Datamatrix.Internal
-{
- ///
- /// bbrown@google.com (Brian Brown)
- ///
- sealed class BitMatrixParser
- {
- private readonly BitMatrix mappingBitMatrix;
- private readonly BitMatrix readMappingMatrix;
- private readonly Version version;
-
- ///
- /// to parse
- /// if dimension is < 8 or >144 or not 0 mod 2
- ///
- internal BitMatrixParser(BitMatrix bitMatrix)
- {
- int dimension = bitMatrix.Height;
- if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0)
- {
- return;
- }
-
- version = readVersion(bitMatrix);
- if (version != null)
- {
- mappingBitMatrix = extractDataRegion(bitMatrix);
- readMappingMatrix = new BitMatrix(mappingBitMatrix.Width, mappingBitMatrix.Height);
- }
- }
-
- public Version Version
- {
- get { return version; }
- }
-
- ///
- /// Creates the version object based on the dimension of the original bit matrix from
- /// the datamatrix code.
- ///
- /// See ISO 16022:2006 Table 7 - ECC 200 symbol attributes
- ///
- /// Original including alignment patterns
- /// encapsulating the Data Matrix Code's "version"
- /// if the dimensions of the mapping matrix are not valid
- /// Data Matrix dimensions.
- ///
- internal static Version readVersion(BitMatrix bitMatrix)
- {
- int numRows = bitMatrix.Height;
- int numColumns = bitMatrix.Width;
- return Version.getVersionForDimensions(numRows, numColumns);
- }
-
- ///
- /// Reads the bits in the representing the mapping matrix (No alignment patterns)
- /// in the correct order in order to reconstitute the codewords bytes contained within the
- /// Data Matrix Code.
- ///
- /// bytes encoded within the Data Matrix Code
- /// if the exact number of bytes expected is not read
- ///
- internal byte[] readCodewords()
- {
- byte[] result = new byte[version.getTotalCodewords()];
- int resultOffset = 0;
-
- int row = 4;
- int column = 0;
-
- int numRows = mappingBitMatrix.Height;
- int numColumns = mappingBitMatrix.Width;
-
- bool corner1Read = false;
- bool corner2Read = false;
- bool corner3Read = false;
- bool corner4Read = false;
-
- // Read all of the codewords
- do
- {
- // Check the four corner cases
- if ((row == numRows) && (column == 0) && !corner1Read)
- {
- result[resultOffset++] = (byte)readCorner1(numRows, numColumns);
- row -= 2;
- column += 2;
- corner1Read = true;
- }
- else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x03) != 0) && !corner2Read)
- {
- result[resultOffset++] = (byte)readCorner2(numRows, numColumns);
- row -= 2;
- column += 2;
- corner2Read = true;
- }
- else if ((row == numRows + 4) && (column == 2) && ((numColumns & 0x07) == 0) && !corner3Read)
- {
- result[resultOffset++] = (byte)readCorner3(numRows, numColumns);
- row -= 2;
- column += 2;
- corner3Read = true;
- }
- else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x07) == 4) && !corner4Read)
- {
- result[resultOffset++] = (byte)readCorner4(numRows, numColumns);
- row -= 2;
- column += 2;
- corner4Read = true;
- }
- else
- {
- // Sweep upward diagonally to the right
- do
- {
- if ((row < numRows) && (column >= 0) && !readMappingMatrix[column, row])
- {
- result[resultOffset++] = (byte)readUtah(row, column, numRows, numColumns);
- }
- row -= 2;
- column += 2;
- } while ((row >= 0) && (column < numColumns));
- row += 1;
- column += 3;
-
- // Sweep downward diagonally to the left
- do
- {
- if ((row >= 0) && (column < numColumns) && !readMappingMatrix[column, row])
- {
- result[resultOffset++] = (byte)readUtah(row, column, numRows, numColumns);
- }
- row += 2;
- column -= 2;
- } while ((row < numRows) && (column >= 0));
- row += 3;
- column += 1;
- }
- } while ((row < numRows) || (column < numColumns));
-
- if (resultOffset != version.getTotalCodewords())
- {
- return null;
- }
- return result;
- }
-
- ///
- /// Reads a bit of the mapping matrix accounting for boundary wrapping.
- ///
- /// Row to read in the mapping matrix
- /// Column to read in the mapping matrix
- /// Number of rows in the mapping matrix
- /// Number of columns in the mapping matrix
- /// value of the given bit in the mapping matrix
- ///
- bool readModule(int row, int column, int numRows, int numColumns)
- {
- // Adjust the row and column indices based on boundary wrapping
- if (row < 0)
- {
- row += numRows;
- column += 4 - ((numRows + 4) & 0x07);
- }
- if (column < 0)
- {
- column += numColumns;
- row += 4 - ((numColumns + 4) & 0x07);
- }
- readMappingMatrix[column, row] = true;
- return mappingBitMatrix[column, row];
- }
-
- ///
- /// Reads the 8 bits of the standard Utah-shaped pattern.
- ///
- /// See ISO 16022:2006, 5.8.1 Figure 6
- ///
- /// Current row in the mapping matrix, anchored at the 8th bit (LSB) of the pattern
- /// Current column in the mapping matrix, anchored at the 8th bit (LSB) of the pattern
- /// Number of rows in the mapping matrix
- /// Number of columns in the mapping matrix
- /// byte from the utah shape
- ///
- int readUtah(int row, int column, int numRows, int numColumns)
- {
- int currentByte = 0;
- if (readModule(row - 2, column - 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(row - 2, column - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(row - 1, column - 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(row - 1, column - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(row - 1, column, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(row, column - 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(row, column - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(row, column, numRows, numColumns))
- {
- currentByte |= 1;
- }
- return currentByte;
- }
-
- ///
- /// Reads the 8 bits of the special corner condition 1.
- ///
- /// See ISO 16022:2006, Figure F.3
- ///
- /// Number of rows in the mapping matrix
- /// Number of columns in the mapping matrix
- /// byte from the Corner condition 1
- ///
- int readCorner1(int numRows, int numColumns)
- {
- int currentByte = 0;
- if (readModule(numRows - 1, 0, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(numRows - 1, 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(numRows - 1, 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(1, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(2, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(3, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- return currentByte;
- }
-
- ///
- /// Reads the 8 bits of the special corner condition 2.
- ///
- /// See ISO 16022:2006, Figure F.4
- ///
- /// Number of rows in the mapping matrix
- /// Number of columns in the mapping matrix
- /// byte from the Corner condition 2
- ///
- int readCorner2(int numRows, int numColumns)
- {
- int currentByte = 0;
- if (readModule(numRows - 3, 0, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(numRows - 2, 0, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(numRows - 1, 0, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 4, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 3, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(1, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- return currentByte;
- }
-
- ///
- /// Reads the 8 bits of the special corner condition 3.
- ///
- /// See ISO 16022:2006, Figure F.5
- ///
- /// Number of rows in the mapping matrix
- /// Number of columns in the mapping matrix
- /// byte from the Corner condition 3
- ///
- int readCorner3(int numRows, int numColumns)
- {
- int currentByte = 0;
- if (readModule(numRows - 1, 0, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(numRows - 1, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 3, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(1, numColumns - 3, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(1, numColumns - 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(1, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- return currentByte;
- }
-
- ///
- /// Reads the 8 bits of the special corner condition 4.
- ///
- /// See ISO 16022:2006, Figure F.6
- ///
- /// Number of rows in the mapping matrix
- /// Number of columns in the mapping matrix
- /// byte from the Corner condition 4
- ///
- int readCorner4(int numRows, int numColumns)
- {
- int currentByte = 0;
- if (readModule(numRows - 3, 0, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(numRows - 2, 0, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(numRows - 1, 0, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 2, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(0, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(1, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(2, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- currentByte <<= 1;
- if (readModule(3, numColumns - 1, numRows, numColumns))
- {
- currentByte |= 1;
- }
- return currentByte;
- }
-
- ///
- /// Extracts the data region from a that contains
- /// alignment patterns.
- ///
- /// Original with alignment patterns
- /// BitMatrix that has the alignment patterns removed
- ///
- BitMatrix extractDataRegion(BitMatrix bitMatrix)
- {
- int symbolSizeRows = version.getSymbolSizeRows();
- int symbolSizeColumns = version.getSymbolSizeColumns();
-
- if (bitMatrix.Height != symbolSizeRows)
- {
- throw new ArgumentException("Dimension of bitMarix must match the version size");
- }
-
- int dataRegionSizeRows = version.getDataRegionSizeRows();
- int dataRegionSizeColumns = version.getDataRegionSizeColumns();
-
- int numDataRegionsRow = symbolSizeRows / dataRegionSizeRows;
- int numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns;
-
- int sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;
- int sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;
-
- BitMatrix bitMatrixWithoutAlignment = new BitMatrix(sizeDataRegionColumn, sizeDataRegionRow);
- for (int dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow)
- {
- int dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;
- for (int dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn; ++dataRegionColumn)
- {
- int dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns;
- for (int i = 0; i < dataRegionSizeRows; ++i)
- {
- int readRowOffset = dataRegionRow * (dataRegionSizeRows + 2) + 1 + i;
- int writeRowOffset = dataRegionRowOffset + i;
- for (int j = 0; j < dataRegionSizeColumns; ++j)
- {
- int readColumnOffset = dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;
- if (bitMatrix[readColumnOffset, readRowOffset])
- {
- int writeColumnOffset = dataRegionColumnOffset + j;
- bitMatrixWithoutAlignment[writeColumnOffset, writeRowOffset] = true;
- }
- }
- }
- }
- }
- return bitMatrixWithoutAlignment;
- }
-
- }
-}
diff --git a/zxing.core/xx/datamatrix/decoder/DataBlock.cs b/zxing.core/xx/datamatrix/decoder/DataBlock.cs
deleted file mode 100644
index ce09b8d..0000000
--- a/zxing.core/xx/datamatrix/decoder/DataBlock.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-
-namespace ZXing.Datamatrix.Internal
-{
- ///
- /// Encapsulates a block of data within a Data Matrix Code. Data Matrix Codes may split their data into
- /// multiple blocks, each of which is a unit of data and error-correction codewords. Each
- /// is represented by an instance of this class.
- ///
- /// bbrown@google.com (Brian Brown)
- ///
- internal sealed class DataBlock
- {
- private readonly int numDataCodewords;
- private readonly byte[] codewords;
-
- private DataBlock(int numDataCodewords, byte[] codewords)
- {
- this.numDataCodewords = numDataCodewords;
- this.codewords = codewords;
- }
-
- ///
- /// When Data Matrix Codes use multiple data blocks, they actually interleave the bytes of each of them.
- /// That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
- /// method will separate the data into original blocks.
- ///
- /// bytes as read directly from the Data Matrix Code
- /// version of the Data Matrix Code
- /// DataBlocks containing original bytes, "de-interleaved" from representation in the
- /// Data Matrix Code
- ///
- internal static DataBlock[] getDataBlocks(byte[] rawCodewords,
- Version version)
- {
- // Figure out the number and size of data blocks used by this version
- Version.ECBlocks ecBlocks = version.getECBlocks();
-
- // First count the total number of data blocks
- int totalBlocks = 0;
- Version.ECB[] ecBlockArray = ecBlocks.ECBlocksValue;
- foreach (Version.ECB ecBlock in ecBlockArray)
- {
- totalBlocks += ecBlock.Count;
- }
-
- // Now establish DataBlocks of the appropriate size and number of data codewords
- DataBlock[] result = new DataBlock[totalBlocks];
- int numResultBlocks = 0;
- foreach (Version.ECB ecBlock in ecBlockArray)
- {
- for (int i = 0; i < ecBlock.Count; i++)
- {
- int numDataCodewords = ecBlock.DataCodewords;
- int numBlockCodewords = ecBlocks.ECCodewords + numDataCodewords;
- result[numResultBlocks++] = new DataBlock(numDataCodewords, new byte[numBlockCodewords]);
- }
- }
-
- // All blocks have the same amount of data, except that the last n
- // (where n may be 0) have 1 less byte. Figure out where these start.
- // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144
- int longerBlocksTotalCodewords = result[0].codewords.Length;
- //int shorterBlocksTotalCodewords = longerBlocksTotalCodewords - 1;
-
- int longerBlocksNumDataCodewords = longerBlocksTotalCodewords - ecBlocks.ECCodewords;
- int shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1;
- // The last elements of result may be 1 element shorter for 144 matrix
- // first fill out as many elements as all of them have minus 1
- int rawCodewordsOffset = 0;
- for (int i = 0; i < shorterBlocksNumDataCodewords; i++)
- {
- for (int j = 0; j < numResultBlocks; j++)
- {
- result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];
- }
- }
-
- // Fill out the last data block in the longer ones
- bool specialVersion = version.getVersionNumber() == 24;
- int numLongerBlocks = specialVersion ? 8 : numResultBlocks;
- for (int j = 0; j < numLongerBlocks; j++)
- {
- result[j].codewords[longerBlocksNumDataCodewords - 1] = rawCodewords[rawCodewordsOffset++];
- }
-
- // Now add in error correction blocks
- int max = result[0].codewords.Length;
- for (int i = longerBlocksNumDataCodewords; i < max; i++)
- {
- for (int j = 0; j < numResultBlocks; j++)
- {
- int jOffset = specialVersion ? (j + 8)%numResultBlocks : j;
- int iOffset = specialVersion && jOffset > 7 ? i - 1 : i;
- result[jOffset].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];
- }
- }
-
- if (rawCodewordsOffset != rawCodewords.Length)
- {
- throw new ArgumentException();
- }
-
- return result;
- }
-
- internal int NumDataCodewords
- {
- get { return numDataCodewords; }
- }
-
- internal byte[] Codewords
- {
- get { return codewords; }
- }
- }
-}
diff --git a/zxing.core/xx/datamatrix/decoder/DecodedBitStreamParser.cs b/zxing.core/xx/datamatrix/decoder/DecodedBitStreamParser.cs
deleted file mode 100644
index badda6b..0000000
--- a/zxing.core/xx/datamatrix/decoder/DecodedBitStreamParser.cs
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.Datamatrix.Internal
-{
- ///
- /// Data Matrix Codes can encode text as bits in one of several modes, and can use multiple modes
- /// in one Data Matrix Code. This class decodes the bits back into text.
- ///
- /// See ISO 16022:2006, 5.2.1 - 5.2.9.2
- ///
- /// bbrown@google.com (Brian Brown)
- /// Sean Owen
- ///
- internal static class DecodedBitStreamParser
- {
- private enum Mode
- {
- PAD_ENCODE, // Not really a mode
- ASCII_ENCODE,
- C40_ENCODE,
- TEXT_ENCODE,
- ANSIX12_ENCODE,
- EDIFACT_ENCODE,
- BASE256_ENCODE
- }
-
- ///
- /// See ISO 16022:2006, Annex C Table C.1
- /// The C40 Basic Character Set (*'s used for placeholders for the shift values)
- ///
- private static readonly char[] C40_BASIC_SET_CHARS =
- {
- '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
- };
-
- private static readonly char[] C40_SHIFT2_SET_CHARS =
- {
- '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
- '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
- };
-
- ///
- /// See ISO 16022:2006, Annex C Table C.2
- /// The Text Basic Character Set (*'s used for placeholders for the shift values)
- ///
- private static readonly char[] TEXT_BASIC_SET_CHARS =
- {
- '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
- };
-
- // Shift 2 for Text is the same encoding as C40
- private static readonly char[] TEXT_SHIFT2_SET_CHARS = C40_SHIFT2_SET_CHARS;
-
- private static readonly char[] TEXT_SHIFT3_SET_CHARS =
- {
- '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{',
- '|', '}', '~', (char) 127
- };
-
- internal static DecoderResult decode(byte[] bytes)
- {
- BitSource bits = new BitSource(bytes);
- StringBuilder result = new StringBuilder(100);
- StringBuilder resultTrailer = new StringBuilder(0);
- List byteSegments = new List(1);
- Mode mode = Mode.ASCII_ENCODE;
- do
- {
- if (mode == Mode.ASCII_ENCODE)
- {
- if (!decodeAsciiSegment(bits, result, resultTrailer, out mode))
- return null;
- }
- else
- {
- switch (mode)
- {
- case Mode.C40_ENCODE:
- if (!decodeC40Segment(bits, result))
- return null;
- break;
- case Mode.TEXT_ENCODE:
- if (!decodeTextSegment(bits, result))
- return null;
- break;
- case Mode.ANSIX12_ENCODE:
- if (!decodeAnsiX12Segment(bits, result))
- return null;
- break;
- case Mode.EDIFACT_ENCODE:
- if (!decodeEdifactSegment(bits, result))
- return null;
- break;
- case Mode.BASE256_ENCODE:
- if (!decodeBase256Segment(bits, result, byteSegments))
- return null;
- break;
- default:
- return null;
- }
- mode = Mode.ASCII_ENCODE;
- }
- } while (mode != Mode.PAD_ENCODE && bits.available() > 0);
- if (resultTrailer.Length > 0)
- {
- result.Append(resultTrailer.ToString());
- }
- return new DecoderResult(bytes, result.ToString(), byteSegments.Count == 0 ? null : byteSegments, null);
- }
-
- ///
- /// See ISO 16022:2006, 5.2.3 and Annex C, Table C.2
- ///
- private static bool decodeAsciiSegment(BitSource bits,
- StringBuilder result,
- StringBuilder resultTrailer,
- out Mode mode)
- {
- bool upperShift = false;
- mode = Mode.ASCII_ENCODE;
- do
- {
- int oneByte = bits.readBits(8);
- if (oneByte == 0)
- {
- return false;
- }
- else if (oneByte <= 128)
- {
- // ASCII data (ASCII value + 1)
- if (upperShift)
- {
- oneByte += 128;
- //upperShift = false;
- }
- result.Append((char) (oneByte - 1));
- mode = Mode.ASCII_ENCODE;
- return true;
- }
- else if (oneByte == 129)
- {
- // Pad
- mode = Mode.PAD_ENCODE;
- return true;
- }
- else if (oneByte <= 229)
- {
- // 2-digit data 00-99 (Numeric Value + 130)
- int value = oneByte - 130;
- if (value < 10)
- {
- // pad with '0' for single digit values
- result.Append('0');
- }
- result.Append(value);
- }
- else if (oneByte == 230)
- {
- // Latch to C40 encodation
- mode = Mode.C40_ENCODE;
- return true;
- }
- else if (oneByte == 231)
- {
- // Latch to Base 256 encodation
- mode = Mode.BASE256_ENCODE;
- return true;
- }
- else if (oneByte == 232)
- {
- // FNC1
- result.Append((char) 29); // translate as ASCII 29
- }
- else if (oneByte == 233 || oneByte == 234)
- {
- // Structured Append, Reader Programming
- // Ignore these symbols for now
- //throw ReaderException.Instance;
- }
- else if (oneByte == 235)
- {
- // Upper Shift (shift to Extended ASCII)
- upperShift = true;
- }
- else if (oneByte == 236)
- {
- // 05 Macro
- result.Append("[)>\u001E05\u001D");
- resultTrailer.Insert(0, "\u001E\u0004");
- }
- else if (oneByte == 237)
- {
- // 06 Macro
- result.Append("[)>\u001E06\u001D");
- resultTrailer.Insert(0, "\u001E\u0004");
- }
- else if (oneByte == 238)
- {
- // Latch to ANSI X12 encodation
- mode = Mode.ANSIX12_ENCODE;
- return true;
- }
- else if (oneByte == 239)
- {
- // Latch to Text encodation
- mode = Mode.TEXT_ENCODE;
- return true;
- }
- else if (oneByte == 240)
- {
- // Latch to EDIFACT encodation
- mode = Mode.EDIFACT_ENCODE;
- return true;
- }
- else if (oneByte == 241)
- {
- // ECI Character
- // TODO(bbrown): I think we need to support ECI
- //throw ReaderException.Instance;
- // Ignore this symbol for now
- }
- else if (oneByte >= 242)
- {
- // Not to be used in ASCII encodation
- // ... but work around encoders that end with 254, latch back to ASCII
- if (oneByte != 254 || bits.available() != 0)
- {
- return false;
- }
- }
- } while (bits.available() > 0);
- mode = Mode.ASCII_ENCODE;
- return true;
- }
-
- ///
- /// See ISO 16022:2006, 5.2.5 and Annex C, Table C.1
- ///
- private static bool decodeC40Segment(BitSource bits, StringBuilder result)
- {
- // Three C40 values are encoded in a 16-bit value as
- // (1600 * C1) + (40 * C2) + C3 + 1
- // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time
- bool upperShift = false;
-
- int[] cValues = new int[3];
- int shift = 0;
-
- do
- {
- // If there is only one byte left then it will be encoded as ASCII
- if (bits.available() == 8)
- {
- return true;
- }
- int firstByte = bits.readBits(8);
- if (firstByte == 254)
- {
- // Unlatch codeword
- return true;
- }
-
- parseTwoBytes(firstByte, bits.readBits(8), cValues);
-
- for (int i = 0; i < 3; i++)
- {
- int cValue = cValues[i];
- switch (shift)
- {
- case 0:
- if (cValue < 3)
- {
- shift = cValue + 1;
- }
- else if (cValue < C40_BASIC_SET_CHARS.Length)
- {
- char c40char = C40_BASIC_SET_CHARS[cValue];
- if (upperShift)
- {
- result.Append((char) (c40char + 128));
- upperShift = false;
- }
- else
- {
- result.Append(c40char);
- }
- }
- else
- {
- return false;
- }
- break;
- case 1:
- if (upperShift)
- {
- result.Append((char) (cValue + 128));
- upperShift = false;
- }
- else
- {
- result.Append((char) cValue);
- }
- shift = 0;
- break;
- case 2:
- if (cValue < C40_SHIFT2_SET_CHARS.Length)
- {
- char c40char = C40_SHIFT2_SET_CHARS[cValue];
- if (upperShift)
- {
- result.Append((char) (c40char + 128));
- upperShift = false;
- }
- else
- {
- result.Append(c40char);
- }
- }
- else if (cValue == 27)
- {
- // FNC1
- result.Append((char) 29); // translate as ASCII 29
- }
- else if (cValue == 30)
- {
- // Upper Shift
- upperShift = true;
- }
- else
- {
- return false;
- }
- shift = 0;
- break;
- case 3:
- if (upperShift)
- {
- result.Append((char) (cValue + 224));
- upperShift = false;
- }
- else
- {
- result.Append((char) (cValue + 96));
- }
- shift = 0;
- break;
- default:
- return false;
- }
- }
- } while (bits.available() > 0);
-
- return true;
- }
-
- ///
- /// See ISO 16022:2006, 5.2.6 and Annex C, Table C.2
- ///
- private static bool decodeTextSegment(BitSource bits, StringBuilder result)
- {
- // Three Text values are encoded in a 16-bit value as
- // (1600 * C1) + (40 * C2) + C3 + 1
- // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time
- bool upperShift = false;
-
- int[] cValues = new int[3];
- int shift = 0;
- do
- {
- // If there is only one byte left then it will be encoded as ASCII
- if (bits.available() == 8)
- {
- return true;
- }
- int firstByte = bits.readBits(8);
- if (firstByte == 254)
- {
- // Unlatch codeword
- return true;
- }
-
- parseTwoBytes(firstByte, bits.readBits(8), cValues);
-
- for (int i = 0; i < 3; i++)
- {
- int cValue = cValues[i];
- switch (shift)
- {
- case 0:
- if (cValue < 3)
- {
- shift = cValue + 1;
- }
- else if (cValue < TEXT_BASIC_SET_CHARS.Length)
- {
- char textChar = TEXT_BASIC_SET_CHARS[cValue];
- if (upperShift)
- {
- result.Append((char) (textChar + 128));
- upperShift = false;
- }
- else
- {
- result.Append(textChar);
- }
- }
- else
- {
- return false;
- }
- break;
- case 1:
- if (upperShift)
- {
- result.Append((char) (cValue + 128));
- upperShift = false;
- }
- else
- {
- result.Append((char) cValue);
- }
- shift = 0;
- break;
- case 2:
- // Shift 2 for Text is the same encoding as C40
- if (cValue < TEXT_SHIFT2_SET_CHARS.Length)
- {
- char textChar = TEXT_SHIFT2_SET_CHARS[cValue];
- if (upperShift)
- {
- result.Append((char) (textChar + 128));
- upperShift = false;
- }
- else
- {
- result.Append(textChar);
- }
- }
- else if (cValue == 27)
- {
- // FNC1
- result.Append((char) 29); // translate as ASCII 29
- }
- else if (cValue == 30)
- {
- // Upper Shift
- upperShift = true;
- }
- else
- {
- return false;
- }
- shift = 0;
- break;
- case 3:
- if (cValue < TEXT_SHIFT3_SET_CHARS.Length)
- {
- char textChar = TEXT_SHIFT3_SET_CHARS[cValue];
- if (upperShift)
- {
- result.Append((char) (textChar + 128));
- upperShift = false;
- }
- else
- {
- result.Append(textChar);
- }
- shift = 0;
- }
- else
- {
- return false;
- }
- break;
- default:
- return false;
- }
- }
- } while (bits.available() > 0);
-
- return true;
- }
-
- ///
- /// See ISO 16022:2006, 5.2.7
- ///
- private static bool decodeAnsiX12Segment(BitSource bits,
- StringBuilder result)
- {
- // Three ANSI X12 values are encoded in a 16-bit value as
- // (1600 * C1) + (40 * C2) + C3 + 1
-
- int[] cValues = new int[3];
- do
- {
- // If there is only one byte left then it will be encoded as ASCII
- if (bits.available() == 8)
- {
- return true;
- }
- int firstByte = bits.readBits(8);
- if (firstByte == 254)
- {
- // Unlatch codeword
- return true;
- }
-
- parseTwoBytes(firstByte, bits.readBits(8), cValues);
-
- for (int i = 0; i < 3; i++)
- {
- int cValue = cValues[i];
- if (cValue == 0)
- {
- // X12 segment terminator
- result.Append('\r');
- }
- else if (cValue == 1)
- {
- // X12 segment separator *
- result.Append('*');
- }
- else if (cValue == 2)
- {
- // X12 sub-element separator >
- result.Append('>');
- }
- else if (cValue == 3)
- {
- // space
- result.Append(' ');
- }
- else if (cValue < 14)
- {
- // 0 - 9
- result.Append((char) (cValue + 44));
- }
- else if (cValue < 40)
- {
- // A - Z
- result.Append((char) (cValue + 51));
- }
- else
- {
- return false;
- }
- }
- } while (bits.available() > 0);
-
- return true;
- }
-
- private static void parseTwoBytes(int firstByte, int secondByte, int[] result)
- {
- int fullBitValue = (firstByte << 8) + secondByte - 1;
- int temp = fullBitValue/1600;
- result[0] = temp;
- fullBitValue -= temp*1600;
- temp = fullBitValue/40;
- result[1] = temp;
- result[2] = fullBitValue - temp*40;
- }
-
- ///
- /// See ISO 16022:2006, 5.2.8 and Annex C Table C.3
- ///
- private static bool decodeEdifactSegment(BitSource bits, StringBuilder result)
- {
- do
- {
- // If there is only two or less bytes left then it will be encoded as ASCII
- if (bits.available() <= 16)
- {
- return true;
- }
-
- for (int i = 0; i < 4; i++)
- {
- int edifactValue = bits.readBits(6);
-
- // Check for the unlatch character
- if (edifactValue == 0x1F)
- {
- // 011111
- // Read rest of byte, which should be 0, and stop
- int bitsLeft = 8 - bits.BitOffset;
- if (bitsLeft != 8)
- {
- bits.readBits(bitsLeft);
- }
- return true;
- }
-
- if ((edifactValue & 0x20) == 0)
- {
- // no 1 in the leading (6th) bit
- edifactValue |= 0x40; // Add a leading 01 to the 6 bit binary value
- }
- result.Append((char) edifactValue);
- }
- } while (bits.available() > 0);
-
- return true;
- }
-
- ///
- /// See ISO 16022:2006, 5.2.9 and Annex B, B.2
- ///
- private static bool decodeBase256Segment(BitSource bits,
- StringBuilder result,
- IList byteSegments)
- {
- // Figure out how long the Base 256 Segment is.
- int codewordPosition = 1 + bits.ByteOffset; // position is 1-indexed
- int d1 = unrandomize255State(bits.readBits(8), codewordPosition++);
- int count;
- if (d1 == 0)
- {
- // Read the remainder of the symbol
- count = bits.available()/8;
- }
- else if (d1 < 250)
- {
- count = d1;
- }
- else
- {
- count = 250*(d1 - 249) + unrandomize255State(bits.readBits(8), codewordPosition++);
- }
-
- // We're seeing NegativeArraySizeException errors from users.
- if (count < 0)
- {
- return false;
- }
-
- byte[] bytes = new byte[count];
- for (int i = 0; i < count; i++)
- {
- // Have seen this particular error in the wild, such as at
- // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2
- if (bits.available() < 8)
- {
- return false;
- }
- bytes[i] = (byte) unrandomize255State(bits.readBits(8), codewordPosition++);
- }
- byteSegments.Add(bytes);
- try
- {
-#if (WINDOWS_PHONE || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || WindowsCE || PORTABLE)
-#if WindowsCE
- result.Append(Encoding.GetEncoding(1252).GetString(bytes, 0, bytes.Length));
-#else
- result.Append(Encoding.GetEncoding("ISO-8859-1").GetString(bytes, 0, bytes.Length));
-#endif
-#else
- result.Append(Encoding.GetEncoding("ISO-8859-1").GetString(bytes));
-#endif
- }
- catch (Exception uee)
- {
- throw new InvalidOperationException("Platform does not support required encoding: " + uee);
- }
-
- return true;
- }
-
- ///
- /// See ISO 16022:2006, Annex B, B.2
- ///
- private static int unrandomize255State(int randomizedBase256Codeword,
- int base256CodewordPosition)
- {
- int pseudoRandomNumber = ((149*base256CodewordPosition)%255) + 1;
- int tempVariable = randomizedBase256Codeword - pseudoRandomNumber;
- return tempVariable >= 0 ? tempVariable : tempVariable + 256;
- }
-
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/decoder/Decoder.cs b/zxing.core/xx/datamatrix/decoder/Decoder.cs
deleted file mode 100644
index dc75c98..0000000
--- a/zxing.core/xx/datamatrix/decoder/Decoder.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2007 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using ZXing.Common;
-using ZXing.Common.ReedSolomon;
-
-namespace ZXing.Datamatrix.Internal
-{
- ///
- /// The main class which implements Data Matrix Code decoding -- as opposed to locating and extracting
- /// the Data Matrix Code from an image.
- ///
- /// bbrown@google.com (Brian Brown)
- ///
- public sealed class Decoder
- {
- private readonly ReedSolomonDecoder rsDecoder;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public Decoder()
- {
- rsDecoder = new ReedSolomonDecoder(GenericGF.DATA_MATRIX_FIELD_256);
- }
-
- ///
- /// Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans.
- /// "true" is taken to mean a black module.
- ///
- /// booleans representing white/black Data Matrix Code modules
- /// text and bytes encoded within the Data Matrix Code
- /// if the Data Matrix Code cannot be decoded
- /// if error correction fails
- ///
- public DecoderResult decode(bool[][] image)
- {
- int dimension = image.Length;
- BitMatrix bits = new BitMatrix(dimension);
- for (int i = 0; i < dimension; i++)
- {
- for (int j = 0; j < dimension; j++)
- {
- if (image[i][j])
- {
- bits[j, i] = true;
- }
- }
- }
- return decode(bits);
- }
-
- ///
- /// Decodes a Data Matrix Code represented as a . A 1 or "true" is taken
- /// to mean a black module.
- ///
- /// booleans representing white/black Data Matrix Code modules
- /// text and bytes encoded within the Data Matrix Code
- public DecoderResult decode(BitMatrix bits)
- {
- // Construct a parser and read version, error-correction level
- BitMatrixParser parser = new BitMatrixParser(bits);
- if (parser.Version == null)
- return null;
-
- // Read codewords
- byte[] codewords = parser.readCodewords();
- if (codewords == null)
- return null;
- // Separate into data blocks
- DataBlock[] dataBlocks = DataBlock.getDataBlocks(codewords, parser.Version);
-
- int dataBlocksCount = dataBlocks.Length;
-
- // Count total number of data bytes
- int totalBytes = 0;
- foreach (var db in dataBlocks)
- {
- totalBytes += db.NumDataCodewords;
- }
- byte[] resultBytes = new byte[totalBytes];
-
- // Error-correct and copy data blocks together into a stream of bytes
- for (int j = 0; j < dataBlocksCount; j++)
- {
- DataBlock dataBlock = dataBlocks[j];
- byte[] codewordBytes = dataBlock.Codewords;
- int numDataCodewords = dataBlock.NumDataCodewords;
- if (!correctErrors(codewordBytes, numDataCodewords))
- return null;
- for (int i = 0; i < numDataCodewords; i++)
- {
- // De-interlace data blocks.
- resultBytes[i * dataBlocksCount + j] = codewordBytes[i];
- }
- }
-
- // Decode the contents of that stream of bytes
- return DecodedBitStreamParser.decode(resultBytes);
- }
-
- ///
- /// Given data and error-correction codewords received, possibly corrupted by errors, attempts to
- /// correct the errors in-place using Reed-Solomon error correction.
- ///
- /// data and error correction codewords
- /// number of codewords that are data bytes
- ///
- private bool correctErrors(byte[] codewordBytes, int numDataCodewords)
- {
- int numCodewords = codewordBytes.Length;
- // First read into an array of ints
- int[] codewordsInts = new int[numCodewords];
- for (int i = 0; i < numCodewords; i++)
- {
- codewordsInts[i] = codewordBytes[i] & 0xFF;
- }
- int numECCodewords = codewordBytes.Length - numDataCodewords;
- if (!rsDecoder.decode(codewordsInts, numECCodewords))
- return false;
-
- // Copy back into array of bytes -- only need to worry about the bytes that were data
- // We don't care about errors in the error-correction codewords
- for (int i = 0; i < numDataCodewords; i++)
- {
- codewordBytes[i] = (byte)codewordsInts[i];
- }
-
- return true;
- }
- }
-}
diff --git a/zxing.core/xx/datamatrix/decoder/Version.cs b/zxing.core/xx/datamatrix/decoder/Version.cs
deleted file mode 100644
index 6ec4e25..0000000
--- a/zxing.core/xx/datamatrix/decoder/Version.cs
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright 2007 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-
-namespace ZXing.Datamatrix.Internal
-{
- ///
- /// The Version object encapsulates attributes about a particular
- /// size Data Matrix Code.
- ///
- /// bbrown@google.com (Brian Brown)
- ///
- public sealed class Version
- {
- private static readonly Version[] VERSIONS = buildVersions();
-
- private readonly int versionNumber;
- private readonly int symbolSizeRows;
- private readonly int symbolSizeColumns;
- private readonly int dataRegionSizeRows;
- private readonly int dataRegionSizeColumns;
- private readonly ECBlocks ecBlocks;
- private readonly int totalCodewords;
-
- internal Version(int versionNumber,
- int symbolSizeRows,
- int symbolSizeColumns,
- int dataRegionSizeRows,
- int dataRegionSizeColumns,
- ECBlocks ecBlocks)
- {
- this.versionNumber = versionNumber;
- this.symbolSizeRows = symbolSizeRows;
- this.symbolSizeColumns = symbolSizeColumns;
- this.dataRegionSizeRows = dataRegionSizeRows;
- this.dataRegionSizeColumns = dataRegionSizeColumns;
- this.ecBlocks = ecBlocks;
-
- // Calculate the total number of codewords
- int total = 0;
- int ecCodewords = ecBlocks.ECCodewords;
- ECB[] ecbArray = ecBlocks.ECBlocksValue;
- foreach (ECB ecBlock in ecbArray)
- {
- total += ecBlock.Count * (ecBlock.DataCodewords + ecCodewords);
- }
- this.totalCodewords = total;
- }
-
- public int getVersionNumber()
- {
- return versionNumber;
- }
-
- public int getSymbolSizeRows()
- {
- return symbolSizeRows;
- }
-
- public int getSymbolSizeColumns()
- {
- return symbolSizeColumns;
- }
-
- public int getDataRegionSizeRows()
- {
- return dataRegionSizeRows;
- }
-
- public int getDataRegionSizeColumns()
- {
- return dataRegionSizeColumns;
- }
-
- public int getTotalCodewords()
- {
- return totalCodewords;
- }
-
- internal ECBlocks getECBlocks()
- {
- return ecBlocks;
- }
-
- ///
- /// Deduces version information from Data Matrix dimensions.
- ///
- /// Number of rows in modules
- /// Number of columns in modules
- /// Version for a Data Matrix Code of those dimensions
- /// if dimensions do correspond to a valid Data Matrix size
- ///
- public static Version getVersionForDimensions(int numRows, int numColumns)
- {
- if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0)
- {
- return null;
- }
-
- foreach (var version in VERSIONS)
- {
- if (version.symbolSizeRows == numRows && version.symbolSizeColumns == numColumns)
- {
- return version;
- }
- }
-
- return null;
- }
-
- ///
- /// Encapsulates a set of error-correction blocks in one symbol version. Most versions will
- /// use blocks of differing sizes within one version, so, this encapsulates the parameters for
- /// each set of blocks. It also holds the number of error-correction codewords per block since it
- /// will be the same across all blocks within one version.
- ///
- internal sealed class ECBlocks
- {
- private readonly int ecCodewords;
- private readonly ECB[] _ecBlocksValue;
-
- internal ECBlocks(int ecCodewords, ECB ecBlocks)
- {
- this.ecCodewords = ecCodewords;
- this._ecBlocksValue = new ECB[] { ecBlocks };
- }
-
- internal ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2)
- {
- this.ecCodewords = ecCodewords;
- this._ecBlocksValue = new ECB[] { ecBlocks1, ecBlocks2 };
- }
-
- internal int ECCodewords
- {
- get { return ecCodewords; }
- }
-
- internal ECB[] ECBlocksValue
- {
- get { return _ecBlocksValue; }
- }
- }
-
- ///
- /// Encapsualtes the parameters for one error-correction block in one symbol version.
- /// This includes the number of data codewords, and the number of times a block with these
- /// parameters is used consecutively in the Data Matrix code version's format.
- ///
- internal sealed class ECB
- {
- private readonly int count;
- private readonly int dataCodewords;
-
- internal ECB(int count, int dataCodewords)
- {
- this.count = count;
- this.dataCodewords = dataCodewords;
- }
-
- internal int Count
- {
- get { return count; }
- }
-
- internal int DataCodewords
- {
- get { return dataCodewords; }
- }
- }
-
- override public String ToString()
- {
- return versionNumber.ToString();
- }
-
- ///
- /// See ISO 16022:2006 5.5.1 Table 7
- ///
- private static Version[] buildVersions()
- {
- return new Version[]
- {
- new Version(1, 10, 10, 8, 8,
- new ECBlocks(5, new ECB(1, 3))),
- new Version(2, 12, 12, 10, 10,
- new ECBlocks(7, new ECB(1, 5))),
- new Version(3, 14, 14, 12, 12,
- new ECBlocks(10, new ECB(1, 8))),
- new Version(4, 16, 16, 14, 14,
- new ECBlocks(12, new ECB(1, 12))),
- new Version(5, 18, 18, 16, 16,
- new ECBlocks(14, new ECB(1, 18))),
- new Version(6, 20, 20, 18, 18,
- new ECBlocks(18, new ECB(1, 22))),
- new Version(7, 22, 22, 20, 20,
- new ECBlocks(20, new ECB(1, 30))),
- new Version(8, 24, 24, 22, 22,
- new ECBlocks(24, new ECB(1, 36))),
- new Version(9, 26, 26, 24, 24,
- new ECBlocks(28, new ECB(1, 44))),
- new Version(10, 32, 32, 14, 14,
- new ECBlocks(36, new ECB(1, 62))),
- new Version(11, 36, 36, 16, 16,
- new ECBlocks(42, new ECB(1, 86))),
- new Version(12, 40, 40, 18, 18,
- new ECBlocks(48, new ECB(1, 114))),
- new Version(13, 44, 44, 20, 20,
- new ECBlocks(56, new ECB(1, 144))),
- new Version(14, 48, 48, 22, 22,
- new ECBlocks(68, new ECB(1, 174))),
- new Version(15, 52, 52, 24, 24,
- new ECBlocks(42, new ECB(2, 102))),
- new Version(16, 64, 64, 14, 14,
- new ECBlocks(56, new ECB(2, 140))),
- new Version(17, 72, 72, 16, 16,
- new ECBlocks(36, new ECB(4, 92))),
- new Version(18, 80, 80, 18, 18,
- new ECBlocks(48, new ECB(4, 114))),
- new Version(19, 88, 88, 20, 20,
- new ECBlocks(56, new ECB(4, 144))),
- new Version(20, 96, 96, 22, 22,
- new ECBlocks(68, new ECB(4, 174))),
- new Version(21, 104, 104, 24, 24,
- new ECBlocks(56, new ECB(6, 136))),
- new Version(22, 120, 120, 18, 18,
- new ECBlocks(68, new ECB(6, 175))),
- new Version(23, 132, 132, 20, 20,
- new ECBlocks(62, new ECB(8, 163))),
- new Version(24, 144, 144, 22, 22,
- new ECBlocks(62, new ECB(8, 156), new ECB(2, 155))),
- new Version(25, 8, 18, 6, 16,
- new ECBlocks(7, new ECB(1, 5))),
- new Version(26, 8, 32, 6, 14,
- new ECBlocks(11, new ECB(1, 10))),
- new Version(27, 12, 26, 10, 24,
- new ECBlocks(14, new ECB(1, 16))),
- new Version(28, 12, 36, 10, 16,
- new ECBlocks(18, new ECB(1, 22))),
- new Version(29, 16, 36, 14, 16,
- new ECBlocks(24, new ECB(1, 32))),
- new Version(30, 16, 48, 14, 22,
- new ECBlocks(28, new ECB(1, 49)))
- };
- }
- }
-}
diff --git a/zxing.core/xx/datamatrix/detector/Detector.cs b/zxing.core/xx/datamatrix/detector/Detector.cs
deleted file mode 100644
index 23b5945..0000000
--- a/zxing.core/xx/datamatrix/detector/Detector.cs
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-
-using ZXing.Common;
-using ZXing.Common.Detector;
-
-namespace ZXing.Datamatrix.Internal
-{
- ///
- /// Encapsulates logic that can detect a Data Matrix Code in an image, even if the Data Matrix Code
- /// is rotated or skewed, or partially obscured.
- ///
- /// Sean Owen
- public sealed class Detector
- {
- private readonly BitMatrix image;
- private readonly WhiteRectangleDetector rectangleDetector;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The image.
- public Detector(BitMatrix image)
- {
- this.image = image;
- rectangleDetector = WhiteRectangleDetector.Create(image);
- }
-
- ///
- /// Detects a Data Matrix Code in an image.
- ///
- /// encapsulating results of detecting a Data Matrix Code or null
- public DetectorResult detect()
- {
- if (rectangleDetector == null)
- // can be null, if the image is to small
- return null;
- ResultPoint[] cornerPoints = rectangleDetector.detect();
- if (cornerPoints == null)
- return null;
- var pointA = cornerPoints[0];
- var pointB = cornerPoints[1];
- var pointC = cornerPoints[2];
- var pointD = cornerPoints[3];
-
- // Point A and D are across the diagonal from one another,
- // as are B and C. Figure out which are the solid black lines
- // by counting transitions
- var transitions = new List(4);
- transitions.Add(transitionsBetween(pointA, pointB));
- transitions.Add(transitionsBetween(pointA, pointC));
- transitions.Add(transitionsBetween(pointB, pointD));
- transitions.Add(transitionsBetween(pointC, pointD));
- transitions.Sort(new ResultPointsAndTransitionsComparator());
-
- // Sort by number of transitions. First two will be the two solid sides; last two
- // will be the two alternating black/white sides
- var lSideOne = transitions[0];
- var lSideTwo = transitions[1];
-
- // Figure out which point is their intersection by tallying up the number of times we see the
- // endpoints in the four endpoints. One will show up twice.
- var pointCount = new Dictionary();
- increment(pointCount, lSideOne.From);
- increment(pointCount, lSideOne.To);
- increment(pointCount, lSideTwo.From);
- increment(pointCount, lSideTwo.To);
-
- ResultPoint maybeTopLeft = null;
- ResultPoint bottomLeft = null;
- ResultPoint maybeBottomRight = null;
- foreach (var entry in pointCount)
- {
- ResultPoint point = entry.Key;
- int value = entry.Value;
- if (value == 2)
- {
- bottomLeft = point; // this is definitely the bottom left, then -- end of two L sides
- }
- else
- {
- // Otherwise it's either top left or bottom right -- just assign the two arbitrarily now
- if (maybeTopLeft == null)
- {
- maybeTopLeft = point;
- }
- else
- {
- maybeBottomRight = point;
- }
- }
- }
-
- if (maybeTopLeft == null || bottomLeft == null || maybeBottomRight == null)
- {
- return null;
- }
-
- // Bottom left is correct but top left and bottom right might be switched
- ResultPoint[] corners = { maybeTopLeft, bottomLeft, maybeBottomRight };
- // Use the dot product trick to sort them out
- ResultPoint.orderBestPatterns(corners);
-
- // Now we know which is which:
- ResultPoint bottomRight = corners[0];
- bottomLeft = corners[1];
- ResultPoint topLeft = corners[2];
-
- // Which point didn't we find in relation to the "L" sides? that's the top right corner
- ResultPoint topRight;
- if (!pointCount.ContainsKey(pointA))
- {
- topRight = pointA;
- }
- else if (!pointCount.ContainsKey(pointB))
- {
- topRight = pointB;
- }
- else if (!pointCount.ContainsKey(pointC))
- {
- topRight = pointC;
- }
- else
- {
- topRight = pointD;
- }
-
- // Next determine the dimension by tracing along the top or right side and counting black/white
- // transitions. Since we start inside a black module, we should see a number of transitions
- // equal to 1 less than the code dimension. Well, actually 2 less, because we are going to
- // end on a black module:
-
- // The top right point is actually the corner of a module, which is one of the two black modules
- // adjacent to the white module at the top right. Tracing to that corner from either the top left
- // or bottom right should work here.
-
- int dimensionTop = transitionsBetween(topLeft, topRight).Transitions;
- int dimensionRight = transitionsBetween(bottomRight, topRight).Transitions;
-
- if ((dimensionTop & 0x01) == 1)
- {
- // it can't be odd, so, round... up?
- dimensionTop++;
- }
- dimensionTop += 2;
-
- if ((dimensionRight & 0x01) == 1)
- {
- // it can't be odd, so, round... up?
- dimensionRight++;
- }
- dimensionRight += 2;
-
- BitMatrix bits;
- ResultPoint correctedTopRight;
-
- // Rectanguar symbols are 6x16, 6x28, 10x24, 10x32, 14x32, or 14x44. If one dimension is more
- // than twice the other, it's certainly rectangular, but to cut a bit more slack we accept it as
- // rectangular if the bigger side is at least 7/4 times the other:
- if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop)
- {
- // The matrix is rectangular
-
- correctedTopRight =
- correctTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight, dimensionTop, dimensionRight);
- if (correctedTopRight == null)
- {
- correctedTopRight = topRight;
- }
-
- dimensionTop = transitionsBetween(topLeft, correctedTopRight).Transitions;
- dimensionRight = transitionsBetween(bottomRight, correctedTopRight).Transitions;
-
- if ((dimensionTop & 0x01) == 1)
- {
- // it can't be odd, so, round... up?
- dimensionTop++;
- }
-
- if ((dimensionRight & 0x01) == 1)
- {
- // it can't be odd, so, round... up?
- dimensionRight++;
- }
-
- bits = sampleGrid(image, topLeft, bottomLeft, bottomRight, correctedTopRight, dimensionTop, dimensionRight);
- }
- else
- {
- // The matrix is square
-
- int dimension = Math.Min(dimensionRight, dimensionTop);
- // correct top right point to match the white module
- correctedTopRight = correctTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension);
- if (correctedTopRight == null)
- {
- correctedTopRight = topRight;
- }
-
- // Redetermine the dimension using the corrected top right point
- int dimensionCorrected = Math.Max(transitionsBetween(topLeft, correctedTopRight).Transitions,
- transitionsBetween(bottomRight, correctedTopRight).Transitions);
- dimensionCorrected++;
- if ((dimensionCorrected & 0x01) == 1)
- {
- dimensionCorrected++;
- }
-
- bits = sampleGrid(image,
- topLeft,
- bottomLeft,
- bottomRight,
- correctedTopRight,
- dimensionCorrected,
- dimensionCorrected);
- }
- if (bits == null)
- return null;
-
- return new DetectorResult(bits, new ResultPoint[] { topLeft, bottomLeft, bottomRight, correctedTopRight });
- }
-
- ///
- /// Calculates the position of the white top right module using the output of the rectangle detector
- /// for a rectangular matrix
- ///
- private ResultPoint correctTopRightRectangular(ResultPoint bottomLeft,
- ResultPoint bottomRight,
- ResultPoint topLeft,
- ResultPoint topRight,
- int dimensionTop,
- int dimensionRight)
- {
-
- float corr = distance(bottomLeft, bottomRight) / (float)dimensionTop;
- int norm = distance(topLeft, topRight);
- if (norm == 0)
- return null;
- float cos = (topRight.X - topLeft.X) / norm;
- float sin = (topRight.Y - topLeft.Y) / norm;
-
- ResultPoint c1 = new ResultPoint(topRight.X + corr * cos, topRight.Y + corr * sin);
-
- corr = distance(bottomLeft, topLeft) / (float)dimensionRight;
- norm = distance(bottomRight, topRight);
- if (norm == 0)
- return null;
- cos = (topRight.X - bottomRight.X) / norm;
- sin = (topRight.Y - bottomRight.Y) / norm;
-
- ResultPoint c2 = new ResultPoint(topRight.X + corr * cos, topRight.Y + corr * sin);
-
- if (!isValid(c1))
- {
- if (isValid(c2))
- {
- return c2;
- }
- return null;
- }
- if (!isValid(c2))
- {
- return c1;
- }
-
- int l1 = Math.Abs(dimensionTop - transitionsBetween(topLeft, c1).Transitions) +
- Math.Abs(dimensionRight - transitionsBetween(bottomRight, c1).Transitions);
- int l2 = Math.Abs(dimensionTop - transitionsBetween(topLeft, c2).Transitions) +
- Math.Abs(dimensionRight - transitionsBetween(bottomRight, c2).Transitions);
-
- if (l1 <= l2)
- {
- return c1;
- }
-
- return c2;
- }
-
- ///
- /// Calculates the position of the white top right module using the output of the rectangle detector
- /// for a square matrix
- ///
- private ResultPoint correctTopRight(ResultPoint bottomLeft,
- ResultPoint bottomRight,
- ResultPoint topLeft,
- ResultPoint topRight,
- int dimension)
- {
-
- float corr = distance(bottomLeft, bottomRight) / (float)dimension;
- int norm = distance(topLeft, topRight);
- if (norm == 0)
- return null;
- float cos = (topRight.X - topLeft.X) / norm;
- float sin = (topRight.Y - topLeft.Y) / norm;
-
- ResultPoint c1 = new ResultPoint(topRight.X + corr * cos, topRight.Y + corr * sin);
-
- corr = distance(bottomLeft, topLeft) / (float)dimension;
- norm = distance(bottomRight, topRight);
- if (norm == 0)
- return null;
- cos = (topRight.X - bottomRight.X) / norm;
- sin = (topRight.Y - bottomRight.Y) / norm;
-
- ResultPoint c2 = new ResultPoint(topRight.X + corr * cos, topRight.Y + corr * sin);
-
- if (!isValid(c1))
- {
- if (isValid(c2))
- {
- return c2;
- }
- return null;
- }
- if (!isValid(c2))
- {
- return c1;
- }
-
- int l1 = Math.Abs(transitionsBetween(topLeft, c1).Transitions -
- transitionsBetween(bottomRight, c1).Transitions);
- int l2 = Math.Abs(transitionsBetween(topLeft, c2).Transitions -
- transitionsBetween(bottomRight, c2).Transitions);
-
- return l1 <= l2 ? c1 : c2;
- }
-
- private bool isValid(ResultPoint p)
- {
- return p.X >= 0 && p.X < image.Width && p.Y > 0 && p.Y < image.Height;
- }
-
- // L2 distance
- private static int distance(ResultPoint a, ResultPoint b)
- {
- return MathUtils.round(ResultPoint.distance(a, b));
- }
-
- ///
- /// Increments the Integer associated with a key by one.
- ///
- private static void increment(IDictionary table, ResultPoint key)
- {
- if (table.ContainsKey(key))
- {
- int value = table[key];
- table[key] = value + 1;
- }
- else
- {
- table[key] = 1;
- }
- }
-
- private static BitMatrix sampleGrid(BitMatrix image,
- ResultPoint topLeft,
- ResultPoint bottomLeft,
- ResultPoint bottomRight,
- ResultPoint topRight,
- int dimensionX,
- int dimensionY)
- {
-
- GridSampler sampler = GridSampler.Instance;
-
- return sampler.sampleGrid(image,
- dimensionX,
- dimensionY,
- 0.5f,
- 0.5f,
- dimensionX - 0.5f,
- 0.5f,
- dimensionX - 0.5f,
- dimensionY - 0.5f,
- 0.5f,
- dimensionY - 0.5f,
- topLeft.X,
- topLeft.Y,
- topRight.X,
- topRight.Y,
- bottomRight.X,
- bottomRight.Y,
- bottomLeft.X,
- bottomLeft.Y);
- }
-
- ///
- /// Counts the number of black/white transitions between two points, using something like Bresenham's algorithm.
- ///
- private ResultPointsAndTransitions transitionsBetween(ResultPoint from, ResultPoint to)
- {
- // See QR Code Detector, sizeOfBlackWhiteBlackRun()
- int fromX = (int)from.X;
- int fromY = (int)from.Y;
- int toX = (int)to.X;
- int toY = (int)to.Y;
- bool steep = Math.Abs(toY - fromY) > Math.Abs(toX - fromX);
- if (steep)
- {
- int temp = fromX;
- fromX = fromY;
- fromY = temp;
- temp = toX;
- toX = toY;
- toY = temp;
- }
-
- int dx = Math.Abs(toX - fromX);
- int dy = Math.Abs(toY - fromY);
- int error = -dx >> 1;
- int ystep = fromY < toY ? 1 : -1;
- int xstep = fromX < toX ? 1 : -1;
- int transitions = 0;
- bool inBlack = image[steep ? fromY : fromX, steep ? fromX : fromY];
- for (int x = fromX, y = fromY; x != toX; x += xstep)
- {
- bool isBlack = image[steep ? y : x, steep ? x : y];
- if (isBlack != inBlack)
- {
- transitions++;
- inBlack = isBlack;
- }
- error += dy;
- if (error > 0)
- {
- if (y == toY)
- {
- break;
- }
- y += ystep;
- error -= dx;
- }
- }
- return new ResultPointsAndTransitions(from, to, transitions);
- }
-
- ///
- /// Simply encapsulates two points and a number of transitions between them.
- ///
- private sealed class ResultPointsAndTransitions
- {
- public ResultPoint From { get; private set; }
- public ResultPoint To { get; private set; }
- public int Transitions { get; private set; }
-
- public ResultPointsAndTransitions(ResultPoint from, ResultPoint to, int transitions)
- {
- From = from;
- To = to;
- Transitions = transitions;
- }
-
- override public String ToString()
- {
- return From + "/" + To + '/' + Transitions;
- }
- }
-
- ///
- /// Orders ResultPointsAndTransitions by number of transitions, ascending.
- ///
- private sealed class ResultPointsAndTransitionsComparator : IComparer
- {
- public int Compare(ResultPointsAndTransitions o1, ResultPointsAndTransitions o2)
- {
- return o1.Transitions - o2.Transitions;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/ASCIIEncoder.cs b/zxing.core/xx/datamatrix/encoder/ASCIIEncoder.cs
deleted file mode 100644
index 3cf1b81..0000000
--- a/zxing.core/xx/datamatrix/encoder/ASCIIEncoder.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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);
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/Base256Encoder.cs b/zxing.core/xx/datamatrix/encoder/Base256Encoder.cs
deleted file mode 100644
index 1cc5344..0000000
--- a/zxing.core/xx/datamatrix/encoder/Base256Encoder.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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);
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/C40Encoder.cs b/zxing.core/xx/datamatrix/encoder/C40Encoder.cs
deleted file mode 100644
index 3babd0f..0000000
--- a/zxing.core/xx/datamatrix/encoder/C40Encoder.cs
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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);
- }
-
- ///
- /// Handle "end of data" situations
- ///
- /// the encoder context
- /// the buffer with the remaining encoded characters
- 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 });
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/DataMatrixSymbolInfo144.cs b/zxing.core/xx/datamatrix/encoder/DataMatrixSymbolInfo144.cs
deleted file mode 100644
index 681e5b1..0000000
--- a/zxing.core/xx/datamatrix/encoder/DataMatrixSymbolInfo144.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/DatamatrixEncodingOptions.cs b/zxing.core/xx/datamatrix/encoder/DatamatrixEncodingOptions.cs
deleted file mode 100644
index d78938e..0000000
--- a/zxing.core/xx/datamatrix/encoder/DatamatrixEncodingOptions.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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
-{
- ///
- /// The class holds the available options for the DatamatrixWriter
- ///
- public class DatamatrixEncodingOptions : EncodingOptions
- {
- ///
- /// Specifies the matrix shape for Data Matrix
- ///
- 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;
- }
- }
- }
-
- ///
- /// Specifies a minimum barcode size
- ///
- 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;
- }
- }
- }
-
- ///
- /// Specifies a maximum barcode size
- ///
- 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;
- }
- }
- }
-
- ///
- /// 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
- ///
- 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;
- }
- }
- }
- }
-}
diff --git a/zxing.core/xx/datamatrix/encoder/DefaultPlacement.cs b/zxing.core/xx/datamatrix/encoder/DefaultPlacement.cs
deleted file mode 100644
index f3bd030..0000000
--- a/zxing.core/xx/datamatrix/encoder/DefaultPlacement.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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
-{
- ///
- /// Symbol Character Placement Program. Adapted from Annex M.1 in ISO/IEC 16022:2000(E).
- ///
- public class DefaultPlacement
- {
- private readonly String codewords;
- private readonly int numrows;
- private readonly int numcols;
- private readonly byte[] bits;
-
- ///
- /// Main constructor
- ///
- /// the codewords to place
- /// the number of columns
- /// the number of rows
- 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);
- }
-
- ///
- /// Places the 8 bits of a utah-shaped symbol character in ECC200.
- ///
- /// The row.
- /// The col.
- /// character position
- 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);
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/EdifactEncoder.cs b/zxing.core/xx/datamatrix/encoder/EdifactEncoder.cs
deleted file mode 100644
index cd17d64..0000000
--- a/zxing.core/xx/datamatrix/encoder/EdifactEncoder.cs
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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);
- }
-
- ///
- /// Handle "end of data" situations
- ///
- /// the encoder context
- /// the buffer with the remaining encoded characters
- 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();
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/Encodation.cs b/zxing.core/xx/datamatrix/encoder/Encodation.cs
deleted file mode 100644
index ba83dc6..0000000
--- a/zxing.core/xx/datamatrix/encoder/Encodation.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
-{
- ///
- /// Enumeration for encodation types
- ///
- 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;
- }
-}
diff --git a/zxing.core/xx/datamatrix/encoder/Encoder.cs b/zxing.core/xx/datamatrix/encoder/Encoder.cs
deleted file mode 100644
index 292976c..0000000
--- a/zxing.core/xx/datamatrix/encoder/Encoder.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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);
- }
-}
diff --git a/zxing.core/xx/datamatrix/encoder/EncoderContext.cs b/zxing.core/xx/datamatrix/encoder/EncoderContext.cs
deleted file mode 100644
index 627afe5..0000000
--- a/zxing.core/xx/datamatrix/encoder/EncoderContext.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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; }
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/ErrorCorrection.cs b/zxing.core/xx/datamatrix/encoder/ErrorCorrection.cs
deleted file mode 100644
index fabccae..0000000
--- a/zxing.core/xx/datamatrix/encoder/ErrorCorrection.cs
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * 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
-{
- ///
- /// Error Correction Code for ECC200.
- ///
- public static class ErrorCorrection
- {
- ///
- /// Lookup table which factors to use for which number of error correction codewords.
- /// See FACTORS.
- ///
- private static readonly int[] FACTOR_SETS
- = { 5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68 };
-
- ///
- /// Precomputed polynomial factors for ECC 200.
- ///
- 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;
- }
- }
- }
-
- ///
- /// Creates the ECC200 error correction for an encoded message.
- ///
- /// The codewords.
- /// information about the symbol to be encoded
- /// the codewords with interleaved error correction.
- 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);
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/HighLevelEncoder.cs b/zxing.core/xx/datamatrix/encoder/HighLevelEncoder.cs
deleted file mode 100644
index 96bd383..0000000
--- a/zxing.core/xx/datamatrix/encoder/HighLevelEncoder.cs
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * 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
-{
- ///
- /// DataMatrix ECC 200 data encoder following the algorithm described in ISO/IEC 16022:200(E) in
- /// annex S.
- ///
- internal static class HighLevelEncoder
- {
- ///
- /// Padding character
- ///
- public const char PAD = (char)129;
- ///
- /// mode latch to C40 encodation mode
- ///
- public const char LATCH_TO_C40 = (char)230;
- ///
- /// mode latch to Base 256 encodation mode
- ///
- public const char LATCH_TO_BASE256 = (char)231;
- ///
- /// FNC1 Codeword
- ///
- public const char FNC1 = (char)232;
- ///
- /// Structured Append Codeword
- ///
- public const char STRUCTURED_APPEND = (char)233;
- ///
- /// Reader Programming
- ///
- public const char READER_PROGRAMMING = (char)234;
- ///
- /// Upper Shift
- ///
- public const char UPPER_SHIFT = (char)235;
- ///
- /// 05 Macro
- ///
- public const char MACRO_05 = (char)236;
- ///
- /// 06 Macro
- ///
- public const char MACRO_06 = (char)237;
- ///
- /// mode latch to ANSI X.12 encodation mode
- ///
- public const char LATCH_TO_ANSIX12 = (char)238;
- ///
- /// mode latch to Text encodation mode
- ///
- public const char LATCH_TO_TEXT = (char)239;
- ///
- /// mode latch to EDIFACT encodation mode
- ///
- public const char LATCH_TO_EDIFACT = (char)240;
- ///
- /// ECI character (Extended Channel Interpretation)
- ///
- public const char ECI = (char)241;
-
- ///
- /// Unlatch from C40 encodation
- ///
- public const char C40_UNLATCH = (char)254;
- ///
- /// Unlatch from X12 encodation
- ///
- public const char X12_UNLATCH = (char)254;
-
- ///
- /// 05 Macro header
- ///
- public const String MACRO_05_HEADER = "[)>\u001E05\u001D";
- ///
- /// 06 Macro header
- ///
- public const String MACRO_06_HEADER = "[)>\u001E06\u001D";
- ///
- /// Macro trailer
- ///
- public const String MACRO_TRAILER = "\u001E\u0004";
-
- /*
- ///
- /// Converts the message to a byte array using the default encoding (cp437) as defined by the
- /// specification
- ///
- /// the message
- /// the byte array of the message
- 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);
- }
-
- ///
- /// Performs message encoding of a DataMatrix message using the algorithm described in annex P
- /// of ISO/IEC 16022:2000(E).
- ///
- /// the message
- /// the encoded message (the char values range from 0 to 255)
- public static String encodeHighLevel(String msg)
- {
- return encodeHighLevel(msg, SymbolShapeHint.FORCE_NONE, null, null, Encodation.ASCII);
- }
-
- ///
- /// Performs message encoding of a DataMatrix message using the algorithm described in annex P
- /// of ISO/IEC 16022:2000(E).
- ///
- /// the message
- /// requested shape. May be {@code SymbolShapeHint.FORCE_NONE},{@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}.
- /// the minimum symbol size constraint or null for no constraint
- /// the maximum symbol size constraint or null for no constraint
- /// the encoded message (the char values range from 0 to 255)
- 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!!!
- }
-
- ///
- /// Determines the number of consecutive characters that are encodable using numeric compaction.
- ///
- /// the message
- /// the start position within the message
- /// the requested character count
- 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));
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/SymbolInfo.cs b/zxing.core/xx/datamatrix/encoder/SymbolInfo.cs
deleted file mode 100644
index f746013..0000000
--- a/zxing.core/xx/datamatrix/encoder/SymbolInfo.cs
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * 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
-{
- ///
- /// Symbol info table for DataMatrix.
- ///
- 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();
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/SymbolShapeHint.cs b/zxing.core/xx/datamatrix/encoder/SymbolShapeHint.cs
deleted file mode 100644
index 66fee11..0000000
--- a/zxing.core/xx/datamatrix/encoder/SymbolShapeHint.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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
-{
- ///
- /// Enumeration for DataMatrix symbol shape hint. It can be used to force square or rectangular
- /// symbols.
- ///
- public enum SymbolShapeHint
- {
- FORCE_NONE,
- FORCE_SQUARE,
- FORCE_RECTANGLE,
- }
-}
diff --git a/zxing.core/xx/datamatrix/encoder/TextEncoder.cs b/zxing.core/xx/datamatrix/encoder/TextEncoder.cs
deleted file mode 100644
index 6f6d5ba..0000000
--- a/zxing.core/xx/datamatrix/encoder/TextEncoder.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/datamatrix/encoder/X12Encoder.cs b/zxing.core/xx/datamatrix/encoder/X12Encoder.cs
deleted file mode 100644
index 02d04a2..0000000
--- a/zxing.core/xx/datamatrix/encoder/X12Encoder.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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);
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.doc.shfbproj b/zxing.core/xx/documentation/zxing.doc.shfbproj
deleted file mode 100644
index 4bdf894..0000000
--- a/zxing.core/xx/documentation/zxing.doc.shfbproj
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {8faf2142-c26e-4d13-9701-f86f6e6d0443}
- 1.9.3.0
-
- zxing.doc
- zxing.doc
- zxing.doc
-
- ..\..\..\Build\Release\Documentation\net4.0\
- zxing.net
- en-US
-
-
-
-
- Standard
- Blank
- False
- vs2010
- False
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
- AllMessages
- HtmlHelp1
- False
- .NET 4.0.30319
- False
- False
- False
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\Build\Release\Documentation\net4.0\
-
-
-
- zxing
- {6431cf13-7a7b-4602-b96a-47cda6f0b008}
- True
-
-
- zxing.presentation
- {ea513204-63f3-4c50-992d-08ff430b6f70}
- True
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.net2.0.doc.shfbproj b/zxing.core/xx/documentation/zxing.net2.0.doc.shfbproj
deleted file mode 100644
index c988b0f..0000000
--- a/zxing.core/xx/documentation/zxing.net2.0.doc.shfbproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {12441bd6-6380-40f8-b6f6-c42a98443bba}
- 1.9.3.0
-
- zxing.net2.0.doc
- zxing.net2.0.doc
- zxing.net2.0.doc
-
- ..\..\..\Build\Release\Documentation\net2.0\
- zxing.net2.0
- en-US
-
-
-
- AllMessages
- HtmlHelp1
- False
- .NET 2.0.50727
- False
- False
- False
- True
- Standard
- Blank
- False
- vs2010
- False
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- zxing.net2.0
- {41b69545-aab6-42a6-96a0-6f6817e654a3}
- True
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.net3.5.doc.shfbproj b/zxing.core/xx/documentation/zxing.net3.5.doc.shfbproj
deleted file mode 100644
index f4ee722..0000000
--- a/zxing.core/xx/documentation/zxing.net3.5.doc.shfbproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {0ddd7a5d-c54a-4841-8555-7940db210df7}
- 1.9.3.0
-
- zxing.net3.5.doc
- zxing.net3.5.doc
- zxing.net3.5.doc
-
- ..\..\..\Build\Release\Documentation\net3.5\
- zxing.net3.5
- en-US
-
-
-
- AllMessages
- HtmlHelp1
- False
- .NET 3.5
- False
- False
- False
- True
- Standard
- Blank
- False
- vs2010
- False
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- zxing.net3.5
- {41b69545-aab6-42a6-96a0-6f6817e654a3}
- True
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.portable.doc.shfbproj b/zxing.core/xx/documentation/zxing.portable.doc.shfbproj
deleted file mode 100644
index 36eed4e..0000000
--- a/zxing.core/xx/documentation/zxing.portable.doc.shfbproj
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {B95B1194-0D6A-4121-A629-695B1F8EF0A7}
- 1.9.3.0
-
- zxing.portable.doc
- zxing.portable.doc
- zxing.portable.doc
-
- ..\..\..\Build\Release\Documentation\portable\
- zxing.net.portable
- en-US
-
-
-
- Standard
- Blank
- False
- vs2010
- False
- Portable 4.0
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
- AllMessages
- HtmlHelp1
- False
- Portable 4.0
- False
- False
- False
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\..\..\Build\Release\Documentation\portable\
-
-
-
- zxing.portable
- {24b441f2-cbe9-4405-9fd0-72ebcbea0ec3}
- True
-
-
-
-
- System.Core
- System.Core.dll
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.sl4.doc.shfbproj b/zxing.core/xx/documentation/zxing.sl4.doc.shfbproj
deleted file mode 100644
index 85a5eb2..0000000
--- a/zxing.core/xx/documentation/zxing.sl4.doc.shfbproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {f983b572-dcd7-4ab4-b9d5-d218a22ba5fe}
- 1.9.3.0
-
- zxing.sl4.doc
- zxing.sl4.doc
- zxing.sl4.doc
-
- ..\..\..\Build\Release\Documentation\sl4\
- zxing.sl4
- en-US
-
-
-
- AllMessages
- HtmlHelp1
- False
- Silverlight 4.0
- False
- False
- False
- True
- Standard
- Blank
- False
- vs2010
- False
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- zxing.sl4
- {03b962bb-7a24-4589-89e5-c42a17ddc376}
- True
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.sl5.doc.shfbproj b/zxing.core/xx/documentation/zxing.sl5.doc.shfbproj
deleted file mode 100644
index deeaa6c..0000000
--- a/zxing.core/xx/documentation/zxing.sl5.doc.shfbproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {cd937642-91a0-4371-9452-336f8cc63121}
- 1.9.3.0
-
- zxing.sl5.doc
- zxing.sl5.doc
- zxing.sl5.doc
-
- ..\..\..\Build\Release\Documentation\sl5\
- zxing.sl5
- en-US
-
-
-
- AllMessages
- HtmlHelp1
- False
- Silverlight 5.0
- False
- False
- False
- True
- Standard
- Blank
- False
- vs2010
- False
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- zxing.sl5
- {a3d48b9c-42a0-4fc8-bb58-d368f239debf}
- True
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.unity.doc.shfbproj b/zxing.core/xx/documentation/zxing.unity.doc.shfbproj
deleted file mode 100644
index ce966be..0000000
--- a/zxing.core/xx/documentation/zxing.unity.doc.shfbproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {9ab81466-791f-46b2-ae88-55d4759de821}
- 1.9.3.0
-
- zxing.unity.doc
- zxing.unity.doc
- zxing.unity.doc
-
- ..\..\..\Build\Release\Documentation\unity\
- zxing.unity
- en-US
-
-
-
- AllMessages
- HtmlHelp1
- False
- .NET 3.5
- False
- False
- False
- True
- Standard
- Blank
- False
- vs2010
- False
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- zxing.unity
- {fd386cf5-e9cd-442c-a44c-b7d996e68ccc}
- True
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.wp7.0.doc.shfbproj b/zxing.core/xx/documentation/zxing.wp7.0.doc.shfbproj
deleted file mode 100644
index 782e4e7..0000000
--- a/zxing.core/xx/documentation/zxing.wp7.0.doc.shfbproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {5fbc3f17-7792-46ce-b974-14753d605a18}
- 1.9.3.0
-
- zxing.wp7.0.doc
- zxing.wp7.0.doc
- zxing.wp7.0.doc
-
- ..\..\..\Build\Release\Documentation\wp7.0\
- zxing.wp7.0
- en-US
-
-
-
- AllMessages
- HtmlHelp1
- False
- Silverlight 4.0
- False
- False
- False
- True
- Standard
- Blank
- False
- vs2010
- False
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- zxing.wp7.0
- {7144c757-8ca7-4433-8c6f-072c24c43c62}
- True
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/documentation/zxing.wp7.1.doc.shfbproj b/zxing.core/xx/documentation/zxing.wp7.1.doc.shfbproj
deleted file mode 100644
index 3d5a4a9..0000000
--- a/zxing.core/xx/documentation/zxing.wp7.1.doc.shfbproj
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- 2.0
- {13addaba-9d04-4503-a9ff-c39e96b6e6b4}
- 1.9.3.0
-
- zxing.wp7.1.doc
- zxing.wp7.1.doc
- zxing.wp7.1.doc
-
- ..\..\..\Build\Release\Documentation\wp7.1\
- zxing.wp7.1
- en-US
-
-
-
- AllMessages
- HtmlHelp1
- False
- Silverlight 4.0
- False
- False
- False
- True
- Standard
- Blank
- False
- vs2010
- False
- Guid
- ZXing.Net
- AboveNamespaces
- Attributes, ExplicitInterfaceImplementations, InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- zxing.wp7.1
- {ec6f52b8-af75-4fa2-85c1-82bf77861fff}
- True
-
-
-
-
-
\ No newline at end of file
diff --git a/zxing.core/xx/imb/IMBReader.cs b/zxing.core/xx/imb/IMBReader.cs
deleted file mode 100644
index 07cf0a4..0000000
--- a/zxing.core/xx/imb/IMBReader.cs
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * Copyright 2014 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 System.Collections.Generic;
-using System.Numerics;
-using System.Text;
-
-using ZXing.Common;
-using ZXing.OneD;
-
-namespace ZXing.IMB
-{
- ///
- /// implements an Intelligent Mail barcode
- /// Rishabh Hatgadkar
- ///
- public sealed class IMBReader : OneDReader
- {
- private const int NUM_BARS_IMB = 65;
-
- private static readonly int[] barPosA = new[] {2, 6, 13, 16, 21, 30, 34, 40, 45, 48, 52, 56, 62};
- private static readonly int[] barPosB = new[] {22, 18, 39, 41, 11, 57, 54, 50, 7, 32, 2, 62, 26};
- private static readonly int[] barPosC = new[] {40, 35, 57, 52, 49, 7, 24, 17, 3, 63, 29, 44, 12};
- private static readonly int[] barPosD = new[] {47, 5, 35, 39, 30, 42, 15, 60, 20, 10, 65, 54, 23};
- private static readonly int[] barPosE = new[] {20, 41, 46, 1, 8, 51, 29, 61, 34, 15, 25, 37, 58};
- private static readonly int[] barPosF = new[] {51, 25, 19, 64, 56, 4, 44, 31, 28, 36, 47, 11, 6};
- private static readonly int[] barPosG = new[] {33, 37, 21, 9, 17, 49, 59, 14, 64, 26, 42, 4, 53};
- private static readonly int[] barPosH = new[] {60, 14, 1, 27, 38, 61, 10, 24, 50, 55, 19, 32, 45};
- private static readonly int[] barPosI = new[] {27, 46, 65, 59, 31, 12, 16, 43, 55, 5, 9, 22, 36};
- private static readonly int[] barPosJ = new[] {63, 58, 53, 48, 43, 38, 33, 28, 23, 18, 13, 8, 3};
- private static readonly int[][] barPos = new[] {barPosA, barPosB, barPosC, barPosD, barPosE, barPosF, barPosG, barPosH, barPosI, barPosJ};
-
- private static readonly char[] barTypeA = new[] {'A', 'D', 'A', 'D', 'A', 'A', 'D', 'D', 'D', 'A', 'A', 'A', 'D'};
- private static readonly char[] barTypeB = new[] {'A', 'D', 'A', 'D', 'A', 'D', 'A', 'A', 'A', 'A', 'D', 'A', 'D'};
- private static readonly char[] barTypeC = new[] {'A', 'D', 'A', 'D', 'A', 'D', 'D', 'A', 'A', 'D', 'A', 'D', 'A'};
- private static readonly char[] barTypeD = new[] {'A', 'A', 'A', 'D', 'D', 'A', 'D', 'A', 'A', 'D', 'D', 'D', 'A'};
- private static readonly char[] barTypeE = new[] {'D', 'A', 'D', 'A', 'D', 'A', 'D', 'D', 'A', 'A', 'A', 'D', 'A'};
- private static readonly char[] barTypeF = new[] {'D', 'D', 'A', 'A', 'D', 'D', 'A', 'A', 'D', 'D', 'D', 'D', 'A'};
- private static readonly char[] barTypeG = new[] {'D', 'A', 'D', 'D', 'D', 'D', 'A', 'A', 'D', 'A', 'D', 'A', 'D'};
- private static readonly char[] barTypeH = new[] {'D', 'D', 'D', 'D', 'A', 'A', 'A', 'A', 'D', 'A', 'D', 'D', 'A'};
- private static readonly char[] barTypeI = new[] {'A', 'A', 'A', 'D', 'D', 'D', 'A', 'D', 'D', 'D', 'A', 'D', 'A'};
- private static readonly char[] barTypeJ = new[] {'A', 'D', 'A', 'D', 'A', 'D', 'A', 'A', 'D', 'A', 'D', 'A', 'D'};
- private static readonly char[][] barType = new[] {barTypeA, barTypeB, barTypeC, barTypeD, barTypeE, barTypeF, barTypeG, barTypeH, barTypeI, barTypeJ};
-
- private const int A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6, H = 7, I = 8, J = 9;
-
- private static readonly IDictionary table1Check;
- private static readonly IDictionary table2Check;
-
- private BinaryBitmap currentBitmap;
-
- static IMBReader()
- {
- ushort[] table1 = {31, 7936, 47, 7808, 55, 7552, 59, 7040, 61, 6016, 62, 3968, 79, 7744, 87, 7488, 91, 6976, 93, 5952, 94, 3904, 103, 7360, 107, 6848, 109, 5824, 110, 3776, 115, 6592, 117, 5568, 118, 3520, 121, 5056, 122, 3008, 124, 1984, 143, 7712, 151, 7456, 155, 6944, 157, 5920, 158, 3872, 167, 7328, 171, 6816, 173, 5792, 174, 3744, 179, 6560, 181, 5536, 182, 3488, 185, 5024, 186, 2976, 188, 1952, 199, 7264, 203, 6752, 205, 5728, 206, 3680, 211, 6496, 213, 5472, 214, 3424, 217, 4960, 218, 2912, 220, 1888, 227, 6368, 229, 5344, 230, 3296, 233, 4832, 234, 2784, 236, 1760, 241, 4576, 242, 2528, 244, 1504, 248, 992, 271, 7696, 279, 7440, 283, 6928, 285, 5904, 286, 3856, 295, 7312, 299, 6800, 301, 5776, 302, 3728, 307, 6544, 309, 5520, 310, 3472, 313, 5008, 314, 2960, 316, 1936, 327, 7248, 331, 6736, 333, 5712, 334, 3664, 339, 6480, 341, 5456, 342, 3408, 345, 4944, 346, 2896, 348, 1872, 355, 6352, 357, 5328, 358, 3280, 361, 4816, 362, 2768, 364, 1744, 369, 4560, 370, 2512, 372, 1488, 376, 976, 391, 7216, 395, 6704, 397, 5680, 398, 3632, 403, 6448, 405, 5424, 406, 3376, 409, 4912, 410, 2864, 412, 1840, 419, 6320, 421, 5296, 422, 3248, 425, 4784, 426, 2736, 428, 1712, 433, 4528, 434, 2480, 436, 1456, 440, 944, 451, 6256, 453, 5232, 454, 3184, 457, 4720, 458, 2672, 460, 1648, 465, 4464, 466, 2416, 468, 1392, 472, 880, 481, 4336, 482, 2288, 484, 1264, 488, 752, 527, 7688, 535, 7432, 539, 6920, 541, 5896, 542, 3848, 551, 7304, 555, 6792, 557, 5768, 558, 3720, 563, 6536, 565, 5512, 566, 3464, 569, 5000, 570, 2952, 572, 1928, 583, 7240, 587, 6728, 589, 5704, 590, 3656, 595, 6472, 597, 5448, 598, 3400, 601, 4936, 602, 2888, 604, 1864, 611, 6344, 613, 5320, 614, 3272, 617, 4808, 618, 2760, 620, 1736, 625, 4552, 626, 2504, 628, 1480, 632, 968, 647, 7208, 651, 6696, 653, 5672, 654, 3624, 659, 6440, 661, 5416, 662, 3368, 665, 4904, 666, 2856, 668, 1832, 675, 6312, 677, 5288, 678, 3240, 681, 4776, 682, 2728, 684, 1704, 689, 4520, 690, 2472, 692, 1448, 696, 936, 707, 6248, 709, 5224, 710, 3176, 713, 4712, 714, 2664, 716, 1640, 721, 4456, 722, 2408, 724, 1384, 728, 872, 737, 4328, 738, 2280, 740, 1256, 775, 7192, 779, 6680, 781, 5656, 782, 3608, 787, 6424, 789, 5400, 790, 3352, 793, 4888, 794, 2840, 796, 1816, 803, 6296, 805, 5272, 806, 3224, 809, 4760, 810, 2712, 812, 1688, 817, 4504, 818, 2456, 820, 1432, 824, 920, 835, 6232, 837, 5208, 838, 3160, 841, 4696, 842, 2648, 844, 1624, 849, 4440, 850, 2392, 852, 1368, 865, 4312, 866, 2264, 868, 1240, 899, 6200, 901, 5176, 902, 3128, 905, 4664, 906, 2616, 908, 1592, 913, 4408, 914, 2360, 916, 1336, 929, 4280, 930, 2232, 932, 1208, 961, 4216, 962, 2168, 964, 1144, 1039, 7684, 1047, 7428, 1051, 6916, 1053, 5892, 1054, 3844, 1063, 7300, 1067, 6788, 1069, 5764, 1070, 3716, 1075, 6532, 1077, 5508, 1078, 3460, 1081, 4996, 1082, 2948, 1084, 1924, 1095, 7236, 1099, 6724, 1101, 5700, 1102, 3652, 1107, 6468, 1109, 5444, 1110, 3396, 1113, 4932, 1114, 2884, 1116, 1860, 1123, 6340, 1125, 5316, 1126, 3268, 1129, 4804, 1130, 2756, 1132, 1732, 1137, 4548, 1138, 2500, 1140, 1476, 1159, 7204, 1163, 6692, 1165, 5668, 1166, 3620, 1171, 6436, 1173, 5412, 1174, 3364, 1177, 4900, 1178, 2852, 1180, 1828, 1187, 6308, 1189, 5284, 1190, 3236, 1193, 4772, 1194, 2724, 1196, 1700, 1201, 4516, 1202, 2468, 1204, 1444, 1219, 6244, 1221, 5220, 1222, 3172, 1225, 4708, 1226, 2660, 1228, 1636, 1233, 4452, 1234, 2404, 1236, 1380, 1249, 4324, 1250, 2276, 1287, 7188, 1291, 6676, 1293, 5652, 1294, 3604, 1299, 6420, 1301, 5396, 1302, 3348, 1305, 4884, 1306, 2836, 1308, 1812, 1315, 6292, 1317, 5268, 1318, 3220, 1321, 4756, 1322, 2708, 1324, 1684, 1329, 4500, 1330, 2452, 1332, 1428, 1347, 6228, 1349, 5204, 1350, 3156, 1353, 4692, 1354, 2644, 1356, 1620, 1361, 4436, 1362, 2388, 1377, 4308, 1378, 2260, 1411, 6196, 1413, 5172, 1414, 3124, 1417, 4660, 1418, 2612, 1420, 1588, 1425, 4404, 1426, 2356, 1441, 4276, 1442, 2228, 1473, 4212, 1474, 2164, 1543, 7180, 1547, 6668, 1549, 5644, 1550, 3596, 1555, 6412, 1557, 5388, 1558, 3340, 1561, 4876, 1562, 2828, 1564, 1804, 1571, 6284, 1573, 5260, 1574, 3212, 1577, 4748, 1578, 2700, 1580, 1676, 1585, 4492, 1586, 2444, 1603, 6220, 1605, 5196, 1606, 3148, 1609, 4684, 1610, 2636, 1617, 4428, 1618, 2380, 1633, 4300, 1634, 2252, 1667, 6188, 1669, 5164, 1670, 3116, 1673, 4652, 1674, 2604, 1681, 4396, 1682, 2348, 1697, 4268, 1698, 2220, 1729, 4204, 1730, 2156, 1795, 6172, 1797, 5148, 1798, 3100, 1801, 4636, 1802, 2588, 1809, 4380, 1810, 2332, 1825, 4252, 1826, 2204, 1857, 4188, 1858, 2140, 1921, 4156, 1922, 2108, 2063, 7682, 2071, 7426, 2075, 6914, 2077, 5890, 2078, 3842, 2087, 7298, 2091, 6786, 2093, 5762, 2094, 3714, 2099, 6530, 2101, 5506, 2102, 3458, 2105, 4994, 2106, 2946, 2119, 7234, 2123, 6722, 2125, 5698, 2126, 3650, 2131, 6466, 2133, 5442, 2134, 3394, 2137, 4930, 2138, 2882, 2147, 6338, 2149, 5314, 2150, 3266, 2153, 4802, 2154, 2754, 2161, 4546, 2162, 2498, 2183, 7202, 2187, 6690, 2189, 5666, 2190, 3618, 2195, 6434, 2197, 5410, 2198, 3362, 2201, 4898, 2202, 2850, 2211, 6306, 2213, 5282, 2214, 3234, 2217, 4770, 2218, 2722, 2225, 4514, 2226, 2466, 2243, 6242, 2245, 5218, 2246, 3170, 2249, 4706, 2250, 2658, 2257, 4450, 2258, 2402, 2273, 4322, 2311, 7186, 2315, 6674, 2317, 5650, 2318, 3602, 2323, 6418, 2325, 5394, 2326, 3346, 2329, 4882, 2330, 2834, 2339, 6290, 2341, 5266, 2342, 3218, 2345, 4754, 2346, 2706, 2353, 4498, 2354, 2450, 2371, 6226, 2373, 5202, 2374, 3154, 2377, 4690, 2378, 2642, 2385, 4434, 2401, 4306, 2435, 6194, 2437, 5170, 2438, 3122, 2441, 4658, 2442, 2610, 2449, 4402, 2465, 4274, 2497, 4210, 2567, 7178, 2571, 6666, 2573, 5642, 2574, 3594, 2579, 6410, 2581, 5386, 2582, 3338, 2585, 4874, 2586, 2826, 2595, 6282, 2597, 5258, 2598, 3210, 2601, 4746, 2602, 2698, 2609, 4490, 2627, 6218, 2629, 5194, 2630, 3146, 2633, 4682, 2641, 4426, 2657, 4298, 2691, 6186, 2693, 5162, 2694, 3114, 2697, 4650, 2705, 4394, 2721, 4266, 2753, 4202, 2819, 6170, 2821, 5146, 2822, 3098, 2825, 4634, 2833, 4378, 2849, 4250, 2881, 4186, 2945, 4154, 3079, 7174, 3083, 6662, 3085, 5638, 3086, 3590, 3091, 6406, 3093, 5382, 3094, 3334, 3097, 4870, 3107, 6278, 3109, 5254, 3110, 3206, 3113, 4742, 3121, 4486, 3139, 6214, 3141, 5190, 3145, 4678, 3153, 4422, 3169, 4294, 3203, 6182, 3205, 5158, 3209, 4646, 3217, 4390, 3233, 4262, 3265, 4198, 3331, 6166, 3333, 5142, 3337, 4630, 3345, 4374, 3361, 4246, 3393, 4182, 3457, 4150, 3587, 6158, 3589, 5134, 3593, 4622, 3601, 4366, 3617, 4238, 3649, 4174, 3713, 4142, 3841, 4126, 4111, 7681, 4119, 7425, 4123, 6913, 4125, 5889, 4135, 7297, 4139, 6785, 4141, 5761, 4147, 6529, 4149, 5505, 4153, 4993, 4167, 7233, 4171, 6721, 4173, 5697, 4179, 6465, 4181, 5441, 4185, 4929, 4195, 6337, 4197, 5313, 4201, 4801, 4209, 4545, 4231, 7201, 4235, 6689, 4237, 5665, 4243, 6433, 4245, 5409, 4249, 4897, 4259, 6305, 4261, 5281, 4265, 4769, 4273, 4513, 4291, 6241, 4293, 5217, 4297, 4705, 4305, 4449, 4359, 7185, 4363, 6673, 4365, 5649, 4371, 6417, 4373, 5393, 4377, 4881, 4387, 6289, 4389, 5265, 4393, 4753, 4401, 4497, 4419, 6225, 4421, 5201, 4425, 4689, 4483, 6193, 4485, 5169, 4489, 4657, 4615, 7177, 4619, 6665, 4621, 5641, 4627, 6409, 4629, 5385, 4633, 4873, 4643, 6281, 4645, 5257, 4649, 4745, 4675, 6217, 4677, 5193, 4739, 6185, 4741, 5161, 4867, 6169, 4869, 5145, 5127, 7173, 5131, 6661, 5133, 5637, 5139, 6405, 5141, 5381, 5155, 6277, 5157, 5253, 5187, 6213, 5251, 6181, 5379, 6165, 5635, 6157, 6151, 7171, 6155, 6659, 6163, 6403, 6179, 6275, 6211, 5189, 4681, 4433, 4321, 3142, 2634, 2386, 2274, 1612, 1364, 1252, 856, 744, 496};
- ushort[] table2 = {3, 6144, 5, 5120, 6, 3072, 9, 4608, 10, 2560, 12, 1536, 17, 4352, 18, 2304, 20, 1280, 24, 768, 33, 4224, 34, 2176, 36, 1152, 40, 640, 48, 384, 65, 4160, 66, 2112, 68, 1088, 72, 576, 80, 320, 96, 192, 129, 4128, 130, 2080, 132, 1056, 136, 544, 144, 288, 257, 4112, 258, 2064, 260, 1040, 264, 528, 513, 4104, 514, 2056, 516, 1032, 1025, 4100, 1026, 2052, 2049, 4098, 4097, 2050, 1028, 520, 272, 160};
-
- // create tables to check decFcsChars
- table1Check = new Dictionary(2000);
- table2Check = new Dictionary(200);
- for (int k = 0; k < table1.Length; k++)
- table1Check.Add(table1[k], k);
- for (int k = 0; k < table2.Length; k++)
- table2Check.Add(table2[k], k);
- }
-
- protected override Result doDecode(BinaryBitmap image, IDictionary hints)
- {
- currentBitmap = image;
- return base.doDecode(image, hints);
- }
-
- public override void reset()
- {
- base.reset();
- currentBitmap = null;
- }
-
- private ushort binaryStringToDec(string binary)
- {
- ushort factor = (ushort) Math.Pow(2, binary.Length - 1);
- ushort result = 0;
-
- foreach (char bit in binary)
- {
- if (bit == '1')
- result += factor;
-
- factor /= 2;
- }
-
- return result;
- }
-
- private string invertedBinaryString(string binary)
- {
- string result = "";
-
- foreach (char bit in binary)
- {
- if (bit == '1')
- result += '0';
- else
- result += '1';
- }
-
- return result;
- }
-
- private bool getCodeWords(out int[] codeWord, string imb, IDictionary table1Check, IDictionary table2Check, int[][] barPos, char[][] barType)
- {
- // initialize the binaryFcsChars to 0 (has 13 bits)
- StringBuilder[] binaryFcsChars = new StringBuilder[10];
- for (int c = 0; c < 10; c++)
- binaryFcsChars[c] = new StringBuilder("0000000000000");
-
- // fill in the binaryFcsChars
- for (int pos = 0; pos < 65; pos++)
- {
- if (imb[pos] != 'D' && imb[pos] != 'A' && imb[pos] != 'F')
- continue;
-
- int offset = pos + 1;
- for (int a = 0; a < 10; a++) // int[][] barPos
- {
- int i;
- for (i = 0; i < 13; i++)
- {
- if (barPos[a][i] == offset)
- {
- if (barType[a][i] == imb[pos] || imb[pos] == 'F')
- binaryFcsChars[a][12 - i] = '1';
- }
- }
- }
- }
-
- // convert each binaryFcsChar into decimal format
- ushort[] decFcsChars = new ushort[10];
- for (int k = 0; k < 10; k++)
- decFcsChars[k] = binaryStringToDec(binaryFcsChars[k].ToString());
-
- // change decFcsChars according to whether FCS rules (whether it is the decFcsChars value is contained in one of the tables)
- for (int k = 0; k < decFcsChars.Length; k++)
- {
- if (!table1Check.ContainsKey(decFcsChars[k]) && !table2Check.ContainsKey(decFcsChars[k]))
- {
- binaryFcsChars[k].Replace(binaryFcsChars[k].ToString(), invertedBinaryString(binaryFcsChars[k].ToString()));
- decFcsChars[k] = binaryStringToDec(binaryFcsChars[k].ToString());
- }
- }
-
- // get codewords A-J
- codeWord = new int[10];
- for (int k = 0; k < 10; k++)
- {
- if (!table1Check.ContainsKey(decFcsChars[k]))
- {
- if (table2Check.ContainsKey(decFcsChars[k]))
- codeWord[k] = table2Check[decFcsChars[k]] + 1287;
- else
- return false; // invert the imb
- }
- else
- codeWord[k] = table1Check[decFcsChars[k]];
- }
-
- return true;
- }
-
- private string getTrackingNumber(string imb)
- {
-
- // get codewords A-J
- int[] codeWord;
- if (!getCodeWords(out codeWord, imb, table1Check, table2Check, barPos, barType))
- {
- // imb is upside down
- StringBuilder invertedImb = new StringBuilder(imb.Length);
- for (int k = imb.Length - 1; k >= 0; k--)
- {
- if (imb[k] == 'A')
- invertedImb.Append('D');
- else if (imb[k] == 'D')
- invertedImb.Append('A');
- else
- invertedImb.Append(imb[k]);
- }
-
- if (!getCodeWords(out codeWord, invertedImb.ToString(), table1Check, table2Check, barPos, barType))
- return null;
- }
-
-
- if (codeWord[A] > 658)
- codeWord[A] -= 659;
- codeWord[J] /= 2;
-
- // codewords to binaryData
- BigInteger binaryData = codeWord[A];
- for (int k = 1; k <= 8; k++)
- binaryData = (binaryData*1365) + codeWord[k];
- binaryData = (binaryData*636) + codeWord[J];
-
- // get tracking code
- int[] tCode = new int[20];
- for (int i = 19; i >= 2; i--)
- {
- tCode[i] = (int) (binaryData%10);
- binaryData /= 10;
- }
- tCode[1] = (int) (binaryData%5);
- binaryData /= 5;
- tCode[0] = (int) (binaryData%10);
- binaryData /= 10;
-
- // get routing code and imb number
- string imbTrackingNumber = "";
- foreach (int t in tCode)
- imbTrackingNumber += t.ToString();
- ulong rCode;
- if (binaryData > 1000000000)
- {
- rCode = (ulong) (binaryData - 1000000000 - 100000 - 1);
- imbTrackingNumber += rCode.ToString().PadLeft(11, '0');
- }
- else if (binaryData > 100000)
- {
- rCode = (ulong) (binaryData - 100000 - 1);
- imbTrackingNumber += rCode.ToString().PadLeft(9, '0');
- }
- else if (binaryData > 0)
- {
- rCode = (ulong) (binaryData - 1);
- imbTrackingNumber += rCode.ToString().PadLeft(5, '0');
- }
-
- return imbTrackingNumber;
- }
-
- private void fillLists(BitArray row, BitArray topRow, BitArray botRow, ref List listRow, ref List listTop, ref List listBot, int start, int stop) // list: 1=black 0=white
- {
- const bool isWhite = false;
- bool insideBar = false;
-
- for (int i = start; i <= stop; i++)
- {
- if (row[i] ^ isWhite) // if current pixel is black
- {
- if (!insideBar)
- {
- insideBar = true;
-
- listRow.Add(1);
-
- if (topRow[i] ^ isWhite)
- listTop.Add(1);
- else
- listTop.Add(0);
-
- if (botRow[i] ^ isWhite)
- listBot.Add(1);
- else
- listBot.Add(0);
- }
- }
- else // if current pixel is white
- {
- if (insideBar)
- {
- listRow.Add(0);
-
- if (topRow[i] ^ isWhite)
- listTop.Add(1);
- else
- listTop.Add(0);
-
- if (botRow[i] ^ isWhite)
- listBot.Add(1);
- else
- listBot.Add(0);
- }
-
- insideBar = false;
- }
- }
- }
-
- private int isIMB(BitArray row, ref int pixelStartOffset, ref int pixelStopOffset, ref int pixelBarLength)
- {
- int width = row.Size;
- int rowOffset = row.getNextSet(0);
- pixelStartOffset = rowOffset;
- int previousPixelOffset = pixelStartOffset;
- const bool isWhite = false;
-
- int countBars = 0;
- bool insideBar = false;
- int currBarLength = 0;
- int prevBarLength = 0;
-
- bool insideWS = false;
- int numWSBetween = 0;
- int currWSLength = 0;
- int prevWSLength = 0;
-
- for (int i = rowOffset; i < width; i++)
- {
- if (row[i] ^ isWhite) // if current pixel is black
- {
- insideWS = false;
-
- if (!insideBar)
- {
- if (countBars <= 1)
- {
- prevWSLength = currWSLength;
- }
- else
- {
- if (prevWSLength != currWSLength)
- {
- numWSBetween = 1;
- prevWSLength = currWSLength;
- countBars = 1;
- pixelStartOffset = previousPixelOffset;
- }
- }
- countBars++;
-
- insideBar = true;
- previousPixelOffset = i;
- }
-
- currWSLength = 0;
-
- currBarLength++;
- }
- else // if current pixel is white
- {
- insideBar = false;
-
- if (!insideWS)
- {
- numWSBetween++;
- insideWS = true;
-
- if (countBars <= 1)
- prevBarLength = currBarLength;
- else
- {
- if (prevBarLength != currBarLength)
- {
- countBars = 1;
- numWSBetween = 1;
- prevWSLength = 0;
- pixelStartOffset = previousPixelOffset;
- prevBarLength = currBarLength;
- }
- else
- {
- if (countBars == 65) // made it this far, so break
- {
- pixelStopOffset = i;
- //pixelBarLength = prevBarLength;
- break;
- }
- }
- }
- currBarLength = 0;
- }
-
-
- currWSLength++;
- }
-
-
- }
-
- pixelBarLength = prevBarLength;
- return (countBars);
- }
-
- private int getNumberBars(BitArray row, int start, int stop, int barWidth)
- {
- const bool isWhite = false;
- bool insideBar = false;
- int countBars = 0;
- int currentBarWidth = 0;
-
- for (int i = start; i <= stop; i++)
- {
- if (row[i] ^ isWhite) // if current pixel is black
- {
- if (!insideBar)
- {
- //countBars++;
- insideBar = true;
- }
- currentBarWidth++;
-
- if (i == stop)
- {
- if (currentBarWidth == barWidth)
- countBars++;
- }
- }
- else // if current pixel is white
- {
- if (insideBar)
- {
- if (currentBarWidth == barWidth)
- countBars++;
- }
- insideBar = false;
- currentBarWidth = 0;
- }
- }
-
- return countBars;
- }
-
- public override Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- if (currentBitmap == null)
- return null;
-
- int pixelStartOffset = 0;
- int pixelStopOffset = currentBitmap.Width - 1;
- int pixelBarLength = 0;
- int numBars = isIMB(row, ref pixelStartOffset, ref pixelStopOffset, ref pixelBarLength);
- if (numBars != NUM_BARS_IMB)
- return null;
-
- // create the two bitarrays to check top and bottom
- BitArray topRow = new BitArray(currentBitmap.Width);
- BitArray botRow = new BitArray(currentBitmap.Width);
- int rowNumberTop = rowNumber;
- int rowNumberBot = rowNumber;
-
- do
- {
- if (rowNumberTop <= 0)
- return null;
- rowNumberTop--;
- topRow = currentBitmap.getBlackRow(rowNumberTop, topRow);
- } while (getNumberBars(topRow, pixelStartOffset, pixelStopOffset, pixelBarLength) >= NUM_BARS_IMB);
- do
- {
- if (rowNumberBot >= (currentBitmap.Height - 1))
- return null;
- rowNumberBot++;
- botRow = currentBitmap.getBlackRow(rowNumberBot, botRow);
- } while (getNumberBars(botRow, pixelStartOffset, pixelStopOffset, pixelBarLength) >= NUM_BARS_IMB);
-
- List listRow = new List();
- List listTop = new List();
- List listBot = new List();
- fillLists(row, topRow, botRow, ref listRow, ref listTop, ref listBot, pixelStartOffset, pixelStopOffset);
-
- string symbolCode = "";
- for (int k = 0; k < listRow.Count; k++)
- {
- if (listRow[k] == 0)
- continue;
-
- if (listBot[k] == 1 && listTop[k] == 1)
- symbolCode += "F";
- else if (listBot[k] == 1)
- symbolCode += "D";
- else if (listTop[k] == 1)
- symbolCode += "A";
- else
- symbolCode += "T";
- }
-
- string trackingNumber = getTrackingNumber(symbolCode);
- if (trackingNumber == null)
- return null;
-
- var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)
- ? null
- : (ResultPointCallback) hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(pixelStartOffset, rowNumber));
- resultPointCallback(new ResultPoint(pixelStopOffset, rowNumber));
- }
-
- return new Result(
- trackingNumber,
- null,
- new[]
- {
- new ResultPoint(pixelStartOffset, rowNumber),
- new ResultPoint(pixelStopOffset, rowNumber)
- },
- BarcodeFormat.IMB);
- }
- }
-}
diff --git a/zxing.core/xx/maxicode/MaxiCodeReader.cs b/zxing.core/xx/maxicode/MaxiCodeReader.cs
deleted file mode 100644
index c9cfbe4..0000000
--- a/zxing.core/xx/maxicode/MaxiCodeReader.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2011 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.Collections.Generic;
-
-using ZXing.Common;
-using ZXing.Maxicode.Internal;
-
-namespace ZXing.Maxicode
-{
- ///
- /// This implementation can detect and decode a MaxiCode in an image.
- ///
- public sealed class MaxiCodeReader : Reader
- {
- private static readonly ResultPoint[] NO_POINTS = new ResultPoint[0];
- private const int MATRIX_WIDTH = 30;
- private const int MATRIX_HEIGHT = 33;
-
- private readonly Decoder decoder = new Decoder();
-
- ///
- /// Locates and decodes a MaxiCode in an image.
- ///
- /// a String representing the content encoded by the MaxiCode
- /// if a MaxiCode cannot be decoded
- ///
- public Result decode(BinaryBitmap image)
- {
- return decode(image, null);
- }
-
- ///
- /// Locates and decodes a MaxiCode within an image. This method also accepts
- /// hints, each possibly associated to some data, which may help the implementation decode.
- ///
- /// image of barcode to decode
- /// passed as a from
- /// to arbitrary data. The
- /// meaning of the data depends upon the hint type. The implementation may or may not do
- /// anything with these hints.
- ///
- /// String which the barcode encodes
- ///
- public Result decode(BinaryBitmap image, IDictionary hints)
- {
- DecoderResult decoderResult;
- if (hints != null && hints.ContainsKey(DecodeHintType.PURE_BARCODE))
- {
- BitMatrix bits = extractPureBits(image.BlackMatrix);
- if (bits == null)
- return null;
- decoderResult = decoder.decode(bits, hints);
- if (decoderResult == null)
- return null;
- }
- else
- {
- return null;
- }
-
- ResultPoint[] points = NO_POINTS;
- Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.MAXICODE);
-
- var ecLevel = decoderResult.ECLevel;
- if (ecLevel != null)
- {
- result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
- }
- return result;
- }
-
- public void reset()
- {
- // do nothing
- }
-
- ///
- /// This method detects a code in a "pure" image -- that is, pure monochrome image
- /// which contains only an unrotated, unskewed, image of a code, with some white border
- /// around it. This is a specialized method that works exceptionally fast in this special
- /// case.
- ///
- ///
- ///
- ///
- private static BitMatrix extractPureBits(BitMatrix image)
- {
-
- int[] enclosingRectangle = image.getEnclosingRectangle();
- if (enclosingRectangle == null)
- {
- return null;
- }
-
- int left = enclosingRectangle[0];
- int top = enclosingRectangle[1];
- int width = enclosingRectangle[2];
- int height = enclosingRectangle[3];
-
- // Now just read off the bits
- BitMatrix bits = new BitMatrix(MATRIX_WIDTH, MATRIX_HEIGHT);
- for (int y = 0; y < MATRIX_HEIGHT; y++)
- {
- int iy = top + (y * height + height / 2) / MATRIX_HEIGHT;
- for (int x = 0; x < MATRIX_WIDTH; x++)
- {
- int ix = left + (x * width + width / 2 + (y & 0x01) * width / 2) / MATRIX_WIDTH;
- if (image[ix, iy])
- {
- bits[x, y] = true;
- }
- }
- }
- return bits;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/maxicode/decoder/BitMatrixParser.cs b/zxing.core/xx/maxicode/decoder/BitMatrixParser.cs
deleted file mode 100644
index 9d7723c..0000000
--- a/zxing.core/xx/maxicode/decoder/BitMatrixParser.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2011 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using ZXing.Common;
-
-namespace ZXing.Maxicode.Internal
-{
- ///
- /// mike32767
- /// Manuel Kasten
- ///
- sealed class BitMatrixParser
- {
- private static readonly int[][] BITNR = new int[][] {
- new[] {121,120,127,126,133,132,139,138,145,144,151,150,157,156,163,162,169,168,175,174,181,180,187,186,193,192,199,198, -2, -2},
- new[] {123,122,129,128,135,134,141,140,147,146,153,152,159,158,165,164,171,170,177,176,183,182,189,188,195,194,201,200,816, -3},
- new[] {125,124,131,130,137,136,143,142,149,148,155,154,161,160,167,166,173,172,179,178,185,184,191,190,197,196,203,202,818,817},
- new[] {283,282,277,276,271,270,265,264,259,258,253,252,247,246,241,240,235,234,229,228,223,222,217,216,211,210,205,204,819, -3},
- new[] {285,284,279,278,273,272,267,266,261,260,255,254,249,248,243,242,237,236,231,230,225,224,219,218,213,212,207,206,821,820},
- new[] {287,286,281,280,275,274,269,268,263,262,257,256,251,250,245,244,239,238,233,232,227,226,221,220,215,214,209,208,822, -3},
- new[] {289,288,295,294,301,300,307,306,313,312,319,318,325,324,331,330,337,336,343,342,349,348,355,354,361,360,367,366,824,823},
- new[] {291,290,297,296,303,302,309,308,315,314,321,320,327,326,333,332,339,338,345,344,351,350,357,356,363,362,369,368,825, -3},
- new[] {293,292,299,298,305,304,311,310,317,316,323,322,329,328,335,334,341,340,347,346,353,352,359,358,365,364,371,370,827,826},
- new[] {409,408,403,402,397,396,391,390, 79, 78, -2, -2, 13, 12, 37, 36, 2, -1, 44, 43,109,108,385,384,379,378,373,372,828, -3},
- new[] {411,410,405,404,399,398,393,392, 81, 80, 40, -2, 15, 14, 39, 38, 3, -1, -1, 45,111,110,387,386,381,380,375,374,830,829},
- new[] {413,412,407,406,401,400,395,394, 83, 82, 41, -3, -3, -3, -3, -3, 5, 4, 47, 46,113,112,389,388,383,382,377,376,831, -3},
- new[] {415,414,421,420,427,426,103,102, 55, 54, 16, -3, -3, -3, -3, -3, -3, -3, 20, 19, 85, 84,433,432,439,438,445,444,833,832},
- new[] {417,416,423,422,429,428,105,104, 57, 56, -3, -3, -3, -3, -3, -3, -3, -3, 22, 21, 87, 86,435,434,441,440,447,446,834, -3},
- new[] {419,418,425,424,431,430,107,106, 59, 58, -3, -3, -3, -3, -3, -3, -3, -3, -3, 23, 89, 88,437,436,443,442,449,448,836,835},
- new[] {481,480,475,474,469,468, 48, -2, 30, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 0, 53, 52,463,462,457,456,451,450,837, -3},
- new[] {483,482,477,476,471,470, 49, -1, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -1,465,464,459,458,453,452,839,838},
- new[] {485,484,479,478,473,472, 51, 50, 31, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 1, -2, 42,467,466,461,460,455,454,840, -3},
- new[] {487,486,493,492,499,498, 97, 96, 61, 60, -3, -3, -3, -3, -3, -3, -3, -3, -3, 26, 91, 90,505,504,511,510,517,516,842,841},
- new[] {489,488,495,494,501,500, 99, 98, 63, 62, -3, -3, -3, -3, -3, -3, -3, -3, 28, 27, 93, 92,507,506,513,512,519,518,843, -3},
- new[] {491,490,497,496,503,502,101,100, 65, 64, 17, -3, -3, -3, -3, -3, -3, -3, 18, 29, 95, 94,509,508,515,514,521,520,845,844},
- new[] {559,558,553,552,547,546,541,540, 73, 72, 32, -3, -3, -3, -3, -3, -3, 10, 67, 66,115,114,535,534,529,528,523,522,846, -3},
- new[] {561,560,555,554,549,548,543,542, 75, 74, -2, -1, 7, 6, 35, 34, 11, -2, 69, 68,117,116,537,536,531,530,525,524,848,847},
- new[] {563,562,557,556,551,550,545,544, 77, 76, -2, 33, 9, 8, 25, 24, -1, -2, 71, 70,119,118,539,538,533,532,527,526,849, -3},
- new[] {565,564,571,570,577,576,583,582,589,588,595,594,601,600,607,606,613,612,619,618,625,624,631,630,637,636,643,642,851,850},
- new[] {567,566,573,572,579,578,585,584,591,590,597,596,603,602,609,608,615,614,621,620,627,626,633,632,639,638,645,644,852, -3},
- new[] {569,568,575,574,581,580,587,586,593,592,599,598,605,604,611,610,617,616,623,622,629,628,635,634,641,640,647,646,854,853},
- new[] {727,726,721,720,715,714,709,708,703,702,697,696,691,690,685,684,679,678,673,672,667,666,661,660,655,654,649,648,855, -3},
- new[] {729,728,723,722,717,716,711,710,705,704,699,698,693,692,687,686,681,680,675,674,669,668,663,662,657,656,651,650,857,856},
- new[] {731,730,725,724,719,718,713,712,707,706,701,700,695,694,689,688,683,682,677,676,671,670,665,664,659,658,653,652,858, -3},
- new[] {733,732,739,738,745,744,751,750,757,756,763,762,769,768,775,774,781,780,787,786,793,792,799,798,805,804,811,810,860,859},
- new[] {735,734,741,740,747,746,753,752,759,758,765,764,771,770,777,776,783,782,789,788,795,794,801,800,807,806,813,812,861, -3},
- new[] {737,736,743,742,749,748,755,754,761,760,767,766,773,772,779,778,785,784,791,790,797,796,803,802,809,808,815,814,863,862}
- };
-
- private readonly BitMatrix bitMatrix;
-
- ///
- /// to parse
- ///
- internal BitMatrixParser(BitMatrix bitMatrix)
- {
- this.bitMatrix = bitMatrix;
- }
-
- internal byte[] readCodewords()
- {
- byte[] result = new byte[144];
- int height = bitMatrix.Height;
- int width = bitMatrix.Width;
- for (int y = 0; y < height; y++)
- {
- int[] bitnrRow = BITNR[y];
- for (int x = 0; x < width; x++)
- {
- int bit = bitnrRow[x];
- if (bit >= 0 && bitMatrix[x, y])
- {
- result[bit / 6] |= (byte)(1 << (5 - (bit % 6)));
- }
- }
- }
- return result;
- }
- }
-}
diff --git a/zxing.core/xx/maxicode/decoder/DecodedBitStreamParser.cs b/zxing.core/xx/maxicode/decoder/DecodedBitStreamParser.cs
deleted file mode 100644
index c991898..0000000
--- a/zxing.core/xx/maxicode/decoder/DecodedBitStreamParser.cs
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright 2011 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Text;
-using ZXing.QrCode.Internal;
-using ZXing.Common;
-
-namespace ZXing.Maxicode.Internal
-{
- ///
- /// MaxiCodes can encode text or structured information as bits in one of several modes,
- /// with multiple character sets in one code. This class decodes the bits back into text.
- ///
- /// mike32767
- /// Manuel Kasten
- ///
- internal static class DecodedBitStreamParser
- {
- private const char SHIFTA = '\uFFF0';
- private const char SHIFTB = '\uFFF1';
- private const char SHIFTC = '\uFFF2';
- private const char SHIFTD = '\uFFF3';
- private const char SHIFTE = '\uFFF4';
- private const char TWOSHIFTA = '\uFFF5';
- private const char THREESHIFTA = '\uFFF6';
- private const char LATCHA = '\uFFF7';
- private const char LATCHB = '\uFFF8';
- private const char LOCK = '\uFFF9';
- private const char ECI = '\uFFFA';
- private const char NS = '\uFFFB';
- private const char PAD = '\uFFFC';
- private const char FS = '\u001C';
- private const char GS = '\u001D';
- private const char RS = '\u001E';
- private const string NINE_DIGITS = "000000000";
- private const string THREE_DIGITS = "000";
-
- private static String[] SETS = {
- "\nABCDEFGHIJKLMNOPQRSTUVWXYZ"+ECI+FS+GS+RS+NS+' '+PAD+"\"#$%&'()*+,-./0123456789:"+SHIFTB+SHIFTC+SHIFTD+SHIFTE+LATCHB,
- "`abcdefghijklmnopqrstuvwxyz"+ECI+FS+GS+RS+NS+'{'+PAD+"}~\u007F;<=>?[\\]^_ ,./:@!|"+PAD+TWOSHIFTA+THREESHIFTA+PAD+SHIFTA+SHIFTC+SHIFTD+SHIFTE+LATCHA,
- "\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D7\u00D8\u00D9\u00DA"+ECI+FS+GS+RS+"\u00DB\u00DC\u00DD\u00DE\u00DF\u00AA\u00AC\u00B1\u00B2\u00B3\u00B5\u00B9\u00BA\u00BC\u00BD\u00BE\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089"+LATCHA+' '+LOCK+SHIFTD+SHIFTE+LATCHB,
- "\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F7\u00F8\u00F9\u00FA"+ECI+FS+GS+RS+NS+"\u00FB\u00FC\u00FD\u00FE\u00FF\u00A1\u00A8\u00AB\u00AF\u00B0\u00B4\u00B7\u00B8\u00BB\u00BF\u008A\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093\u0094"+LATCHA+' '+SHIFTC+LOCK+SHIFTE+LATCHB,
- "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\n\u000B\u000C\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A"+ECI+PAD+PAD+'\u001B'+NS+FS+GS+RS+"\u001F\u009F\u00A0\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7\u00A9\u00AD\u00AE\u00B6\u0095\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E"+LATCHA+' '+SHIFTC+SHIFTD+LOCK+LATCHB,
- "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\n\u000B\u000C\r\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u0020\u0021\"\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u002D\u002E\u002F\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003A\u003B\u003C\u003D\u003E\u003F"
- };
-
- internal static DecoderResult decode(byte[] bytes, int mode)
- {
- StringBuilder result = new StringBuilder(144);
- switch (mode)
- {
- case 2:
- case 3:
- String postcode;
- if (mode == 2)
- {
- int pc = getPostCode2(bytes);
- var df = "0000000000".Substring(0, getPostCode2Length(bytes));
- postcode = pc.ToString(df);
- }
- else
- {
- postcode = getPostCode3(bytes);
- }
- String country = getCountry(bytes).ToString(THREE_DIGITS);
- String service = getServiceClass(bytes).ToString(THREE_DIGITS);
- result.Append(getMessage(bytes, 10, 84));
- if (result.ToString().StartsWith("[)>" + RS + "01" + GS))
- {
- result.Insert(9, postcode + GS + country + GS + service + GS);
- }
- else
- {
- result.Insert(0, postcode + GS + country + GS + service + GS);
- }
- break;
- case 4:
- result.Append(getMessage(bytes, 1, 93));
- break;
- case 5:
- result.Append(getMessage(bytes, 1, 77));
- break;
- }
-
- return new DecoderResult(bytes, result.ToString(), null, mode.ToString());
- }
-
- private static int getBit(int bit, byte[] bytes)
- {
- bit--;
- return (bytes[bit / 6] & (1 << (5 - (bit % 6)))) == 0 ? 0 : 1;
- }
-
- private static int getInt(byte[] bytes, byte[] x)
- {
- if (x.Length == 0)
- throw new ArgumentException("x");
-
- int val = 0;
- for (int i = 0; i < x.Length; i++)
- {
- val += getBit(x[i], bytes) << (x.Length - i - 1);
- }
- return val;
- }
-
- private static int getCountry(byte[] bytes)
- {
- return getInt(bytes, new byte[] { 53, 54, 43, 44, 45, 46, 47, 48, 37, 38 });
- }
-
- private static int getServiceClass(byte[] bytes)
- {
- return getInt(bytes, new byte[] { 55, 56, 57, 58, 59, 60, 49, 50, 51, 52 });
- }
-
- private static int getPostCode2Length(byte[] bytes)
- {
- return getInt(bytes, new byte[] { 39, 40, 41, 42, 31, 32 });
- }
-
- private static int getPostCode2(byte[] bytes)
- {
- return getInt(bytes, new byte[] {33, 34, 35, 36, 25, 26, 27, 28, 29, 30, 19,
- 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2});
- }
-
- private static String getPostCode3(byte[] bytes)
- {
- return new String(
- new char[]
- {
- SETS[0][getInt(bytes, new byte[] {39, 40, 41, 42, 31, 32})],
- SETS[0][getInt(bytes, new byte[] {33, 34, 35, 36, 25, 26})],
- SETS[0][getInt(bytes, new byte[] {27, 28, 29, 30, 19, 20})],
- SETS[0][getInt(bytes, new byte[] {21, 22, 23, 24, 13, 14})],
- SETS[0][getInt(bytes, new byte[] {15, 16, 17, 18, 7, 8})],
- SETS[0][getInt(bytes, new byte[] {9, 10, 11, 12, 1, 2})],
- }
- );
- }
-
- private static String getMessage(byte[] bytes, int start, int len)
- {
- StringBuilder sb = new StringBuilder();
- int shift = -1;
- int set = 0;
- int lastset = 0;
- for (int i = start; i < start + len; i++)
- {
- char c = SETS[set][bytes[i]];
- switch (c)
- {
- case LATCHA:
- set = 0;
- shift = -1;
- break;
- case LATCHB:
- set = 1;
- shift = -1;
- break;
- case SHIFTA:
- case SHIFTB:
- case SHIFTC:
- case SHIFTD:
- case SHIFTE:
- lastset = set;
- set = c - SHIFTA;
- shift = 1;
- break;
- case TWOSHIFTA:
- lastset = set;
- set = 0;
- shift = 2;
- break;
- case THREESHIFTA:
- lastset = set;
- set = 0;
- shift = 3;
- break;
- case NS:
- int nsval = (bytes[++i] << 24) + (bytes[++i] << 18) + (bytes[++i] << 12) + (bytes[++i] << 6) + bytes[++i];
- sb.Append(nsval.ToString(NINE_DIGITS));
- break;
- case LOCK:
- shift = -1;
- break;
- default:
- sb.Append(c);
- break;
- }
- if (shift-- == 0)
- {
- set = lastset;
- }
- }
- while (sb.Length > 0 && sb[sb.Length - 1] == PAD)
- {
- sb.Length = sb.Length - 1;
- }
- return sb.ToString();
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/maxicode/decoder/Decoder.cs b/zxing.core/xx/maxicode/decoder/Decoder.cs
deleted file mode 100644
index 9d02680..0000000
--- a/zxing.core/xx/maxicode/decoder/Decoder.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2011 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ZXing.Common;
-using ZXing.Common.ReedSolomon;
-
-namespace ZXing.Maxicode.Internal
-{
- ///
- /// The main class which implements MaxiCode decoding -- as opposed to locating and extracting
- /// the MaxiCode from an image.
- ///
- /// Manuel Kasten
- ///
- public sealed class Decoder
- {
- private const int ALL = 0;
- private const int EVEN = 1;
- private const int ODD = 2;
-
- private readonly ReedSolomonDecoder rsDecoder;
-
- public Decoder()
- {
- rsDecoder = new ReedSolomonDecoder(GenericGF.MAXICODE_FIELD_64);
- }
-
- public DecoderResult decode(BitMatrix bits)
- {
- return decode(bits, null);
- }
-
- public DecoderResult decode(BitMatrix bits,
- IDictionary hints)
- {
- BitMatrixParser parser = new BitMatrixParser(bits);
- byte[] codewords = parser.readCodewords();
-
- if (!correctErrors(codewords, 0, 10, 10, ALL))
- return null;
-
- int mode = codewords[0] & 0x0F;
- byte[] datawords;
- switch (mode)
- {
- case 2:
- case 3:
- case 4:
- if (!correctErrors(codewords, 20, 84, 40, EVEN))
- return null;
- if (!correctErrors(codewords, 20, 84, 40, ODD))
- return null;
- datawords = new byte[94];
- break;
- case 5:
- if (!correctErrors(codewords, 20, 68, 56, EVEN))
- return null;
- if (!correctErrors(codewords, 20, 68, 56, ODD))
- return null;
- datawords = new byte[78];
- break;
- default:
- return null;
- }
-
- Array.Copy(codewords, 0, datawords, 0, 10);
- Array.Copy(codewords, 20, datawords, 10, datawords.Length - 10);
-
- return DecodedBitStreamParser.decode(datawords, mode);
- }
-
- private bool correctErrors(byte[] codewordBytes,
- int start,
- int dataCodewords,
- int ecCodewords,
- int mode)
- {
- int codewords = dataCodewords + ecCodewords;
-
- // in EVEN or ODD mode only half the codewords
- int divisor = mode == ALL ? 1 : 2;
-
- // First read into an array of ints
- int[] codewordsInts = new int[codewords / divisor];
- for (int i = 0; i < codewords; i++)
- {
- if ((mode == ALL) || (i % 2 == (mode - 1)))
- {
- codewordsInts[i / divisor] = codewordBytes[i + start] & 0xFF;
- }
- }
-
- if (!rsDecoder.decode(codewordsInts, ecCodewords / divisor))
- return false;
-
- // Copy back into array of bytes -- only need to worry about the bytes that were data
- // We don't care about errors in the error-correction codewords
- for (int i = 0; i < dataCodewords; i++)
- {
- if ((mode == ALL) || (i % 2 == (mode - 1)))
- {
- codewordBytes[i + start] = (byte)codewordsInts[i / divisor];
- }
- }
-
- return true;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/multi/ByQuadrantReader.cs b/zxing.core/xx/multi/ByQuadrantReader.cs
deleted file mode 100644
index fdf3215..0000000
--- a/zxing.core/xx/multi/ByQuadrantReader.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
-* Copyright 2009 ZXing authors
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-using System.Collections.Generic;
-
-namespace ZXing.Multi
-{
- ///
- /// This class attempts to decode a barcode from an image, not by scanning the whole image,
- /// but by scanning subsets of the image. This is important when there may be multiple barcodes in
- /// an image, and detecting a barcode may find parts of multiple barcode and fail to decode
- /// (e.g. QR Codes). Instead this scans the four quadrants of the image -- and also the center
- /// 'quadrant' to cover the case where a barcode is found in the center.
- ///
- ///
- public sealed class ByQuadrantReader : Reader
- {
- private readonly Reader @delegate;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The @delegate.
- public ByQuadrantReader(Reader @delegate)
- {
- this.@delegate = @delegate;
- }
-
- ///
- /// Locates and decodes a barcode in some format within an image.
- ///
- /// image of barcode to decode
- ///
- /// String which the barcode encodes
- ///
- public Result decode(BinaryBitmap image)
- {
- return decode(image, null);
- }
-
- ///
- /// Locates and decodes a barcode in some format within an image. This method also accepts
- /// hints, each possibly associated to some data, which may help the implementation decode.
- ///
- /// image of barcode to decode
- /// passed as a from
- /// to arbitrary data. The
- /// meaning of the data depends upon the hint type. The implementation may or may not do
- /// anything with these hints.
- ///
- /// String which the barcode encodes
- ///
- public Result decode(BinaryBitmap image, IDictionary hints)
- {
- int width = image.Width;
- int height = image.Height;
- int halfWidth = width/2;
- int halfHeight = height/2;
-
- // No need to call makeAbsolute as results will be relative to original top left here
- var result = @delegate.decode(image.crop(0, 0, halfWidth, halfHeight), hints);
- if (result != null)
- return result;
-
- result = @delegate.decode(image.crop(halfWidth, 0, halfWidth, halfHeight), hints);
- if (result != null)
- {
- makeAbsolute(result.ResultPoints, halfWidth, 0);
- return result;
- }
-
- result = @delegate.decode(image.crop(0, halfHeight, halfWidth, halfHeight), hints);
- if (result != null)
- {
- makeAbsolute(result.ResultPoints, 0, halfHeight);
- return result;
- }
-
- result = @delegate.decode(image.crop(halfWidth, halfHeight, halfWidth, halfHeight), hints);
- if (result != null)
- {
- makeAbsolute(result.ResultPoints, halfWidth, halfHeight);
- return result;
- }
-
- int quarterWidth = halfWidth/2;
- int quarterHeight = halfHeight/2;
- var center = image.crop(quarterWidth, quarterHeight, halfWidth, halfHeight);
- result = @delegate.decode(center, hints);
- makeAbsolute(result.ResultPoints, quarterWidth, quarterHeight);
- return result;
- }
-
- ///
- /// Resets any internal state the implementation has after a decode, to prepare it
- /// for reuse.
- ///
- public void reset()
- {
- @delegate.reset();
- }
-
- private static void makeAbsolute(ResultPoint[] points, int leftOffset, int topOffset)
- {
- if (points != null)
- {
- for (int i = 0; i < points.Length; i++)
- {
- ResultPoint relative = points[i];
- points[i] = new ResultPoint(relative.X + leftOffset, relative.Y + topOffset);
- }
- }
- }
- }
-}
diff --git a/zxing.core/xx/multi/GenericMultipleBarcodeReader.cs b/zxing.core/xx/multi/GenericMultipleBarcodeReader.cs
deleted file mode 100644
index 0013ab4..0000000
--- a/zxing.core/xx/multi/GenericMultipleBarcodeReader.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
-* Copyright 2009 ZXing authors
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-using System.Collections.Generic;
-
-namespace ZXing.Multi
-{
- ///
- /// Attempts to locate multiple barcodes in an image by repeatedly decoding portion of the image.
- /// After one barcode is found, the areas left, above, right and below the barcode's
- /// {@link com.google.zxing.ResultPoint}s are scanned, recursively.
- /// A caller may want to also employ {@link ByQuadrantReader} when attempting to find multiple
- /// 2D barcodes, like QR Codes, in an image, where the presence of multiple barcodes might prevent
- /// detecting any one of them.
- /// That is, instead of passing a {@link Reader} a caller might pass
- /// new ByQuadrantReader(reader).
- /// Sean Owen
- ///
- public sealed class GenericMultipleBarcodeReader : MultipleBarcodeReader, Reader
- {
- private const int MIN_DIMENSION_TO_RECUR = 30;
- private const int MAX_DEPTH = 4;
-
- private readonly Reader _delegate;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The @delegate.
- public GenericMultipleBarcodeReader(Reader @delegate)
- {
- this._delegate = @delegate;
- }
-
- ///
- /// Decodes the multiple.
- ///
- /// The image.
- ///
- public Result[] decodeMultiple(BinaryBitmap image)
- {
- return decodeMultiple(image, null);
- }
-
- ///
- /// Decodes the multiple.
- ///
- /// The image.
- /// The hints.
- ///
- public Result[] decodeMultiple(BinaryBitmap image, IDictionary hints)
- {
- var results = new List();
- doDecodeMultiple(image, hints, results, 0, 0, 0);
- if ((results.Count == 0))
- {
- return null;
- }
- int numResults = results.Count;
- Result[] resultArray = new Result[numResults];
- for (int i = 0; i < numResults; i++)
- {
- resultArray[i] = (Result)results[i];
- }
- return resultArray;
- }
-
- private void doDecodeMultiple(BinaryBitmap image, IDictionary hints, IList results, int xOffset, int yOffset, int currentDepth)
- {
- if (currentDepth > MAX_DEPTH)
- {
- return;
- }
-
- Result result = _delegate.decode(image, hints);
- if (result == null)
- return;
-
- bool alreadyFound = false;
- for (int i = 0; i < results.Count; i++)
- {
- Result existingResult = (Result)results[i];
- if (existingResult.Text.Equals(result.Text))
- {
- alreadyFound = true;
- break;
- }
- }
- if (!alreadyFound)
- {
- results.Add(translateResultPoints(result, xOffset, yOffset));
- }
-
- ResultPoint[] resultPoints = result.ResultPoints;
- if (resultPoints == null || resultPoints.Length == 0)
- {
- return;
- }
- int width = image.Width;
- int height = image.Height;
- float minX = width;
- float minY = height;
- float maxX = 0.0f;
- float maxY = 0.0f;
- for (int i = 0; i < resultPoints.Length; i++)
- {
- ResultPoint point = resultPoints[i];
- if (point == null)
- {
- continue;
- }
- float x = point.X;
- float y = point.Y;
- if (x < minX)
- {
- minX = x;
- }
- if (y < minY)
- {
- minY = y;
- }
- if (x > maxX)
- {
- maxX = x;
- }
- if (y > maxY)
- {
- maxY = y;
- }
- }
-
- // Decode left of barcode
- if (minX > MIN_DIMENSION_TO_RECUR)
- {
- doDecodeMultiple(image.crop(0, 0, (int)minX, height), hints, results, xOffset, yOffset, currentDepth + 1);
- }
- // Decode above barcode
- if (minY > MIN_DIMENSION_TO_RECUR)
- {
- doDecodeMultiple(image.crop(0, 0, width, (int)minY), hints, results, xOffset, yOffset, currentDepth + 1);
- }
- // Decode right of barcode
- if (maxX < width - MIN_DIMENSION_TO_RECUR)
- {
- doDecodeMultiple(image.crop((int)maxX, 0, width - (int)maxX, height), hints, results, xOffset + (int)maxX, yOffset, currentDepth + 1);
- }
- // Decode below barcode
- if (maxY < height - MIN_DIMENSION_TO_RECUR)
- {
- doDecodeMultiple(image.crop(0, (int)maxY, width, height - (int)maxY), hints, results, xOffset, yOffset + (int)maxY, currentDepth + 1);
- }
- }
-
- private static Result translateResultPoints(Result result, int xOffset, int yOffset)
- {
- var oldResultPoints = result.ResultPoints;
- var newResultPoints = new ResultPoint[oldResultPoints.Length];
- for (int i = 0; i < oldResultPoints.Length; i++)
- {
- var oldPoint = oldResultPoints[i];
- if (oldPoint != null)
- {
- newResultPoints[i] = new ResultPoint(oldPoint.X + xOffset, oldPoint.Y + yOffset);
- }
- }
- var newResult = new Result(result.Text, result.RawBytes, newResultPoints, result.BarcodeFormat);
- newResult.putAllMetadata(result.ResultMetadata);
- return newResult;
- }
-
- ///
- /// Locates and decodes a barcode in some format within an image.
- ///
- /// image of barcode to decode
- ///
- /// String which the barcode encodes
- ///
- public Result decode(BinaryBitmap image)
- {
- return _delegate.decode(image);
- }
-
- ///
- /// Locates and decodes a barcode in some format within an image. This method also accepts
- /// hints, each possibly associated to some data, which may help the implementation decode.
- ///
- /// image of barcode to decode
- /// passed as a from
- /// to arbitrary data. The
- /// meaning of the data depends upon the hint type. The implementation may or may not do
- /// anything with these hints.
- ///
- /// String which the barcode encodes
- ///
- public Result decode(BinaryBitmap image, IDictionary hints)
- {
- return _delegate.decode(image, hints);
- }
-
- ///
- /// Resets any internal state the implementation has after a decode, to prepare it
- /// for reuse.
- ///
- public void reset()
- {
- _delegate.reset();
- }
- }
-}
diff --git a/zxing.core/xx/multi/MultipleBarcodeReader.cs b/zxing.core/xx/multi/MultipleBarcodeReader.cs
deleted file mode 100644
index 65fac63..0000000
--- a/zxing.core/xx/multi/MultipleBarcodeReader.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-* Copyright 2009 ZXing authors
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-using System.Collections.Generic;
-
-namespace ZXing.Multi
-{
- ///
- /// Implementation of this interface attempt to read several barcodes from one image.
- /// Sean Owen
- ///
- ///
- public interface MultipleBarcodeReader
- {
- ///
- /// Decodes the multiple.
- ///
- /// The image.
- ///
- Result[] decodeMultiple(BinaryBitmap image);
-
- ///
- /// Decodes the multiple.
- ///
- /// The image.
- /// The hints.
- ///
- Result[] decodeMultiple(BinaryBitmap image, IDictionary hints);
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/multi/qrcode/QRCodeMultiReader.cs b/zxing.core/xx/multi/qrcode/QRCodeMultiReader.cs
deleted file mode 100644
index 92f53b7..0000000
--- a/zxing.core/xx/multi/qrcode/QRCodeMultiReader.cs
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-
-using ZXing.Common;
-using ZXing.Multi.QrCode.Internal;
-using ZXing.QrCode;
-using ZXing.QrCode.Internal;
-
-namespace ZXing.Multi.QrCode
-{
- ///
- /// This implementation can detect and decode multiple QR Codes in an image.
- ///
- public sealed class QRCodeMultiReader : QRCodeReader, MultipleBarcodeReader
- {
- private static readonly ResultPoint[] NO_POINTS = new ResultPoint[0];
-
- ///
- /// Decodes the multiple.
- ///
- /// The image.
- ///
- public Result[] decodeMultiple(BinaryBitmap image)
- {
- return decodeMultiple(image, null);
- }
-
- ///
- /// Decodes the multiple.
- ///
- /// The image.
- /// The hints.
- ///
- public Result[] decodeMultiple(BinaryBitmap image, IDictionary hints)
- {
- var results = new List();
- var detectorResults = new MultiDetector(image.BlackMatrix).detectMulti(hints);
- foreach (DetectorResult detectorResult in detectorResults)
- {
- var decoderResult = getDecoder().decode(detectorResult.Bits, hints);
- if (decoderResult == null)
- continue;
-
- var points = detectorResult.Points;
- // If the code was mirrored: swap the bottom-left and the top-right points.
- var data = decoderResult.Other as QRCodeDecoderMetaData;
- if (data != null)
- {
- data.applyMirroredCorrection(points);
- }
- var result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);
- var byteSegments = decoderResult.ByteSegments;
- if (byteSegments != null)
- {
- result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
- }
- var ecLevel = decoderResult.ECLevel;
- if (ecLevel != null)
- {
- result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
- }
- if (decoderResult.StructuredAppend)
- {
- result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.StructuredAppendSequenceNumber);
- result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.StructuredAppendParity);
- }
- results.Add(result);
- }
- if (results.Count == 0)
- {
- return null;
- }
- results = ProcessStructuredAppend(results);
- return results.ToArray();
- }
-
- private List ProcessStructuredAppend(List results)
- {
- bool hasSA = false;
- // first, check, if there is at least on SA result in the list
- foreach (var result in results)
- {
- if (result.ResultMetadata.ContainsKey(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE))
- {
- hasSA = true;
- break;
- }
- }
- if (!hasSA)
- {
- return results;
- }
- // it is, second, split the lists and built a new result list
- var newResults = new List();
- var saResults = new List();
- foreach (var result in results)
- {
- newResults.Add(result);
- if (result.ResultMetadata.ContainsKey(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE))
- {
- saResults.Add(result);
- }
- }
- // sort and concatenate the SA list items
- saResults.Sort(SaSequenceSort);
- var concatedText = String.Empty;
- var rawBytesLen = 0;
- int byteSegmentLength = 0;
- foreach (var saResult in saResults)
- {
- concatedText += saResult.Text;
- rawBytesLen += saResult.RawBytes.Length;
- if (saResult.ResultMetadata.ContainsKey(ResultMetadataType.BYTE_SEGMENTS))
- {
- foreach (var segment in (IEnumerable) saResult.ResultMetadata[ResultMetadataType.BYTE_SEGMENTS])
- {
- byteSegmentLength += segment.Length;
- }
- }
- }
- var newRawBytes = new byte[rawBytesLen];
- byte[] newByteSegment = new byte[byteSegmentLength];
- int newRawBytesIndex = 0;
- int byteSegmentIndex = 0;
- foreach (var saResult in saResults)
- {
- Array.Copy(saResult.RawBytes, 0, newRawBytes, newRawBytesIndex, saResult.RawBytes.Length);
- newRawBytesIndex += saResult.RawBytes.Length;
- if (saResult.ResultMetadata.ContainsKey(ResultMetadataType.BYTE_SEGMENTS))
- {
- foreach (var segment in (IEnumerable) saResult.ResultMetadata[ResultMetadataType.BYTE_SEGMENTS])
- {
- Array.Copy(segment, 0, newByteSegment, byteSegmentIndex, segment.Length);
- byteSegmentIndex += segment.Length;
- }
- }
- }
- Result newResult = new Result(concatedText, newRawBytes, NO_POINTS, BarcodeFormat.QR_CODE);
- if (byteSegmentLength > 0)
- {
- var byteSegmentList = new List();
- byteSegmentList.Add(newByteSegment);
- newResult.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegmentList);
- }
- newResults.Add(newResult);
- return newResults;
- }
-
- private int SaSequenceSort(Result a, Result b)
- {
- var aNumber = (int)(a.ResultMetadata[ResultMetadataType.STRUCTURED_APPEND_SEQUENCE]);
- var bNumber = (int)(b.ResultMetadata[ResultMetadataType.STRUCTURED_APPEND_SEQUENCE]);
- return aNumber - bNumber;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/multi/qrcode/detector/MultiDetector.cs b/zxing.core/xx/multi/qrcode/detector/MultiDetector.cs
deleted file mode 100644
index 7c8142d..0000000
--- a/zxing.core/xx/multi/qrcode/detector/MultiDetector.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.Collections.Generic;
-using ZXing.Common;
-using ZXing.QrCode.Internal;
-
-namespace ZXing.Multi.QrCode.Internal
-{
- ///
- /// Encapsulates logic that can detect one or more QR Codes in an image, even if the QR Code
- /// is rotated or skewed, or partially obscured.
- ///
- /// Sean Owen
- /// Hannes Erven
- ///
- public sealed class MultiDetector : Detector
- {
- private static readonly DetectorResult[] EMPTY_DETECTOR_RESULTS = new DetectorResult[0];
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The image.
- public MultiDetector(BitMatrix image)
- : base(image)
- {
- }
-
- ///
- /// Detects the multi.
- ///
- /// The hints.
- ///
- public DetectorResult[] detectMulti(IDictionary hints)
- {
- var image = Image;
- var resultPointCallback =
- hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK) ? null : (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
- var finder = new MultiFinderPatternFinder(image, resultPointCallback);
- var infos = finder.findMulti(hints);
-
- if (infos.Length == 0)
- {
- return EMPTY_DETECTOR_RESULTS;
- }
-
- var result = new List();
- foreach (FinderPatternInfo info in infos)
- {
- var oneResult = processFinderPatternInfo(info);
- if (oneResult != null)
- result.Add(oneResult);
- }
- if (result.Count == 0)
- {
- return EMPTY_DETECTOR_RESULTS;
- }
- else
- {
- return result.ToArray();
- }
- }
- }
-}
diff --git a/zxing.core/xx/multi/qrcode/detector/MultiFinderPatternFinder.cs b/zxing.core/xx/multi/qrcode/detector/MultiFinderPatternFinder.cs
deleted file mode 100644
index 542d0ec..0000000
--- a/zxing.core/xx/multi/qrcode/detector/MultiFinderPatternFinder.cs
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ZXing.Common;
-using ZXing.QrCode.Internal;
-
-namespace ZXing.Multi.QrCode.Internal
-{
- ///
- /// This class attempts to find finder patterns in a QR Code. Finder patterns are the square
- /// markers at three corners of a QR Code.
- ///
- /// This class is thread-safe but not reentrant. Each thread must allocate its own object.
- ///
- ///
In contrast to , this class will return an array of all possible
- /// QR code locations in the image.
- ///
- /// Use the TRY_HARDER hint to ask for a more thorough detection.
- ///
- /// Sean Owen
- /// Hannes Erven
- ///
- sealed class MultiFinderPatternFinder : FinderPatternFinder
- {
-
- private static FinderPatternInfo[] EMPTY_RESULT_ARRAY = new FinderPatternInfo[0];
-
- // TODO MIN_MODULE_COUNT and MAX_MODULE_COUNT would be great hints to ask the user for
- // since it limits the number of regions to decode
-
- // max. legal count of modules per QR code edge (177)
- private static float MAX_MODULE_COUNT_PER_EDGE = 180;
- // min. legal count per modules per QR code edge (11)
- private static float MIN_MODULE_COUNT_PER_EDGE = 9;
-
- ///
- /// More or less arbitrary cutoff point for determining if two finder patterns might belong
- /// to the same code if they differ less than DIFF_MODSIZE_CUTOFF_PERCENT percent in their
- /// estimated modules sizes.
- ///
- private static float DIFF_MODSIZE_CUTOFF_PERCENT = 0.05f;
-
- ///
- /// More or less arbitrary cutoff point for determining if two finder patterns might belong
- /// to the same code if they differ less than DIFF_MODSIZE_CUTOFF pixels/module in their
- /// estimated modules sizes.
- ///
- private const float DIFF_MODSIZE_CUTOFF = 0.5f;
-
-
- ///
- /// A comparator that orders FinderPatterns by their estimated module size.
- ///
- private sealed class ModuleSizeComparator : IComparer
- {
- public int Compare(FinderPattern center1, FinderPattern center2)
- {
- float value = center2.EstimatedModuleSize - center1.EstimatedModuleSize;
- return value < 0.0 ? -1 : value > 0.0 ? 1 : 0;
- }
- }
-
- ///
- /// Creates a finder that will search the image for three finder patterns.
- ///
- /// image to search
- ///
- internal MultiFinderPatternFinder(BitMatrix image)
- : base(image)
- {
- }
-
- internal MultiFinderPatternFinder(BitMatrix image, ResultPointCallback resultPointCallback)
- : base(image, resultPointCallback)
- {
- }
-
- ///
- ///
- /// the 3 best s from our list of candidates. The "best" are
- /// those that have been detected at least CENTER_QUORUM times, and whose module
- /// size differs from the average among those patterns the least
- ///
- private FinderPattern[][] selectMutipleBestPatterns()
- {
- List possibleCenters = PossibleCenters;
- int size = possibleCenters.Count;
-
- if (size < 3)
- {
- // Couldn't find enough finder patterns
- return null;
- }
-
- /*
- * Begin HE modifications to safely detect multiple codes of equal size
- */
- if (size == 3)
- {
- return new FinderPattern[][]
- {
- new FinderPattern[]
- {
- possibleCenters[0],
- possibleCenters[1],
- possibleCenters[2]
- }
- };
- }
-
- // Sort by estimated module size to speed up the upcoming checks
- possibleCenters.Sort(new ModuleSizeComparator());
-
- /*
- * Now lets start: build a list of tuples of three finder locations that
- * - feature similar module sizes
- * - are placed in a distance so the estimated module count is within the QR specification
- * - have similar distance between upper left/right and left top/bottom finder patterns
- * - form a triangle with 90° angle (checked by comparing top right/bottom left distance
- * with pythagoras)
- *
- * Note: we allow each point to be used for more than one code region: this might seem
- * counterintuitive at first, but the performance penalty is not that big. At this point,
- * we cannot make a good quality decision whether the three finders actually represent
- * a QR code, or are just by chance layouted so it looks like there might be a QR code there.
- * So, if the layout seems right, lets have the decoder try to decode.
- */
-
- List results = new List(); // holder for the results
-
- for (int i1 = 0; i1 < (size - 2); i1++)
- {
- FinderPattern p1 = possibleCenters[i1];
- if (p1 == null)
- {
- continue;
- }
-
- for (int i2 = i1 + 1; i2 < (size - 1); i2++)
- {
- FinderPattern p2 = possibleCenters[i2];
- if (p2 == null)
- {
- continue;
- }
-
- // Compare the expected module sizes; if they are really off, skip
- float vModSize12 = (p1.EstimatedModuleSize - p2.EstimatedModuleSize) /
- Math.Min(p1.EstimatedModuleSize, p2.EstimatedModuleSize);
- float vModSize12A = Math.Abs(p1.EstimatedModuleSize - p2.EstimatedModuleSize);
- if (vModSize12A > DIFF_MODSIZE_CUTOFF && vModSize12 >= DIFF_MODSIZE_CUTOFF_PERCENT)
- {
- // break, since elements are ordered by the module size deviation there cannot be
- // any more interesting elements for the given p1.
- break;
- }
-
- for (int i3 = i2 + 1; i3 < size; i3++)
- {
- FinderPattern p3 = possibleCenters[i3];
- if (p3 == null)
- {
- continue;
- }
-
- // Compare the expected module sizes; if they are really off, skip
- float vModSize23 = (p2.EstimatedModuleSize - p3.EstimatedModuleSize) /
- Math.Min(p2.EstimatedModuleSize, p3.EstimatedModuleSize);
- float vModSize23A = Math.Abs(p2.EstimatedModuleSize - p3.EstimatedModuleSize);
- if (vModSize23A > DIFF_MODSIZE_CUTOFF && vModSize23 >= DIFF_MODSIZE_CUTOFF_PERCENT)
- {
- // break, since elements are ordered by the module size deviation there cannot be
- // any more interesting elements for the given p1.
- break;
- }
-
- FinderPattern[] test = { p1, p2, p3 };
- ResultPoint.orderBestPatterns(test);
-
- // Calculate the distances: a = topleft-bottomleft, b=topleft-topright, c = diagonal
- FinderPatternInfo info = new FinderPatternInfo(test);
- float dA = ResultPoint.distance(info.TopLeft, info.BottomLeft);
- float dC = ResultPoint.distance(info.TopRight, info.BottomLeft);
- float dB = ResultPoint.distance(info.TopLeft, info.TopRight);
-
- // Check the sizes
- float estimatedModuleCount = (dA + dB) / (p1.EstimatedModuleSize * 2.0f);
- if (estimatedModuleCount > MAX_MODULE_COUNT_PER_EDGE ||
- estimatedModuleCount < MIN_MODULE_COUNT_PER_EDGE)
- {
- continue;
- }
-
- // Calculate the difference of the edge lengths in percent
- float vABBC = Math.Abs((dA - dB) / Math.Min(dA, dB));
- if (vABBC >= 0.1f)
- {
- continue;
- }
-
- // Calculate the diagonal length by assuming a 90° angle at topleft
- float dCpy = (float)Math.Sqrt(dA * dA + dB * dB);
- // Compare to the real distance in %
- float vPyC = Math.Abs((dC - dCpy) / Math.Min(dC, dCpy));
-
- if (vPyC >= 0.1f)
- {
- continue;
- }
-
- // All tests passed!
- results.Add(test);
- } // end iterate p3
- } // end iterate p2
- } // end iterate p1
-
- if (results.Count != 0)
- {
- return results.ToArray();
- }
-
- // Nothing found!
- return null;
- }
-
- public FinderPatternInfo[] findMulti(IDictionary hints)
- {
- bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
- bool pureBarcode = hints != null && hints.ContainsKey(DecodeHintType.PURE_BARCODE);
- BitMatrix image = Image;
- int maxI = image.Height;
- int maxJ = image.Width;
- // We are looking for black/white/black/white/black modules in
- // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far
-
- // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
- // image, and then account for the center being 3 modules in size. This gives the smallest
- // number of pixels the center could be, so skip this often. When trying harder, look for all
- // QR versions regardless of how dense they are.
- int iSkip = (int)(maxI / (MAX_MODULES * 4.0f) * 3);
- if (iSkip < MIN_SKIP || tryHarder)
- {
- iSkip = MIN_SKIP;
- }
-
- int[] stateCount = new int[5];
- for (int i = iSkip - 1; i < maxI; i += iSkip)
- {
- // Get a row of black/white values
- stateCount[0] = 0;
- stateCount[1] = 0;
- stateCount[2] = 0;
- stateCount[3] = 0;
- stateCount[4] = 0;
- int currentState = 0;
- for (int j = 0; j < maxJ; j++)
- {
- if (image[j, i])
- {
- // Black pixel
- if ((currentState & 1) == 1)
- { // Counting white pixels
- currentState++;
- }
- stateCount[currentState]++;
- }
- else
- { // White pixel
- if ((currentState & 1) == 0)
- { // Counting black pixels
- if (currentState == 4)
- { // A winner?
- if (foundPatternCross(stateCount) && handlePossibleCenter(stateCount, i, j, pureBarcode))
- { // Yes
- // Clear state to start looking again
- currentState = 0;
- stateCount[0] = 0;
- stateCount[1] = 0;
- stateCount[2] = 0;
- stateCount[3] = 0;
- stateCount[4] = 0;
- }
- else
- { // No, shift counts back by two
- stateCount[0] = stateCount[2];
- stateCount[1] = stateCount[3];
- stateCount[2] = stateCount[4];
- stateCount[3] = 1;
- stateCount[4] = 0;
- currentState = 3;
- }
- }
- else
- {
- stateCount[++currentState]++;
- }
- }
- else
- { // Counting white pixels
- stateCount[currentState]++;
- }
- }
- } // for j=...
-
- if (foundPatternCross(stateCount))
- {
- handlePossibleCenter(stateCount, i, maxJ, pureBarcode);
- } // end if foundPatternCross
- } // for i=iSkip-1 ...
- FinderPattern[][] patternInfo = selectMutipleBestPatterns();
- if (patternInfo == null)
- return EMPTY_RESULT_ARRAY;
- List result = new List();
- foreach (FinderPattern[] pattern in patternInfo)
- {
- ResultPoint.orderBestPatterns(pattern);
- result.Add(new FinderPatternInfo(pattern));
- }
-
- if (result.Count == 0)
- {
- return EMPTY_RESULT_ARRAY;
- }
- else
- {
- return result.ToArray();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/CodaBarReader.cs b/zxing.core/xx/oned/CodaBarReader.cs
deleted file mode 100644
index a0b5db5..0000000
--- a/zxing.core/xx/oned/CodaBarReader.cs
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Decodes Codabar barcodes.
- ///
- /// Bas Vijfwinkel
- ///
- public sealed class CodaBarReader : OneDReader
- {
- // These values are critical for determining how permissive the decoding
- // will be. All stripe sizes must be within the window these define, as
- // compared to the average stripe size.
- private static readonly int MAX_ACCEPTABLE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 2.0f);
- private static readonly int PADDING = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 1.5f);
-
- private const String ALPHABET_STRING = "0123456789-$:/.+ABCD";
- internal static readonly char[] ALPHABET = ALPHABET_STRING.ToCharArray();
-
- /**
- * These represent the encodings of characters, as patterns of wide and narrow bars. The 7 least-significant bits of
- * each int correspond to the pattern of wide and narrow, with 1s representing "wide" and 0s representing narrow.
- */
-
- internal static int[] CHARACTER_ENCODINGS = {
- 0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, // 0-9
- 0x00c, 0x018, 0x045, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E, // -$:/.+ABCD
- };
-
- // minimal number of characters that should be present (inclusing start and stop characters)
- // under normal circumstances this should be set to 3, but can be set higher
- // as a last-ditch attempt to reduce false positives.
- private const int MIN_CHARACTER_LENGTH = 3;
-
- // official start and end patterns
- private static readonly char[] STARTEND_ENCODING = { 'A', 'B', 'C', 'D' };
- // some codabar generator allow the codabar string to be closed by every
- // character. This will cause lots of false positives!
-
- // some industries use a checksum standard but this is not part of the original codabar standard
- // for more information see : http://www.mecsw.com/specs/codabar.html
-
- // Keep some instance variables to avoid reallocations
- private readonly StringBuilder decodeRowResult;
- private int[] counters;
- private int counterLength;
-
- public CodaBarReader()
- {
- decodeRowResult = new StringBuilder(20);
- counters = new int[80];
- counterLength = 0;
- }
-
- public override Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- for (var index = 0; index < counters.Length; index++)
- counters[index] = 0;
-
- if (!setCounters(row))
- return null;
-
- int startOffset = findStartPattern();
- if (startOffset < 0)
- return null;
-
- int nextStart = startOffset;
-
- decodeRowResult.Length = 0;
- do
- {
- int charOffset = toNarrowWidePattern(nextStart);
- if (charOffset == -1)
- {
- return null;
- }
- // Hack: We store the position in the alphabet table into a
- // StringBuilder, so that we can access the decoded patterns in
- // validatePattern. We'll translate to the actual characters later.
- decodeRowResult.Append((char) charOffset);
- nextStart += 8;
- // Stop as soon as we see the end character.
- if (decodeRowResult.Length > 1 &&
- arrayContains(STARTEND_ENCODING, ALPHABET[charOffset]))
- {
- break;
- }
- } while (nextStart < counterLength); // no fixed end pattern so keep on reading while data is available
-
- // Look for whitespace after pattern:
- int trailingWhitespace = counters[nextStart - 1];
- int lastPatternSize = 0;
- for (int i = -8; i < -1; i++)
- {
- lastPatternSize += counters[nextStart + i];
- }
-
- // We need to see whitespace equal to 50% of the last pattern size,
- // otherwise this is probably a false positive. The exception is if we are
- // at the end of the row. (I.e. the barcode barely fits.)
- if (nextStart < counterLength && trailingWhitespace < lastPatternSize/2)
- {
- return null;
- }
-
- if (!validatePattern(startOffset))
- return null;
-
- // Translate character table offsets to actual characters.
- for (int i = 0; i < decodeRowResult.Length; i++)
- {
- decodeRowResult[i] = ALPHABET[decodeRowResult[i]];
- }
- // Ensure a valid start and end character
- char startchar = decodeRowResult[0];
- if (!arrayContains(STARTEND_ENCODING, startchar))
- {
- return null;
- }
- char endchar = decodeRowResult[decodeRowResult.Length - 1];
- if (!arrayContains(STARTEND_ENCODING, endchar))
- {
- return null;
- }
-
- // remove stop/start characters character and check if a long enough string is contained
- if (decodeRowResult.Length <= MIN_CHARACTER_LENGTH)
- {
- // Almost surely a false positive ( start + stop + at least 1 character)
- return null;
- }
-
- if (!SupportClass.GetValue(hints, DecodeHintType.RETURN_CODABAR_START_END, false))
- {
- decodeRowResult.Remove(decodeRowResult.Length - 1, 1);
- decodeRowResult.Remove(0, 1);
- }
-
- int runningCount = 0;
- for (int i = 0; i < startOffset; i++)
- {
- runningCount += counters[i];
- }
- float left = runningCount;
- for (int i = startOffset; i < nextStart - 1; i++)
- {
- runningCount += counters[i];
- }
- float right = runningCount;
-
- var resultPointCallback = SupportClass.GetValue(hints, DecodeHintType.NEED_RESULT_POINT_CALLBACK, (ResultPointCallback) null);
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(left, rowNumber));
- resultPointCallback(new ResultPoint(right, rowNumber));
- }
-
- return new Result(
- decodeRowResult.ToString(),
- null,
- new[]
- {
- new ResultPoint(left, rowNumber),
- new ResultPoint(right, rowNumber)
- },
- BarcodeFormat.CODABAR);
- }
-
- private bool validatePattern(int start)
- {
- // First, sum up the total size of our four categories of stripe sizes;
- int[] sizes = { 0, 0, 0, 0 };
- int[] counts = { 0, 0, 0, 0 };
- int end = decodeRowResult.Length - 1;
-
- // We break out of this loop in the middle, in order to handle
- // inter-character spaces properly.
- int pos = start;
- for (int i = 0; true; i++)
- {
- int pattern = CHARACTER_ENCODINGS[decodeRowResult[i]];
- for (int j = 6; j >= 0; j--)
- {
- // Even j = bars, while odd j = spaces. Categories 2 and 3 are for
- // long stripes, while 0 and 1 are for short stripes.
- int category = (j & 1) + (pattern & 1) * 2;
- sizes[category] += counters[pos + j];
- counts[category]++;
- pattern >>= 1;
- }
- if (i >= end)
- {
- break;
- }
- // We ignore the inter-character space - it could be of any size.
- pos += 8;
- }
-
- // Calculate our allowable size thresholds using fixed-point math.
- int[] maxes = new int[4];
- int[] mins = new int[4];
- // Define the threshold of acceptability to be the midpoint between the
- // average small stripe and the average large stripe. No stripe lengths
- // should be on the "wrong" side of that line.
- for (int i = 0; i < 2; i++)
- {
- mins[i] = 0; // Accept arbitrarily small "short" stripes.
- mins[i + 2] = ((sizes[i] << INTEGER_MATH_SHIFT) / counts[i] +
- (sizes[i + 2] << INTEGER_MATH_SHIFT) / counts[i + 2]) >> 1;
- maxes[i] = mins[i + 2];
- maxes[i + 2] = (sizes[i + 2] * MAX_ACCEPTABLE + PADDING) / counts[i + 2];
- }
-
- // Now verify that all of the stripes are within the thresholds.
- pos = start;
- for (int i = 0; true; i++)
- {
- int pattern = CHARACTER_ENCODINGS[decodeRowResult[i]];
- for (int j = 6; j >= 0; j--)
- {
- // Even j = bars, while odd j = spaces. Categories 2 and 3 are for
- // long stripes, while 0 and 1 are for short stripes.
- int category = (j & 1) + (pattern & 1) * 2;
- int size = counters[pos + j] << INTEGER_MATH_SHIFT;
- if (size < mins[category] || size > maxes[category])
- {
- return false;
- }
- pattern >>= 1;
- }
- if (i >= end)
- {
- break;
- }
- pos += 8;
- }
-
- return true;
- }
-
- ///
- /// Records the size of all runs of white and black pixels, starting with white.
- /// This is just like recordPattern, except it records all the counters, and
- /// uses our builtin "counters" member for storage.
- ///
- /// row to count from
- private bool setCounters(BitArray row)
- {
- counterLength = 0;
- // Start from the first white bit.
- int i = row.getNextUnset(0);
- int end = row.Size;
- if (i >= end)
- {
- return false;
- }
- bool isWhite = true;
- int count = 0;
- while (i < end)
- {
- if (row[i] ^ isWhite)
- {
- // that is, exactly one is true
- count++;
- }
- else
- {
- counterAppend(count);
- count = 1;
- isWhite = !isWhite;
- }
- i++;
- }
- counterAppend(count);
- return true;
- }
-
- private void counterAppend(int e)
- {
- counters[counterLength] = e;
- counterLength++;
- if (counterLength >= counters.Length)
- {
- int[] temp = new int[counterLength * 2];
- Array.Copy(counters, 0, temp, 0, counterLength);
- counters = temp;
- }
- }
-
- private int findStartPattern()
- {
- for (int i = 1; i < counterLength; i += 2)
- {
- int charOffset = toNarrowWidePattern(i);
- if (charOffset != -1 && arrayContains(STARTEND_ENCODING, ALPHABET[charOffset]))
- {
- // Look for whitespace before start pattern, >= 50% of width of start pattern
- // We make an exception if the whitespace is the first element.
- int patternSize = 0;
- for (int j = i; j < i + 7; j++)
- {
- patternSize += counters[j];
- }
- if (i == 1 || counters[i - 1] >= patternSize / 2)
- {
- return i;
- }
- }
- }
- return -1;
- }
-
- internal static bool arrayContains(char[] array, char key)
- {
- if (array != null)
- {
- foreach (char c in array)
- {
- if (c == key)
- {
- return true;
- }
- }
- }
- return false;
- }
-
- // Assumes that counters[position] is a bar.
- private int toNarrowWidePattern(int position)
- {
- int end = position + 7;
- if (end >= counterLength)
- {
- return -1;
- }
- int[] theCounters = counters;
-
- int maxBar = 0;
- int minBar = Int32.MaxValue;
- for (int j = position; j < end; j += 2)
- {
- int currentCounter = theCounters[j];
- if (currentCounter < minBar)
- {
- minBar = currentCounter;
- }
- if (currentCounter > maxBar)
- {
- maxBar = currentCounter;
- }
- }
- int thresholdBar = (minBar + maxBar) / 2;
-
- int maxSpace = 0;
- int minSpace = Int32.MaxValue;
- for (int j = position + 1; j < end; j += 2)
- {
- int currentCounter = theCounters[j];
- if (currentCounter < minSpace)
- {
- minSpace = currentCounter;
- }
- if (currentCounter > maxSpace)
- {
- maxSpace = currentCounter;
- }
- }
- int thresholdSpace = (minSpace + maxSpace) / 2;
-
- int bitmask = 1 << 7;
- int pattern = 0;
- for (int i = 0; i < 7; i++)
- {
- int threshold = (i & 1) == 0 ? thresholdBar : thresholdSpace;
- bitmask >>= 1;
- if (theCounters[position + i] > threshold)
- {
- pattern |= bitmask;
- }
- }
-
- for (int i = 0; i < CHARACTER_ENCODINGS.Length; i++)
- {
- if (CHARACTER_ENCODINGS[i] == pattern)
- {
- return i;
- }
- }
- return -1;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/CodaBarWriter.cs b/zxing.core/xx/oned/CodaBarWriter.cs
deleted file mode 100644
index 1fbe0ed..0000000
--- a/zxing.core/xx/oned/CodaBarWriter.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2011 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-
-namespace ZXing.OneD
-{
- ///
- /// This class renders CodaBar as [].
- ///
- /// dsbnatut@gmail.com (Kazuki Nishiura)
- public sealed class CodaBarWriter : OneDimensionalCodeWriter
- {
- private static readonly char[] START_END_CHARS = {'A', 'B', 'C', 'D'};
- private static readonly char[] ALT_START_END_CHARS = {'T', 'N', '*', 'E'};
- private static readonly char[] CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED = {'/', ':', '+', '.'};
- private static readonly char DEFAULT_GUARD = START_END_CHARS[0];
-
- public override bool[] encode(String contents)
- {
- if (contents.Length < 2)
- {
- // Can't have a start/end guard, so tentatively add default guards
- contents = DEFAULT_GUARD + contents + DEFAULT_GUARD;
- }
- else
- {
- // Verify input and calculate decoded length.
- char firstChar = Char.ToUpper(contents[0]);
- char lastChar = Char.ToUpper(contents[contents.Length - 1]);
- bool startsNormal = CodaBarReader.arrayContains(START_END_CHARS, firstChar);
- bool endsNormal = CodaBarReader.arrayContains(START_END_CHARS, lastChar);
- bool startsAlt = CodaBarReader.arrayContains(ALT_START_END_CHARS, firstChar);
- bool endsAlt = CodaBarReader.arrayContains(ALT_START_END_CHARS, lastChar);
- if (startsNormal)
- {
- if (!endsNormal)
- {
- throw new ArgumentException("Invalid start/end guards: " + contents);
- }
- // else already has valid start/end
- }
- else if (startsAlt)
- {
- if (!endsAlt)
- {
- throw new ArgumentException("Invalid start/end guards: " + contents);
- }
- // else already has valid start/end
- }
- else
- {
- // Doesn't start with a guard
- if (endsNormal || endsAlt)
- {
- throw new ArgumentException("Invalid start/end guards: " + contents);
- }
- // else doesn't end with guard either, so add a default
- contents = DEFAULT_GUARD + contents + DEFAULT_GUARD;
- }
- }
-
- // The start character and the end character are decoded to 10 length each.
- int resultLength = 20;
- for (int i = 1; i < contents.Length - 1; i++)
- {
- if (Char.IsDigit(contents[i]) || contents[i] == '-' || contents[i] == '$')
- {
- resultLength += 9;
- }
- else if (CodaBarReader.arrayContains(CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED, contents[i]))
- {
- resultLength += 10;
- }
- else
- {
- throw new ArgumentException("Cannot encode : '" + contents[i] + '\'');
- }
- }
- // A blank is placed between each character.
- resultLength += contents.Length - 1;
-
- var result = new bool[resultLength];
- int position = 0;
- for (int index = 0; index < contents.Length; index++)
- {
- char c = Char.ToUpper(contents[index]);
- if (index == 0 || index == contents.Length - 1)
- {
- // The start/end chars are not in the CodaBarReader.ALPHABET.
- switch (c)
- {
- case 'T':
- c = 'A';
- break;
- case 'N':
- c = 'B';
- break;
- case '*':
- c = 'C';
- break;
- case 'E':
- c = 'D';
- break;
- }
- }
- int code = 0;
- for (int i = 0; i < CodaBarReader.ALPHABET.Length; i++)
- {
- // Found any, because I checked above.
- if (c == CodaBarReader.ALPHABET[i])
- {
- code = CodaBarReader.CHARACTER_ENCODINGS[i];
- break;
- }
- }
- bool color = true;
- int counter = 0;
- int bit = 0;
- while (bit < 7)
- {
- // A character consists of 7 digit.
- result[position] = color;
- position++;
- if (((code >> (6 - bit)) & 1) == 0 || counter == 1)
- {
- color = !color; // Flip the color.
- bit++;
- counter = 0;
- }
- else
- {
- counter++;
- }
- }
- if (index < contents.Length - 1)
- {
- result[position] = false;
- position++;
- }
- }
- return result;
- }
- }
-}
diff --git a/zxing.core/xx/oned/Code128EncodingOptions.cs b/zxing.core/xx/oned/Code128EncodingOptions.cs
deleted file mode 100644
index a681759..0000000
--- a/zxing.core/xx/oned/Code128EncodingOptions.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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;
-
-namespace ZXing.OneD
-{
- ///
- /// The class holds the available options for the QrCodeWriter
- ///
- public class Code128EncodingOptions : EncodingOptions
- {
- ///
- /// if true, don't switch to codeset C for numbers
- ///
- public bool ForceCodesetB
- {
- get
- {
- if (Hints.ContainsKey(EncodeHintType.CODE128_FORCE_CODESET_B))
- {
- return (bool)Hints[EncodeHintType.CODE128_FORCE_CODESET_B];
- }
- return false;
- }
- set
- {
- Hints[EncodeHintType.CODE128_FORCE_CODESET_B] = value;
- }
- }
- }
-}
diff --git a/zxing.core/xx/oned/Code128Reader.cs b/zxing.core/xx/oned/Code128Reader.cs
deleted file mode 100644
index 69108f5..0000000
--- a/zxing.core/xx/oned/Code128Reader.cs
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Decodes Code 128 barcodes.
- ///
- /// Sean Owen
- ///
- public sealed class Code128Reader : OneDReader
- {
- internal static int[][] CODE_PATTERNS = {
- new[] {2, 1, 2, 2, 2, 2}, // 0
- new[] {2, 2, 2, 1, 2, 2},
- new[] {2, 2, 2, 2, 2, 1},
- new[] {1, 2, 1, 2, 2, 3},
- new[] {1, 2, 1, 3, 2, 2},
- new[] {1, 3, 1, 2, 2, 2}, // 5
- new[] {1, 2, 2, 2, 1, 3},
- new[] {1, 2, 2, 3, 1, 2},
- new[] {1, 3, 2, 2, 1, 2},
- new[] {2, 2, 1, 2, 1, 3},
- new[] {2, 2, 1, 3, 1, 2}, // 10
- new[] {2, 3, 1, 2, 1, 2},
- new[] {1, 1, 2, 2, 3, 2},
- new[] {1, 2, 2, 1, 3, 2},
- new[] {1, 2, 2, 2, 3, 1},
- new[] {1, 1, 3, 2, 2, 2}, // 15
- new[] {1, 2, 3, 1, 2, 2},
- new[] {1, 2, 3, 2, 2, 1},
- new[] {2, 2, 3, 2, 1, 1},
- new[] {2, 2, 1, 1, 3, 2},
- new[] {2, 2, 1, 2, 3, 1}, // 20
- new[] {2, 1, 3, 2, 1, 2},
- new[] {2, 2, 3, 1, 1, 2},
- new[] {3, 1, 2, 1, 3, 1},
- new[] {3, 1, 1, 2, 2, 2},
- new[] {3, 2, 1, 1, 2, 2}, // 25
- new[] {3, 2, 1, 2, 2, 1},
- new[] {3, 1, 2, 2, 1, 2},
- new[] {3, 2, 2, 1, 1, 2},
- new[] {3, 2, 2, 2, 1, 1},
- new[] {2, 1, 2, 1, 2, 3}, // 30
- new[] {2, 1, 2, 3, 2, 1},
- new[] {2, 3, 2, 1, 2, 1},
- new[] {1, 1, 1, 3, 2, 3},
- new[] {1, 3, 1, 1, 2, 3},
- new[] {1, 3, 1, 3, 2, 1}, // 35
- new[] {1, 1, 2, 3, 1, 3},
- new[] {1, 3, 2, 1, 1, 3},
- new[] {1, 3, 2, 3, 1, 1},
- new[] {2, 1, 1, 3, 1, 3},
- new[] {2, 3, 1, 1, 1, 3}, // 40
- new[] {2, 3, 1, 3, 1, 1},
- new[] {1, 1, 2, 1, 3, 3},
- new[] {1, 1, 2, 3, 3, 1},
- new[] {1, 3, 2, 1, 3, 1},
- new[] {1, 1, 3, 1, 2, 3}, // 45
- new[] {1, 1, 3, 3, 2, 1},
- new[] {1, 3, 3, 1, 2, 1},
- new[] {3, 1, 3, 1, 2, 1},
- new[] {2, 1, 1, 3, 3, 1},
- new[] {2, 3, 1, 1, 3, 1}, // 50
- new[] {2, 1, 3, 1, 1, 3},
- new[] {2, 1, 3, 3, 1, 1},
- new[] {2, 1, 3, 1, 3, 1},
- new[] {3, 1, 1, 1, 2, 3},
- new[] {3, 1, 1, 3, 2, 1}, // 55
- new[] {3, 3, 1, 1, 2, 1},
- new[] {3, 1, 2, 1, 1, 3},
- new[] {3, 1, 2, 3, 1, 1},
- new[] {3, 3, 2, 1, 1, 1},
- new[] {3, 1, 4, 1, 1, 1}, // 60
- new[] {2, 2, 1, 4, 1, 1},
- new[] {4, 3, 1, 1, 1, 1},
- new[] {1, 1, 1, 2, 2, 4},
- new[] {1, 1, 1, 4, 2, 2},
- new[] {1, 2, 1, 1, 2, 4}, // 65
- new[] {1, 2, 1, 4, 2, 1},
- new[] {1, 4, 1, 1, 2, 2},
- new[] {1, 4, 1, 2, 2, 1},
- new[] {1, 1, 2, 2, 1, 4},
- new[] {1, 1, 2, 4, 1, 2}, // 70
- new[] {1, 2, 2, 1, 1, 4},
- new[] {1, 2, 2, 4, 1, 1},
- new[] {1, 4, 2, 1, 1, 2},
- new[] {1, 4, 2, 2, 1, 1},
- new[] {2, 4, 1, 2, 1, 1}, // 75
- new[] {2, 2, 1, 1, 1, 4},
- new[] {4, 1, 3, 1, 1, 1},
- new[] {2, 4, 1, 1, 1, 2},
- new[] {1, 3, 4, 1, 1, 1},
- new[] {1, 1, 1, 2, 4, 2}, // 80
- new[] {1, 2, 1, 1, 4, 2},
- new[] {1, 2, 1, 2, 4, 1},
- new[] {1, 1, 4, 2, 1, 2},
- new[] {1, 2, 4, 1, 1, 2},
- new[] {1, 2, 4, 2, 1, 1}, // 85
- new[] {4, 1, 1, 2, 1, 2},
- new[] {4, 2, 1, 1, 1, 2},
- new[] {4, 2, 1, 2, 1, 1},
- new[] {2, 1, 2, 1, 4, 1},
- new[] {2, 1, 4, 1, 2, 1}, // 90
- new[] {4, 1, 2, 1, 2, 1},
- new[] {1, 1, 1, 1, 4, 3},
- new[] {1, 1, 1, 3, 4, 1},
- new[] {1, 3, 1, 1, 4, 1},
- new[] {1, 1, 4, 1, 1, 3}, // 95
- new[] {1, 1, 4, 3, 1, 1},
- new[] {4, 1, 1, 1, 1, 3},
- new[] {4, 1, 1, 3, 1, 1},
- new[] {1, 1, 3, 1, 4, 1},
- new[] {1, 1, 4, 1, 3, 1}, // 100
- new[] {3, 1, 1, 1, 4, 1},
- new[] {4, 1, 1, 1, 3, 1},
- new[] {2, 1, 1, 4, 1, 2},
- new[] {2, 1, 1, 2, 1, 4},
- new[] {2, 1, 1, 2, 3, 2}, // 105
- new[] {2, 3, 3, 1, 1, 1, 2}
- };
-
- private static readonly int MAX_AVG_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.25f);
- private static readonly int MAX_INDIVIDUAL_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f);
-
- private const int CODE_SHIFT = 98;
-
- private const int CODE_CODE_C = 99;
- private const int CODE_CODE_B = 100;
- private const int CODE_CODE_A = 101;
-
- private const int CODE_FNC_1 = 102;
- private const int CODE_FNC_2 = 97;
- private const int CODE_FNC_3 = 96;
- private const int CODE_FNC_4_A = 101;
- private const int CODE_FNC_4_B = 100;
-
- private const int CODE_START_A = 103;
- private const int CODE_START_B = 104;
- private const int CODE_START_C = 105;
- private const int CODE_STOP = 106;
-
- private static int[] findStartPattern(BitArray row)
- {
- int width = row.Size;
- int rowOffset = row.getNextSet(0);
-
- int counterPosition = 0;
- int[] counters = new int[6];
- int patternStart = rowOffset;
- bool isWhite = false;
- int patternLength = counters.Length;
-
- for (int i = rowOffset; i < width; i++)
- {
- if (row[i] ^ isWhite)
- {
- counters[counterPosition]++;
- }
- else
- {
- if (counterPosition == patternLength - 1)
- {
- int bestVariance = MAX_AVG_VARIANCE;
- int bestMatch = -1;
- for (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++)
- {
- int variance = patternMatchVariance(counters, CODE_PATTERNS[startCode],
- MAX_INDIVIDUAL_VARIANCE);
- if (variance < bestVariance)
- {
- bestVariance = variance;
- bestMatch = startCode;
- }
- }
- if (bestMatch >= 0)
- {
- // Look for whitespace before start pattern, >= 50% of width of start pattern
- if (row.isRange(Math.Max(0, patternStart - (i - patternStart) / 2), patternStart,
- false))
- {
- return new int[] { patternStart, i, bestMatch };
- }
- }
- patternStart += counters[0] + counters[1];
- Array.Copy(counters, 2, counters, 0, patternLength - 2);
- counters[patternLength - 2] = 0;
- counters[patternLength - 1] = 0;
- counterPosition--;
- }
- else
- {
- counterPosition++;
- }
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- return null;
- }
-
- private static bool decodeCode(BitArray row, int[] counters, int rowOffset, out int code)
- {
- code = -1;
- if (!recordPattern(row, rowOffset, counters))
- return false;
-
- int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
- for (int d = 0; d < CODE_PATTERNS.Length; d++)
- {
- int[] pattern = CODE_PATTERNS[d];
- int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
- if (variance < bestVariance)
- {
- bestVariance = variance;
- code = d;
- }
- }
- // TODO We're overlooking the fact that the STOP pattern has 7 values, not 6.
- return code >= 0;
- }
-
- override public Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- bool convertFNC1 = hints != null && hints.ContainsKey(DecodeHintType.ASSUME_GS1);
-
- int[] startPatternInfo = findStartPattern(row);
- if (startPatternInfo == null)
- return null;
- int startCode = startPatternInfo[2];
-
- var rawCodes = new List(20);
- rawCodes.Add((byte)startCode);
-
- int codeSet;
- switch (startCode)
- {
- case CODE_START_A:
- codeSet = CODE_CODE_A;
- break;
- case CODE_START_B:
- codeSet = CODE_CODE_B;
- break;
- case CODE_START_C:
- codeSet = CODE_CODE_C;
- break;
- default:
- return null;
- }
-
- bool done = false;
- bool isNextShifted = false;
-
- var result = new StringBuilder(20);
-
- int lastStart = startPatternInfo[0];
- int nextStart = startPatternInfo[1];
- int[] counters = new int[6];
-
- int lastCode = 0;
- int code = 0;
- int checksumTotal = startCode;
- int multiplier = 0;
- bool lastCharacterWasPrintable = true;
- bool upperMode = false;
- bool shiftUpperMode = false;
-
- while (!done)
- {
- bool unshift = isNextShifted;
- isNextShifted = false;
-
- // Save off last code
- lastCode = code;
-
- // Decode another code from image
- if (!decodeCode(row, counters, nextStart, out code))
- return null;
-
- rawCodes.Add((byte)code);
-
- // Remember whether the last code was printable or not (excluding CODE_STOP)
- if (code != CODE_STOP)
- {
- lastCharacterWasPrintable = true;
- }
-
- // Add to checksum computation (if not CODE_STOP of course)
- if (code != CODE_STOP)
- {
- multiplier++;
- checksumTotal += multiplier * code;
- }
-
- // Advance to where the next code will to start
- lastStart = nextStart;
- foreach (int counter in counters)
- {
- nextStart += counter;
- }
-
- // Take care of illegal start codes
- switch (code)
- {
- case CODE_START_A:
- case CODE_START_B:
- case CODE_START_C:
- return null;
- }
-
- switch (codeSet)
- {
-
- case CODE_CODE_A:
- if (code < 64)
- {
- if (shiftUpperMode == upperMode)
- {
- result.Append((char) (' ' + code));
- }
- else
- {
- result.Append((char) (' ' + code + 128));
- }
- shiftUpperMode = false;
- }
- else if (code < 96)
- {
- if (shiftUpperMode == upperMode)
- {
- result.Append((char) (code - 64));
- }
- else
- {
- result.Append((char) (code + 64));
- }
- shiftUpperMode = false;
- }
- else
- {
- // Don't let CODE_STOP, which always appears, affect whether whether we think the last
- // code was printable or not.
- if (code != CODE_STOP)
- {
- lastCharacterWasPrintable = false;
- }
- switch (code)
- {
- case CODE_FNC_1:
- if (convertFNC1)
- {
- if (result.Length == 0)
- {
- // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
- // is FNC1 then this is GS1-128. We add the symbology identifier.
- result.Append("]C1");
- }
- else
- {
- // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
- result.Append((char) 29);
- }
- }
- break;
- case CODE_FNC_2:
- case CODE_FNC_3:
- // do nothing?
- break;
- case CODE_FNC_4_A:
- if (!upperMode && shiftUpperMode)
- {
- upperMode = true;
- shiftUpperMode = false;
- }
- else if (upperMode && shiftUpperMode)
- {
- upperMode = false;
- shiftUpperMode = false;
- }
- else
- {
- shiftUpperMode = true;
- }
- break;
- case CODE_SHIFT:
- isNextShifted = true;
- codeSet = CODE_CODE_B;
- break;
- case CODE_CODE_B:
- codeSet = CODE_CODE_B;
- break;
- case CODE_CODE_C:
- codeSet = CODE_CODE_C;
- break;
- case CODE_STOP:
- done = true;
- break;
- }
- }
- break;
- case CODE_CODE_B:
- if (code < 96)
- {
- if (shiftUpperMode == upperMode)
- {
- result.Append((char)(' ' + code));
- }
- else
- {
- result.Append((char)(' ' + code + 128));
- }
- shiftUpperMode = false;
- }
- else
- {
- if (code != CODE_STOP)
- {
- lastCharacterWasPrintable = false;
- }
- switch (code)
- {
- case CODE_FNC_1:
- if (convertFNC1)
- {
- if (result.Length == 0)
- {
- // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
- // is FNC1 then this is GS1-128. We add the symbology identifier.
- result.Append("]C1");
- }
- else
- {
- // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
- result.Append((char)29);
- }
- }
- break;
- case CODE_FNC_2:
- case CODE_FNC_3:
- // do nothing?
- break;
- case CODE_FNC_4_B:
- if (!upperMode && shiftUpperMode)
- {
- upperMode = true;
- shiftUpperMode = false;
- }
- else if (upperMode && shiftUpperMode)
- {
- upperMode = false;
- shiftUpperMode = false;
- }
- else
- {
- shiftUpperMode = true;
- }
- break;
- case CODE_SHIFT:
- isNextShifted = true;
- codeSet = CODE_CODE_A;
- break;
- case CODE_CODE_A:
- codeSet = CODE_CODE_A;
- break;
- case CODE_CODE_C:
- codeSet = CODE_CODE_C;
- break;
- case CODE_STOP:
- done = true;
- break;
- }
- }
- break;
- case CODE_CODE_C:
- if (code < 100)
- {
- if (code < 10)
- {
- result.Append('0');
- }
- result.Append(code);
- }
- else
- {
- if (code != CODE_STOP)
- {
- lastCharacterWasPrintable = false;
- }
- switch (code)
- {
- case CODE_FNC_1:
- if (convertFNC1)
- {
- if (result.Length == 0)
- {
- // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
- // is FNC1 then this is GS1-128. We add the symbology identifier.
- result.Append("]C1");
- }
- else
- {
- // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
- result.Append((char) 29);
- }
- }
- break;
- case CODE_CODE_A:
- codeSet = CODE_CODE_A;
- break;
- case CODE_CODE_B:
- codeSet = CODE_CODE_B;
- break;
- case CODE_STOP:
- done = true;
- break;
- }
- }
- break;
- }
-
- // Unshift back to another code set if we were shifted
- if (unshift)
- {
- codeSet = codeSet == CODE_CODE_A ? CODE_CODE_B : CODE_CODE_A;
- }
-
- }
-
- int lastPatternSize = nextStart - lastStart;
-
- // Check for ample whitespace following pattern, but, to do this we first need to remember that
- // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left
- // to read off. Would be slightly better to properly read. Here we just skip it:
- nextStart = row.getNextUnset(nextStart);
- if (!row.isRange(nextStart,
- Math.Min(row.Size, nextStart + (nextStart - lastStart) / 2),
- false))
- {
- return null;
- }
-
- // Pull out from sum the value of the penultimate check code
- checksumTotal -= multiplier * lastCode;
- // lastCode is the checksum then:
- if (checksumTotal % 103 != lastCode)
- {
- return null;
- }
-
- // Need to pull out the check digits from string
- int resultLength = result.Length;
- if (resultLength == 0)
- {
- // false positive
- return null;
- }
-
- // Only bother if the result had at least one character, and if the checksum digit happened to
- // be a printable character. If it was just interpreted as a control code, nothing to remove.
- if (resultLength > 0 && lastCharacterWasPrintable)
- {
- if (codeSet == CODE_CODE_C)
- {
- result.Remove(resultLength - 2, 2);
- }
- else
- {
- result.Remove(resultLength - 1, 1);
- }
- }
-
- float left = (startPatternInfo[1] + startPatternInfo[0]) / 2.0f;
- float right = lastStart + lastPatternSize / 2.0f;
-
- var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)
- ? null
- : (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(left, rowNumber));
- resultPointCallback(new ResultPoint(right, rowNumber));
- }
-
- int rawCodesSize = rawCodes.Count;
- var rawBytes = new byte[rawCodesSize];
- for (int i = 0; i < rawCodesSize; i++)
- {
- rawBytes[i] = rawCodes[i];
- }
-
- return new Result(
- result.ToString(),
- rawBytes,
- new []
- {
- new ResultPoint(left, rowNumber),
- new ResultPoint(right, rowNumber)
- },
- BarcodeFormat.CODE_128);
- }
- }
-}
diff --git a/zxing.core/xx/oned/Code128Writer.cs b/zxing.core/xx/oned/Code128Writer.cs
deleted file mode 100644
index 023380d..0000000
--- a/zxing.core/xx/oned/Code128Writer.cs
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// This object renders a CODE128 code as a .
- ///
- /// erik.barbara@gmail.com (Erik Barbara)
- ///
- public sealed class Code128Writer : OneDimensionalCodeWriter
- {
- private const int CODE_START_B = 104;
- private const int CODE_START_C = 105;
- private const int CODE_CODE_B = 100;
- private const int CODE_CODE_C = 99;
- private const int CODE_STOP = 106;
-
- // Dummy characters used to specify control characters in input
- private const char ESCAPE_FNC_1 = '\u00f1';
- private const char ESCAPE_FNC_2 = '\u00f2';
- private const char ESCAPE_FNC_3 = '\u00f3';
- private const char ESCAPE_FNC_4 = '\u00f4';
-
- private const int CODE_FNC_1 = 102; // Code A, Code B, Code C
- private const int CODE_FNC_2 = 97; // Code A, Code B
- private const int CODE_FNC_3 = 96; // Code A, Code B
- private const int CODE_FNC_4_B = 100; // Code B
-
- private bool forceCodesetB;
-
- public override BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (format != BarcodeFormat.CODE_128)
- {
- throw new ArgumentException("Can only encode CODE_128, but got " + format);
- }
-
- forceCodesetB = (hints != null &&
- hints.ContainsKey(EncodeHintType.CODE128_FORCE_CODESET_B) &&
- (bool) hints[EncodeHintType.CODE128_FORCE_CODESET_B]);
-
- return base.encode(contents, format, width, height, hints);
- }
-
- override public bool[] encode(String contents)
- {
- int length = contents.Length;
- // Check length
- if (length < 1 || length > 80)
- {
- throw new ArgumentException(
- "Contents length should be between 1 and 80 characters, but got " + length);
- }
- // Check content
- for (int i = 0; i < length; i++)
- {
- char c = contents[i];
- if (c < ' ' || c > '~')
- {
- switch (c)
- {
- case ESCAPE_FNC_1:
- case ESCAPE_FNC_2:
- case ESCAPE_FNC_3:
- case ESCAPE_FNC_4:
- break;
- default:
- throw new ArgumentException("Bad character in input: " + c);
- }
- }
- }
-
- var patterns = new List(); // temporary storage for patterns
- int checkSum = 0;
- int checkWeight = 1;
- int codeSet = 0; // selected code (CODE_CODE_B or CODE_CODE_C)
- int position = 0; // position in contents
-
- while (position < length)
- {
- //Select code to use
- int requiredDigitCount = codeSet == CODE_CODE_C ? 2 : 4;
- int newCodeSet;
- if (isDigits(contents, position, requiredDigitCount))
- {
- newCodeSet = forceCodesetB ? CODE_CODE_B : CODE_CODE_C;
- }
- else
- {
- newCodeSet = CODE_CODE_B;
- }
-
- //Get the pattern index
- int patternIndex;
- if (newCodeSet == codeSet)
- {
- // Encode the current character
- // First handle escapes
- switch (contents[position])
- {
- case ESCAPE_FNC_1:
- patternIndex = CODE_FNC_1;
- break;
- case ESCAPE_FNC_2:
- patternIndex = CODE_FNC_2;
- break;
- case ESCAPE_FNC_3:
- patternIndex = CODE_FNC_3;
- break;
- case ESCAPE_FNC_4:
- patternIndex = CODE_FNC_4_B; // FIXME if this ever outputs Code A
- break;
- default:
- // Then handle normal characters otherwise
- if (codeSet == CODE_CODE_B)
- {
- patternIndex = contents[position] - ' ';
- }
- else
- { // CODE_CODE_C
- patternIndex = Int32.Parse(contents.Substring(position, 2));
- position++; // Also incremented below
- }
- break;
- }
- position++;
- }
- else
- {
- // Should we change the current code?
- // Do we have a code set?
- if (codeSet == 0)
- {
- // No, we don't have a code set
- if (newCodeSet == CODE_CODE_B)
- {
- patternIndex = CODE_START_B;
- }
- else
- {
- // CODE_CODE_C
- patternIndex = CODE_START_C;
- }
- }
- else
- {
- // Yes, we have a code set
- patternIndex = newCodeSet;
- }
- codeSet = newCodeSet;
- }
-
- // Get the pattern
- patterns.Add(Code128Reader.CODE_PATTERNS[patternIndex]);
-
- // Compute checksum
- checkSum += patternIndex * checkWeight;
- if (position != 0)
- {
- checkWeight++;
- }
- }
-
- // Compute and append checksum
- checkSum %= 103;
- patterns.Add(Code128Reader.CODE_PATTERNS[checkSum]);
-
- // Append stop code
- patterns.Add(Code128Reader.CODE_PATTERNS[CODE_STOP]);
-
- // Compute code width
- int codeWidth = 0;
- foreach (int[] pattern in patterns)
- {
- foreach (int width in pattern)
- {
- codeWidth += width;
- }
- }
-
- // Compute result
- var result = new bool[codeWidth];
- int pos = 0;
- foreach (int[] pattern in patterns)
- {
- pos += appendPattern(result, pos, pattern, true);
- }
-
- return result;
- }
-
- private static bool isDigits(String value, int start, int length)
- {
- int end = start + length;
- int last = value.Length;
- for (int i = start; i < end && i < last; i++)
- {
- char c = value[i];
- if (c < '0' || c > '9')
- {
- if (c != ESCAPE_FNC_1)
- {
- return false;
- }
- end++; // ignore FNC_1
- }
- }
- return end <= last; // end > last if we've run out of string
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/Code39Reader.cs b/zxing.core/xx/oned/Code39Reader.cs
deleted file mode 100644
index 8d18f64..0000000
--- a/zxing.core/xx/oned/Code39Reader.cs
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Decodes Code 39 barcodes. This does not support "Full ASCII Code 39" yet.
- /// Sean Owen
- /// @see Code93Reader
- ///
- public sealed class Code39Reader : OneDReader
- {
- internal static String ALPHABET_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%";
- private static readonly char[] ALPHABET = ALPHABET_STRING.ToCharArray();
-
- ///
- /// Returns a string with all possible characters
- ///
- public static string Alphabet
- {
- get { return ALPHABET_STRING; }
- }
-
- ///
- /// These represent the encodings of characters, as patterns of wide and narrow bars.
- /// The 9 least-significant bits of each int correspond to the pattern of wide and narrow,
- /// with 1s representing "wide" and 0s representing narrow.
- ///
- internal static int[] CHARACTER_ENCODINGS = {
- 0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, // 0-9
- 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, // A-J
- 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, // K-T
- 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x094, // U-*
- 0x0A8, 0x0A2, 0x08A, 0x02A // $-%
- };
-
- private static readonly int ASTERISK_ENCODING = CHARACTER_ENCODINGS[39];
-
- private readonly bool usingCheckDigit;
- private readonly bool extendedMode;
- private readonly StringBuilder decodeRowResult;
- private readonly int[] counters;
-
- ///
- /// Creates a reader that assumes all encoded data is data, and does not treat the final
- /// character as a check digit. It will not decoded "extended Code 39" sequences.
- ///
- public Code39Reader()
- :this(false)
- {
- }
-
- ///
- /// Creates a reader that can be configured to check the last character as a check digit.
- /// It will not decoded "extended Code 39" sequences.
- ///
- /// if true, treat the last data character as a check digit, not
- /// data, and verify that the checksum passes.
- public Code39Reader(bool usingCheckDigit)
- :this(usingCheckDigit, false)
- {
- }
-
- ///
- /// Creates a reader that can be configured to check the last character as a check digit,
- /// or optionally attempt to decode "extended Code 39" sequences that are used to encode
- /// the full ASCII character set.
- ///
- /// if true, treat the last data character as a check digit, not
- /// data, and verify that the checksum passes.
- /// if true, will attempt to decode extended Code 39 sequences in the text.
- public Code39Reader(bool usingCheckDigit, bool extendedMode)
- {
- this.usingCheckDigit = usingCheckDigit;
- this.extendedMode = extendedMode;
- decodeRowResult = new StringBuilder(20);
- counters = new int[9];
- }
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- /// containing encoded string and start/end of barcode
- override public Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- for (var index = 0; index < counters.Length; index++)
- counters[index] = 0;
- decodeRowResult.Length = 0;
-
- int[] start = findAsteriskPattern(row, counters);
- if (start == null)
- return null;
-
- // Read off white space
- int nextStart = row.getNextSet(start[1]);
- int end = row.Size;
-
- char decodedChar;
- int lastStart;
- do
- {
- if (!recordPattern(row, nextStart, counters))
- return null;
-
- int pattern = toNarrowWidePattern(counters);
- if (pattern < 0)
- {
- return null;
- }
- if (!patternToChar(pattern, out decodedChar))
- return null;
- decodeRowResult.Append(decodedChar);
- lastStart = nextStart;
- foreach (int counter in counters)
- {
- nextStart += counter;
- }
- // Read off white space
- nextStart = row.getNextSet(nextStart);
- } while (decodedChar != '*');
- decodeRowResult.Length = decodeRowResult.Length - 1; // remove asterisk
-
- // Look for whitespace after pattern:
- int lastPatternSize = 0;
- foreach (int counter in counters)
- {
- lastPatternSize += counter;
- }
- int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
- // If 50% of last pattern size, following last pattern, is not whitespace, fail
- // (but if it's whitespace to the very end of the image, that's OK)
- if (nextStart != end && (whiteSpaceAfterEnd << 1) < lastPatternSize)
- {
- return null;
- }
-
- // overriding constructor value is possible
- bool useCode39CheckDigit = usingCheckDigit;
- if (hints != null && hints.ContainsKey(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT))
- {
- useCode39CheckDigit = (bool) hints[DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT];
- }
-
- if (useCode39CheckDigit)
- {
- int max = decodeRowResult.Length - 1;
- int total = 0;
- for (int i = 0; i < max; i++)
- {
- total += ALPHABET_STRING.IndexOf(decodeRowResult[i]);
- }
- if (decodeRowResult[max] != ALPHABET[total % 43])
- {
- return null;
- }
- decodeRowResult.Length = max;
- }
-
- if (decodeRowResult.Length == 0)
- {
- // false positive
- return null;
- }
-
- // overriding constructor value is possible
- bool useCode39ExtendedMode = extendedMode;
- if (hints != null && hints.ContainsKey(DecodeHintType.USE_CODE_39_EXTENDED_MODE))
- {
- useCode39ExtendedMode = (bool)hints[DecodeHintType.USE_CODE_39_EXTENDED_MODE];
- }
-
- String resultString;
- if (useCode39ExtendedMode)
- {
- resultString = decodeExtended(decodeRowResult.ToString());
- if (resultString == null)
- {
- if (hints != null &&
- hints.ContainsKey(DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE) &&
- Convert.ToBoolean(hints[DecodeHintType.RELAXED_CODE_39_EXTENDED_MODE]))
- resultString = decodeRowResult.ToString();
- else
- return null;
- }
- }
- else
- {
- resultString = decodeRowResult.ToString();
- }
-
- float left = (start[1] + start[0])/2.0f;
- float right = lastStart + lastPatternSize / 2.0f;
-
- var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)
- ? null
- : (ResultPointCallback) hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(left, rowNumber));
- resultPointCallback(new ResultPoint(right, rowNumber));
- }
-
- return new Result(
- resultString,
- null,
- new[]
- {
- new ResultPoint(left, rowNumber),
- new ResultPoint(right, rowNumber)
- },
- BarcodeFormat.CODE_39);
- }
-
- private static int[] findAsteriskPattern(BitArray row, int[] counters)
- {
- int width = row.Size;
- int rowOffset = row.getNextSet(0);
-
- int counterPosition = 0;
- int patternStart = rowOffset;
- bool isWhite = false;
- int patternLength = counters.Length;
-
- for (int i = rowOffset; i < width; i++)
- {
- if (row[i] ^ isWhite)
- {
- counters[counterPosition]++;
- }
- else
- {
- if (counterPosition == patternLength - 1)
- {
- if (toNarrowWidePattern(counters) == ASTERISK_ENCODING)
- {
- // Look for whitespace before start pattern, >= 50% of width of start pattern
- if (row.isRange(Math.Max(0, patternStart - ((i - patternStart) >> 1)), patternStart, false))
- {
- return new int[] { patternStart, i };
- }
- }
- patternStart += counters[0] + counters[1];
- Array.Copy(counters, 2, counters, 0, patternLength - 2);
- counters[patternLength - 2] = 0;
- counters[patternLength - 1] = 0;
- counterPosition--;
- }
- else
- {
- counterPosition++;
- }
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- return null;
- }
-
- // For efficiency, returns -1 on failure. Not throwing here saved as many as 700 exceptions
- // per image when using some of our blackbox images.
- private static int toNarrowWidePattern(int[] counters)
- {
- int numCounters = counters.Length;
- int maxNarrowCounter = 0;
- int wideCounters;
- do
- {
- int minCounter = Int32.MaxValue;
- foreach (var counter in counters)
- {
- if (counter < minCounter && counter > maxNarrowCounter)
- {
- minCounter = counter;
- }
- }
- maxNarrowCounter = minCounter;
- wideCounters = 0;
- int totalWideCountersWidth = 0;
- int pattern = 0;
- for (int i = 0; i < numCounters; i++)
- {
- int counter = counters[i];
- if (counter > maxNarrowCounter)
- {
- pattern |= 1 << (numCounters - 1 - i);
- wideCounters++;
- totalWideCountersWidth += counter;
- }
- }
- if (wideCounters == 3)
- {
- // Found 3 wide counters, but are they close enough in width?
- // We can perform a cheap, conservative check to see if any individual
- // counter is more than 1.5 times the average:
- for (int i = 0; i < numCounters && wideCounters > 0; i++)
- {
- int counter = counters[i];
- if (counter > maxNarrowCounter)
- {
- wideCounters--;
- // totalWideCountersWidth = 3 * average, so this checks if counter >= 3/2 * average
- if ((counter << 1) >= totalWideCountersWidth)
- {
- return -1;
- }
- }
- }
- return pattern;
- }
- } while (wideCounters > 3);
- return -1;
- }
-
- private static bool patternToChar(int pattern, out char c)
- {
- for (int i = 0; i < CHARACTER_ENCODINGS.Length; i++)
- {
- if (CHARACTER_ENCODINGS[i] == pattern)
- {
- c = ALPHABET[i];
- return true;
- }
- }
- c = '*';
- return false;
- }
-
- private static String decodeExtended(String encoded)
- {
- int length = encoded.Length;
- StringBuilder decoded = new StringBuilder(length);
- for (int i = 0; i < length; i++)
- {
- char c = encoded[i];
- if (c == '+' || c == '$' || c == '%' || c == '/')
- {
- if (i + 1 >= encoded.Length)
- {
- return null;
- }
-
- char next = encoded[i + 1];
- char decodedChar = '\0';
- switch (c)
- {
- case '+':
- // +A to +Z map to a to z
- if (next >= 'A' && next <= 'Z')
- {
- decodedChar = (char)(next + 32);
- }
- else
- {
- return null;
- }
- break;
- case '$':
- // $A to $Z map to control codes SH to SB
- if (next >= 'A' && next <= 'Z')
- {
- decodedChar = (char)(next - 64);
- }
- else
- {
- return null;
- }
- break;
- case '%':
- // %A to %E map to control codes ESC to US
- if (next >= 'A' && next <= 'E')
- {
- decodedChar = (char)(next - 38);
- }
- else if (next >= 'F' && next <= 'W')
- {
- decodedChar = (char)(next - 11);
- }
- else
- {
- return null;
- }
- break;
- case '/':
- // /A to /O map to ! to , and /Z maps to :
- if (next >= 'A' && next <= 'O')
- {
- decodedChar = (char)(next - 32);
- }
- else if (next == 'Z')
- {
- decodedChar = ':';
- }
- else
- {
- return null;
- }
- break;
- }
- decoded.Append(decodedChar);
- // bump up i again since we read two characters
- i++;
- }
- else
- {
- decoded.Append(c);
- }
- }
- return decoded.ToString();
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/Code39Writer.cs b/zxing.core/xx/oned/Code39Writer.cs
deleted file mode 100644
index d0ed277..0000000
--- a/zxing.core/xx/oned/Code39Writer.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// This object renders a CODE39 code as a .
- /// erik.barbara@gmail.com (Erik Barbara)
- ///
- public sealed class Code39Writer : OneDimensionalCodeWriter
- {
- ///
- /// Encode the contents following specified format.
- /// {@code width} and {@code height} are required size. This method may return bigger size
- /// {@code BitMatrix} when specified size is too small. The user can set both {@code width} and
- /// {@code height} to zero to get minimum size barcode. If negative value is set to {@code width}
- /// or {@code height}, {@code IllegalArgumentException} is thrown.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public override BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (format != BarcodeFormat.CODE_39)
- {
- throw new ArgumentException("Can only encode CODE_39, but got " + format);
- }
- return base.encode(contents, format, width, height, hints);
- }
-
- ///
- /// Encode the contents to byte array expression of one-dimensional barcode.
- /// Start code and end code should be included in result, and side margins should not be included.
- /// a {@code boolean[]} of horizontal pixels (false = white, true = black)
- ///
- ///
- ///
- public override bool[] encode(String contents)
- {
- int length = contents.Length;
- if (length > 80)
- {
- throw new ArgumentException(
- "Requested contents should be less than 80 digits long, but got " + length);
- }
- for (int i = 0; i < length; i++)
- {
- int indexInString = Code39Reader.ALPHABET_STRING.IndexOf(contents[i]);
- if (indexInString < 0)
- throw new ArgumentException("Requested contents contains a not encodable character: '" + contents[i] + "'");
- }
-
- int[] widths = new int[9];
- int codeWidth = 24 + 1 + length;
- for (int i = 0; i < length; i++)
- {
- int indexInString = Code39Reader.ALPHABET_STRING.IndexOf(contents[i]);
- if (indexInString < 0)
- {
- throw new ArgumentException("Bad contents: " + contents);
- }
- toIntArray(Code39Reader.CHARACTER_ENCODINGS[indexInString], widths);
- foreach (int width in widths)
- {
- codeWidth += width;
- }
- }
- var result = new bool[codeWidth];
- toIntArray(Code39Reader.CHARACTER_ENCODINGS[39], widths);
- int pos = appendPattern(result, 0, widths, true);
- int[] narrowWhite = {1};
- pos += appendPattern(result, pos, narrowWhite, false);
- //append next character to byte matrix
- for (int i = 0; i < length; i++)
- {
- int indexInString = Code39Reader.ALPHABET_STRING.IndexOf(contents[i]);
- toIntArray(Code39Reader.CHARACTER_ENCODINGS[indexInString], widths);
- pos += appendPattern(result, pos, widths, true);
- pos += appendPattern(result, pos, narrowWhite, false);
- }
- toIntArray(Code39Reader.CHARACTER_ENCODINGS[39], widths);
- appendPattern(result, pos, widths, true);
- return result;
- }
-
- private static void toIntArray(int a, int[] toReturn)
- {
- for (int i = 0; i < 9; i++)
- {
- int temp = a & (1 << (8 - i));
- toReturn[i] = temp == 0 ? 1 : 2;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/Code93Reader.cs b/zxing.core/xx/oned/Code93Reader.cs
deleted file mode 100644
index d22dd30..0000000
--- a/zxing.core/xx/oned/Code93Reader.cs
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Decodes Code 93 barcodes.
- /// Sean Owen
- ///
- ///
- public sealed class Code93Reader : OneDReader
- {
- // Note that 'abcd' are dummy characters in place of control characters.
- private const String ALPHABET_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*";
- private static readonly char[] ALPHABET = ALPHABET_STRING.ToCharArray();
-
- ///
- /// These represent the encodings of characters, as patterns of wide and narrow bars.
- /// The 9 least-significant bits of each int correspond to the pattern of wide and narrow.
- ///
- private static readonly int[] CHARACTER_ENCODINGS = {
- 0x114, 0x148, 0x144, 0x142, 0x128, 0x124, 0x122, 0x150, 0x112, 0x10A, // 0-9
- 0x1A8, 0x1A4, 0x1A2, 0x194, 0x192, 0x18A, 0x168, 0x164, 0x162, 0x134, // A-J
- 0x11A, 0x158, 0x14C, 0x146, 0x12C, 0x116, 0x1B4, 0x1B2, 0x1AC, 0x1A6, // K-T
- 0x196, 0x19A, 0x16C, 0x166, 0x136, 0x13A, // U-Z
- 0x12E, 0x1D4, 0x1D2, 0x1CA, 0x16E, 0x176, 0x1AE, // - - %
- 0x126, 0x1DA, 0x1D6, 0x132, 0x15E, // Control chars? $-*
- };
- private static readonly int ASTERISK_ENCODING = CHARACTER_ENCODINGS[47];
-
- private readonly StringBuilder decodeRowResult;
- private readonly int[] counters;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public Code93Reader()
- {
- decodeRowResult = new StringBuilder(20);
- counters = new int[6];
- }
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- /// containing encoded string and start/end of barcode
- override public Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- for (var index = 0; index < counters.Length; index++)
- counters[index] = 0;
- decodeRowResult.Length = 0;
-
- int[] start = findAsteriskPattern(row);
- if (start == null)
- return null;
-
- // Read off white space
- int nextStart = row.getNextSet(start[1]);
- int end = row.Size;
-
- char decodedChar;
- int lastStart;
- do
- {
- if (!recordPattern(row, nextStart, counters))
- return null;
-
- int pattern = toPattern(counters);
- if (pattern < 0)
- {
- return null;
- }
- if (!patternToChar(pattern, out decodedChar))
- return null;
- decodeRowResult.Append(decodedChar);
- lastStart = nextStart;
- foreach (int counter in counters)
- {
- nextStart += counter;
- }
- // Read off white space
- nextStart = row.getNextSet(nextStart);
- } while (decodedChar != '*');
- decodeRowResult.Remove(decodeRowResult.Length - 1, 1); // remove asterisk
-
- int lastPatternSize = 0;
- foreach (int counter in counters)
- {
- lastPatternSize += counter;
- }
-
- // Should be at least one more black module
- if (nextStart == end || !row[nextStart])
- {
- return null;
- }
-
- if (decodeRowResult.Length < 2)
- {
- // false positive -- need at least 2 checksum digits
- return null;
- }
-
- if (!checkChecksums(decodeRowResult))
- return null;
- // Remove checksum digits
- decodeRowResult.Length = decodeRowResult.Length - 2;
-
- String resultString = decodeExtended(decodeRowResult);
- if (resultString == null)
- return null;
-
- float left = (start[1] + start[0])/2.0f;
- float right = lastStart + lastPatternSize / 2.0f;
-
- var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)
- ? null
- : (ResultPointCallback) hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(left, rowNumber));
- resultPointCallback(new ResultPoint(right, rowNumber));
- }
-
- return new Result(
- resultString,
- null,
- new[]
- {
- new ResultPoint(left, rowNumber),
- new ResultPoint(right, rowNumber)
- },
- BarcodeFormat.CODE_93);
- }
-
- private int[] findAsteriskPattern(BitArray row)
- {
- int width = row.Size;
- int rowOffset = row.getNextSet(0);
-
- for (var index = 0; index < counters.Length; index++)
- counters[index] = 0;
- int counterPosition = 0;
- int patternStart = rowOffset;
- bool isWhite = false;
- int patternLength = counters.Length;
-
- for (int i = rowOffset; i < width; i++)
- {
- if (row[i] ^ isWhite)
- {
- counters[counterPosition]++;
- }
- else
- {
- if (counterPosition == patternLength - 1)
- {
- if (toPattern(counters) == ASTERISK_ENCODING)
- {
- return new int[] { patternStart, i };
- }
- patternStart += counters[0] + counters[1];
- Array.Copy(counters, 2, counters, 0, patternLength - 2);
- counters[patternLength - 2] = 0;
- counters[patternLength - 1] = 0;
- counterPosition--;
- }
- else
- {
- counterPosition++;
- }
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- return null;
- }
-
- private static int toPattern(int[] counters)
- {
- int max = counters.Length;
- int sum = 0;
- foreach (var counter in counters)
- {
- sum += counter;
- }
- int pattern = 0;
- for (int i = 0; i < max; i++)
- {
- int scaledShifted = (counters[i] << INTEGER_MATH_SHIFT) * 9 / sum;
- int scaledUnshifted = scaledShifted >> INTEGER_MATH_SHIFT;
- if ((scaledShifted & 0xFF) > 0x7F)
- {
- scaledUnshifted++;
- }
- if (scaledUnshifted < 1 || scaledUnshifted > 4)
- {
- return -1;
- }
- if ((i & 0x01) == 0)
- {
- for (int j = 0; j < scaledUnshifted; j++)
- {
- pattern = (pattern << 1) | 0x01;
- }
- }
- else
- {
- pattern <<= scaledUnshifted;
- }
- }
- return pattern;
- }
-
- private static bool patternToChar(int pattern, out char c)
- {
- for (int i = 0; i < CHARACTER_ENCODINGS.Length; i++)
- {
- if (CHARACTER_ENCODINGS[i] == pattern)
- {
- c = ALPHABET[i];
- return true;
- }
- }
- c = '*';
- return false;
- }
-
- private static String decodeExtended(StringBuilder encoded)
- {
- int length = encoded.Length;
- StringBuilder decoded = new StringBuilder(length);
- for (int i = 0; i < length; i++)
- {
- char c = encoded[i];
- if (c >= 'a' && c <= 'd')
- {
- if (i >= length - 1)
- {
- return null;
- }
- char next = encoded[i + 1];
- char decodedChar = '\0';
- switch (c)
- {
- case 'd':
- // +A to +Z map to a to z
- if (next >= 'A' && next <= 'Z')
- {
- decodedChar = (char)(next + 32);
- }
- else
- {
- return null;
- }
- break;
- case 'a':
- // $A to $Z map to control codes SH to SB
- if (next >= 'A' && next <= 'Z')
- {
- decodedChar = (char)(next - 64);
- }
- else
- {
- return null;
- }
- break;
- case 'b':
- // %A to %E map to control codes ESC to US
- if (next >= 'A' && next <= 'E')
- {
- decodedChar = (char)(next - 38);
- }
- else if (next >= 'F' && next <= 'W')
- {
- decodedChar = (char)(next - 11);
- }
- else
- {
- return null;
- }
- break;
- case 'c':
- // /A to /O map to ! to , and /Z maps to :
- if (next >= 'A' && next <= 'O')
- {
- decodedChar = (char)(next - 32);
- }
- else if (next == 'Z')
- {
- decodedChar = ':';
- }
- else
- {
- return null;
- }
- break;
- }
- decoded.Append(decodedChar);
- // bump up i again since we read two characters
- i++;
- }
- else
- {
- decoded.Append(c);
- }
- }
- return decoded.ToString();
- }
-
- private static bool checkChecksums(StringBuilder result)
- {
- int length = result.Length;
- if (!checkOneChecksum(result, length - 2, 20))
- return false;
- if (!checkOneChecksum(result, length - 1, 15))
- return false;
- return true;
- }
-
- private static bool checkOneChecksum(StringBuilder result, int checkPosition, int weightMax)
- {
- int weight = 1;
- int total = 0;
- for (int i = checkPosition - 1; i >= 0; i--)
- {
- total += weight * ALPHABET_STRING.IndexOf(result[i]);
- if (++weight > weightMax)
- {
- weight = 1;
- }
- }
- if (result[checkPosition] != ALPHABET[total % 47])
- {
- return false;
- }
- return true;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/EAN13Reader.cs b/zxing.core/xx/oned/EAN13Reader.cs
deleted file mode 100644
index 7550b9c..0000000
--- a/zxing.core/xx/oned/EAN13Reader.cs
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Implements decoding of the EAN-13 format.
- ///
- /// dswitkin@google.com (Daniel Switkin)
- /// Sean Owen
- /// alasdair@google.com (Alasdair Mackintosh)
- ///
- public sealed class EAN13Reader : UPCEANReader
- {
- // For an EAN-13 barcode, the first digit is represented by the parities used
- // to encode the next six digits, according to the table below. For example,
- // if the barcode is 5 123456 789012 then the value of the first digit is
- // signified by using odd for '1', even for '2', even for '3', odd for '4',
- // odd for '5', and even for '6'. See http://en.wikipedia.org/wiki/EAN-13
- //
- // Parity of next 6 digits
- // Digit 0 1 2 3 4 5
- // 0 Odd Odd Odd Odd Odd Odd
- // 1 Odd Odd Even Odd Even Even
- // 2 Odd Odd Even Even Odd Even
- // 3 Odd Odd Even Even Even Odd
- // 4 Odd Even Odd Odd Even Even
- // 5 Odd Even Even Odd Odd Even
- // 6 Odd Even Even Even Odd Odd
- // 7 Odd Even Odd Even Odd Even
- // 8 Odd Even Odd Even Even Odd
- // 9 Odd Even Even Odd Even Odd
- //
- // Note that the encoding for '0' uses the same parity as a UPC barcode. Hence
- // a UPC barcode can be converted to an EAN-13 barcode by prepending a 0.
- //
- // The encoding is represented by the following array, which is a bit pattern
- // using Odd = 0 and Even = 1. For example, 5 is represented by:
- //
- // Odd Even Even Odd Odd Even
- // in binary:
- // 0 1 1 0 0 1 == 0x19
- //
- internal static int[] FIRST_DIGIT_ENCODINGS = {
- 0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A
- };
-
- private readonly int[] decodeMiddleCounters;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public EAN13Reader()
- {
- decodeMiddleCounters = new int[4];
- }
-
- ///
- /// Subclasses override this to decode the portion of a barcode between the start
- /// and end guard patterns.
- ///
- /// row of black/white values to search
- /// start/end offset of start guard pattern
- /// to append decoded chars to
- ///
- /// horizontal offset of first pixel after the "middle" that was decoded or -1 if decoding could not complete successfully
- ///
- override protected internal int decodeMiddle(BitArray row,
- int[] startRange,
- StringBuilder resultString)
- {
- int[] counters = decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- int end = row.Size;
- int rowOffset = startRange[1];
-
- int lgPatternFound = 0;
-
- for (int x = 0; x < 6 && rowOffset < end; x++)
- {
- int bestMatch;
- if (!decodeDigit(row, counters, rowOffset, L_AND_G_PATTERNS, out bestMatch))
- return -1;
- resultString.Append((char) ('0' + bestMatch%10));
- foreach (int counter in counters)
- {
- rowOffset += counter;
- }
- if (bestMatch >= 10)
- {
- lgPatternFound |= 1 << (5 - x);
- }
- }
-
- if (!determineFirstDigit(resultString, lgPatternFound))
- return -1;
-
- int[] middleRange = findGuardPattern(row, rowOffset, true, MIDDLE_PATTERN);
- if (middleRange == null)
- return -1;
- rowOffset = middleRange[1];
-
- for (int x = 0; x < 6 && rowOffset < end; x++)
- {
- int bestMatch;
- if (!decodeDigit(row, counters, rowOffset, L_PATTERNS, out bestMatch))
- return -1;
- resultString.Append((char) ('0' + bestMatch));
- foreach (int counter in counters)
- {
- rowOffset += counter;
- }
- }
-
- return rowOffset;
- }
-
- ///
- /// Get the format of this decoder.
- /// The 1D format.
- ///
- override internal BarcodeFormat BarcodeFormat
- {
- get { return BarcodeFormat.EAN_13; }
- }
-
- ///
- /// Based on pattern of odd-even ('L' and 'G') patterns used to encoded the explicitly-encoded
- /// digits in a barcode, determines the implicitly encoded first digit and adds it to the
- /// result string.
- ///
- /// string to insert decoded first digit into
- /// int whose bits indicates the pattern of odd/even L/G patterns used to
- /// encode digits
- /// -1 if first digit cannot be determined
- private static bool determineFirstDigit(StringBuilder resultString, int lgPatternFound)
- {
- for (int d = 0; d < 10; d++)
- {
- if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d])
- {
- resultString.Insert(0, new[] { (char)('0' + d) });
- return true;
- }
- }
- return false;
- }
- }
-}
diff --git a/zxing.core/xx/oned/EAN13Writer.cs b/zxing.core/xx/oned/EAN13Writer.cs
deleted file mode 100644
index 2036a09..0000000
--- a/zxing.core/xx/oned/EAN13Writer.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// This object renders an EAN13 code as a .
- /// aripollak@gmail.com (Ari Pollak)
- ///
- public sealed class EAN13Writer : UPCEANWriter
- {
- private const int CODE_WIDTH = 3 + // start guard
- (7 * 6) + // left bars
- 5 + // middle guard
- (7 * 6) + // right bars
- 3; // end guard
-
- ///
- /// Encode the contents following specified format.
- /// {@code width} and {@code height} are required size. This method may return bigger size
- /// {@code BitMatrix} when specified size is too small. The user can set both {@code width} and
- /// {@code height} to zero to get minimum size barcode. If negative value is set to {@code width}
- /// or {@code height}, {@code IllegalArgumentException} is thrown.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public override BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (format != BarcodeFormat.EAN_13)
- {
- throw new ArgumentException("Can only encode EAN_13, but got " + format);
- }
-
- return base.encode(contents, format, width, height, hints);
- }
-
- ///
- /// Encode the contents to byte array expression of one-dimensional barcode.
- /// Start code and end code should be included in result, and side margins should not be included.
- /// a {@code boolean[]} of horizontal pixels (false = white, true = black)
- ///
- ///
- ///
- override public bool[] encode(String contents)
- {
- if (contents.Length < 12 || contents.Length > 13)
- {
- throw new ArgumentException(
- "Requested contents should be 12 (without checksum digit) or 13 digits long, but got " + contents.Length);
- }
- foreach (var ch in contents)
- {
- if (!Char.IsDigit(ch))
- throw new ArgumentException("Requested contents should only contain digits, but got '" + ch + "'");
- }
-
- if (contents.Length == 12)
- {
- contents = CalculateChecksumDigitModulo10(contents);
- }
- else
- {
- if (!UPCEANReader.checkStandardUPCEANChecksum(contents))
- {
- throw new ArgumentException("Contents do not pass checksum");
- }
- }
-
- int firstDigit = Int32.Parse(contents.Substring(0, 1));
- int parities = EAN13Reader.FIRST_DIGIT_ENCODINGS[firstDigit];
- var result = new bool[CODE_WIDTH];
- int pos = 0;
-
- pos += appendPattern(result, pos, UPCEANReader.START_END_PATTERN, true);
-
- // See {@link #EAN13Reader} for a description of how the first digit & left bars are encoded
- for (int i = 1; i <= 6; i++)
- {
- int digit = Int32.Parse(contents.Substring(i, 1));
- if ((parities >> (6 - i) & 1) == 1)
- {
- digit += 10;
- }
- pos += appendPattern(result, pos, UPCEANReader.L_AND_G_PATTERNS[digit], false);
- }
-
- pos += appendPattern(result, pos, UPCEANReader.MIDDLE_PATTERN, false);
-
- for (int i = 7; i <= 12; i++)
- {
- int digit = Int32.Parse(contents.Substring(i, 1));
- pos += appendPattern(result, pos, UPCEANReader.L_PATTERNS[digit], true);
- }
- appendPattern(result, pos, UPCEANReader.START_END_PATTERN, true);
-
- return result;
- }
- }
-}
diff --git a/zxing.core/xx/oned/EAN8Reader.cs b/zxing.core/xx/oned/EAN8Reader.cs
deleted file mode 100644
index e855ace..0000000
--- a/zxing.core/xx/oned/EAN8Reader.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Implements decoding of the EAN-8 format.
- /// Sean Owen
- ///
- public sealed class EAN8Reader : UPCEANReader
- {
- private readonly int[] decodeMiddleCounters;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public EAN8Reader()
- {
- decodeMiddleCounters = new int[4];
- }
-
- ///
- /// Decodes the middle.
- ///
- /// The row.
- /// The start range.
- /// The result.
- ///
- override protected internal int decodeMiddle(BitArray row,
- int[] startRange,
- StringBuilder result)
- {
- int[] counters = decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- int end = row.Size;
- int rowOffset = startRange[1];
-
- for (int x = 0; x < 4 && rowOffset < end; x++)
- {
- int bestMatch;
- if (!decodeDigit(row, counters, rowOffset, L_PATTERNS, out bestMatch))
- return -1;
- result.Append((char)('0' + bestMatch));
- foreach (int counter in counters)
- {
- rowOffset += counter;
- }
- }
-
- int[] middleRange = findGuardPattern(row, rowOffset, true, MIDDLE_PATTERN);
- if (middleRange == null)
- return -1;
- rowOffset = middleRange[1];
-
- for (int x = 0; x < 4 && rowOffset < end; x++)
- {
- int bestMatch;
- if (!decodeDigit(row, counters, rowOffset, L_PATTERNS, out bestMatch))
- return -1;
- result.Append((char)('0' + bestMatch));
- foreach (int counter in counters)
- {
- rowOffset += counter;
- }
- }
-
- return rowOffset;
- }
-
- ///
- /// Get the format of this decoder.
- /// The 1D format.
- ///
- override internal BarcodeFormat BarcodeFormat
- {
- get { return BarcodeFormat.EAN_8; }
- }
- }
-}
diff --git a/zxing.core/xx/oned/EAN8Writer.cs b/zxing.core/xx/oned/EAN8Writer.cs
deleted file mode 100644
index 0220f2e..0000000
--- a/zxing.core/xx/oned/EAN8Writer.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// This object renders an EAN8 code as a .
- /// aripollak@gmail.com (Ari Pollak)
- ///
- public sealed class EAN8Writer : UPCEANWriter
- {
- private const int CODE_WIDTH = 3 + // start guard
- (7 * 4) + // left bars
- 5 + // middle guard
- (7 * 4) + // right bars
- 3; // end guard
-
- ///
- /// Encode the contents following specified format.
- /// {@code width} and {@code height} are required size. This method may return bigger size
- /// {@code BitMatrix} when specified size is too small. The user can set both {@code width} and
- /// {@code height} to zero to get minimum size barcode. If negative value is set to {@code width}
- /// or {@code height}, {@code IllegalArgumentException} is thrown.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public override BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (format != BarcodeFormat.EAN_8)
- {
- throw new ArgumentException("Can only encode EAN_8, but got "
- + format);
- }
-
- return base.encode(contents, format, width, height, hints);
- }
-
- ///
- ///
- ///
- /// a byte array of horizontal pixels (false = white, true = black)
- ///
- override public bool[] encode(String contents)
- {
- if (contents.Length < 7 || contents.Length > 8)
- {
- throw new ArgumentException(
- "Requested contents should be 7 (without checksum digit) or 8 digits long, but got " + contents.Length);
- }
- foreach (var ch in contents)
- {
- if (!Char.IsDigit(ch))
- throw new ArgumentException("Requested contents should only contain digits, but got '" + ch + "'");
- }
- if (contents.Length == 7)
- contents = CalculateChecksumDigitModulo10(contents);
-
- var result = new bool[CODE_WIDTH];
- int pos = 0;
-
- pos += appendPattern(result, pos, UPCEANReader.START_END_PATTERN, true);
-
- for (int i = 0; i <= 3; i++)
- {
- int digit = Int32.Parse(contents.Substring(i, 1));
- pos += appendPattern(result, pos, UPCEANReader.L_PATTERNS[digit], false);
- }
-
- pos += appendPattern(result, pos, UPCEANReader.MIDDLE_PATTERN, false);
-
- for (int i = 4; i <= 7; i++)
- {
- int digit = Int32.Parse(contents.Substring(i, 1));
- pos += appendPattern(result, pos, UPCEANReader.L_PATTERNS[digit], true);
- }
- appendPattern(result, pos, UPCEANReader.START_END_PATTERN, true);
-
- return result;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/EANManufacturerOrgSupport.cs b/zxing.core/xx/oned/EANManufacturerOrgSupport.cs
deleted file mode 100644
index adad206..0000000
--- a/zxing.core/xx/oned/EANManufacturerOrgSupport.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-
-namespace ZXing.OneD
-{
- ///
- /// Records EAN prefix to GS1 Member Organization, where the member organization
- /// correlates strongly with a country. This is an imperfect means of identifying
- /// a country of origin by EAN-13 barcode value. See
- ///
- /// http://en.wikipedia.org/wiki/List_of_GS1_country_codes.
- ///
- /// Sean Owen
- ///
- internal sealed class EANManufacturerOrgSupport
- {
- private List ranges = new List();
- private List countryIdentifiers = new List();
-
- internal String lookupCountryIdentifier(String productCode)
- {
- initIfNeeded();
- int prefix = Int32.Parse(productCode.Substring(0, 3));
- int max = ranges.Count;
- for (int i = 0; i < max; i++)
- {
- int[] range = ranges[i];
- int start = range[0];
- if (prefix < start)
- {
- return null;
- }
- int end = range.Length == 1 ? start : range[1];
- if (prefix <= end)
- {
- return countryIdentifiers[i];
- }
- }
- return null;
- }
-
- private void add(int[] range, String id)
- {
- ranges.Add(range);
- countryIdentifiers.Add(id);
- }
-
- private void initIfNeeded()
- {
- if (ranges.Count != 0)
- {
- return;
- }
- add(new int[] {0, 19}, "US/CA");
- add(new int[] {30, 39}, "US");
- add(new int[] {60, 139}, "US/CA");
- add(new int[] {300, 379}, "FR");
- add(new int[] {380}, "BG");
- add(new int[] {383}, "SI");
- add(new int[] {385}, "HR");
- add(new int[] {387}, "BA");
- add(new int[] {400, 440}, "DE");
- add(new int[] {450, 459}, "JP");
- add(new int[] {460, 469}, "RU");
- add(new int[] {471}, "TW");
- add(new int[] {474}, "EE");
- add(new int[] {475}, "LV");
- add(new int[] {476}, "AZ");
- add(new int[] {477}, "LT");
- add(new int[] {478}, "UZ");
- add(new int[] {479}, "LK");
- add(new int[] {480}, "PH");
- add(new int[] {481}, "BY");
- add(new int[] {482}, "UA");
- add(new int[] {484}, "MD");
- add(new int[] {485}, "AM");
- add(new int[] {486}, "GE");
- add(new int[] {487}, "KZ");
- add(new int[] {489}, "HK");
- add(new int[] {490, 499}, "JP");
- add(new int[] {500, 509}, "GB");
- add(new int[] {520}, "GR");
- add(new int[] {528}, "LB");
- add(new int[] {529}, "CY");
- add(new int[] {531}, "MK");
- add(new int[] {535}, "MT");
- add(new int[] {539}, "IE");
- add(new int[] {540, 549}, "BE/LU");
- add(new int[] {560}, "PT");
- add(new int[] {569}, "IS");
- add(new int[] {570, 579}, "DK");
- add(new int[] {590}, "PL");
- add(new int[] {594}, "RO");
- add(new int[] {599}, "HU");
- add(new int[] {600, 601}, "ZA");
- add(new int[] {603}, "GH");
- add(new int[] {608}, "BH");
- add(new int[] {609}, "MU");
- add(new int[] {611}, "MA");
- add(new int[] {613}, "DZ");
- add(new int[] {616}, "KE");
- add(new int[] {618}, "CI");
- add(new int[] {619}, "TN");
- add(new int[] {621}, "SY");
- add(new int[] {622}, "EG");
- add(new int[] {624}, "LY");
- add(new int[] {625}, "JO");
- add(new int[] {626}, "IR");
- add(new int[] {627}, "KW");
- add(new int[] {628}, "SA");
- add(new int[] {629}, "AE");
- add(new int[] {640, 649}, "FI");
- add(new int[] {690, 695}, "CN");
- add(new int[] {700, 709}, "NO");
- add(new int[] {729}, "IL");
- add(new int[] {730, 739}, "SE");
- add(new int[] {740}, "GT");
- add(new int[] {741}, "SV");
- add(new int[] {742}, "HN");
- add(new int[] {743}, "NI");
- add(new int[] {744}, "CR");
- add(new int[] {745}, "PA");
- add(new int[] {746}, "DO");
- add(new int[] {750}, "MX");
- add(new int[] {754, 755}, "CA");
- add(new int[] {759}, "VE");
- add(new int[] {760, 769}, "CH");
- add(new int[] {770}, "CO");
- add(new int[] {773}, "UY");
- add(new int[] {775}, "PE");
- add(new int[] {777}, "BO");
- add(new int[] {779}, "AR");
- add(new int[] {780}, "CL");
- add(new int[] {784}, "PY");
- add(new int[] {785}, "PE");
- add(new int[] {786}, "EC");
- add(new int[] {789, 790}, "BR");
- add(new int[] {800, 839}, "IT");
- add(new int[] {840, 849}, "ES");
- add(new int[] {850}, "CU");
- add(new int[] {858}, "SK");
- add(new int[] {859}, "CZ");
- add(new int[] {860}, "YU");
- add(new int[] {865}, "MN");
- add(new int[] {867}, "KP");
- add(new int[] {868, 869}, "TR");
- add(new int[] {870, 879}, "NL");
- add(new int[] {880}, "KR");
- add(new int[] {885}, "TH");
- add(new int[] {888}, "SG");
- add(new int[] {890}, "IN");
- add(new int[] {893}, "VN");
- add(new int[] {896}, "PK");
- add(new int[] {899}, "ID");
- add(new int[] {900, 919}, "AT");
- add(new int[] {930, 939}, "AU");
- add(new int[] {940, 949}, "AZ");
- add(new int[] {955}, "MY");
- add(new int[] {958}, "MO");
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/ITFReader.cs b/zxing.core/xx/oned/ITFReader.cs
deleted file mode 100644
index 48115c9..0000000
--- a/zxing.core/xx/oned/ITFReader.cs
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Implements decoding of the ITF format, or Interleaved Two of Five.
- ///
- /// This Reader will scan ITF barcodes of certain lengths only.
- /// At the moment it reads length 6, 8, 10, 12, 14, 16, 18, 20, 24, 44 and 48 as these have appeared "in the wild". Not all
- /// lengths are scanned, especially shorter ones, to avoid false positives. This in turn is due to a lack of
- /// required checksum function.
- ///
- /// The checksum is optional and is not applied by this Reader. The consumer of the decoded
- /// value will have to apply a checksum if required.
- ///
- /// http://en.wikipedia.org/wiki/Interleaved_2_of_5
- /// is a great reference for Interleaved 2 of 5 information.
- ///
- /// kevin.osullivan@sita.aero, SITA Lab.
- ///
- public sealed class ITFReader : OneDReader
- {
- private static readonly int MAX_AVG_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f);
- private static readonly int MAX_INDIVIDUAL_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.78f);
-
- private const int W = 3; // Pixel width of a wide line
- private const int N = 1; // Pixed width of a narrow line
-
- ///
- /// Valid ITF lengths. Anything longer than the largest value is also allowed.
- ///
- private static readonly int[] DEFAULT_ALLOWED_LENGTHS = { 6, 8, 10, 12, 14 };
- private const int LARGEST_DEFAULT_ALLOWED_LENGTH = 14;
-
- // Stores the actual narrow line width of the image being decoded.
- private int narrowLineWidth = -1;
-
- ///
- /// Start/end guard pattern.
- ///
- /// Note: The end pattern is reversed because the row is reversed before
- /// searching for the END_PATTERN
- ///
- private static readonly int[] START_PATTERN = { N, N, N, N };
- private static readonly int[] END_PATTERN_REVERSED = { N, N, W };
-
- ///
- /// Patterns of Wide / Narrow lines to indicate each digit
- ///
- internal static int[][] PATTERNS = new int[][]
- {
- new int[] {N, N, W, W, N}, // 0
- new int[] {W, N, N, N, W}, // 1
- new int[] {N, W, N, N, W}, // 2
- new int[] {W, W, N, N, N}, // 3
- new int[] {N, N, W, N, W}, // 4
- new int[] {W, N, W, N, N}, // 5
- new int[] {N, W, W, N, N}, // 6
- new int[] {N, N, N, W, W}, // 7
- new int[] {W, N, N, W, N}, // 8
- new int[] {N, W, N, W, N} // 9
- };
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- ///
- /// containing encoded string and start/end of barcode
- ///
- override public Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- // Find out where the Middle section (payload) starts & ends
- int[] startRange = decodeStart(row);
- if (startRange == null)
- return null;
-
- int[] endRange = decodeEnd(row);
- if (endRange == null)
- return null;
-
- StringBuilder result = new StringBuilder(20);
- if (!decodeMiddle(row, startRange[1], endRange[0], result))
- return null;
-
- String resultString = result.ToString();
-
- int[] allowedLengths = null;
- int maxAllowedLength = LARGEST_DEFAULT_ALLOWED_LENGTH;
- if (hints != null && hints.ContainsKey(DecodeHintType.ALLOWED_LENGTHS))
- {
- allowedLengths = (int[]) hints[DecodeHintType.ALLOWED_LENGTHS];
- maxAllowedLength = 0;
- }
- if (allowedLengths == null)
- {
- allowedLengths = DEFAULT_ALLOWED_LENGTHS;
- maxAllowedLength = LARGEST_DEFAULT_ALLOWED_LENGTH;
- }
-
- // To avoid false positives with 2D barcodes (and other patterns), make
- // an assumption that the decoded string must be a 'standard' length if it's short
- int length = resultString.Length;
- bool lengthOK = length > LARGEST_DEFAULT_ALLOWED_LENGTH;
- if (!lengthOK)
- {
- foreach (int allowedLength in allowedLengths)
- {
- if (length == allowedLength)
- {
- lengthOK = true;
- break;
- }
- if (allowedLength > maxAllowedLength)
- {
- maxAllowedLength = allowedLength;
- }
- }
- if (!lengthOK && length > maxAllowedLength)
- {
- lengthOK = true;
- }
- if (!lengthOK)
- {
- return null;
- }
- }
-
- var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)
- ? null
- : (ResultPointCallback) hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(startRange[1], rowNumber));
- resultPointCallback(new ResultPoint(endRange[0], rowNumber));
- }
-
- return new Result(
- resultString,
- null, // no natural byte representation for these barcodes
- new ResultPoint[]
- {
- new ResultPoint(startRange[1], rowNumber),
- new ResultPoint(endRange[0], rowNumber)
- },
- BarcodeFormat.ITF);
- }
-
- ///
- ///
- /// row of black/white values to search
- /// offset of start pattern
- /// The payload end.
- /// to append decoded chars to
- ///
- /// false, if decoding could not complete successfully
- ///
- private static bool decodeMiddle(BitArray row,
- int payloadStart,
- int payloadEnd,
- StringBuilder resultString)
- {
- // Digits are interleaved in pairs - 5 black lines for one digit, and the
- // 5
- // interleaved white lines for the second digit.
- // Therefore, need to scan 10 lines and then
- // split these into two arrays
- int[] counterDigitPair = new int[10];
- int[] counterBlack = new int[5];
- int[] counterWhite = new int[5];
-
- while (payloadStart < payloadEnd)
- {
- // Get 10 runs of black/white.
- if (!recordPattern(row, payloadStart, counterDigitPair))
- return false;
-
- // Split them into each array
- for (int k = 0; k < 5; k++)
- {
- int twoK = k << 1;
- counterBlack[k] = counterDigitPair[twoK];
- counterWhite[k] = counterDigitPair[twoK + 1];
- }
-
- int bestMatch;
- if (!decodeDigit(counterBlack, out bestMatch))
- return false;
- resultString.Append((char)('0' + bestMatch));
- if (!decodeDigit(counterWhite, out bestMatch))
- return false;
- resultString.Append((char)('0' + bestMatch));
-
- foreach (int counterDigit in counterDigitPair)
- {
- payloadStart += counterDigit;
- }
- }
-
- return true;
- }
-
- ///
- /// Identify where the start of the middle / payload section starts.
- ///
- /// row of black/white values to search
- /// Array, containing index of start of 'start block' and end of 'start block'
- int[] decodeStart(BitArray row)
- {
- int endStart = skipWhiteSpace(row);
- if (endStart < 0)
- return null;
-
- int[] startPattern = findGuardPattern(row, endStart, START_PATTERN);
- if (startPattern == null)
- return null;
-
- // Determine the width of a narrow line in pixels. We can do this by
- // getting the width of the start pattern and dividing by 4 because its
- // made up of 4 narrow lines.
- narrowLineWidth = (startPattern[1] - startPattern[0]) >> 2;
-
- if (!validateQuietZone(row, startPattern[0]))
- return null;
-
- return startPattern;
- }
-
- ///
- /// The start & end patterns must be pre/post fixed by a quiet zone. This
- /// zone must be at least 10 times the width of a narrow line. Scan back until
- /// we either get to the start of the barcode or match the necessary number of
- /// quiet zone pixels.
- ///
- /// Note: Its assumed the row is reversed when using this method to find
- /// quiet zone after the end pattern.
- ///
- /// ref: http://www.barcode-1.net/i25code.html
- ///
- /// bit array representing the scanned barcode.
- /// index into row of the start or end pattern.
- /// false, if the quiet zone cannot be found
- private bool validateQuietZone(BitArray row, int startPattern)
- {
- int quietCount = this.narrowLineWidth * 10; // expect to find this many pixels of quiet zone
-
- // if there are not so many pixel at all let's try as many as possible
- quietCount = quietCount < startPattern ? quietCount : startPattern;
-
- for (int i = startPattern - 1; quietCount > 0 && i >= 0; i--)
- {
- if (row[i])
- {
- break;
- }
- quietCount--;
- }
- if (quietCount != 0)
- {
- // Unable to find the necessary number of quiet zone pixels.
- return false;
- }
- return true;
- }
-
- ///
- /// Skip all whitespace until we get to the first black line.
- ///
- /// row of black/white values to search
- /// index of the first black line or -1 if no black lines are found in the row.
- private static int skipWhiteSpace(BitArray row)
- {
- int width = row.Size;
- int endStart = row.getNextSet(0);
- if (endStart == width)
- {
- return -1;
- }
-
- return endStart;
- }
-
- ///
- /// Identify where the end of the middle / payload section ends.
- ///
- /// row of black/white values to search
- /// Array, containing index of start of 'end block' and end of 'end
- /// block' or null, if nothing found
- int[] decodeEnd(BitArray row)
- {
- // For convenience, reverse the row and then
- // search from 'the start' for the end block
- row.reverse();
- int endStart = skipWhiteSpace(row);
- if (endStart < 0)
- return null;
- int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
- if (endPattern == null)
- {
- row.reverse();
- return null;
- }
-
- // The start & end patterns must be pre/post fixed by a quiet zone. This
- // zone must be at least 10 times the width of a narrow line.
- // ref: http://www.barcode-1.net/i25code.html
- if (!validateQuietZone(row, endPattern[0]))
- {
- row.reverse();
- return null;
- }
-
- // Now recalculate the indices of where the 'endblock' starts & stops to
- // accommodate
- // the reversed nature of the search
- int temp = endPattern[0];
- endPattern[0] = row.Size - endPattern[1];
- endPattern[1] = row.Size - temp;
-
- row.reverse();
- return endPattern;
- }
-
- ///
- ///
- /// row of black/white values to search
- /// position to start search
- /// pattern of counts of number of black and white pixels that are being searched for as a pattern
- /// start/end horizontal offset of guard pattern, as an array of two ints
- private static int[] findGuardPattern(BitArray row,
- int rowOffset,
- int[] pattern)
- {
-
- // TODO: This is very similar to implementation in UPCEANReader. Consider if they can be
- // merged to a single method.
- int patternLength = pattern.Length;
- int[] counters = new int[patternLength];
- int width = row.Size;
- bool isWhite = false;
-
- int counterPosition = 0;
- int patternStart = rowOffset;
- for (int x = rowOffset; x < width; x++)
- {
- if (row[x] ^ isWhite)
- {
- counters[counterPosition]++;
- }
- else
- {
- if (counterPosition == patternLength - 1)
- {
- if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE)
- {
- return new int[] { patternStart, x };
- }
- patternStart += counters[0] + counters[1];
- Array.Copy(counters, 2, counters, 0, patternLength - 2);
- counters[patternLength - 2] = 0;
- counters[patternLength - 1] = 0;
- counterPosition--;
- }
- else
- {
- counterPosition++;
- }
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- return null;
- }
-
- ///
- /// Attempts to decode a sequence of ITF black/white lines into single
- /// digit.
- ///
- /// the counts of runs of observed black/white/black/... values
- /// The decoded digit
- ///
- /// false, if digit cannot be decoded
- ///
- private static bool decodeDigit(int[] counters, out int bestMatch)
- {
- int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
- bestMatch = -1;
- int max = PATTERNS.Length;
- for (int i = 0; i < max; i++)
- {
- int[] pattern = PATTERNS[i];
- int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
- if (variance < bestVariance)
- {
- bestVariance = variance;
- bestMatch = i;
- }
- }
- return bestMatch >= 0;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/ITFWriter.cs b/zxing.core/xx/oned/ITFWriter.cs
deleted file mode 100644
index f2f816e..0000000
--- a/zxing.core/xx/oned/ITFWriter.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// This object renders a ITF code as a .
- ///
- /// erik.barbara@gmail.com (Erik Barbara)
- ///
- public sealed class ITFWriter : OneDimensionalCodeWriter
- {
- private static readonly int[] START_PATTERN = {1, 1, 1, 1};
- private static readonly int[] END_PATTERN = {3, 1, 1};
-
- ///
- /// Encode the contents following specified format.
- /// {@code width} and {@code height} are required size. This method may return bigger size
- /// {@code BitMatrix} when specified size is too small. The user can set both {@code width} and
- /// {@code height} to zero to get minimum size barcode. If negative value is set to {@code width}
- /// or {@code height}, {@code IllegalArgumentException} is thrown.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public override BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (format != BarcodeFormat.ITF)
- {
- throw new ArgumentException("Can only encode ITF, but got " + format);
- }
-
- return base.encode(contents, format, width, height, hints);
- }
-
- ///
- /// Encode the contents to bool array expression of one-dimensional barcode.
- /// Start code and end code should be included in result, and side margins should not be included.
- /// a {@code bool[]} of horizontal pixels (false = white, true = black)
- ///
- ///
- ///
- override public bool[] encode(String contents)
- {
- int length = contents.Length;
- if (length % 2 != 0)
- {
- throw new ArgumentException("The lenght of the input should be even");
- }
- if (length > 80)
- {
- throw new ArgumentException(
- "Requested contents should be less than 80 digits long, but got " + length);
- }
- for (var i = 0; i < length; i++)
- {
- if (!Char.IsDigit(contents[i]))
- throw new ArgumentException("Requested contents should only contain digits, but got '" + contents[i] + "'");
- }
-
- var result = new bool[9 + 9 * length];
- int pos = appendPattern(result, 0, START_PATTERN, true);
- for (int i = 0; i < length; i += 2)
- {
- int one = Convert.ToInt32(contents[i].ToString(), 10);
- int two = Convert.ToInt32(contents[i + 1].ToString(), 10);
- int[] encoding = new int[18];
- for (int j = 0; j < 5; j++)
- {
- encoding[j << 1] = ITFReader.PATTERNS[one][j];
- encoding[(j << 1) + 1] = ITFReader.PATTERNS[two][j];
- }
- pos += appendPattern(result, pos, encoding, true);
- }
- appendPattern(result, pos, END_PATTERN, true);
-
- return result;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/MSIReader.cs b/zxing.core/xx/oned/MSIReader.cs
deleted file mode 100644
index 8ce6d8d..0000000
--- a/zxing.core/xx/oned/MSIReader.cs
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * 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 System.Collections.Generic;
-using System.Text;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Decodes MSI barcodes.
- ///
- public sealed class MSIReader : OneDReader
- {
- internal static String ALPHABET_STRING = "0123456789";
- private static readonly char[] ALPHABET = ALPHABET_STRING.ToCharArray();
-
- ///
- /// These represent the encodings of characters, as patterns of wide and narrow bars.
- /// The 9 least-significant bits of each int correspond to the pattern of wide and narrow,
- /// with 1s representing "wide" and 0s representing narrow.
- ///
- internal static int[] CHARACTER_ENCODINGS = {
- 0x924, 0x926, 0x934, 0x936, 0x9A4, 0x9A6, 0x9B4, 0x9B6, 0xD24, 0xD26 // 0-9
- };
-
- private const int START_ENCODING = 0x06;
- private const int END_ENCODING = 0x09;
-
- private readonly bool usingCheckDigit;
- private readonly StringBuilder decodeRowResult;
- private readonly int[] counters;
- private int averageCounterWidth;
-
- ///
- /// Creates a reader that assumes all encoded data is data, and does not treat the final
- /// character as a check digit.
- ///
- public MSIReader()
- : this(false)
- {
- }
-
- ///
- /// Creates a reader that can be configured to check the last character as a check digit,
- ///
- /// if true, treat the last data character as a check digit, not
- /// data, and verify that the checksum passes.
- public MSIReader(bool usingCheckDigit)
- {
- this.usingCheckDigit = usingCheckDigit;
- decodeRowResult = new StringBuilder(20);
- counters = new int[8];
- }
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- /// containing encoded string and start/end of barcode
- override public Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- for (var index = 0; index < counters.Length; index++)
- counters[index] = 0;
- decodeRowResult.Length = 0;
-
- int[] start = findStartPattern(row, counters);
- if (start == null)
- return null;
-
- // Read off white space
- int nextStart = row.getNextSet(start[1]);
-
- char decodedChar;
- int lastStart = nextStart;
- int pattern;
- do
- {
- if (!recordPattern(row, nextStart, counters, 8))
- {
- // not enough bars for a number but perhaps enough for the end pattern
- var endPattern = findEndPattern(row, nextStart, counters);
- if (endPattern == null)
- return null;
- lastStart = nextStart;
- nextStart = endPattern[1];
- break;
- }
- pattern = toPattern(counters, 8);
- if (!patternToChar(pattern, out decodedChar))
- {
- // pattern doesn't result in an encoded number
- // but it could be the end pattern followed by some black areas
- var endPattern = findEndPattern(row, nextStart, counters);
- if (endPattern == null)
- return null;
- lastStart = nextStart;
- nextStart = endPattern[1];
- break;
- }
- decodeRowResult.Append(decodedChar);
- lastStart = nextStart;
- foreach (int counter in counters)
- {
- nextStart += counter;
- }
- // Read off white space
- nextStart = row.getNextSet(nextStart);
- } while (decodedChar != '*');
-
- // at least 3 digits to prevent false positives within other kind
- // of codes like PDF417
- if (decodeRowResult.Length < 3)
- {
- return null;
- }
-
- var rawBytes = Encoding.UTF8.GetBytes(decodeRowResult.ToString());
- var resultString = decodeRowResult.ToString();
-
- if (usingCheckDigit)
- {
- var resultStringWithoutChecksum = resultString.Substring(0, resultString.Length - 1);
- int checkSum = CalculateChecksumLuhn(resultStringWithoutChecksum);
- if ((char)(checkSum + 48) != resultString[resultStringWithoutChecksum.Length])
- {
- return null;
- }
- }
-
- float left = (float)(start[1] + start[0]) / 2.0f;
- float right = (float)(nextStart + lastStart) / 2.0f;
-
- var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)
- ? null
- : (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(left, rowNumber));
- resultPointCallback(new ResultPoint(right, rowNumber));
- }
-
- return new Result(
- resultString,
- rawBytes,
- new[]
- {
- new ResultPoint(left, rowNumber),
- new ResultPoint(right, rowNumber)
- },
- BarcodeFormat.MSI);
- }
-
- private int[] findStartPattern(BitArray row, int[] counters)
- {
- const int patternLength = 2;
-
- int width = row.Size;
- int rowOffset = row.getNextSet(0);
-
- int counterPosition = 0;
- int patternStart = rowOffset;
- bool isWhite = false;
-
- counters[0] = 0;
- counters[1] = 0;
- for (int i = rowOffset; i < width; i++)
- {
- if (row[i] ^ isWhite)
- {
- counters[counterPosition]++;
- }
- else
- {
- if (counterPosition == patternLength - 1)
- {
- // narrow and wide areas should be as near as possible to factor 2
- // lets say we will check 1.5 <= factor <= 5
- var factorNarrowToWide = ((float)counters[0]) / ((float)counters[1]);
- if (factorNarrowToWide >= 1.5 && factorNarrowToWide <= 5)
- {
- calculateAverageCounterWidth(counters, patternLength);
- if (toPattern(counters, patternLength) == START_ENCODING)
- {
- // Look for whitespace before start pattern, >= 50% of width of start pattern
- if (row.isRange(Math.Max(0, patternStart - ((i - patternStart) >> 1)), patternStart, false))
- {
- return new int[] {patternStart, i};
- }
- }
- }
- patternStart += counters[0] + counters[1];
- Array.Copy(counters, 2, counters, 0, patternLength - 2);
- counters[patternLength - 2] = 0;
- counters[patternLength - 1] = 0;
- counterPosition--;
- }
- else
- {
- counterPosition++;
- }
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- return null;
- }
-
- private int[] findEndPattern(BitArray row, int rowOffset, int[] counters)
- {
- const int patternLength = 3;
-
- int width = row.Size;
-
- int counterPosition = 0;
- int patternStart = rowOffset;
- bool isWhite = false;
-
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- for (int i = rowOffset; i < width; i++)
- {
- if (row[i] ^ isWhite)
- {
- counters[counterPosition]++;
- }
- else
- {
- if (counterPosition == patternLength - 1)
- {
- var factorNarrowToWide = ((float)counters[1]) / ((float)counters[0]);
- if (factorNarrowToWide >= 1.5 && factorNarrowToWide <= 5)
- {
- if (toPattern(counters, patternLength) == END_ENCODING)
- {
- // Look for whitespace after end pattern, >= 50% of width of end pattern
- var minEndOfWhite = Math.Min(row.Size - 1, i + ((i - patternStart) >> 1));
- if (row.isRange(i, minEndOfWhite, false))
- {
- return new int[] {patternStart, i};
- }
- }
- }
- return null;
- }
- counterPosition++;
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- return null;
- }
-
- private void calculateAverageCounterWidth(int[] counters, int patternLength)
- {
- // look for the minimum and the maximum width of the bars
- // there are only two sizes for MSI barcodes
- // all numbers are encoded as a chain of the pattern 100 and 110
- // the complete pattern of one number always starts with 1 or 11 (black bar(s))
- int minCounter = Int32.MaxValue;
- int maxCounter = 0;
- for (var index = 0; index < patternLength; index++)
- {
- var counter = counters[index];
- if (counter < minCounter)
- {
- minCounter = counter;
- }
- if (counter > maxCounter)
- {
- maxCounter = counter;
- }
- }
- // calculate the average of the minimum and maximum width
- // using some bit shift to get a higher resolution without floating point arithmetic
- averageCounterWidth = ((maxCounter << 8) + (minCounter << 8)) / 2;
- }
-
- private int toPattern(int[] counters, int patternLength)
- {
- // calculating the encoded value from the pattern
- int pattern = 0;
- int bit = 1;
- int doubleBit = 3;
- for (var index = 0; index < patternLength; index++)
- {
- var counter = counters[index];
- if ((counter << 8) < averageCounterWidth)
- {
- pattern = (pattern << 1) | bit;
- }
- else
- {
- pattern = (pattern << 2) | doubleBit;
- }
- bit = bit ^ 1;
- doubleBit = doubleBit ^ 3;
- }
-
- return pattern;
- }
-
- private static bool patternToChar(int pattern, out char c)
- {
- for (int i = 0; i < CHARACTER_ENCODINGS.Length; i++)
- {
- if (CHARACTER_ENCODINGS[i] == pattern)
- {
- c = ALPHABET[i];
- return true;
- }
- }
- c = '*';
- return false;
- }
-
- private static readonly int[] doubleAndCrossSum = new [] { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 };
-
- private static int CalculateChecksumLuhn(string number)
- {
- var checksum = 0;
-
- for (var index = number.Length - 2; index >= 0; index -= 2)
- {
- var digit = number[index] - 48;
- checksum += digit;
- }
- for (var index = number.Length - 1; index >= 0; index -= 2)
- {
- var digit = doubleAndCrossSum[number[index] - 48];
- checksum += digit;
- }
-
- return (10 - (checksum % 10)) % 10;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/MSIWriter.cs b/zxing.core/xx/oned/MSIWriter.cs
deleted file mode 100644
index e90fb38..0000000
--- a/zxing.core/xx/oned/MSIWriter.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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 System.Collections.Generic;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// This object renders a MSI code as a .
- ///
- public sealed class MSIWriter : OneDimensionalCodeWriter
- {
- private static readonly int[] startWidths = new [] { 2, 1 };
- private static readonly int[] endWidths = new[] { 1, 2, 1 };
- private static readonly int[][] numberWidths = new[]
- {
- new[] { 1, 2, 1, 2, 1, 2, 1, 2 },
- new[] { 1, 2, 1, 2, 1, 2, 2, 1 },
- new[] { 1, 2, 1, 2, 2, 1, 1, 2 },
- new[] { 1, 2, 1, 2, 2, 1, 2, 1 },
- new[] { 1, 2, 2, 1, 1, 2, 1, 2 },
- new[] { 1, 2, 2, 1, 1, 2, 2, 1 },
- new[] { 1, 2, 2, 1, 2, 1, 1, 2 },
- new[] { 1, 2, 2, 1, 2, 1, 2, 1 },
- new[] { 2, 1, 1, 2, 1, 2, 1, 2 },
- new[] { 2, 1, 1, 2, 1, 2, 2, 1 }
- };
-
- ///
- /// Encode the contents following specified format.
- /// {@code width} and {@code height} are required size. This method may return bigger size
- /// {@code BitMatrix} when specified size is too small. The user can set both {@code width} and
- /// {@code height} to zero to get minimum size barcode. If negative value is set to {@code width}
- /// or {@code height}, {@code IllegalArgumentException} is thrown.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public override BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (format != BarcodeFormat.MSI)
- {
- throw new ArgumentException("Can only encode MSI, but got " + format);
- }
- return base.encode(contents, format, width, height, hints);
- }
-
- ///
- /// Encode the contents to byte array expression of one-dimensional barcode.
- /// Start code and end code should be included in result, and side margins should not be included.
- /// a {@code boolean[]} of horizontal pixels (false = white, true = black)
- ///
- ///
- ///
- override public bool[] encode(String contents)
- {
- var length = contents.Length;
- for (var i = 0; i < length; i++)
- {
- int indexInString = MSIReader.ALPHABET_STRING.IndexOf(contents[i]);
- if (indexInString < 0)
- throw new ArgumentException("Requested contents contains a not encodable character: '" + contents[i] + "'");
- }
-
- var codeWidth = 3 + length*12 + 4;
- var result = new bool[codeWidth];
- var pos = appendPattern(result, 0, startWidths, true);
- for (var i = 0; i < length; i++)
- {
- var indexInString = MSIReader.ALPHABET_STRING.IndexOf(contents[i]);
- var widths = numberWidths[indexInString];
- pos += appendPattern(result, pos, widths, true);
- }
- appendPattern(result, pos, endWidths, true);
- return result;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/MultiFormatOneDReader.cs b/zxing.core/xx/oned/MultiFormatOneDReader.cs
deleted file mode 100644
index 32bc9c0..0000000
--- a/zxing.core/xx/oned/MultiFormatOneDReader.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.Collections.Generic;
-
-using ZXing.Common;
-using ZXing.OneD.RSS;
-using ZXing.OneD.RSS.Expanded;
-
-namespace ZXing.OneD
-{
- ///
- /// dswitkin@google.com (Daniel Switkin)
- /// Sean Owen
- ///
- public sealed class MultiFormatOneDReader : OneDReader
- {
- private readonly IList readers;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The hints.
- public MultiFormatOneDReader(IDictionary hints)
- {
- var possibleFormats = hints == null || !hints.ContainsKey(DecodeHintType.POSSIBLE_FORMATS) ? null :
- (IList)hints[DecodeHintType.POSSIBLE_FORMATS];
- readers = new List();
- if (possibleFormats != null)
- {
- if (possibleFormats.Contains(BarcodeFormat.All_1D) ||
- possibleFormats.Contains(BarcodeFormat.EAN_13) ||
- possibleFormats.Contains(BarcodeFormat.UPC_A) ||
- possibleFormats.Contains(BarcodeFormat.EAN_8) ||
- possibleFormats.Contains(BarcodeFormat.UPC_E))
- {
- readers.Add(new MultiFormatUPCEANReader(hints));
- }
- if (possibleFormats.Contains(BarcodeFormat.MSI))
- {
- // MSI needs to be activated explicit
- bool useMsiCheckDigit = (hints.ContainsKey(DecodeHintType.ASSUME_MSI_CHECK_DIGIT)
- ? (bool)hints[DecodeHintType.ASSUME_MSI_CHECK_DIGIT]
- : false);
- readers.Add(new MSIReader(useMsiCheckDigit));
- }
- if (possibleFormats.Contains(BarcodeFormat.CODE_39) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- bool useCode39CheckDigit = hints.ContainsKey(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT) &&
- (bool) hints[DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT];
- bool useCode39ExtendedMode = hints.ContainsKey(DecodeHintType.USE_CODE_39_EXTENDED_MODE) &&
- (bool) hints[DecodeHintType.USE_CODE_39_EXTENDED_MODE];
- readers.Add(new Code39Reader(useCode39CheckDigit, useCode39ExtendedMode));
- }
- if (possibleFormats.Contains(BarcodeFormat.CODE_93) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new Code93Reader());
- }
- if (possibleFormats.Contains(BarcodeFormat.CODE_128) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new Code128Reader());
- }
- if (possibleFormats.Contains(BarcodeFormat.ITF) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new ITFReader());
- }
- if (possibleFormats.Contains(BarcodeFormat.CODABAR) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new CodaBarReader());
- }
- if (possibleFormats.Contains(BarcodeFormat.RSS_14) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new RSS14Reader());
- }
- if (possibleFormats.Contains(BarcodeFormat.RSS_EXPANDED) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new RSSExpandedReader());
- }
- }
- if (readers.Count == 0)
- {
- bool useCode39CheckDigit = hints != null && hints.ContainsKey(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT) &&
- (bool) hints[DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT];
- bool useCode39ExtendedMode = hints != null && hints.ContainsKey(DecodeHintType.USE_CODE_39_EXTENDED_MODE) &&
- (bool) hints[DecodeHintType.USE_CODE_39_EXTENDED_MODE];
- // MSI needs to be activated explicit
-
- readers.Add(new MultiFormatUPCEANReader(hints));
- readers.Add(new Code39Reader(useCode39CheckDigit, useCode39ExtendedMode));
- readers.Add(new CodaBarReader());
- readers.Add(new Code93Reader());
- readers.Add(new Code128Reader());
- readers.Add(new ITFReader());
- readers.Add(new RSS14Reader());
- readers.Add(new RSSExpandedReader());
- }
- }
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- ///
- /// containing encoded string and start/end of barcode or null, if an error occurs or barcode cannot be found
- ///
- override public Result decodeRow(int rowNumber,
- BitArray row,
- IDictionary hints)
- {
- foreach (OneDReader reader in readers)
- {
- var result = reader.decodeRow(rowNumber, row, hints);
- if (result != null)
- return result;
- }
-
- return null;
- }
-
- ///
- /// Resets any internal state the implementation has after a decode, to prepare it
- /// for reuse.
- ///
- public override void reset()
- {
- foreach (Reader reader in readers)
- {
- reader.reset();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/MultiFormatUPCEANReader.cs b/zxing.core/xx/oned/MultiFormatUPCEANReader.cs
deleted file mode 100644
index 90beae9..0000000
--- a/zxing.core/xx/oned/MultiFormatUPCEANReader.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.Collections.Generic;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// A reader that can read all available UPC/EAN formats. If a caller wants to try to
- /// read all such formats, it is most efficient to use this implementation rather than invoke
- /// individual readers.
- /// Sean Owen
- ///
- public sealed class MultiFormatUPCEANReader : OneDReader
- {
- private readonly UPCEANReader[] readers;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The hints.
- public MultiFormatUPCEANReader(IDictionary hints)
- {
- var possibleFormats = hints == null || !hints.ContainsKey(DecodeHintType.POSSIBLE_FORMATS) ? null :
- (IList)hints[DecodeHintType.POSSIBLE_FORMATS];
- var readers = new List();
- if (possibleFormats != null)
- {
- if (possibleFormats.Contains(BarcodeFormat.EAN_13) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new EAN13Reader());
- }
- else if (possibleFormats.Contains(BarcodeFormat.UPC_A) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new UPCAReader());
- }
- if (possibleFormats.Contains(BarcodeFormat.EAN_8) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new EAN8Reader());
- }
- if (possibleFormats.Contains(BarcodeFormat.UPC_E) || possibleFormats.Contains(BarcodeFormat.All_1D))
- {
- readers.Add(new UPCEReader());
- }
- }
- if (readers.Count == 0)
- {
- readers.Add(new EAN13Reader());
- // UPC-A is covered by EAN-13
- readers.Add(new EAN8Reader());
- readers.Add(new UPCEReader());
- }
- this.readers = readers.ToArray();
- }
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- ///
- /// containing encoded string and start/end of barcode or null if an error occurs or barcode cannot be found
- ///
- override public Result decodeRow(int rowNumber,
- BitArray row,
- IDictionary hints)
- {
- // Compute this location once and reuse it on multiple implementations
- int[] startGuardPattern = UPCEANReader.findStartGuardPattern(row);
- if (startGuardPattern == null)
- return null;
-
- foreach (UPCEANReader reader in readers)
- {
- Result result = reader.decodeRow(rowNumber, row, startGuardPattern, hints);
- if (result == null)
- continue;
-
- // Special case: a 12-digit code encoded in UPC-A is identical to a "0"
- // followed by those 12 digits encoded as EAN-13. Each will recognize such a code,
- // UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with "0".
- // Individually these are correct and their readers will both read such a code
- // and correctly call it EAN-13, or UPC-A, respectively.
- //
- // In this case, if we've been looking for both types, we'd like to call it
- // a UPC-A code. But for efficiency we only run the EAN-13 decoder to also read
- // UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A
- // result if appropriate.
- //
- // But, don't return UPC-A if UPC-A was not a requested format!
- bool ean13MayBeUPCA =
- result.BarcodeFormat == BarcodeFormat.EAN_13 &&
- result.Text[0] == '0';
- var possibleFormats =
- hints == null || !hints.ContainsKey(DecodeHintType.POSSIBLE_FORMATS) ? null : (IList)hints[DecodeHintType.POSSIBLE_FORMATS];
- bool canReturnUPCA = possibleFormats == null || possibleFormats.Contains(BarcodeFormat.UPC_A) || possibleFormats.Contains(BarcodeFormat.All_1D);
-
- if (ean13MayBeUPCA && canReturnUPCA)
- {
- // Transfer the metdata across
- var resultUPCA = new Result(result.Text.Substring(1),
- result.RawBytes,
- result.ResultPoints,
- BarcodeFormat.UPC_A);
- resultUPCA.putAllMetadata(result.ResultMetadata);
- return resultUPCA;
- }
- return result;
- }
-
- return null;
- }
-
- ///
- /// Resets any internal state the implementation has after a decode, to prepare it
- /// for reuse.
- ///
- public override void reset()
- {
- foreach (Reader reader in readers)
- {
- reader.reset();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/OneDReader.cs b/zxing.core/xx/oned/OneDReader.cs
deleted file mode 100644
index 871f056..0000000
--- a/zxing.core/xx/oned/OneDReader.cs
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Encapsulates functionality and implementation that is common to all families
- /// of one-dimensional barcodes.
- /// dswitkin@google.com (Daniel Switkin)
- /// Sean Owen
- ///
- public abstract class OneDReader : Reader
- {
- ///
- ///
- ///
- protected static int INTEGER_MATH_SHIFT = 8;
- ///
- ///
- ///
- protected static int PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT;
-
- ///
- /// Locates and decodes a barcode in some format within an image.
- ///
- /// image of barcode to decode
- ///
- /// String which the barcode encodes
- ///
- public Result decode(BinaryBitmap image)
- {
- return decode(image, null);
- }
-
- ///
- /// Locates and decodes a barcode in some format within an image. This method also accepts
- /// hints, each possibly associated to some data, which may help the implementation decode.
- /// Note that we don't try rotation without the try harder flag, even if rotation was supported.
- ///
- /// image of barcode to decode
- /// passed as a from
- /// to arbitrary data. The
- /// meaning of the data depends upon the hint type. The implementation may or may not do
- /// anything with these hints.
- ///
- /// String which the barcode encodes
- ///
- virtual public Result decode(BinaryBitmap image, IDictionary hints)
- {
- var result = doDecode(image, hints);
- if (result == null)
- {
- bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
- bool tryHarderWithoutRotation = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER_WITHOUT_ROTATION);
- if (tryHarder && !tryHarderWithoutRotation && image.RotateSupported)
- {
- BinaryBitmap rotatedImage = image.rotateCounterClockwise();
- result = doDecode(rotatedImage, hints);
- if (result == null)
- return null;
- // Record that we found it rotated 90 degrees CCW / 270 degrees CW
- IDictionary metadata = result.ResultMetadata;
- int orientation = 270;
- if (metadata != null && metadata.ContainsKey(ResultMetadataType.ORIENTATION))
- {
- // But if we found it reversed in doDecode(), add in that result here:
- orientation = (orientation +
- (int) metadata[ResultMetadataType.ORIENTATION])%360;
- }
- result.putMetadata(ResultMetadataType.ORIENTATION, orientation);
- // Update result points
- ResultPoint[] points = result.ResultPoints;
- if (points != null)
- {
- int height = rotatedImage.Height;
- for (int i = 0; i < points.Length; i++)
- {
- points[i] = new ResultPoint(height - points[i].Y - 1, points[i].X);
- }
- }
- }
- }
- return result;
- }
-
- ///
- /// Resets any internal state the implementation has after a decode, to prepare it
- /// for reuse.
- ///
- virtual public void reset()
- {
- // do nothing
- }
-
- ///
- /// We're going to examine rows from the middle outward, searching alternately above and below the
- /// middle, and farther out each time. rowStep is the number of rows between each successive
- /// attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
- /// middle + rowStep, then middle - (2 * rowStep), etc.
- /// rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
- /// decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
- /// image if "trying harder".
- ///
- /// The image to decode
- /// Any hints that were requested
- /// The contents of the decoded barcode
- virtual protected Result doDecode(BinaryBitmap image, IDictionary hints)
- {
- int width = image.Width;
- int height = image.Height;
- BitArray row = new BitArray(width);
-
- int middle = height >> 1;
- bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);
- int rowStep = Math.Max(1, height >> (tryHarder ? 8 : 5));
- int maxLines;
- if (tryHarder)
- {
- maxLines = height; // Look at the whole image, not just the center
- }
- else
- {
- maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
- }
-
- for (int x = 0; x < maxLines; x++)
- {
-
- // Scanning from the middle out. Determine which row we're looking at next:
- int rowStepsAboveOrBelow = (x + 1) >> 1;
- bool isAbove = (x & 0x01) == 0; // i.e. is x even?
- int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
- if (rowNumber < 0 || rowNumber >= height)
- {
- // Oops, if we run off the top or bottom, stop
- break;
- }
-
- // Estimate black point for this row and load it:
- row = image.getBlackRow(rowNumber, row);
- if (row == null)
- continue;
-
- // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
- // handle decoding upside down barcodes.
- for (int attempt = 0; attempt < 2; attempt++)
- {
- if (attempt == 1)
- {
- // trying again?
- row.reverse(); // reverse the row and continue
- // This means we will only ever draw result points *once* in the life of this method
- // since we want to avoid drawing the wrong points after flipping the row, and,
- // don't want to clutter with noise from every single row scan -- just the scans
- // that start on the center line.
- if (hints != null && hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
- {
- IDictionary newHints = new Dictionary();
- foreach (var hint in hints)
- {
- if (hint.Key != DecodeHintType.NEED_RESULT_POINT_CALLBACK)
- newHints.Add(hint.Key, hint.Value);
- }
- hints = newHints;
- }
- }
- // Look for a barcode
- Result result = decodeRow(rowNumber, row, hints);
- if (result == null)
- continue;
-
- // We found our barcode
- if (attempt == 1)
- {
- // But it was upside down, so note that
- result.putMetadata(ResultMetadataType.ORIENTATION, 180);
- // And remember to flip the result points horizontally.
- ResultPoint[] points = result.ResultPoints;
- if (points != null)
- {
- points[0] = new ResultPoint(width - points[0].X - 1, points[0].Y);
- points[1] = new ResultPoint(width - points[1].X - 1, points[1].Y);
- }
- }
- return result;
- }
- }
-
- return null;
- }
-
- ///
- /// Records the size of successive runs of white and black pixels in a row, starting at a given point.
- /// The values are recorded in the given array, and the number of runs recorded is equal to the size
- /// of the array. If the row starts on a white pixel at the given start point, then the first count
- /// recorded is the run of white pixels starting from that point; likewise it is the count of a run
- /// of black pixels if the row begin on a black pixels at that point.
- ///
- /// row to count from
- /// offset into row to start at
- /// array into which to record counts
- protected static bool recordPattern(BitArray row,
- int start,
- int[] counters)
- {
- return recordPattern(row, start, counters, counters.Length);
- }
-
- ///
- /// Records the size of successive runs of white and black pixels in a row, starting at a given point.
- /// The values are recorded in the given array, and the number of runs recorded is equal to the size
- /// of the array. If the row starts on a white pixel at the given start point, then the first count
- /// recorded is the run of white pixels starting from that point; likewise it is the count of a run
- /// of black pixels if the row begin on a black pixels at that point.
- ///
- /// row to count from
- /// offset into row to start at
- /// array into which to record counts
- protected static bool recordPattern(BitArray row,
- int start,
- int[] counters,
- int numCounters)
- {
- for (int idx = 0; idx < numCounters; idx++)
- {
- counters[idx] = 0;
- }
- int end = row.Size;
- if (start >= end)
- {
- return false;
- }
- bool isWhite = !row[start];
- int counterPosition = 0;
- int i = start;
- while (i < end)
- {
- if (row[i] ^ isWhite)
- { // that is, exactly one is true
- counters[counterPosition]++;
- }
- else
- {
- counterPosition++;
- if (counterPosition == numCounters)
- {
- break;
- }
- else
- {
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- i++;
- }
- // If we read fully the last section of pixels and filled up our counters -- or filled
- // the last counter but ran off the side of the image, OK. Otherwise, a problem.
- return (counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end));
- }
-
- ///
- /// Records the pattern in reverse.
- ///
- /// The row.
- /// The start.
- /// The counters.
- ///
- protected static bool recordPatternInReverse(BitArray row, int start, int[] counters)
- {
- // This could be more efficient I guess
- int numTransitionsLeft = counters.Length;
- bool last = row[start];
- while (start > 0 && numTransitionsLeft >= 0)
- {
- if (row[--start] != last)
- {
- numTransitionsLeft--;
- last = !last;
- }
- }
- if (numTransitionsLeft >= 0)
- {
- return false;
- }
- return recordPattern(row, start + 1, counters);
- }
-
- ///
- /// Determines how closely a set of observed counts of runs of black/white values matches a given
- /// target pattern. This is reported as the ratio of the total variance from the expected pattern
- /// proportions across all pattern elements, to the length of the pattern.
- ///
- /// observed counters
- /// expected pattern
- /// The most any counter can differ before we give up
- /// ratio of total variance between counters and pattern compared to total pattern size,
- /// where the ratio has been multiplied by 256. So, 0 means no variance (perfect match); 256 means
- /// the total variance between counters and patterns equals the pattern length, higher values mean
- /// even more variance
- protected static int patternMatchVariance(int[] counters,
- int[] pattern,
- int maxIndividualVariance)
- {
- int numCounters = counters.Length;
- int total = 0;
- int patternLength = 0;
- for (int i = 0; i < numCounters; i++)
- {
- total += counters[i];
- patternLength += pattern[i];
- }
- if (total < patternLength)
- {
- // If we don't even have one pixel per unit of bar width, assume this is too small
- // to reliably match, so fail:
- return Int32.MaxValue;
- }
- // We're going to fake floating-point math in integers. We just need to use more bits.
- // Scale up patternLength so that intermediate values below like scaledCounter will have
- // more "significant digits"
- int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;
- maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT;
-
- int totalVariance = 0;
- for (int x = 0; x < numCounters; x++)
- {
- int counter = counters[x] << INTEGER_MATH_SHIFT;
- int scaledPattern = pattern[x] * unitBarWidth;
- int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
- if (variance > maxIndividualVariance)
- {
- return Int32.MaxValue;
- }
- totalVariance += variance;
- }
- return totalVariance / total;
- }
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- ///
- /// containing encoded string and start/end of barcode
- ///
- public abstract Result decodeRow(int rowNumber, BitArray row, IDictionary hints);
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/OneDimensionalCodeWriter.cs b/zxing.core/xx/oned/OneDimensionalCodeWriter.cs
deleted file mode 100644
index 062e8dc..0000000
--- a/zxing.core/xx/oned/OneDimensionalCodeWriter.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2011 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Encapsulates functionality and implementation that is common to one-dimensional barcodes.
- /// dsbnatut@gmail.com (Kazuki Nishiura)
- ///
- public abstract class OneDimensionalCodeWriter : Writer
- {
- ///
- /// Encode a barcode using the default settings.
- ///
- /// The contents to encode in the barcode
- /// The barcode format to generate
- /// The preferred width in pixels
- /// The preferred height in pixels
- ///
- /// The generated barcode as a Matrix of unsigned bytes (0 == black, 255 == white)
- ///
- public BitMatrix encode(String contents, BarcodeFormat format, int width, int height)
- {
- return encode(contents, format, width, height, null);
- }
-
- ///
- /// Encode the contents following specified format.
- /// {@code width} and {@code height} are required size. This method may return bigger size
- /// {@code BitMatrix} when specified size is too small. The user can set both {@code width} and
- /// {@code height} to zero to get minimum size barcode. If negative value is set to {@code width}
- /// or {@code height}, {@code IllegalArgumentException} is thrown.
- ///
- public virtual BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (String.IsNullOrEmpty(contents))
- {
- throw new ArgumentException("Found empty contents");
- }
-
- if (width < 0 || height < 0)
- {
- throw new ArgumentException("Negative size is not allowed. Input: "
- + width + 'x' + height);
- }
-
- int sidesMargin = DefaultMargin;
- if (hints != null)
- {
- var sidesMarginInt = hints.ContainsKey(EncodeHintType.MARGIN) ? (int)hints[EncodeHintType.MARGIN] : (int?)null;
- if (sidesMarginInt != null)
- {
- sidesMargin = sidesMarginInt.Value;
- }
- }
-
- var code = encode(contents);
- return renderResult(code, width, height, sidesMargin);
- }
-
- ///
- ///
- /// a byte array of horizontal pixels (0 = white, 1 = black)
- private static BitMatrix renderResult(bool[] code, int width, int height, int sidesMargin)
- {
- int inputWidth = code.Length;
- // Add quiet zone on both sides.
- int fullWidth = inputWidth + sidesMargin;
- int outputWidth = Math.Max(width, fullWidth);
- int outputHeight = Math.Max(1, height);
-
- int multiple = outputWidth / fullWidth;
- int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
-
- BitMatrix output = new BitMatrix(outputWidth, outputHeight);
- for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple)
- {
- if (code[inputX])
- {
- output.setRegion(outputX, 0, multiple, outputHeight);
- }
- }
- return output;
- }
-
-
- ///
- /// Appends the given pattern to the target array starting at pos.
- ///
- /// encode black/white pattern into this array
- /// position to start encoding at in target
- /// lengths of black/white runs to encode
- /// starting color - false for white, true for black
- /// the number of elements added to target.
- protected static int appendPattern(bool[] target, int pos, int[] pattern, bool startColor)
- {
- bool color = startColor;
- int numAdded = 0;
- foreach (int len in pattern)
- {
- for (int j = 0; j < len; j++)
- {
- target[pos++] = color;
- }
- numAdded += len;
- color = !color; // flip color after each segment
- }
- return numAdded;
- }
-
- ///
- /// Gets the default margin.
- ///
- virtual public int DefaultMargin
- {
- get
- {
- // CodaBar spec requires a side margin to be more than ten times wider than narrow space.
- // This seems like a decent idea for a default for all formats.
- return 10;
- }
- }
-
- ///
- /// Encode the contents to bool array expression of one-dimensional barcode.
- /// Start code and end code should be included in result, and side margins should not be included.
- ///
- /// barcode contents to encode
- /// a bool[] of horizontal pixels (false = white, true = black)
- public abstract bool[] encode(String contents);
-
- ///
- /// Calculates the checksum digit modulo10.
- ///
- /// The contents.
- ///
- public static String CalculateChecksumDigitModulo10(String contents)
- {
- var oddsum = 0;
- var evensum = 0;
-
- for (var index = contents.Length - 1; index >= 0; index -= 2)
- {
- oddsum += (contents[index] - '0');
- }
- for (var index = contents.Length - 2; index >= 0; index -= 2)
- {
- evensum += (contents[index] - '0');
- }
-
- return contents + ((10 - ((oddsum * 3 + evensum) % 10)) % 10);
- }
- }
-}
diff --git a/zxing.core/xx/oned/PlesseyWriter.cs b/zxing.core/xx/oned/PlesseyWriter.cs
deleted file mode 100644
index 6a37e65..0000000
--- a/zxing.core/xx/oned/PlesseyWriter.cs
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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 System.Collections.Generic;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// This object renders a Plessey code as a .
- ///
- public sealed class PlesseyWriter : OneDimensionalCodeWriter
- {
- private const String ALPHABET_STRING = "0123456789ABCDEF";
- private static readonly int[] startWidths = new[] { 14, 11, 14, 11, 5, 20, 14, 11 };
- private static readonly int[] terminationWidths = new[] { 25 };
- private static readonly int[] endWidths = new[] { 20, 5, 20, 5, 14, 11, 14, 11 };
- private static readonly int[][] numberWidths = new[]
- {
- new[] { 5, 20, 5, 20, 5, 20, 5, 20 }, // 0
- new[] { 14, 11, 5, 20, 5, 20, 5, 20 }, // 1
- new[] { 5, 20, 14, 11, 5, 20, 5, 20 }, // 2
- new[] { 14, 11, 14, 11, 5, 20, 5, 20 }, // 3
- new[] { 5, 20, 5, 20, 14, 11, 5, 20 }, // 4
- new[] { 14, 11, 5, 20, 14, 11, 5, 20 }, // 5
- new[] { 5, 20, 14, 11, 14, 11, 5, 20 }, // 6
- new[] { 14, 11, 14, 11, 14, 11, 5, 20 }, // 7
- new[] { 5, 20, 5, 20, 5, 20, 14, 11 }, // 8
- new[] { 14, 11, 5, 20, 5, 20, 14, 11 }, // 9
- new[] { 5, 20, 14, 11, 5, 20, 14, 11 }, // A / 10
- new[] { 14, 11, 14, 11, 5, 20, 14, 11 }, // B / 11
- new[] { 5, 20, 5, 20, 14, 11, 14, 11 }, // C / 12
- new[] { 14, 11, 5, 20, 14, 11, 14, 11 }, // D / 13
- new[] { 5, 20, 14, 11, 14, 11, 14, 11 }, // E / 14
- new[] { 14, 11, 14, 11, 14, 11, 14, 11 }, // F / 15
- };
- private static readonly byte[] crcGrid = new byte[] { 1, 1, 1, 1, 0, 1, 0, 0, 1 };
- private static readonly int[] crc0Widths = new[] {5, 20};
- private static readonly int[] crc1Widths = new[] {14, 11};
-
- ///
- /// Encode the contents following specified format.
- /// {@code width} and {@code height} are required size. This method may return bigger size
- /// {@code BitMatrix} when specified size is too small. The user can set both {@code width} and
- /// {@code height} to zero to get minimum size barcode. If negative value is set to {@code width}
- /// or {@code height}, {@code IllegalArgumentException} is thrown.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public override BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (format != BarcodeFormat.PLESSEY)
- {
- throw new ArgumentException("Can only encode Plessey, but got " + format);
- }
- return base.encode(contents, format, width, height, hints);
- }
-
- ///
- /// Encode the contents to byte array expression of one-dimensional barcode.
- /// Start code and end code should be included in result, and side margins should not be included.
- /// a {@code boolean[]} of horizontal pixels (false = white, true = black)
- ///
- ///
- ///
- override public bool[] encode(String contents)
- {
- var length = contents.Length;
- for (var i = 0; i < length; i++)
- {
- int indexInString = ALPHABET_STRING.IndexOf(contents[i]);
- if (indexInString < 0)
- throw new ArgumentException("Requested contents contains a not encodable character: '" + contents[i] + "'");
- }
-
- // quiet zone + start pattern + data + crc + termination bar + end pattern + quiet zone
- var codeWidth = 100 + 100 + length * 100 + 25 * 8 + 25 + 100 + 100;
- var result = new bool[codeWidth];
- var crcBuffer = new byte[4*length + 8];
- var crcBufferPos = 0;
- var pos = 100;
- // start pattern
- pos += appendPattern(result, pos, startWidths, true);
- // data
- for (var i = 0; i < length; i++)
- {
- var indexInString = ALPHABET_STRING.IndexOf(contents[i]);
- var widths = numberWidths[indexInString];
- pos += appendPattern(result, pos, widths, true);
- // remember the position number for crc calculation
- crcBuffer[crcBufferPos++] = (byte)(indexInString & 1);
- crcBuffer[crcBufferPos++] = (byte)((indexInString >> 1) & 1);
- crcBuffer[crcBufferPos++] = (byte)((indexInString >> 2) & 1);
- crcBuffer[crcBufferPos++] = (byte)((indexInString >> 3) & 1);
- }
- // CRC calculation
- for (var i = 0; i < (4 * length); i++)
- {
- if (crcBuffer[i] != 0)
- {
- for (var j = 0; j < 9; j++)
- {
- crcBuffer[i + j] ^= crcGrid[j];
- }
- }
- }
- // append CRC pattern
- for (var i = 0; i < 8; i++)
- {
- switch (crcBuffer[length * 4 + i])
- {
- case 0:
- pos += appendPattern(result, pos, crc0Widths, true);
- break;
- case 1:
- pos += appendPattern(result, pos, crc1Widths, true);
- break;
- }
- }
- // termination bar
- pos += appendPattern(result, pos, terminationWidths, true);
- // end pattern
- appendPattern(result, pos, endWidths, false);
- return result;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/UPCAReader.cs b/zxing.core/xx/oned/UPCAReader.cs
deleted file mode 100644
index 2eb1e4c..0000000
--- a/zxing.core/xx/oned/UPCAReader.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Implements decoding of the UPC-A format.
- /// dswitkin@google.com (Daniel Switkin)
- /// Sean Owen
- ///
- public sealed class UPCAReader : UPCEANReader
- {
- private readonly UPCEANReader ean13Reader = new EAN13Reader();
-
- ///
- /// Like decodeRow(int, BitArray, java.util.Map), but
- /// allows caller to inform method about where the UPC/EAN start pattern is
- /// found. This allows this to be computed once and reused across many implementations.
- ///
- ///
- ///
- ///
- ///
- ///
- override public Result decodeRow(int rowNumber,
- BitArray row,
- int[] startGuardRange,
- IDictionary hints)
- {
- return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardRange, hints));
- }
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- ///
- /// containing encoded string and start/end of barcode or null, if an error occurs or barcode cannot be found
- ///
- override public Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, hints));
- }
-
- ///
- /// Decodes the specified image.
- ///
- /// The image.
- /// The hints.
- ///
- override public Result decode(BinaryBitmap image, IDictionary hints)
- {
- return maybeReturnResult(ean13Reader.decode(image, hints));
- }
-
- ///
- /// Get the format of this decoder.
- /// The 1D format.
- ///
- override internal BarcodeFormat BarcodeFormat
- {
- get { return BarcodeFormat.UPC_A; }
- }
-
- ///
- /// Subclasses override this to decode the portion of a barcode between the start
- /// and end guard patterns.
- ///
- /// row of black/white values to search
- /// start/end offset of start guard pattern
- /// to append decoded chars to
- ///
- /// horizontal offset of first pixel after the "middle" that was decoded or -1 if decoding could not complete successfully
- ///
- override protected internal int decodeMiddle(BitArray row, int[] startRange, StringBuilder resultString)
- {
- return ean13Reader.decodeMiddle(row, startRange, resultString);
- }
-
- private static Result maybeReturnResult(Result result)
- {
- if (result == null)
- return null;
-
- String text = result.Text;
- if (text[0] == '0')
- {
- return new Result(text.Substring(1), null, result.ResultPoints, BarcodeFormat.UPC_A);
- }
- else
- {
- return null;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/UPCAWriter.cs b/zxing.core/xx/oned/UPCAWriter.cs
deleted file mode 100644
index 3227302..0000000
--- a/zxing.core/xx/oned/UPCAWriter.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// This object renders a UPC-A code as a .
- /// qwandor@google.com (Andrew Walbran)
- ///
- public class UPCAWriter : Writer
- {
- private readonly EAN13Writer subWriter = new EAN13Writer();
-
- ///
- /// Encode a barcode using the default settings.
- ///
- /// The contents to encode in the barcode
- /// The barcode format to generate
- /// The preferred width in pixels
- /// The preferred height in pixels
- ///
- /// The generated barcode as a Matrix of unsigned bytes (0 == black, 255 == white)
- ///
- public BitMatrix encode(String contents, BarcodeFormat format, int width, int height)
- {
- return encode(contents, format, width, height, null);
- }
-
- ///
- ///
- /// The contents to encode in the barcode
- /// The barcode format to generate
- /// The preferred width in pixels
- /// The preferred height in pixels
- /// Additional parameters to supply to the encoder
- ///
- /// The generated barcode as a Matrix of unsigned bytes (0 == black, 255 == white)
- ///
- public BitMatrix encode(String contents,
- BarcodeFormat format,
- int width,
- int height,
- IDictionary hints)
- {
- if (format != BarcodeFormat.UPC_A)
- {
- throw new ArgumentException("Can only encode UPC-A, but got " + format);
- }
- return subWriter.encode(preencode(contents), BarcodeFormat.EAN_13, width, height, hints);
- }
-
- ///
- /// Transform a UPC-A code into the equivalent EAN-13 code, and add a check digit if it is not
- /// already present.
- ///
- private static String preencode(String contents)
- {
- int length = contents.Length;
- if (length == 11)
- {
- // No check digit present, calculate it and add it
- int sum = 0;
- for (int i = 0; i < 11; ++i)
- {
- sum += (contents[i] - '0') * (i % 2 == 0 ? 3 : 1);
- }
- contents += (1000 - sum) % 10;
- }
- else if (length != 12)
- {
- throw new ArgumentException(
- "Requested contents should be 11 or 12 digits long, but got " + contents.Length);
- }
- return '0' + contents;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/UPCEANExtension2Support.cs b/zxing.core/xx/oned/UPCEANExtension2Support.cs
deleted file mode 100644
index 8ff4ea6..0000000
--- a/zxing.core/xx/oned/UPCEANExtension2Support.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// @see UPCEANExtension5Support
- ///
- sealed class UPCEANExtension2Support
- {
- private readonly int[] decodeMiddleCounters = new int[4];
- private readonly StringBuilder decodeRowStringBuffer = new StringBuilder();
-
- internal Result decodeRow(int rowNumber, BitArray row, int[] extensionStartRange)
- {
- StringBuilder result = decodeRowStringBuffer;
- result.Length = 0;
- int end = decodeMiddle(row, extensionStartRange, result);
- if (end < 0)
- return null;
-
- String resultString = result.ToString();
- IDictionary extensionData = parseExtensionString(resultString);
-
- Result extensionResult =
- new Result(resultString,
- null,
- new ResultPoint[] {
- new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0f, (float) rowNumber),
- new ResultPoint((float) end, (float) rowNumber),
- },
- BarcodeFormat.UPC_EAN_EXTENSION);
- if (extensionData != null)
- {
- extensionResult.putAllMetadata(extensionData);
- }
- return extensionResult;
- }
-
- int decodeMiddle(BitArray row, int[] startRange, StringBuilder resultString)
- {
- int[] counters = decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- int end = row.Size;
- int rowOffset = startRange[1];
-
- int checkParity = 0;
-
- for (int x = 0; x < 2 && rowOffset < end; x++)
- {
- int bestMatch;
- if (!UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_AND_G_PATTERNS, out bestMatch))
- return -1;
- resultString.Append((char)('0' + bestMatch % 10));
- foreach (int counter in counters)
- {
- rowOffset += counter;
- }
- if (bestMatch >= 10)
- {
- checkParity |= 1 << (1 - x);
- }
- if (x != 1)
- {
- // Read off separator if not last
- rowOffset = row.getNextSet(rowOffset);
- rowOffset = row.getNextUnset(rowOffset);
- }
- }
-
- if (resultString.Length != 2)
- {
- return -1;
- }
-
- if (int.Parse(resultString.ToString()) % 4 != checkParity)
- {
- return -1;
- }
-
- return rowOffset;
- }
-
- ///
- /// Parses the extension string.
- ///
- /// raw content of extension
- /// formatted interpretation of raw content as a {@link Map} mapping
- private static IDictionary parseExtensionString(String raw)
- {
- if (raw.Length != 2)
- {
- return null;
- }
- IDictionary result = new Dictionary();
- result[ResultMetadataType.ISSUE_NUMBER] = Convert.ToInt32(raw);
- return result;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/UPCEANExtension5Support.cs b/zxing.core/xx/oned/UPCEANExtension5Support.cs
deleted file mode 100644
index ba6a6ff..0000000
--- a/zxing.core/xx/oned/UPCEANExtension5Support.cs
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- /**
- * @see UPCEANExtension2Support
- */
- sealed class UPCEANExtension5Support
- {
-
- private static readonly int[] CHECK_DIGIT_ENCODINGS = {
- 0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05
- };
-
- private readonly int[] decodeMiddleCounters = new int[4];
- private readonly StringBuilder decodeRowStringBuffer = new StringBuilder();
-
- internal Result decodeRow(int rowNumber, BitArray row, int[] extensionStartRange)
- {
- StringBuilder result = decodeRowStringBuffer;
- result.Length = 0;
- int end = decodeMiddle(row, extensionStartRange, result);
- if (end < 0)
- return null;
-
- String resultString = result.ToString();
- IDictionary extensionData = parseExtensionString(resultString);
-
- Result extensionResult =
- new Result(resultString,
- null,
- new ResultPoint[] {
- new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0f, (float) rowNumber),
- new ResultPoint((float) end, (float) rowNumber),
- },
- BarcodeFormat.UPC_EAN_EXTENSION);
- if (extensionData != null)
- {
- extensionResult.putAllMetadata(extensionData);
- }
- return extensionResult;
- }
-
- int decodeMiddle(BitArray row, int[] startRange, StringBuilder resultString)
- {
- int[] counters = decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- int end = row.Size;
- int rowOffset = startRange[1];
-
- int lgPatternFound = 0;
-
- for (int x = 0; x < 5 && rowOffset < end; x++)
- {
- int bestMatch;
- if (!UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_AND_G_PATTERNS, out bestMatch))
- return -1;
- resultString.Append((char)('0' + bestMatch % 10));
- foreach (int counter in counters)
- {
- rowOffset += counter;
- }
- if (bestMatch >= 10)
- {
- lgPatternFound |= 1 << (4 - x);
- }
- if (x != 4)
- {
- // Read off separator if not last
- rowOffset = row.getNextSet(rowOffset);
- rowOffset = row.getNextUnset(rowOffset);
- }
- }
-
- if (resultString.Length != 5)
- {
- return -1;
- }
-
- int checkDigit;
- if (!determineCheckDigit(lgPatternFound, out checkDigit))
- return -1;
-
- if (extensionChecksum(resultString.ToString()) != checkDigit)
- {
- return -1;
- }
-
- return rowOffset;
- }
-
- private static int extensionChecksum(String s)
- {
- int length = s.Length;
- int sum = 0;
- for (int i = length - 2; i >= 0; i -= 2)
- {
- sum += (int)s[i] - (int)'0';
- }
- sum *= 3;
- for (int i = length - 1; i >= 0; i -= 2)
- {
- sum += (int)s[i] - (int)'0';
- }
- sum *= 3;
- return sum % 10;
- }
-
- private static bool determineCheckDigit(int lgPatternFound, out int checkDigit)
- {
- for (checkDigit = 0; checkDigit < 10; checkDigit++)
- {
- if (lgPatternFound == CHECK_DIGIT_ENCODINGS[checkDigit])
- {
- return true;
- }
- }
- return false;
- }
-
- ///
- /// Parses the extension string.
- ///
- /// raw content of extension
- /// formatted interpretation of raw content as a {@link Map} mapping
- /// one {@link ResultMetadataType} to appropriate value, or {@code null} if not known
- private static IDictionary parseExtensionString(String raw)
- {
- if (raw.Length != 5)
- {
- return null;
- }
- Object value = parseExtension5String(raw);
- if (value == null)
- {
- return null;
- }
- IDictionary result = new Dictionary();
- result[ResultMetadataType.SUGGESTED_PRICE] = value;
- return result;
- }
-
- private static String parseExtension5String(String raw)
- {
- String currency;
- switch (raw[0])
- {
- case '0':
- currency = "£";
- break;
- case '5':
- currency = "$";
- break;
- case '9':
- // Reference: http://www.jollytech.com
- if ("90000".Equals(raw))
- {
- // No suggested retail price
- return null;
- }
- if ("99991".Equals(raw))
- {
- // Complementary
- return "0.00";
- }
- if ("99990".Equals(raw))
- {
- return "Used";
- }
- // Otherwise... unknown currency?
- currency = "";
- break;
- default:
- currency = "";
- break;
- }
- int rawAmount = int.Parse(raw.Substring(1));
- String unitsString = (rawAmount / 100).ToString();
- int hundredths = rawAmount % 100;
- String hundredthsString = hundredths < 10 ? "0" + hundredths : hundredths.ToString();
- return currency + unitsString + '.' + hundredthsString;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/UPCEANExtensionSupport.cs b/zxing.core/xx/oned/UPCEANExtensionSupport.cs
deleted file mode 100644
index 3992bb1..0000000
--- a/zxing.core/xx/oned/UPCEANExtensionSupport.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- sealed class UPCEANExtensionSupport
- {
- private static readonly int[] EXTENSION_START_PATTERN = { 1, 1, 2 };
-
- private readonly UPCEANExtension2Support twoSupport = new UPCEANExtension2Support();
- private readonly UPCEANExtension5Support fiveSupport = new UPCEANExtension5Support();
-
- internal Result decodeRow(int rowNumber, BitArray row, int rowOffset)
- {
- int[] extensionStartRange = UPCEANReader.findGuardPattern(row, rowOffset, false, EXTENSION_START_PATTERN);
- if (extensionStartRange == null)
- return null;
- var result = fiveSupport.decodeRow(rowNumber, row, extensionStartRange);
- if (result == null)
- result = twoSupport.decodeRow(rowNumber, row, extensionStartRange);
- return result;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/UPCEANReader.cs b/zxing.core/xx/oned/UPCEANReader.cs
deleted file mode 100644
index 24942df..0000000
--- a/zxing.core/xx/oned/UPCEANReader.cs
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Encapsulates functionality and implementation that is common to UPC and EAN families
- /// of one-dimensional barcodes.
- /// dswitkin@google.com (Daniel Switkin)
- /// Sean Owen
- /// alasdair@google.com (Alasdair Mackintosh)
- ///
- public abstract class UPCEANReader : OneDReader
- {
-
- // These two values are critical for determining how permissive the decoding will be.
- // We've arrived at these values through a lot of trial and error. Setting them any higher
- // lets false positives creep in quickly.
- private static readonly int MAX_AVG_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.48f);
- private static readonly int MAX_INDIVIDUAL_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f);
-
- ///
- /// Start/end guard pattern.
- ///
- internal static int[] START_END_PATTERN = { 1, 1, 1, };
-
- ///
- /// Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
- ///
- internal static int[] MIDDLE_PATTERN = { 1, 1, 1, 1, 1 };
-
- ///
- /// "Odd", or "L" patterns used to encode UPC/EAN digits.
- ///
- internal static int[][] L_PATTERNS = {
- new[] {3, 2, 1, 1}, // 0
- new[] {2, 2, 2, 1}, // 1
- new[] {2, 1, 2, 2}, // 2
- new[] {1, 4, 1, 1}, // 3
- new[] {1, 1, 3, 2}, // 4
- new[] {1, 2, 3, 1}, // 5
- new[] {1, 1, 1, 4}, // 6
- new[] {1, 3, 1, 2}, // 7
- new[] {1, 2, 1, 3}, // 8
- new[] {3, 1, 1, 2} // 9
- };
-
- ///
- /// As above but also including the "even", or "G" patterns used to encode UPC/EAN digits.
- ///
- internal static int[][] L_AND_G_PATTERNS;
-
- static UPCEANReader()
- {
- L_AND_G_PATTERNS = new int[20][];
- Array.Copy(L_PATTERNS, 0, L_AND_G_PATTERNS, 0, 10);
- for (int i = 10; i < 20; i++)
- {
- int[] widths = L_PATTERNS[i - 10];
- int[] reversedWidths = new int[widths.Length];
- for (int j = 0; j < widths.Length; j++)
- {
- reversedWidths[j] = widths[widths.Length - j - 1];
- }
- L_AND_G_PATTERNS[i] = reversedWidths;
- }
- }
-
- private readonly StringBuilder decodeRowStringBuffer;
- private readonly UPCEANExtensionSupport extensionReader;
- private readonly EANManufacturerOrgSupport eanManSupport;
-
- ///
- /// Initializes a new instance of the class.
- ///
- protected UPCEANReader()
- {
- decodeRowStringBuffer = new StringBuilder(20);
- extensionReader = new UPCEANExtensionSupport();
- eanManSupport = new EANManufacturerOrgSupport();
- }
-
- internal static int[] findStartGuardPattern(BitArray row)
- {
- bool foundStart = false;
- int[] startRange = null;
- int nextStart = 0;
- int[] counters = new int[START_END_PATTERN.Length];
- while (!foundStart)
- {
- for (int idx = 0; idx < START_END_PATTERN.Length; idx++)
- counters[idx] = 0;
- startRange = findGuardPattern(row, nextStart, false, START_END_PATTERN, counters);
- if (startRange == null)
- return null;
- int start = startRange[0];
- nextStart = startRange[1];
- // Make sure there is a quiet zone at least as big as the start pattern before the barcode.
- // If this check would run off the left edge of the image, do not accept this barcode,
- // as it is very likely to be a false positive.
- int quietStart = start - (nextStart - start);
- if (quietStart >= 0)
- {
- foundStart = row.isRange(quietStart, start, false);
- }
- }
- return startRange;
- }
-
- ///
- /// Attempts to decode a one-dimensional barcode format given a single row of
- /// an image.
- ///
- /// row number from top of the row
- /// the black/white pixel data of the row
- /// decode hints
- ///
- /// containing encoded string and start/end of barcode or null, if an error occurs or barcode cannot be found
- ///
- override public Result decodeRow(int rowNumber, BitArray row, IDictionary hints)
- {
- return decodeRow(rowNumber, row, findStartGuardPattern(row), hints);
- }
-
- ///
- /// Like decodeRow(int, BitArray, java.util.Map), but
- /// allows caller to inform method about where the UPC/EAN start pattern is
- /// found. This allows this to be computed once and reused across many implementations.
- ///
- /// row index into the image
- /// encoding of the row of the barcode image
- /// start/end column where the opening start pattern was found
- /// optional hints that influence decoding
- /// encapsulating the result of decoding a barcode in the row
- virtual public Result decodeRow(int rowNumber,
- BitArray row,
- int[] startGuardRange,
- IDictionary hints)
- {
- var resultPointCallback = hints == null || !hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK) ? null :
- (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
-
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(
- (startGuardRange[0] + startGuardRange[1]) / 2.0f, rowNumber
- ));
- }
-
- var result = decodeRowStringBuffer;
- result.Length = 0;
- var endStart = decodeMiddle(row, startGuardRange, result);
- if (endStart < 0)
- return null;
-
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(
- endStart, rowNumber
- ));
- }
-
- var endRange = decodeEnd(row, endStart);
- if (endRange == null)
- return null;
-
- if (resultPointCallback != null)
- {
- resultPointCallback(new ResultPoint(
- (endRange[0] + endRange[1]) / 2.0f, rowNumber
- ));
- }
-
-
- // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
- // spec might want more whitespace, but in practice this is the maximum we can count on.
- var end = endRange[1];
- var quietEnd = end + (end - endRange[0]);
- if (quietEnd >= row.Size || !row.isRange(end, quietEnd, false))
- {
- return null;
- }
-
- var resultString = result.ToString();
- // UPC/EAN should never be less than 8 chars anyway
- if (resultString.Length < 8)
- {
- return null;
- }
- if (!checkChecksum(resultString))
- {
- return null;
- }
-
- var left = (startGuardRange[1] + startGuardRange[0]) / 2.0f;
- var right = (endRange[1] + endRange[0]) / 2.0f;
- var format = BarcodeFormat;
- var decodeResult = new Result(resultString,
- null, // no natural byte representation for these barcodes
- new ResultPoint[]
- {
- new ResultPoint(left, rowNumber),
- new ResultPoint(right, rowNumber)
- },
- format);
-
- var extensionResult = extensionReader.decodeRow(rowNumber, row, endRange[1]);
- if (extensionResult != null)
- {
- decodeResult.putMetadata(ResultMetadataType.UPC_EAN_EXTENSION, extensionResult.Text);
- decodeResult.putAllMetadata(extensionResult.ResultMetadata);
- decodeResult.addResultPoints(extensionResult.ResultPoints);
- int extensionLength = extensionResult.Text.Length;
- int[] allowedExtensions = hints != null && hints.ContainsKey(DecodeHintType.ALLOWED_EAN_EXTENSIONS) ?
- (int[]) hints[DecodeHintType.ALLOWED_EAN_EXTENSIONS] : null;
- if (allowedExtensions != null)
- {
- bool valid = false;
- foreach (int length in allowedExtensions)
- {
- if (extensionLength == length)
- {
- valid = true;
- break;
- }
- }
- if (!valid)
- {
- return null;
- }
- }
- }
-
- if (format == BarcodeFormat.EAN_13 || format == BarcodeFormat.UPC_A)
- {
- String countryID = eanManSupport.lookupCountryIdentifier(resultString);
- if (countryID != null)
- {
- decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);
- }
- }
-
- return decodeResult;
- }
-
- ///
- ///
- /// string of digits to check
- /// see
- virtual protected bool checkChecksum(String s)
- {
- return checkStandardUPCEANChecksum(s);
- }
-
- ///
- /// Computes the UPC/EAN checksum on a string of digits, and reports
- /// whether the checksum is correct or not.
- ///
- /// string of digits to check
- /// true iff string of digits passes the UPC/EAN checksum algorithm
- internal static bool checkStandardUPCEANChecksum(String s)
- {
- int length = s.Length;
- if (length == 0)
- {
- return false;
- }
-
- int sum = 0;
- for (int i = length - 2; i >= 0; i -= 2)
- {
- int digit = (int)s[i] - (int)'0';
- if (digit < 0 || digit > 9)
- {
- return false;
- }
- sum += digit;
- }
- sum *= 3;
- for (int i = length - 1; i >= 0; i -= 2)
- {
- int digit = (int)s[i] - (int)'0';
- if (digit < 0 || digit > 9)
- {
- return false;
- }
- sum += digit;
- }
- return sum % 10 == 0;
- }
-
- ///
- /// Decodes the end.
- ///
- /// The row.
- /// The end start.
- ///
- virtual protected int[] decodeEnd(BitArray row, int endStart)
- {
- return findGuardPattern(row, endStart, false, START_END_PATTERN);
- }
-
- internal static int[] findGuardPattern(BitArray row,
- int rowOffset,
- bool whiteFirst,
- int[] pattern)
- {
- return findGuardPattern(row, rowOffset, whiteFirst, pattern, new int[pattern.Length]);
- }
-
- ///
- ///
- /// row of black/white values to search
- /// position to start search
- /// if true, indicates that the pattern specifies white/black/white/...
- /// pixel counts, otherwise, it is interpreted as black/white/black/...
- /// pattern of counts of number of black and white pixels that are being
- /// searched for as a pattern
- /// array of counters, as long as pattern, to re-use
- /// start/end horizontal offset of guard pattern, as an array of two ints
- internal static int[] findGuardPattern(BitArray row,
- int rowOffset,
- bool whiteFirst,
- int[] pattern,
- int[] counters)
- {
- int patternLength = pattern.Length;
- int width = row.Size;
- bool isWhite = whiteFirst;
- rowOffset = whiteFirst ? row.getNextUnset(rowOffset) : row.getNextSet(rowOffset);
- int counterPosition = 0;
- int patternStart = rowOffset;
- for (int x = rowOffset; x < width; x++)
- {
- if (row[x] ^ isWhite)
- {
- counters[counterPosition]++;
- }
- else
- {
- if (counterPosition == patternLength - 1)
- {
- if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE)
- {
- return new int[] { patternStart, x };
- }
- patternStart += counters[0] + counters[1];
- Array.Copy(counters, 2, counters, 0, patternLength - 2);
- counters[patternLength - 2] = 0;
- counters[patternLength - 1] = 0;
- counterPosition--;
- }
- else
- {
- counterPosition++;
- }
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- return null;
- }
-
- ///
- /// Attempts to decode a single UPC/EAN-encoded digit.
- ///
- /// row of black/white values to decode
- /// the counts of runs of observed black/white/black/... values
- /// horizontal offset to start decoding from
- /// the set of patterns to use to decode -- sometimes different encodings
- /// for the digits 0-9 are used, and this indicates the encodings for 0 to 9 that should
- /// be used
- /// horizontal offset of first pixel beyond the decoded digit
- internal static bool decodeDigit(BitArray row, int[] counters, int rowOffset, int[][] patterns, out int digit)
- {
- digit = -1;
-
- if (!recordPattern(row, rowOffset, counters))
- return false;
-
- int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
- int max = patterns.Length;
- for (int i = 0; i < max; i++)
- {
- int[] pattern = patterns[i];
- int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
- if (variance < bestVariance)
- {
- bestVariance = variance;
- digit = i;
- }
- }
- return digit >= 0;
- }
-
- ///
- /// Get the format of this decoder.
- ///
- /// The 1D format.
- internal abstract BarcodeFormat BarcodeFormat { get; }
-
- ///
- /// Subclasses override this to decode the portion of a barcode between the start
- /// and end guard patterns.
- ///
- /// row of black/white values to search
- /// start/end offset of start guard pattern
- /// to append decoded chars to
- /// horizontal offset of first pixel after the "middle" that was decoded or -1 if decoding could not complete successfully
- protected internal abstract int decodeMiddle(BitArray row,
- int[] startRange,
- StringBuilder resultString);
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/UPCEANWriter.cs b/zxing.core/xx/oned/UPCEANWriter.cs
deleted file mode 100644
index b56475b..0000000
--- a/zxing.core/xx/oned/UPCEANWriter.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace ZXing.OneD
-{
- ///
- /// Encapsulates functionality and implementation that is common to UPC and EAN families
- /// of one-dimensional barcodes.
- /// aripollak@gmail.com (Ari Pollak)
- /// dsbnatut@gmail.com (Kazuki Nishiura)
- ///
- public abstract class UPCEANWriter : OneDimensionalCodeWriter
- {
- ///
- /// Gets the default margin.
- ///
- public override int DefaultMargin
- {
- get
- {
- // Use a different default more appropriate for UPC/EAN
- return UPCEANReader.START_END_PATTERN.Length;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/UPCEReader.cs b/zxing.core/xx/oned/UPCEReader.cs
deleted file mode 100644
index 10d61e5..0000000
--- a/zxing.core/xx/oned/UPCEReader.cs
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Text;
-
-using ZXing.Common;
-
-namespace ZXing.OneD
-{
- ///
- /// Implements decoding of the UPC-E format.
- /// Thisis a great reference for
- /// UPC-E information.
- /// Sean Owen
- ///
- public sealed class UPCEReader : UPCEANReader
- {
- ///
- /// The pattern that marks the middle, and end, of a UPC-E pattern.
- /// There is no "second half" to a UPC-E barcode.
- ///
- private static readonly int[] MIDDLE_END_PATTERN = { 1, 1, 1, 1, 1, 1 };
-
- ///
- /// See L_AND_G_PATTERNS these values similarly represent patterns of
- /// even-odd parity encodings of digits that imply both the number system (0 or 1)
- /// used, and the check digit.
- ///
- private static readonly int[][] NUMSYS_AND_CHECK_DIGIT_PATTERNS = {
- new[] { 0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25 },
- new[] { 0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A }
- };
-
- private readonly int[] decodeMiddleCounters;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public UPCEReader()
- {
- decodeMiddleCounters = new int[4];
- }
-
- ///
- /// Decodes the middle.
- ///
- /// The row.
- /// The start range.
- /// The result.
- ///
- override internal protected int decodeMiddle(BitArray row, int[] startRange, StringBuilder result)
- {
- int[] counters = decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- int end = row.Size;
- int rowOffset = startRange[1];
-
- int lgPatternFound = 0;
-
- for (int x = 0; x < 6 && rowOffset < end; x++)
- {
- int bestMatch;
- if (!decodeDigit(row, counters, rowOffset, L_AND_G_PATTERNS, out bestMatch))
- return -1;
- result.Append((char)('0' + bestMatch % 10));
- foreach (int counter in counters)
- {
- rowOffset += counter;
- }
- if (bestMatch >= 10)
- {
- lgPatternFound |= 1 << (5 - x);
- }
- }
-
- if (!determineNumSysAndCheckDigit(result, lgPatternFound))
- return -1;
-
- return rowOffset;
- }
-
- ///
- /// Decodes the end.
- ///
- /// The row.
- /// The end start.
- ///
- override protected int[] decodeEnd(BitArray row, int endStart)
- {
- return findGuardPattern(row, endStart, true, MIDDLE_END_PATTERN);
- }
-
- ///
- /// see checkStandardUPCEANChecksum(String)
- ///
- ///
- ///
- override protected bool checkChecksum(String s)
- {
- return base.checkChecksum(convertUPCEtoUPCA(s));
- }
-
- ///
- /// Determines the num sys and check digit.
- ///
- /// The result string.
- /// The lg pattern found.
- ///
- private static bool determineNumSysAndCheckDigit(StringBuilder resultString, int lgPatternFound)
- {
-
- for (int numSys = 0; numSys <= 1; numSys++)
- {
- for (int d = 0; d < 10; d++)
- {
- if (lgPatternFound == NUMSYS_AND_CHECK_DIGIT_PATTERNS[numSys][d])
- {
- resultString.Insert(0, new[] { (char)('0' + numSys) });
- resultString.Append((char)('0' + d));
- return true;
- }
- }
- }
- return false;
- }
-
- ///
- /// Get the format of this decoder.
- /// The 1D format.
- ///
- override internal BarcodeFormat BarcodeFormat
- {
- get { return BarcodeFormat.UPC_E; }
- }
-
- ///
- /// Expands a UPC-E value back into its full, equivalent UPC-A code value.
- ///
- /// UPC-E code as string of digits
- /// equivalent UPC-A code as string of digits
- ///
- public static String convertUPCEtoUPCA(String upce)
- {
- var upceChars = upce.Substring(1, 6);
- StringBuilder result = new StringBuilder(12);
- result.Append(upce[0]);
- char lastChar = upceChars[5];
- switch (lastChar)
- {
- case '0':
- case '1':
- case '2':
- result.Append(upceChars, 0, 2);
- result.Append(lastChar);
- result.Append("0000");
- result.Append(upceChars, 2, 3);
- break;
- case '3':
- result.Append(upceChars, 0, 3);
- result.Append("00000");
- result.Append(upceChars, 3, 2);
- break;
- case '4':
- result.Append(upceChars, 0, 4);
- result.Append("00000");
- result.Append(upceChars[4]);
- break;
- default:
- result.Append(upceChars, 0, 5);
- result.Append("0000");
- result.Append(lastChar);
- break;
- }
- result.Append(upce[7]);
- return result.ToString();
- }
- }
-}
diff --git a/zxing.core/xx/oned/rss/AbstractRSSReader.cs b/zxing.core/xx/oned/rss/AbstractRSSReader.cs
deleted file mode 100644
index 89ffa71..0000000
--- a/zxing.core/xx/oned/rss/AbstractRSSReader.cs
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2010 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-
-namespace ZXing.OneD.RSS
-{
- ///
- ///
- ///
- public abstract class AbstractRSSReader : OneDReader
- {
- private static readonly int MAX_AVG_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.2f);
- private static readonly int MAX_INDIVIDUAL_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.45f);
-
- private const float MIN_FINDER_PATTERN_RATIO = 9.5f / 12.0f;
- private const float MAX_FINDER_PATTERN_RATIO = 12.5f / 14.0f;
-
- private readonly int[] decodeFinderCounters;
- private readonly int[] dataCharacterCounters;
- private readonly float[] oddRoundingErrors;
- private readonly float[] evenRoundingErrors;
- private readonly int[] oddCounts;
- private readonly int[] evenCounts;
-
- ///
- /// Initializes a new instance of the class.
- ///
- protected AbstractRSSReader()
- {
- decodeFinderCounters = new int[4];
- dataCharacterCounters = new int[8];
- oddRoundingErrors = new float[4];
- evenRoundingErrors = new float[4];
- oddCounts = new int[dataCharacterCounters.Length / 2];
- evenCounts = new int[dataCharacterCounters.Length / 2];
- }
-
- ///
- /// Gets the decode finder counters.
- ///
- ///
- protected int[] getDecodeFinderCounters()
- {
- return decodeFinderCounters;
- }
-
- ///
- /// Gets the data character counters.
- ///
- ///
- protected int[] getDataCharacterCounters()
- {
- return dataCharacterCounters;
- }
-
- ///
- /// Gets the odd rounding errors.
- ///
- ///
- protected float[] getOddRoundingErrors()
- {
- return oddRoundingErrors;
- }
-
- ///
- /// Gets the even rounding errors.
- ///
- ///
- protected float[] getEvenRoundingErrors()
- {
- return evenRoundingErrors;
- }
-
- ///
- /// Gets the odd counts.
- ///
- ///
- protected int[] getOddCounts()
- {
- return oddCounts;
- }
-
- ///
- /// Gets the even counts.
- ///
- ///
- protected int[] getEvenCounts()
- {
- return evenCounts;
- }
-
- ///
- /// Parses the finder value.
- ///
- /// The counters.
- /// The finder patterns.
- /// The value.
- ///
- protected static bool parseFinderValue(int[] counters,
- int[][] finderPatterns,
- out int value)
- {
- for (value = 0; value < finderPatterns.Length; value++)
- {
- if (patternMatchVariance(counters, finderPatterns[value], MAX_INDIVIDUAL_VARIANCE) <
- MAX_AVG_VARIANCE)
- {
- return true;
- }
- }
- return false;
- }
-
- ///
- /// Counts the specified array.
- ///
- /// The array.
- ///
- protected static int count(int[] array)
- {
- int count = 0;
- foreach (int a in array)
- {
- count += a;
- }
- return count;
- }
-
- ///
- /// Increments the specified array.
- ///
- /// The array.
- /// The errors.
- protected static void increment(int[] array, float[] errors)
- {
- int index = 0;
- float biggestError = errors[0];
- for (int i = 1; i < array.Length; i++)
- {
- if (errors[i] > biggestError)
- {
- biggestError = errors[i];
- index = i;
- }
- }
- array[index]++;
- }
-
- ///
- /// Decrements the specified array.
- ///
- /// The array.
- /// The errors.
- protected static void decrement(int[] array, float[] errors)
- {
- int index = 0;
- float biggestError = errors[0];
- for (int i = 1; i < array.Length; i++)
- {
- if (errors[i] < biggestError)
- {
- biggestError = errors[i];
- index = i;
- }
- }
- array[index]--;
- }
-
- ///
- /// Determines whether [is finder pattern] [the specified counters].
- ///
- /// The counters.
- ///
- /// true if [is finder pattern] [the specified counters]; otherwise, false.
- ///
- protected static bool isFinderPattern(int[] counters)
- {
- int firstTwoSum = counters[0] + counters[1];
- int sum = firstTwoSum + counters[2] + counters[3];
- float ratio = (float)firstTwoSum / (float)sum;
- if (ratio >= MIN_FINDER_PATTERN_RATIO && ratio <= MAX_FINDER_PATTERN_RATIO)
- {
- // passes ratio test in spec, but see if the counts are unreasonable
- int minCounter = Int32.MaxValue;
- int maxCounter = Int32.MinValue;
- foreach (int counter in counters)
- {
- if (counter > maxCounter)
- {
- maxCounter = counter;
- }
- if (counter < minCounter)
- {
- minCounter = counter;
- }
- }
- return maxCounter < 10 * minCounter;
- }
- return false;
- }
- }
-}
diff --git a/zxing.core/xx/oned/rss/DataCharacter.cs b/zxing.core/xx/oned/rss/DataCharacter.cs
deleted file mode 100644
index c0601bf..0000000
--- a/zxing.core/xx/oned/rss/DataCharacter.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-
-namespace ZXing.OneD.RSS
-{
- ///
- ///
- ///
- public class DataCharacter
- {
- ///
- /// Gets the value.
- ///
- public int Value { get; private set; }
- ///
- /// Gets the checksum portion.
- ///
- public int ChecksumPortion { get; private set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The value.
- /// The checksum portion.
- public DataCharacter(int value, int checksumPortion)
- {
- Value = value;
- ChecksumPortion = checksumPortion;
- }
-
- ///
- /// Returns a that represents this instance.
- ///
- ///
- /// A that represents this instance.
- ///
- override public String ToString()
- {
- return Value + "(" + ChecksumPortion + ')';
- }
-
- ///
- /// Determines whether the specified is equal to this instance.
- ///
- /// The to compare with this instance.
- ///
- /// true if the specified is equal to this instance; otherwise, false.
- ///
- override public bool Equals(Object o)
- {
- if (!(o is DataCharacter))
- {
- return false;
- }
- DataCharacter that = (DataCharacter)o;
- return Value == that.Value && ChecksumPortion == that.ChecksumPortion;
- }
-
- ///
- /// Returns a hash code for this instance.
- ///
- ///
- /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
- ///
- override public int GetHashCode()
- {
- return Value ^ ChecksumPortion;
- }
- }
-}
diff --git a/zxing.core/xx/oned/rss/FinderPattern.cs b/zxing.core/xx/oned/rss/FinderPattern.cs
deleted file mode 100644
index 4e8259c..0000000
--- a/zxing.core/xx/oned/rss/FinderPattern.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-
-namespace ZXing.OneD.RSS
-{
- ///
- ///
- ///
- public sealed class FinderPattern
- {
- ///
- /// Gets the value.
- ///
- public int Value { get; private set; }
- ///
- /// Gets the start end.
- ///
- public int[] StartEnd { get; private set; }
- ///
- /// Gets the result points.
- ///
- public ResultPoint[] ResultPoints { get; private set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The value.
- /// The start end.
- /// The start.
- /// The end.
- /// The row number.
- public FinderPattern(int value, int[] startEnd, int start, int end, int rowNumber)
- {
- Value = value;
- StartEnd = startEnd;
- ResultPoints = new ResultPoint[]
- {
- new ResultPoint(start, rowNumber),
- new ResultPoint(end, rowNumber),
- };
- }
-
- ///
- /// Determines whether the specified is equal to this instance.
- ///
- /// The to compare with this instance.
- ///
- /// true if the specified is equal to this instance; otherwise, false.
- ///
- override public bool Equals(Object o)
- {
- if (!(o is FinderPattern))
- {
- return false;
- }
- FinderPattern that = (FinderPattern)o;
- return Value == that.Value;
- }
-
- ///
- /// Returns a hash code for this instance.
- ///
- ///
- /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
- ///
- override public int GetHashCode()
- {
- return Value;
- }
- }
-}
\ No newline at end of file
diff --git a/zxing.core/xx/oned/rss/Pair.cs b/zxing.core/xx/oned/rss/Pair.cs
deleted file mode 100644
index c8f79d9..0000000
--- a/zxing.core/xx/oned/rss/Pair.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace ZXing.OneD.RSS
-{
- internal sealed class Pair : DataCharacter
- {
- public FinderPattern FinderPattern { get; private set; }
- public int Count { get; private set; }
-
- internal Pair(int value, int checksumPortion, FinderPattern finderPattern)
- : base(value, checksumPortion)
- {
- FinderPattern = finderPattern;
- }
-
- public void incrementCount()
- {
- Count++;
- }
- }
-}
diff --git a/zxing.core/xx/oned/rss/RSS14Reader.cs b/zxing.core/xx/oned/rss/RSS14Reader.cs
deleted file mode 100644
index b72af15..0000000
--- a/zxing.core/xx/oned/rss/RSS14Reader.cs
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright 2009 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using ZXing.Common;
-
-namespace ZXing.OneD.RSS
-{
- ///
- /// Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006.
- ///
- public sealed class RSS14Reader : AbstractRSSReader
- {
- private static readonly int[] OUTSIDE_EVEN_TOTAL_SUBSET = { 1, 10, 34, 70, 126 };
- private static readonly int[] INSIDE_ODD_TOTAL_SUBSET = { 4, 20, 48, 81 };
- private static readonly int[] OUTSIDE_GSUM = { 0, 161, 961, 2015, 2715 };
- private static readonly int[] INSIDE_GSUM = { 0, 336, 1036, 1516 };
- private static readonly int[] OUTSIDE_ODD_WIDEST = { 8, 6, 4, 3, 1 };
- private static readonly int[] INSIDE_ODD_WIDEST = { 2, 4, 6, 8 };
-
- private static readonly int[][] FINDER_PATTERNS = {
- new[] {3, 8, 2, 1},
- new[] {3, 5, 5, 1},
- new[] {3, 3, 7, 1},
- new[] {3, 1, 9, 1},
- new[] {2, 7, 4, 1},
- new[] {2, 5, 6, 1},
- new[] {2, 3, 8, 1},
- new[] {1, 5, 7, 1},
- new[] {1, 3, 9, 1},
- };
-
- private readonly List possibleLeftPairs;
- private readonly List possibleRightPairs;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public RSS14Reader()
- {
- possibleLeftPairs = new List();
- possibleRightPairs = new List();
- }
-
- ///
- ///