internal bool GetStep(DmtxPixelLoc target, ref int travel, ref int outward) { /* Determine necessary step along and outward from Bresenham line */ if (this._steep) { travel = (this._yStep > 0) ? target.Y - this._loc.Y : this._loc.Y - target.Y; Step(travel, 0); outward = (this._xOut > 0) ? target.X - this._loc.X : this._loc.X - target.X; if (this._yOut != 0) { throw new Exception("Invald yOut value for bresline step!"); } } else { travel = (this._xStep > 0) ? target.X - this._loc.X : this._loc.X - target.X; Step(travel, 0); outward = (this._yOut > 0) ? target.Y - this._loc.Y : this._loc.Y - target.Y; if (this._xOut != 0) { throw new Exception("Invald xOut value for bresline step!"); } } return(true); }
internal DmtxBresLine(DmtxBresLine orig) { this._error = orig._error; this._loc = new DmtxPixelLoc() { X = orig._loc.X, Y = orig._loc.Y }; this._loc0 = new DmtxPixelLoc() { X = orig._loc0.X, Y = orig._loc0.Y }; this._loc1 = new DmtxPixelLoc() { X = orig._loc1.X, Y = orig._loc1.Y }; this._outward = orig._outward; this._steep = orig._steep; this._travel = orig._travel; this._xDelta = orig._xDelta; this._xOut = orig._xOut; this._xStep = orig._xStep; this._yDelta = orig._yDelta; this._yOut = orig._yOut; this._yStep = orig._yStep; }
internal DmtxBresLine(DmtxPixelLoc loc0, DmtxPixelLoc loc1, DmtxPixelLoc locInside) { int cp; DmtxPixelLoc locBeg, locEnd; /* Values that stay the same after initialization */ this._loc0 = loc0; this._loc1 = loc1; this._xStep = (loc0.X < loc1.X) ? +1 : -1; this._yStep = (loc0.Y < loc1.Y) ? +1 : -1; this._xDelta = Math.Abs(loc1.X - loc0.X); this._yDelta = Math.Abs(loc1.Y - loc0.Y); this._steep = (this._yDelta > this._xDelta); /* Take cross product to determine outward step */ if (this._steep) { /* Point first vector up to get correct sign */ if (loc0.Y < loc1.Y) { locBeg = loc0; locEnd = loc1; } else { locBeg = loc1; locEnd = loc0; } cp = (((locEnd.X - locBeg.X) * (locInside.Y - locEnd.Y)) - ((locEnd.Y - locBeg.Y) * (locInside.X - locEnd.X))); this._xOut = (cp > 0) ? +1 : -1; this._yOut = 0; } else { /* Point first vector left to get correct sign */ if (loc0.X > loc1.X) { locBeg = loc0; locEnd = loc1; } else { locBeg = loc1; locEnd = loc0; } cp = (((locEnd.X - locBeg.X) * (locInside.Y - locEnd.Y)) - ((locEnd.Y - locBeg.Y) * (locInside.X - locEnd.X))); this._xOut = 0; this._yOut = (cp > 0) ? +1 : -1; } /* Values that change while stepping through line */ this._loc = loc0; this._travel = 0; this._outward = 0; this._error = (this._steep) ? this._yDelta / 2 : this._xDelta / 2; }
internal DmtxRange PopGridLocation(ref DmtxPixelLoc loc) { DmtxRange locStatus; do { locStatus = GetGridCoordinates(ref loc); /* Always leave grid pointing at next available location */ this._pixelCount++; } while (locStatus == DmtxRange.DmtxRangeBad); return(locStatus); }
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 void CacheFillQuad(DmtxPixelLoc p0, DmtxPixelLoc p1, DmtxPixelLoc p2, DmtxPixelLoc p3) { DmtxBresLine[] lines = new DmtxBresLine[4]; DmtxPixelLoc pEmpty = new DmtxPixelLoc() { X = 0, Y = 0 }; int[] scanlineMin; int[] scanlineMax; int minY, maxY, sizeY, posY, posX; int i, idx; lines[0] = new DmtxBresLine(p0, p1, pEmpty); lines[1] = new DmtxBresLine(p1, p2, pEmpty); lines[2] = new DmtxBresLine(p2, p3, pEmpty); lines[3] = new DmtxBresLine(p3, p0, pEmpty); minY = this._yMax; maxY = 0; minY = DmtxCommon.Min<int>(minY, p0.Y); maxY = DmtxCommon.Max<int>(maxY, p0.Y); minY = DmtxCommon.Min<int>(minY, p1.Y); maxY = DmtxCommon.Max<int>(maxY, p1.Y); minY = DmtxCommon.Min<int>(minY, p2.Y); maxY = DmtxCommon.Max<int>(maxY, p2.Y); minY = DmtxCommon.Min<int>(minY, p3.Y); maxY = DmtxCommon.Max<int>(maxY, p3.Y); sizeY = maxY - minY + 1; scanlineMin = new int[sizeY]; scanlineMax = new int[sizeY]; for (i = 0; i < sizeY; i++) { scanlineMin[i] = this._xMax; } for (i = 0; i < 4; i++) { while (lines[i].Loc.X != lines[i].Loc1.X || lines[i].Loc.Y != lines[i].Loc1.Y) { idx = lines[i].Loc.Y - minY; scanlineMin[idx] = DmtxCommon.Min<int>(scanlineMin[idx], lines[i].Loc.X); scanlineMax[idx] = DmtxCommon.Max<int>(scanlineMax[idx], lines[i].Loc.X); lines[i].Step(1, 0); } } for (posY = minY; posY < maxY && posY < this._yMax; posY++) { idx = posY - minY; for (posX = scanlineMin[idx]; posX < scanlineMax[idx] && posX < this._xMax; posX++) { if (posX < 0 || posY < 0) { continue; } try { int cacheIndex = GetCacheIndex(posX, posY); this._cache[cacheIndex] |= 0x80; } catch (Exception) { // FIXXXME: log here as soon as there is a logger } } } }
DmtxFollow FollowSeekLoc(DmtxPixelLoc loc) { DmtxFollow follow = new DmtxFollow(); follow.Loc = loc; follow.Step = 0; follow.Ptr = this._cache; follow.PtrIndex = DecodeGetCache(follow.Loc.X, follow.Loc.Y); return follow; }
private DmtxRange GetGridCoordinates(ref DmtxPixelLoc locRef) { /* Initially pixelCount may fall beyond acceptable limits. Update grid * state before testing coordinates */ /* Jump to next cross pattern horizontally if current column is done */ if (this._pixelCount >= this._pixelTotal) { this._pixelCount = 0; this._xCenter += this._jumpSize; } /* Jump to next cross pattern vertically if current row is done */ if (this._xCenter > this._maxExtent) { this._xCenter = this._startPos; this._yCenter += this._jumpSize; } /* Increment level when vertical step goes too far */ if (this._yCenter > this._maxExtent) { this._total *= 4; this._extent /= 2; SetDerivedFields(); } if (this._extent == 0 || this._extent < this._minExtent) { locRef.X = locRef.Y = -1; return(DmtxRange.DmtxRangeEnd); } int count = this._pixelCount; if (count >= this._pixelTotal) { throw new Exception("Scangrid is beyong image limits!"); } DmtxPixelLoc loc = new DmtxPixelLoc(); if (count == this._pixelTotal - 1) { /* center pixel */ loc.X = this._xCenter; loc.Y = this._yCenter; } else { int half = this._pixelTotal / 2; int quarter = half / 2; /* horizontal portion */ if (count < half) { loc.X = this._xCenter + ((count < quarter) ? (count - quarter) : (half - count)); loc.Y = this._yCenter; } /* vertical portion */ else { count -= half; loc.X = this._xCenter; loc.Y = this._yCenter + ((count < quarter) ? (count - quarter) : (half - count)); } } loc.X += this._xOffset; loc.Y += this._yOffset; locRef.X = loc.X; locRef.Y = loc.Y; if (loc.X < this._xMin || loc.X > this._xMax || loc.Y < this._yMin || loc.Y > this._yMax) { return(DmtxRange.DmtxRangeBad); } return(DmtxRange.DmtxRangeGood); }
private DmtxRange GetGridCoordinates(ref DmtxPixelLoc locRef) { /* Initially pixelCount may fall beyond acceptable limits. Update grid * state before testing coordinates */ /* Jump to next cross pattern horizontally if current column is done */ if (this._pixelCount >= this._pixelTotal) { this._pixelCount = 0; this._xCenter += this._jumpSize; } /* Jump to next cross pattern vertically if current row is done */ if (this._xCenter > this._maxExtent) { this._xCenter = this._startPos; this._yCenter += this._jumpSize; } /* Increment level when vertical step goes too far */ if (this._yCenter > this._maxExtent) { this._total *= 4; this._extent /= 2; SetDerivedFields(); } if (this._extent == 0 || this._extent < this._minExtent) { locRef.X = locRef.Y = -1; return DmtxRange.DmtxRangeEnd; } int count = this._pixelCount; if (count >= this._pixelTotal) { throw new Exception("Scangrid is beyong image limits!"); } DmtxPixelLoc loc = new DmtxPixelLoc(); if (count == this._pixelTotal - 1) { /* center pixel */ loc.X = this._xCenter; loc.Y = this._yCenter; } else { int half = this._pixelTotal / 2; int quarter = half / 2; /* horizontal portion */ if (count < half) { loc.X = this._xCenter + ((count < quarter) ? (count - quarter) : (half - count)); loc.Y = this._yCenter; } /* vertical portion */ else { count -= half; loc.X = this._xCenter; loc.Y = this._yCenter + ((count < quarter) ? (count - quarter) : (half - count)); } } loc.X += this._xOffset; loc.Y += this._yOffset; locRef.X = loc.X; locRef.Y = loc.Y; if (loc.X < this._xMin || loc.X > this._xMax || loc.Y < this._yMin || loc.Y > this._yMax) { return DmtxRange.DmtxRangeBad; } return DmtxRange.DmtxRangeGood; }
DmtxPointFlow FindStrongestNeighbor(DmtxPointFlow center, int sign) { int i; int strongIdx; int attempt, attemptDiff; int occupied; DmtxPixelLoc loc = new DmtxPixelLoc(); DmtxPointFlow[] flow = new DmtxPointFlow[8]; attempt = (sign < 0) ? center.Depart : (center.Depart + 4) % 8; occupied = 0; strongIdx = DmtxConstants.DmtxUndefined; for (i = 0; i < 8; i++) { loc.X = center.Loc.X + DmtxConstants.DmtxPatternX[i]; loc.Y = center.Loc.Y + DmtxConstants.DmtxPatternY[i]; int cacheIndex = DecodeGetCache(loc.X, loc.Y); if (cacheIndex == DmtxConstants.DmtxUndefined) { continue; } if ((int)(this._cache[cacheIndex] & 0x80) != 0x00) { if (++occupied > 2) return DmtxConstants.DmtxBlankEdge; else continue; } attemptDiff = Math.Abs(attempt - i); if (attemptDiff > 4) attemptDiff = 8 - attemptDiff; if (attemptDiff > 1) continue; flow[i] = GetPointFlow(center.Plane, loc, i); if (strongIdx == DmtxConstants.DmtxUndefined || flow[i].Mag > flow[strongIdx].Mag || (flow[i].Mag == flow[strongIdx].Mag && ((i & 0x01) != 0))) { strongIdx = i; } } return (strongIdx == DmtxConstants.DmtxUndefined) ? DmtxConstants.DmtxBlankEdge : flow[strongIdx]; }
DmtxPointFlow GetPointFlow(int colorPlane, DmtxPixelLoc loc, int arrive) { int[] coefficient = new int[] { 0, 1, 2, 1, 0, -1, -2, -1 }; bool err; int patternIdx, coefficientIdx; int compass, compassMax; int[] mag = new int[4]; int xAdjust, yAdjust; int color; int[] colorPattern = new int[8]; DmtxPointFlow flow = new DmtxPointFlow(); for (patternIdx = 0; patternIdx < 8; patternIdx++) { xAdjust = loc.X + DmtxConstants.DmtxPatternX[patternIdx]; yAdjust = loc.Y + DmtxConstants.DmtxPatternY[patternIdx]; err = GetPixelValue(xAdjust, yAdjust, colorPlane, ref colorPattern[patternIdx]); if (err == false) { return DmtxConstants.DmtxBlankEdge; } } /* Calculate this pixel's flow intensity for each direction (-45, 0, 45, 90) */ compassMax = 0; for (compass = 0; compass < 4; compass++) { /* Add portion from each position in the convolution matrix pattern */ for (patternIdx = 0; patternIdx < 8; patternIdx++) { coefficientIdx = (patternIdx - compass + 8) % 8; if (coefficient[coefficientIdx] == 0) continue; color = colorPattern[patternIdx]; switch (coefficient[coefficientIdx]) { case 2: mag[compass] += 2 * color; break; case 1: mag[compass] += color; break; case -2: mag[compass] -= 2 * color; break; case -1: mag[compass] -= color; break; } } /* Identify strongest compass flow */ if (compass != 0 && Math.Abs(mag[compass]) > Math.Abs(mag[compassMax])) compassMax = compass; } /* Convert signed compass direction into unique flow directions (0-7) */ flow.Plane = colorPlane; flow.Arrive = arrive; flow.Depart = (mag[compassMax] > 0) ? compassMax + 4 : compassMax; flow.Mag = Math.Abs(mag[compassMax]); flow.Loc = loc; return flow; }
bool MatrixRegionAlignCalibEdge(DmtxRegion reg, DmtxEdge edgeLoc) { int streamDir; int steps; int avoidAngle; DmtxSymbolSize symbolShape; DmtxVector2 pTmp = new DmtxVector2(); DmtxPixelLoc loc0 = new DmtxPixelLoc(); DmtxPixelLoc loc1 = new DmtxPixelLoc(); DmtxPixelLoc locOrigin = new DmtxPixelLoc(); DmtxBresLine line; DmtxFollow follow; DmtxBestLine bestLine; /* Determine pixel coordinates of origin */ pTmp.X = 0.0; pTmp.Y = 0.0; pTmp *= reg.Fit2raw; locOrigin.X = (int)(pTmp.X + 0.5); locOrigin.Y = (int)(pTmp.Y + 0.5); if (this._sizeIdxExpected == DmtxSymbolSize.DmtxSymbolSquareAuto || (this._sizeIdxExpected >= DmtxSymbolSize.DmtxSymbol10x10 && this._sizeIdxExpected <= DmtxSymbolSize.DmtxSymbol144x144)) symbolShape = DmtxSymbolSize.DmtxSymbolSquareAuto; else if (this._sizeIdxExpected == DmtxSymbolSize.DmtxSymbolRectAuto || (this._sizeIdxExpected >= DmtxSymbolSize.DmtxSymbol8x18 && this._sizeIdxExpected <= DmtxSymbolSize.DmtxSymbol16x48)) symbolShape = DmtxSymbolSize.DmtxSymbolRectAuto; else symbolShape = DmtxSymbolSize.DmtxSymbolShapeAuto; /* Determine end locations of test line */ if (edgeLoc == DmtxEdge.DmtxEdgeTop) { streamDir = reg.Polarity * -1; avoidAngle = reg.LeftLine.Angle; follow = FollowSeekLoc(reg.LocT); pTmp.X = 0.8; pTmp.Y = (symbolShape == DmtxSymbolSize.DmtxSymbolRectAuto) ? 0.2 : 0.6; } else { streamDir = reg.Polarity; avoidAngle = reg.BottomLine.Angle; follow = FollowSeekLoc(reg.LocR); pTmp.X = (symbolShape == DmtxSymbolSize.DmtxSymbolSquareAuto) ? 0.7 : 0.9; pTmp.Y = 0.8; } pTmp *= reg.Fit2raw; loc1.X = (int)(pTmp.X + 0.5); loc1.Y = (int)(pTmp.Y + 0.5); loc0 = follow.Loc; line = new DmtxBresLine(loc0, loc1, locOrigin); steps = TrailBlazeGapped(reg, line, streamDir); bestLine = FindBestSolidLine2(loc0, steps, streamDir, avoidAngle); if (bestLine.Mag < 5) { ; } if (edgeLoc == DmtxEdge.DmtxEdgeTop) { reg.TopKnown = 1; reg.TopAngle = bestLine.Angle; reg.TopLoc = bestLine.LocBeg; } else { reg.RightKnown = 1; reg.RightAngle = bestLine.Angle; reg.RightLoc = bestLine.LocBeg; } return true; }
DmtxPointFlow MatrixRegionSeekEdge(DmtxPixelLoc loc) { DmtxPointFlow flow; DmtxPointFlow[] flowPlane = new DmtxPointFlow[3]; DmtxPointFlow flowPos, flowPosBack; DmtxPointFlow flowNeg, flowNegBack; int channelCount = _image.ChannelCount; /* Find whether red, green, or blue shows the strongest edge */ int strongIdx = 0; for (int i = 0; i < channelCount; i++) { flowPlane[i] = GetPointFlow(i, loc, DmtxConstants.DmtxNeighborNone); if (i > 0 && flowPlane[i].Mag > flowPlane[strongIdx].Mag) strongIdx = i; } if (flowPlane[strongIdx].Mag < 10) return DmtxConstants.DmtxBlankEdge; flow = flowPlane[strongIdx]; flowPos = FindStrongestNeighbor(flow, +1); flowNeg = FindStrongestNeighbor(flow, -1); if (flowPos.Mag != 0 && flowNeg.Mag != 0) { flowPosBack = FindStrongestNeighbor(flowPos, -1); flowNegBack = FindStrongestNeighbor(flowNeg, +1); if (flowPos.Arrive == (flowPosBack.Arrive + 4) % 8 && flowNeg.Arrive == (flowNegBack.Arrive + 4) % 8) { flow.Arrive = DmtxConstants.DmtxNeighborNone; //CALLBACK_POINT_PLOT(flow.Loc, 1, 1, 1); return flow; } } return DmtxConstants.DmtxBlankEdge; }
internal bool GetStep(DmtxPixelLoc target, ref int travel, ref int outward) { /* Determine necessary step along and outward from Bresenham line */ if (this._steep) { travel = (this._yStep > 0) ? target.Y - this._loc.Y : this._loc.Y - target.Y; Step(travel, 0); outward = (this._xOut > 0) ? target.X - this._loc.X : this._loc.X - target.X; if (this._yOut != 0) { throw new Exception("Invald yOut value for bresline step!"); } } else { travel = (this._xStep > 0) ? target.X - this._loc.X : this._loc.X - target.X; Step(travel, 0); outward = (this._yOut > 0) ? target.Y - this._loc.Y : this._loc.Y - target.Y; if (this._xOut != 0) { throw new Exception("Invald xOut value for bresline step!"); } } return true; }
DmtxRegion RegionScanPixel(int x, int y) { DmtxRegion reg = new DmtxRegion(); DmtxPointFlow flowBegin; DmtxPixelLoc loc = new DmtxPixelLoc(); loc.X = x; loc.Y = y; int cacheIndex = this.DecodeGetCache(loc.X, loc.Y); if (cacheIndex == -1) return null; if (this._cache[cacheIndex] != 0x00) return null; /* Test for presence of any reasonable edge at this location */ flowBegin = MatrixRegionSeekEdge(loc); if (flowBegin.Mag < (int)(this._edgeThresh * 7.65 + 0.5)) return null; /* Determine barcode orientation */ if (MatrixRegionOrientation(reg, flowBegin) == false) return null; if (RegionUpdateXfrms(reg) == false) return null; /* Define top edge */ if (MatrixRegionAlignCalibEdge(reg, DmtxEdge.DmtxEdgeTop) == false) return null; if (RegionUpdateXfrms(reg) == false) return null; /* Define right edge */ if (MatrixRegionAlignCalibEdge(reg, DmtxEdge.DmtxEdgeRight) == false) return null; if (RegionUpdateXfrms(reg) == false) return null; //CALLBACK_MATRIX(®); /* Calculate the best fitting symbol size */ if (MatrixRegionFindSize(reg) == false) return null; /* Found a valid matrix region */ return new DmtxRegion(reg); }
internal bool Step(int travel, int outward) { int i; if (Math.Abs(travel) >= 2) { throw new ArgumentException("Invalid value for 'travel' in BaseLineStep!"); } /* Perform forward step */ if (travel > 0) { this._travel++; if (this._steep) { this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y + this._yStep }; this._error -= this._xDelta; if (this._error < 0) { this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xStep, Y = this._loc.Y }; this._error += this._yDelta; } } else { this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xStep, Y = this._loc.Y }; this._error -= this._yDelta; if (this._error < 0) { this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y + this._yStep }; this._error += this._xDelta; } } } else if (travel < 0) { this._travel--; if (this._steep) { this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y - this._yStep }; this._error += this._xDelta; if (this.Error >= this.YDelta) { this._loc = new DmtxPixelLoc() { X = this._loc.X - this._xStep, Y = this._loc.Y }; this._error -= this._yDelta; } } else { this._loc = new DmtxPixelLoc() { X = this._loc.X - this._xStep, Y = this._loc.Y }; this._error += this._yDelta; if (this._error >= this._xDelta) { this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y - this._yStep }; this._error -= this._xDelta; } } } for (i = 0; i < outward; i++) { /* Outward steps */ this._outward++; this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xOut, Y = this._loc.Y + this._yOut }; } return true; }
internal DmtxMessage MatrixRegion(DmtxRegion reg, int fix) { DmtxMessage result = new DmtxMessage(reg.SizeIdx, DmtxFormat.Matrix); DmtxVector2 topLeft = new DmtxVector2(); DmtxVector2 topRight = new DmtxVector2(); DmtxVector2 bottomLeft = new DmtxVector2(); DmtxVector2 bottomRight = new DmtxVector2(); DmtxPixelLoc pxTopLeft = new DmtxPixelLoc(); DmtxPixelLoc pxTopRight = new DmtxPixelLoc(); DmtxPixelLoc pxBottomLeft = new DmtxPixelLoc(); DmtxPixelLoc pxBottomRight = new DmtxPixelLoc(); if (!PopulateArrayFromMatrix(reg, result)) { throw new Exception("Populating Array from matrix failed!"); } /* maybe place remaining logic into new dmtxDecodePopulatedArray() function so other people can pass in their own arrays */ ModulePlacementEcc200(result.Array, result.Code, reg.SizeIdx, DmtxConstants.DmtxModuleOnRed | DmtxConstants.DmtxModuleOnGreen | DmtxConstants.DmtxModuleOnBlue); if (DmtxCommon.DecodeCheckErrors(result.Code, 0, reg.SizeIdx, fix) != true) { return null; } topLeft.X = bottomLeft.X = topLeft.Y = topRight.Y = -0.1; topRight.X = bottomRight.X = bottomLeft.Y = bottomRight.Y = 1.1; topLeft *= reg.Fit2raw; topRight *= reg.Fit2raw; bottomLeft *= reg.Fit2raw; bottomLeft *= reg.Fit2raw; pxTopLeft.X = (int)(0.5 + topLeft.X); pxTopLeft.Y = (int)(0.5 + topLeft.Y); pxBottomLeft.X = (int)(0.5 + bottomLeft.X); pxBottomLeft.Y = (int)(0.5 + bottomLeft.Y); pxTopRight.X = (int)(0.5 + topRight.X); pxTopRight.Y = (int)(0.5 + topRight.Y); pxBottomRight.X = (int)(0.5 + bottomRight.X); pxBottomRight.Y = (int)(0.5 + bottomRight.Y); CacheFillQuad(pxTopLeft, pxTopRight, pxBottomRight, pxBottomLeft); result.DecodeDataStream(reg.SizeIdx, null); return result; }
internal DmtxRegion RegionFindNext(TimeSpan timeout) { DmtxRange locStatus; DmtxPixelLoc loc = new DmtxPixelLoc(); DmtxRegion reg; DateTime startTime = DateTime.Now; /* Continue until we find a region or run out of chances */ for (; ; ) { locStatus = this._grid.PopGridLocation(ref loc); if (locStatus == DmtxRange.DmtxRangeEnd) break; /* Scan location for presence of valid barcode region */ reg = RegionScanPixel(loc.X, loc.Y); if (reg != null) return reg; /* Ran out of time? */ if (DateTime.Now - startTime > timeout) { break; } } return null; }
int DistanceSquared(DmtxPixelLoc a, DmtxPixelLoc b) { int xDelta, yDelta; xDelta = a.X - b.X; yDelta = a.Y - b.Y; return (xDelta * xDelta) + (yDelta * yDelta); }
internal bool Step(int travel, int outward) { int i; if (Math.Abs(travel) >= 2) { throw new ArgumentException("Invalid value for 'travel' in BaseLineStep!"); } /* Perform forward step */ if (travel > 0) { this._travel++; if (this._steep) { this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y + this._yStep }; this._error -= this._xDelta; if (this._error < 0) { this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xStep, Y = this._loc.Y }; this._error += this._yDelta; } } else { this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xStep, Y = this._loc.Y }; this._error -= this._yDelta; if (this._error < 0) { this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y + this._yStep }; this._error += this._xDelta; } } } else if (travel < 0) { this._travel--; if (this._steep) { this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y - this._yStep }; this._error += this._xDelta; if (this.Error >= this.YDelta) { this._loc = new DmtxPixelLoc() { X = this._loc.X - this._xStep, Y = this._loc.Y }; this._error -= this._yDelta; } } else { this._loc = new DmtxPixelLoc() { X = this._loc.X - this._xStep, Y = this._loc.Y }; this._error += this._yDelta; if (this._error >= this._xDelta) { this._loc = new DmtxPixelLoc() { X = this._loc.X, Y = this._loc.Y - this._yStep }; this._error -= this._xDelta; } } } for (i = 0; i < outward; i++) { /* Outward steps */ this._outward++; this._loc = new DmtxPixelLoc() { X = this._loc.X + this._xOut, Y = this._loc.Y + this._yOut }; } return(true); }
DmtxBestLine FindBestSolidLine2(DmtxPixelLoc loc0, int tripSteps, int sign, int houghAvoid) { int[,] hough = new int[3, DmtxConstants.DmtxHoughRes]; int houghMin, houghMax; char[] houghTest = new char[DmtxConstants.DmtxHoughRes]; int i; int step; int angleBest; int hOffset, hOffsetBest; int xDiff, yDiff; int dH; DmtxBestLine line = new DmtxBestLine(); DmtxPixelLoc rHp; DmtxFollow follow; angleBest = 0; hOffset = hOffsetBest = 0; follow = FollowSeekLoc(loc0); rHp = line.LocBeg = line.LocPos = line.LocNeg = follow.Loc; line.StepBeg = line.StepPos = line.StepNeg = 0; /* Predetermine which angles to test */ for (i = 0; i < DmtxConstants.DmtxHoughRes; i++) { if (houghAvoid == DmtxConstants.DmtxUndefined) { houghTest[i] = (char)1; } else { houghMin = (houghAvoid + DmtxConstants.DmtxHoughRes / 6) % DmtxConstants.DmtxHoughRes; houghMax = (houghAvoid - DmtxConstants.DmtxHoughRes / 6 + DmtxConstants.DmtxHoughRes) % DmtxConstants.DmtxHoughRes; if (houghMin > houghMax) houghTest[i] = (i > houghMin || i < houghMax) ? (char)1 : (char)0; else houghTest[i] = (i > houghMin && i < houghMax) ? (char)1 : (char)0; } } /* Test each angle for steps along path */ for (step = 0; step < tripSteps; step++) { xDiff = follow.Loc.X - rHp.X; yDiff = follow.Loc.Y - rHp.Y; /* Increment Hough accumulator */ for (i = 0; i < DmtxConstants.DmtxHoughRes; i++) { if ((int)houghTest[i] == 0) continue; dH = (DmtxConstants.rHvX[i] * yDiff) - (DmtxConstants.rHvY[i] * xDiff); if (dH >= -384 && dH <= 384) { if (dH > 128) hOffset = 2; else if (dH >= -128) hOffset = 1; else hOffset = 0; hough[hOffset, i]++; /* New angle takes over lead */ if (hough[hOffset, i] > hough[hOffsetBest, angleBest]) { angleBest = i; hOffsetBest = hOffset; } } } follow = FollowStep2(follow, sign); } line.Angle = angleBest; line.HOffset = hOffsetBest; line.Mag = hough[hOffsetBest, angleBest]; return line; }
internal DmtxRange PopGridLocation(ref DmtxPixelLoc loc) { DmtxRange locStatus; do { locStatus = GetGridCoordinates(ref loc); /* Always leave grid pointing at next available location */ this._pixelCount++; } while (locStatus == DmtxRange.DmtxRangeBad); return locStatus; }