internal static bool DecodeCheckErrors(byte[] code, int codeIndex, DmtxSymbolSize sizeIdx, int fix) { byte[] data = new byte[255]; int interleavedBlocks = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribInterleavedBlocks, sizeIdx); int blockErrorWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribBlockErrorWords, sizeIdx); const int fixedErr = 0; int fixedErrSum = 0; for (int i = 0; i < interleavedBlocks; i++) { int blockTotalWords = blockErrorWords + GetBlockDataSize(sizeIdx, i); int j; for (j = 0; j < blockTotalWords; j++) { data[j] = code[j * interleavedBlocks + i]; } fixedErrSum += fixedErr; for (j = 0; j < blockTotalWords; j++) { code[j * interleavedBlocks + i] = data[j]; } } if (fix != DmtxConstants.DmtxUndefined && fix >= 0 && fix < fixedErrSum) { return(false); } return(true); }
internal int SymbolModuleStatus(DmtxSymbolSize sizeIdx, int symbolRow, int symbolCol) { int dataRegionRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribDataRegionRows, sizeIdx); int dataRegionCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribDataRegionCols, sizeIdx); int symbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, sizeIdx); int mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, sizeIdx); int symbolRowReverse = symbolRows - symbolRow - 1; int mappingRow = symbolRowReverse - 1 - 2 * (symbolRowReverse / (dataRegionRows + 2)); int mappingCol = symbolCol - 1 - 2 * (symbolCol / (dataRegionCols + 2)); /* Solid portion of alignment patterns */ if (symbolRow % (dataRegionRows + 2) == 0 || symbolCol % (dataRegionCols + 2) == 0) { return(DmtxConstants.DmtxModuleOnRGB | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0)); // check if unary not is correct } /* Horinzontal calibration bars */ if ((symbolRow + 1) % (dataRegionRows + 2) == 0) { return((((symbolCol & 0x01) != 0) ? 0 : DmtxConstants.DmtxModuleOnRGB) | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0)); } /* Vertical calibration bars */ if ((symbolCol + 1) % (dataRegionCols + 2) == 0) { return((((symbolRow & 0x01) != 0) ? 0 : DmtxConstants.DmtxModuleOnRGB) | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0)); } /* Data modules */ return(this.Array[mappingRow * mappingCols + mappingCol] | DmtxConstants.DmtxModuleData); }
internal void DecodeDataStream(DmtxSymbolSize sizeIdx, byte[] outputStart) { bool macro = false; this.Output = outputStart ?? this.Output; this._outputIdx = 0; byte[] ptr = this.Code; int dataEndIndex = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx); /* Print macro header if first codeword triggers it */ if (ptr[0] == DmtxConstants.DmtxChar05Macro || ptr[0] == DmtxConstants.DmtxChar06Macro) { PushOutputMacroHeader(ptr[0]); macro = true; } for (int codeIter = 0; codeIter < dataEndIndex;) { DmtxScheme encScheme = GetEncodationScheme(this.Code[codeIter]); if (encScheme != DmtxScheme.DmtxSchemeAscii) { codeIter++; } switch (encScheme) { case DmtxScheme.DmtxSchemeAscii: codeIter = DecodeSchemeAscii(codeIter, dataEndIndex); break; case DmtxScheme.DmtxSchemeC40: case DmtxScheme.DmtxSchemeText: codeIter = DecodeSchemeC40Text(codeIter, dataEndIndex, encScheme); break; case DmtxScheme.DmtxSchemeX12: codeIter = DecodeSchemeX12(codeIter, dataEndIndex); break; case DmtxScheme.DmtxSchemeEdifact: codeIter = DecodeSchemeEdifact(codeIter, dataEndIndex); break; case DmtxScheme.DmtxSchemeBase256: codeIter = DecodeSchemeBase256(codeIter, dataEndIndex); break; } } /* Print macro trailer if required */ if (macro) { PushOutputMacroTrailer(); } }
internal DmtxEncode() { this._scheme = DmtxScheme.DmtxSchemeAscii; this._sizeIdxRequest = DmtxSymbolSize.DmtxSymbolSquareAuto; this._marginSize = 10; this._moduleSize = 5; this._pixelPacking = DmtxPackOrder.DmtxPack24bppRGB; this._imageFlip = DmtxFlip.DmtxFlipNone; this._rowPadBytes = 0; }
internal static int GetSymbolAttribute(DmtxSymAttribute attribute, DmtxSymbolSize sizeIdx) { if (sizeIdx < 0 || (int)sizeIdx >= DmtxConstants.DmtxSymbolSquareCount + DmtxConstants.DmtxSymbolRectCount) { return(DmtxConstants.DmtxUndefined); } switch (attribute) { case DmtxSymAttribute.DmtxSymAttribSymbolRows: return(DmtxConstants.SymbolRows[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribSymbolCols: return(DmtxConstants.SymbolCols[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribDataRegionRows: return(DmtxConstants.DataRegionRows[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribDataRegionCols: return(DmtxConstants.DataRegionCols[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribHorizDataRegions: return(DmtxConstants.HorizDataRegions[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribVertDataRegions: return(((int)sizeIdx < DmtxConstants.DmtxSymbolSquareCount) ? DmtxConstants.HorizDataRegions[(int)sizeIdx] : 1); case DmtxSymAttribute.DmtxSymAttribMappingMatrixRows: return(DmtxConstants.DataRegionRows[(int)sizeIdx] * GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribVertDataRegions, sizeIdx)); case DmtxSymAttribute.DmtxSymAttribMappingMatrixCols: return(DmtxConstants.DataRegionCols[(int)sizeIdx] * DmtxConstants.HorizDataRegions[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribInterleavedBlocks: return(DmtxConstants.InterleavedBlocks[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribBlockErrorWords: return(DmtxConstants.BlockErrorWords[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribBlockMaxCorrectable: return(DmtxConstants.BlockMaxCorrectable[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribSymbolDataWords: return(DmtxConstants.SymbolDataWords[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribSymbolErrorWords: return(DmtxConstants.BlockErrorWords[(int)sizeIdx] * DmtxConstants.InterleavedBlocks[(int)sizeIdx]); case DmtxSymAttribute.DmtxSymAttribSymbolMaxCorrectable: return(DmtxConstants.BlockMaxCorrectable[(int)sizeIdx] * DmtxConstants.InterleavedBlocks[(int)sizeIdx]); } return(DmtxConstants.DmtxUndefined); }
internal static int GetBlockDataSize(DmtxSymbolSize sizeIdx, int blockIdx) { int symbolDataWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx); int interleavedBlocks = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribInterleavedBlocks, sizeIdx); int count = symbolDataWords / interleavedBlocks; if (symbolDataWords < 1 || interleavedBlocks < 1) { return(DmtxConstants.DmtxUndefined); } return((sizeIdx == DmtxSymbolSize.DmtxSymbol144x144 && blockIdx < 8) ? count + 1 : count); }
private DmtxEncode(DmtxEncode src) { this._scheme = src._scheme; this._sizeIdxRequest = src._sizeIdxRequest; this._marginSize = src._marginSize; this._moduleSize = src._moduleSize; this._pixelPacking = src._pixelPacking; this._imageFlip = src._imageFlip; this._rowPadBytes = src._rowPadBytes; this._image = src._image; this._message = src._message; this._method = src._method; this._region = src._region; }
internal static DmtxSymbolSize FindCorrectSymbolSize(int dataWords, DmtxSymbolSize sizeIdxRequest) { DmtxSymbolSize sizeIdx; if (dataWords <= 0) { return(DmtxSymbolSize.DmtxSymbolShapeAuto); } if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolSquareAuto || sizeIdxRequest == DmtxSymbolSize.DmtxSymbolRectAuto) { DmtxSymbolSize idxBeg; DmtxSymbolSize idxEnd; if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolSquareAuto) { idxBeg = 0; idxEnd = (DmtxSymbolSize)DmtxConstants.DmtxSymbolSquareCount; } else { idxBeg = (DmtxSymbolSize)DmtxConstants.DmtxSymbolSquareCount; idxEnd = (DmtxSymbolSize)(DmtxConstants.DmtxSymbolSquareCount + DmtxConstants.DmtxSymbolRectCount); } for (sizeIdx = idxBeg; sizeIdx < idxEnd; sizeIdx++) { if (GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx) >= dataWords) { break; } } if (sizeIdx == idxEnd) { return(DmtxSymbolSize.DmtxSymbolShapeAuto); } } else { sizeIdx = sizeIdxRequest; } if (dataWords > GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx)) { return(DmtxSymbolSize.DmtxSymbolShapeAuto); } return(sizeIdx); }
internal DmtxMessage(DmtxSymbolSize sizeIdx, DmtxFormat symbolFormat) { if (symbolFormat != DmtxFormat.Matrix && symbolFormat != DmtxFormat.Mosaic) { throw new ArgumentException("Only DmtxFormats Matrix and Mosaic are currently supported"); } int mappingRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixRows, sizeIdx); int mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, sizeIdx); _array = new byte[mappingCols * mappingRows]; int codeSize = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx) + DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolErrorWords, sizeIdx); _code = new byte[codeSize]; _output = new byte[10 * codeSize]; }
int _outputIdx; /* Internal index used to store output progress */ #endregion #region Constructors internal DmtxMessage(DmtxSymbolSize sizeIdx, DmtxFormat symbolFormat) { if (symbolFormat != DmtxFormat.Matrix && symbolFormat != DmtxFormat.Mosaic) { throw new ArgumentException("Only DmtxFormats Matrix and Mosaic are currently supported"); } int mappingRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixRows, sizeIdx); int mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, sizeIdx); this.Array = new byte[mappingCols * mappingRows]; int codeSize = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx) + DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolErrorWords, sizeIdx); this.Code = new byte[codeSize]; this.Output = new byte[10 * codeSize]; }
internal DmtxRegion(DmtxRegion src) { this._bottomAngle = src._bottomAngle; this._bottomKnown = src._bottomKnown; this._bottomLine = src._bottomLine; this._bottomLoc = src._bottomLoc; this._boundMax = src._boundMax; this._boundMin = src._boundMin; this._finalNeg = src._finalNeg; this._finalPos = src._finalPos; this._fit2raw = new DmtxMatrix3(src._fit2raw); this._flowBegin = src._flowBegin; this._jumpToNeg = src._jumpToNeg; this._jumpToPos = src._jumpToPos; this._leftAngle = src._leftAngle; this._leftKnown = src._leftKnown; this._leftLine = src._leftLine; this._leftLoc = src._leftLoc; this._locR = src._locR; this._locT = src._locT; this._mappingCols = src._mappingCols; this._mappingRows = src._mappingRows; this._offColor = src._offColor; this._onColor = src._onColor; this._polarity = src._polarity; this._raw2fit = new DmtxMatrix3(src._raw2fit); this._rightAngle = src._rightAngle; this._rightKnown = src._rightKnown; this._rightLoc = src._rightLoc; this._sizeIdx = src._sizeIdx; this._stepR = src._stepR; this._stepsTotal = src._stepsTotal; this._stepT = src._stepT; this._symbolCols = src._symbolCols; this._symbolRows = src._symbolRows; this._topAngle = src._topAngle; this._topKnown = src._topKnown; this._topLoc = src._topLoc; }
internal DmtxDecode(DmtxImage img, int scale) { int width = img.Width / scale; int height = img.Height / scale; this._edgeMin = DmtxConstants.DmtxUndefined; this._edgeMax = DmtxConstants.DmtxUndefined; this._scanGap = 1; this._squareDevn = Math.Cos(50.0 * (Math.PI / 180.0)); this._sizeIdxExpected = DmtxSymbolSize.DmtxSymbolShapeAuto; this._edgeThresh = 10; this._xMin = 0; this._xMax = width - 1; this._yMin = 0; this._yMax = height - 1; this._scale = scale; this._cache = new byte[width * height]; this._image = img; ValidateSettingsAndInitScanGrid(); }
private DmtxSymbolSize FindCorrectSymbolSize(int dataWords, DmtxSymbolSize sizeIdxRequest) { DmtxSymbolSize sizeIdx; int idxBeg, idxEnd; if (dataWords <= 0) return DmtxSymbolSize.DmtxSymbolShapeAuto; if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolSquareAuto || sizeIdxRequest == DmtxSymbolSize.DmtxSymbolRectAuto) { if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolSquareAuto) { idxBeg = 0; idxEnd = DmtxConstants.DmtxSymbolSquareCount; } else { idxBeg = DmtxConstants.DmtxSymbolSquareCount; idxEnd = DmtxConstants.DmtxSymbolSquareCount + DmtxConstants.DmtxSymbolRectCount; } for (sizeIdx = (DmtxSymbolSize)idxBeg; sizeIdx < (DmtxSymbolSize)idxEnd; sizeIdx++) { if (DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx) >= dataWords) { break; } } if (sizeIdx == (DmtxSymbolSize)idxEnd) { return DmtxSymbolSize.DmtxSymbolShapeAuto; } } else { sizeIdx = sizeIdxRequest; } if (dataWords > DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx)) { return DmtxSymbolSize.DmtxSymbolShapeAuto; } return sizeIdx; }
int EncodeDataCodewords(byte[] buf, byte[] inputString, ref DmtxSymbolSize sizeIdx) { int dataWordCount; /* * This function needs to take both dataWordCount and sizeIdx into account * because symbol size is tied to an encodation. That is, a data stream * might be different from one symbol size to another */ /* Encode input string into data codewords */ switch (this._scheme) { case DmtxScheme.DmtxSchemeAutoBest: dataWordCount = EncodeAutoBest(buf, inputString); break; case DmtxScheme.DmtxSchemeAutoFast: dataWordCount = 0; break; default: dataWordCount = EncodeSingleScheme(buf, inputString, this._scheme); break; } /* XXX must fix ... will need to handle sizeIdx requests here because it is needed by Encode...() for triplet termination */ /* parameter sizeIdx is requested value, returned sizeIdx is decision */ sizeIdx = FindCorrectSymbolSize(dataWordCount, sizeIdx); if (sizeIdx == DmtxSymbolSize.DmtxSymbolShapeAuto) return 0; return dataWordCount; }
internal DmtxRegion(DmtxRegion src) { this._bottomAngle = src._bottomAngle; this._bottomKnown = src._bottomKnown; this._bottomLine = src._bottomLine; this._bottomLoc = src._bottomLoc; this._boundMax = src._boundMax; this._boundMin = src._boundMin; this._finalNeg = src._finalNeg; this._finalPos = src._finalPos; this._fit2raw = new DmtxMatrix3(src._fit2raw); this._flowBegin = src._flowBegin; this._jumpToNeg = src._jumpToNeg; this._jumpToPos = src._jumpToPos; this._leftAngle = src._leftAngle; this._leftKnown = src._leftKnown; this._leftLine = src._leftLine; this._leftLoc = src._leftLoc; this._locR = src._locR; this._locT = src._locT; this._mappingCols = src._mappingCols; this._mappingRows = src._mappingRows; this._offColor = src._offColor; this._onColor = src._onColor; this._polarity = src._polarity; this._raw2fit = new DmtxMatrix3(src._raw2fit); this._rightAngle = src._rightAngle; this._rightKnown = src._rightKnown; this._rightLoc = src._rightLoc; this._sizeIdx = src._sizeIdx; this._stepR = src._stepR; this._stepsTotal = src._stepsTotal; this._stepT = src._stepT; this._symbolCols = src._symbolCols; this._symbolRows = src._symbolRows; this._topAngle = src._topAngle; this._topKnown = src._topKnown; this._topLoc = src._topLoc; }
internal static void GenReedSolEcc(DmtxMessage message, DmtxSymbolSize sizeIdx) { byte[] g = new byte[69]; byte[] b = new byte[68]; int symbolDataWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx); int symbolErrorWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolErrorWords, sizeIdx); int symbolTotalWords = symbolDataWords + symbolErrorWords; int blockErrorWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribBlockErrorWords, sizeIdx); int step = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribInterleavedBlocks, sizeIdx); if (blockErrorWords != symbolErrorWords / step) { throw new Exception("Error generation reed solomon error correction"); } for (int gI = 0; gI < g.Length; gI++) { g[gI] = 0x01; } // Generate ECC polynomia for (int i = 1; i <= blockErrorWords; i++) { for (int j = i - 1; j >= 0; j--) { g[j] = GfDoublify(g[j], i); // g[j] *= 2**i if (j > 0) { g[j] = GfSum(g[j], g[j - 1]); // g[j] += g[j-1] } } } // Populate error codeword array for (int block = 0; block < step; block++) { for (int bI = 0; bI < b.Length; bI++) { b[bI] = 0; } for (int i = block; i < symbolDataWords; i += step) { int val = GfSum(b[blockErrorWords - 1], message.Code[i]); for (int j = blockErrorWords - 1; j > 0; j--) { b[j] = GfSum(b[j - 1], GfProduct(g[j], val)); } b[0] = GfProduct(g[0], val); } int blockDataWords = GetBlockDataSize(sizeIdx, block); int bIndex = blockErrorWords; for (int i = block + (step * blockDataWords); i < symbolTotalWords; i += step) { message.Code[i] = b[--bIndex]; } if (bIndex != 0) { throw new Exception("Error generation error correction code!"); } } }
private int ReadModuleColor(DmtxRegion reg, int symbolRow, int symbolCol, DmtxSymbolSize sizeIdx, int colorPlane) { int i; int symbolRows, symbolCols; int color, colorTmp; double[] sampleX = { 0.5, 0.4, 0.5, 0.6, 0.5 }; double[] sampleY = { 0.5, 0.5, 0.4, 0.5, 0.6 }; DmtxVector2 p = new DmtxVector2(); symbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, sizeIdx); symbolCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolCols, sizeIdx); colorTmp = color = 0; for (i = 0; i < 5; i++) { p.X = (1.0 / symbolCols) * (symbolCol + sampleX[i]); p.Y = (1.0 / symbolRows) * (symbolRow + sampleY[i]); p *= reg.Fit2raw; GetPixelValue((int)(p.X + 0.5), (int)(p.Y + 0.5), colorPlane, ref colorTmp); color += colorTmp; } return color / 5; }
internal static int ModulePlacementEcc200(byte[] modules, byte[] codewords, DmtxSymbolSize sizeIdx, int moduleOnColor) { int row, col, chr; int mappingRows, mappingCols; if ((moduleOnColor & (DmtxConstants.DmtxModuleOnRed | DmtxConstants.DmtxModuleOnGreen | DmtxConstants.DmtxModuleOnBlue)) == 0) { throw new Exception("Error with module placement ECC 200"); } mappingRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixRows, sizeIdx); mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, sizeIdx); /* Start in the nominal location for the 8th bit of the first character */ chr = 0; row = 4; col = 0; do { /* Repeatedly first check for one of the special corner cases */ if ((row == mappingRows) && (col == 0)) PatternShapeSpecial1(modules, mappingRows, mappingCols, codewords, chr++, moduleOnColor); else if ((row == mappingRows - 2) && (col == 0) && (mappingCols % 4 != 0)) PatternShapeSpecial2(modules, mappingRows, mappingCols, codewords, chr++, moduleOnColor); else if ((row == mappingRows - 2) && (col == 0) && (mappingCols % 8 == 4)) PatternShapeSpecial3(modules, mappingRows, mappingCols, codewords, chr++, moduleOnColor); else if ((row == mappingRows + 4) && (col == 2) && (mappingCols % 8 == 0)) PatternShapeSpecial4(modules, mappingRows, mappingCols, codewords, chr++, moduleOnColor); /* Sweep upward diagonally, inserting successive characters */ do { if ((row < mappingRows) && (col >= 0) && (modules[row * mappingCols + col] & DmtxConstants.DmtxModuleVisited) == 0) PatternShapeStandard(modules, mappingRows, mappingCols, row, col, codewords, chr++, moduleOnColor); row -= 2; col += 2; } while ((row >= 0) && (col < mappingCols)); row += 1; col += 3; /* Sweep downward diagonally, inserting successive characters */ do { if ((row >= 0) && (col < mappingCols) && (modules[row * mappingCols + col] & DmtxConstants.DmtxModuleVisited) == 0) PatternShapeStandard(modules, mappingRows, mappingCols, row, col, codewords, chr++, moduleOnColor); row += 2; col -= 2; } while ((row < mappingRows) && (col >= 0)); row += 3; col += 1; /* ... until the entire modules array is scanned */ } while ((row < mappingRows) || (col < mappingCols)); /* If lower righthand corner is untouched then fill in the fixed pattern */ if ((modules[mappingRows * mappingCols - 1] & DmtxConstants.DmtxModuleVisited) == 0) { modules[mappingRows * mappingCols - 1] |= (byte)moduleOnColor; modules[(mappingRows * mappingCols) - mappingCols - 2] |= (byte)moduleOnColor; } /* XXX should this fixed pattern also be used in reading somehow? */ /* XXX compare that chr == region->dataSize here */ return chr; /* XXX number of codewords read off */ }
internal void DecodeDataStream(DmtxSymbolSize sizeIdx, byte[] outputStart) { bool macro = false; DmtxScheme encScheme; int dataEndIndex; byte[] ptr; this._output = (outputStart == null) ? this._output : outputStart; this._outputIdx = 0; ptr = this._code; dataEndIndex = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx); /* Print macro header if first codeword triggers it */ if (ptr[0] == DmtxConstants.DmtxChar05Macro || ptr[0] == DmtxConstants.DmtxChar06Macro) { PushOutputMacroHeader(ptr[0]); macro = true; } for (int codeIter = 0; codeIter < dataEndIndex; ) { encScheme = GetEncodationScheme(this._code[codeIter]); if (encScheme != DmtxScheme.DmtxSchemeAscii) codeIter++; switch (encScheme) { case DmtxScheme.DmtxSchemeAscii: codeIter = DecodeSchemeAscii(codeIter, dataEndIndex); break; case DmtxScheme.DmtxSchemeC40: case DmtxScheme.DmtxSchemeText: codeIter = DecodeSchemeC40Text(codeIter, dataEndIndex, encScheme); break; case DmtxScheme.DmtxSchemeX12: codeIter = DecodeSchemeX12(codeIter, dataEndIndex); break; case DmtxScheme.DmtxSchemeEdifact: codeIter = DecodeSchemeEdifact(codeIter, dataEndIndex); break; case DmtxScheme.DmtxSchemeBase256: codeIter = DecodeSchemeBase256(codeIter, dataEndIndex); break; default: /* error */ break; } } /* Print macro trailer if required */ if (macro) { PushOutputMacroTrailer(); } }
internal bool EncodeDataMosaic(byte[] inputString) { int dataWordCount; int tmpInputSize; int inputStartIndex; int[] splitInputSize = new int[3]; DmtxSymbolSize sizeIdx, sizeIdxRequest; DmtxSymbolSize splitSizeIdxAttempt, splitSizeIdxFirst, splitSizeIdxLast; List<byte[]> buf = new List<byte[]>(3); for (int i = 0; i < 3; i++) { buf.Add(new byte[4096]); } DmtxEncode encGreen, encBlue; int row, col, mappingRows, mappingCols; /* 1) count how many codewords it would take to encode the whole thing * 2) take ceiling N of codeword count divided by 3 * 3) using minimum symbol size that can accomodate N codewords: * 4) create several barcodes over iterations of increasing numbers of * input codewords until you go one too far * 5) if codewords remain after filling R, G, and B barcodes then go back * to 3 and try with next larger size * 6) take the 3 different images you created and write out a new barcode */ /* Encode full input string to establish baseline data codeword count */ sizeIdx = sizeIdxRequest = this._sizeIdxRequest; /* XXX buf can be changed here to use all 3 buffers' length */ dataWordCount = EncodeDataCodewords(buf[0], inputString, ref sizeIdx); if (dataWordCount <= 0) return false; /* Use 1/3 (ceiling) of inputSize establish input size target */ tmpInputSize = (inputString.Length + 2) / 3; splitInputSize[0] = tmpInputSize; splitInputSize[1] = tmpInputSize; splitInputSize[2] = inputString.Length - (splitInputSize[0] + splitInputSize[1]); /* XXX clean up above lines later for corner cases */ /* Use 1/3 (floor) of dataWordCount establish first symbol size attempt */ splitSizeIdxFirst = FindCorrectSymbolSize(tmpInputSize, sizeIdxRequest); if (splitSizeIdxFirst == DmtxSymbolSize.DmtxSymbolShapeAuto) return false; /* Set the last possible symbol size for this symbol shape or specific size request */ if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolSquareAuto) { splitSizeIdxLast = DmtxSymbolSize.DmtxSymbol144x144; } else if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolRectAuto) { splitSizeIdxLast = DmtxSymbolSize.DmtxSymbol16x48; } else { splitSizeIdxLast = splitSizeIdxFirst; } /* XXX would be nice if we could choose a size and then fill up each layer as we go, but this can cause problems with all data fits on first 2 layers. Revisit this later after things look a bit cleaner. */ /* Try increasing symbol sizes until 3 of them can hold all input values */ byte[] tmpRed = new byte[splitInputSize[0]]; for (int i = 0; i < splitInputSize[0]; i++) { tmpRed[i] = inputString[i]; } byte[] tmpGreen = new byte[splitInputSize[1]]; for (int i = splitInputSize[0]; i < splitInputSize[0] + splitInputSize[1]; i++) { tmpGreen[i - splitInputSize[0]] = inputString[i]; } byte[] tmpBlue = new byte[splitInputSize[2]]; for (int i = splitInputSize[0] + splitInputSize[1]; i < inputString.Length; i++) { tmpBlue[i - splitInputSize[0] - splitInputSize[1]] = inputString[i]; } for (splitSizeIdxAttempt = splitSizeIdxFirst; splitSizeIdxAttempt <= splitSizeIdxLast; splitSizeIdxAttempt++) { /* RED LAYER */ sizeIdx = splitSizeIdxAttempt; inputStartIndex = 0; EncodeDataCodewords(buf[0], tmpRed, ref sizeIdx); if (sizeIdx != splitSizeIdxAttempt) continue; /* GREEN LAYER */ sizeIdx = splitSizeIdxAttempt; inputStartIndex += splitInputSize[0]; EncodeDataCodewords(buf[1], tmpGreen, ref sizeIdx); if (sizeIdx != splitSizeIdxAttempt) continue; /* BLUE LAYER */ sizeIdx = splitSizeIdxAttempt; inputStartIndex += splitInputSize[1]; EncodeDataCodewords(buf[2], tmpBlue, ref sizeIdx); if (sizeIdx != splitSizeIdxAttempt) continue; break; } this._sizeIdxRequest = splitSizeIdxAttempt; /* Now we have the correct lengths for splitInputSize, and they all fit into the desired size */ encGreen = new DmtxEncode(this); encBlue = new DmtxEncode(this); /* First encode red to the main encode struct (image portion will be overwritten) */ EncodeDataMatrix(null, null, tmpRed); encGreen.EncodeDataMatrix(null, null, tmpGreen); encBlue.EncodeDataMatrix(null, null, tmpBlue); mappingRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixRows, splitSizeIdxAttempt); mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, splitSizeIdxAttempt); for (int i = 0; i < this._region.MappingCols * this._region.MappingRows; i++) { this._message.Array[i] = 0; } DmtxDecode.ModulePlacementEcc200(this._message.Array, this._message.Code, this._region.SizeIdx, DmtxConstants.DmtxModuleOnRed); //string s = Encoding.ASCII.GetString(_array); //Console.WriteLine(s); /* Data Mosaic will traverse this array multiple times -- reset DmtxModuleAssigned and DMX_MODULE_VISITED bits before starting */ for (row = 0; row < mappingRows; row++) { for (col = 0; col < mappingCols; col++) { this._message.Array[row * mappingCols + col] &= (byte)(0xff ^ (DmtxConstants.DmtxModuleAssigned | DmtxConstants.DmtxModuleVisited)); } } DmtxDecode.ModulePlacementEcc200(this._message.Array, encGreen.Message.Code, this._region.SizeIdx, DmtxConstants.DmtxModuleOnGreen); /* Data Mosaic will traverse this array multiple times -- reset DmtxModuleAssigned and DMX_MODULE_VISITED bits before starting */ for (row = 0; row < mappingRows; row++) { for (col = 0; col < mappingCols; col++) { this._message.Array[row * mappingCols + col] &= (byte)(0xff ^ (DmtxConstants.DmtxModuleAssigned | DmtxConstants.DmtxModuleVisited)); } } DmtxDecode.ModulePlacementEcc200(this._message.Array, encBlue.Message.Code, this._region.SizeIdx, DmtxConstants.DmtxModuleOnBlue); PrintPattern(null, null); return true; }
internal int SymbolModuleStatus(DmtxSymbolSize sizeIdx, int symbolRow, int symbolCol) { int dataRegionRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribDataRegionRows, sizeIdx); int dataRegionCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribDataRegionCols, sizeIdx); int symbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, sizeIdx); int mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, sizeIdx); int symbolRowReverse = symbolRows - symbolRow - 1; int mappingRow = symbolRowReverse - 1 - 2 * (symbolRowReverse / (dataRegionRows + 2)); int mappingCol = symbolCol - 1 - 2 * (symbolCol / (dataRegionCols + 2)); /* Solid portion of alignment patterns */ if (symbolRow % (dataRegionRows + 2) == 0 || symbolCol % (dataRegionCols + 2) == 0) { return (DmtxConstants.DmtxModuleOnRGB | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0)); // check if unary not is correct } /* Horinzontal calibration bars */ if ((symbolRow + 1) % (dataRegionRows + 2) == 0) { return (((symbolCol & 0x01) != 0) ? 0 : DmtxConstants.DmtxModuleOnRGB) | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0); } /* Vertical calibration bars */ if ((symbolCol + 1) % (dataRegionCols + 2) == 0) { return (((symbolRow & 0x01) != 0) ? 0 : DmtxConstants.DmtxModuleOnRGB) | (DmtxConstants.DmtxModuleData == 0 ? 1 : 0); } /* Data modules */ return (this._array[mappingRow * mappingCols + mappingCol] | DmtxConstants.DmtxModuleData); }