int CountJumpTally(DmtxRegion reg, int xStart, int yStart, DmtxDirection dir) { int x, xInc = 0; int y, yInc = 0; int state = DmtxConstants.DmtxModuleOn; int jumpCount = 0; int jumpThreshold; int tModule, tPrev; bool darkOnLight; int color; if (xStart != 0 && yStart != 0) { throw new Exception("CountJumpTally failed, xStart or yStart must be zero!"); } if (dir == DmtxDirection.DmtxDirRight) { xInc = 1; } else { yInc = 1; } if (xStart == -1 || xStart == reg.SymbolCols || yStart == -1 || yStart == reg.SymbolRows) { state = DmtxConstants.DmtxModuleOff; } darkOnLight = (reg.OffColor > reg.OnColor); jumpThreshold = Math.Abs((int)(0.4 * (reg.OnColor - reg.OffColor) + 0.5)); color = ReadModuleColor(reg, yStart, xStart, reg.SizeIdx, reg.FlowBegin.Plane); tModule = (darkOnLight) ? reg.OffColor - color : color - reg.OffColor; for (x = xStart + xInc, y = yStart + yInc; (dir == DmtxDirection.DmtxDirRight && x < reg.SymbolCols) || (dir == DmtxDirection.DmtxDirUp && y < reg.SymbolRows); x += xInc, y += yInc) { tPrev = tModule; color = ReadModuleColor(reg, y, x, reg.SizeIdx, reg.FlowBegin.Plane); tModule = (darkOnLight) ? reg.OffColor - color : color - reg.OffColor; if (state == DmtxConstants.DmtxModuleOff) { if (tModule > tPrev + jumpThreshold) { jumpCount++; state = DmtxConstants.DmtxModuleOn; } } else { if (tModule < tPrev - jumpThreshold) { jumpCount++; state = DmtxConstants.DmtxModuleOff; } } } return jumpCount; }
private void TallyModuleJumps(DmtxRegion reg, int[,] tally, int xOrigin, int yOrigin, int mapWidth, int mapHeight, DmtxDirection dir) { int extent, weight; int mapRow, mapCol; int lineStart, lineStop; int travelStart, travelStop; int line; int travel; int jumpThreshold; int color; int statusPrev, statusModule; int tPrev, tModule; if (!(dir == DmtxDirection.DmtxDirUp || dir == DmtxDirection.DmtxDirLeft || dir == DmtxDirection.DmtxDirDown || dir == DmtxDirection.DmtxDirRight)) { throw new ArgumentException("Only orthogonal directions are allowed in tally module jumps!"); } int travelStep = (dir == DmtxDirection.DmtxDirUp || dir == DmtxDirection.DmtxDirRight) ? 1 : -1; /* Abstract row and column progress using pointers to allow grid traversal in all 4 directions using same logic */ bool horizontal = false; if ((dir & DmtxDirection.DmtxDirHorizontal) != 0x00) { horizontal = true; line = 0; travel = 0; extent = mapWidth; lineStart = yOrigin; lineStop = yOrigin + mapHeight; travelStart = (travelStep == 1) ? xOrigin - 1 : xOrigin + mapWidth; travelStop = (travelStep == 1) ? xOrigin + mapWidth : xOrigin - 1; } else { line = 0; travel = 0; extent = mapHeight; lineStart = xOrigin; lineStop = xOrigin + mapWidth; travelStart = (travelStep == 1) ? yOrigin - 1 : yOrigin + mapHeight; travelStop = (travelStep == 1) ? yOrigin + mapHeight : yOrigin - 1; } bool darkOnLight = (reg.OffColor > reg.OnColor); jumpThreshold = Math.Abs((int)(0.4 * (reg.OffColor - reg.OnColor) + 0.5)); if (jumpThreshold < 0) { throw new Exception("Negative jump threshold is not allowed in tally module jumps"); } for (line = lineStart; line < lineStop; line++) { /* Capture tModule for each leading border module as normal but decide status based on predictable barcode border pattern */ travel = travelStart; if (horizontal) { color = ReadModuleColor(reg, line, travel, reg.SizeIdx, reg.FlowBegin.Plane); } else { color = ReadModuleColor(reg, travel, line, reg.SizeIdx, reg.FlowBegin.Plane); } tModule = (darkOnLight) ? reg.OffColor - color : color - reg.OffColor; statusModule = (travelStep == 1 || (line & 0x01) == 0) ? DmtxConstants.DmtxModuleOnRGB : DmtxConstants.DmtxModuleOff; weight = extent; while ((travel += travelStep) != travelStop) { tPrev = tModule; statusPrev = statusModule; /* For normal data-bearing modules capture color and decide module status based on comparison to previous "known" module */ if (horizontal) { color = ReadModuleColor(reg, line, travel, reg.SizeIdx, reg.FlowBegin.Plane); } else { color = ReadModuleColor(reg, travel, line, reg.SizeIdx, reg.FlowBegin.Plane); } tModule = (darkOnLight) ? reg.OffColor - color : color - reg.OffColor; if (statusPrev == DmtxConstants.DmtxModuleOnRGB) { if (tModule < tPrev - jumpThreshold) { statusModule = DmtxConstants.DmtxModuleOff; } else { statusModule = DmtxConstants.DmtxModuleOnRGB; } } else if (statusPrev == DmtxConstants.DmtxModuleOff) { if (tModule > tPrev + jumpThreshold) { statusModule = DmtxConstants.DmtxModuleOnRGB; } else { statusModule = DmtxConstants.DmtxModuleOff; } } if (horizontal) { mapRow = line - yOrigin; mapCol = travel - xOrigin; } else { mapRow = travel - yOrigin; mapCol = line - xOrigin; } if (!(mapRow < 24 && mapCol < 24)) { throw new Exception("Tally module mump failed, index out of range!"); } if (statusModule == DmtxConstants.DmtxModuleOnRGB) { tally[mapRow, mapCol] += (2 * weight); } weight--; } if (weight != 0) { throw new Exception("Tally module jump failed, weight <> 0!"); } } }