⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmtxregion.c

📁 Linux系统下,二维码生成源代码.希望对大家有所帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
}/** * XXX * * @param * @return XXX */static intEdgeScanNextEdge(DmtxEdgeScan *edgeScan, DmtxDecode *decode, DmtxGradient *gradient){   int pxlOffset;   float lower, upper;   if(edgeScan->edge.offset == edgeScan->range.lastPos)      return DMTX_END_OF_RANGE;   while(edgeScan->edge.offset != edgeScan->range.lastPos) {      edgeScan->edge = edgeScan->edgeNext;      (edgeScan->edgeNext.offset)++;      // XXX pretty ugly test... should happen as part of structure with no test needed      if(edgeScan->edge.offset == edgeScan->range.firstPos) {         pxlOffset = dmtxImageGetOffset(&(decode->image), edgeScan->range.dir,               edgeScan->range.lineNbr, edgeScan->edge.offset);         dmtxColor3FromPixel(&(edgeScan->edge.color), &(decode->image.pxl[pxlOffset]));         edgeScan->edge.t = dmtxDistanceAlongRay3(&(gradient->ray), &(edgeScan->edge.color));      }      pxlOffset = dmtxImageGetOffset(&(decode->image), edgeScan->range.dir,            edgeScan->range.lineNbr, edgeScan->edgeNext.offset);      dmtxColor3FromPixel(&(edgeScan->edgeNext.color), &(decode->image.pxl[pxlOffset]));      edgeScan->edgeNext.t = dmtxDistanceAlongRay3(&(gradient->ray), &(edgeScan->edgeNext.color));      // XXX This test should not be necessary, but loop boundaries are currently sketchy      if(dmtxDistanceFromRay3(&(gradient->ray), &(edgeScan->edgeNext.color)) > 10.0)         return DMTX_END_OF_RANGE;      lower = gradient->tMid - edgeScan->edge.t;      upper = gradient->tMid - edgeScan->edgeNext.t;      // edge and edgeNext have the same color      if(fabs(lower - upper) < DMTX_ALMOST_ZERO) {         continue;      }      // Boundary color falls between edge and edgeNext      else if(lower * upper <= 0) {         edgeScan->subPixelOffset = lower / (lower - upper);         if(decode && decode->crossScanCallback)            (*(decode->crossScanCallback))(&(edgeScan->range), gradient, edgeScan);         return DMTX_SUCCESS;      }   }   if(decode && decode->crossScanCallback)      (*(decode->crossScanCallback))(&(edgeScan->range), gradient, edgeScan);   return DMTX_SUCCESS;}/** * XXX * * @param follow   XXX * @param edgeScan XXX * @param gradient XXX * @param dir      XXX * @return XXX */static voidEdgeFollowerInit(DmtxEdgeFollower *follow, DmtxEdgeScan *edgeScan, DmtxGradient *gradient, DmtxDirection dir){   memset(follow, 0x00, sizeof(DmtxEdgeFollower));   follow->slope = (edgeScan->edgeNext.t > edgeScan->edge.t) ? 1 : -1;   follow->paraOffset = edgeScan->range.lineNbr;   follow->perpOffset = edgeScan->edge.offset + edgeScan->subPixelOffset;   follow->tMin = gradient->tMin;   follow->tMid = gradient->tMid;   follow->tMax = gradient->tMax;   follow->ray = gradient->ray;   follow->dir = dir;}/** * XXX * * @param follow XXX * @return XXX */static DmtxVector2EdgeFollowerGetLoc(DmtxEdgeFollower *follow){   DmtxVector2 loc;   if(follow->dir & DmtxDirVertical) {      loc.X = follow->perpOffset;      loc.Y = follow->paraOffset;   }   else {      loc.X = follow->paraOffset;      loc.Y = follow->perpOffset;   }   return loc;}/** * XXX * * @param follow XXX * @param decode XXX * @return XXX */static intEdgeFollowerFollow(DmtxEdgeFollower *follow, DmtxDecode *decode){   // initialize line0 and line1 to "unset" and zero strength   int i;   int anchorStrength = 0;   float offPath, offAngle;   DmtxVector2 vTmp, anchorStep, fStep[DMTX_FOLLOW_STEPS];   DmtxRay2 rayAnchor, rayNext;   memset(&(follow->line0), 0x00, sizeof(DmtxRay2));   memset(&(follow->line1), 0x00, sizeof(DmtxRay2));   // Build first vector by incrementing 5 steps   anchorStep = fStep[0] = EdgeFollowerGetLoc(follow);   for(i = 1; i < DMTX_FOLLOW_STEPS; i++) {      if(EdgeFollowerIncrement(follow, decode) != DMTX_EDGE_FOUND) {         if(decode && decode->plotPointCallback)            (*(decode->plotPointCallback))(EdgeFollowerGetLoc(follow), 1, 2, DMTX_DISPLAY_SQUARE);         return 0; // Lost edge before completing first vector      }      fStep[i] = EdgeFollowerGetLoc(follow);   }   dmtxVector2Sub(&vTmp, &(fStep[DMTX_FOLLOW_STEPS-1]), &(fStep[0]));   dmtxVector2Norm(&vTmp); // XXX potential problem here if follower ends up in starting point (div/0)   rayAnchor.p = fStep[0];   rayAnchor.v = vTmp;   // Continue while we can still find an edge   while(EdgeFollowerIncrement(follow, decode) == DMTX_EDGE_FOUND) {      if(follow->turnCount > 2) { // Reached maximum number of turns         if(decode && decode->plotPointCallback) // Plot a red X where edge was lost            (*(decode->plotPointCallback))(fStep[0], 1, 2, DMTX_DISPLAY_SQUARE);          return 0; // XXX this should probably reflect the edge status (e.g. lost, max_turns, etc...)      }      // incrementProgress(follow, anchorVector); (using current followVector)      for(i = 0; i < DMTX_FOLLOW_STEPS - 1; i++) {         fStep[i] = fStep[i+1]; // XXX innefficient, but simple      }      fStep[i] = EdgeFollowerGetLoc(follow);      dmtxVector2Sub(&vTmp, &(fStep[DMTX_FOLLOW_STEPS-1]), &(fStep[0]));      dmtxVector2Norm(&vTmp);      rayNext.p = fStep[0];      rayNext.v = vTmp;      offPath = fabs(dmtxDistanceFromRay2(&rayAnchor, &(fStep[0])));      offAngle = fabs(dmtxVector2Dot(&(rayAnchor.v), &(rayNext.v)));      // Step is in direction of predicted path      if(offAngle > 0.984) {         anchorStrength++;      }      else { // Step is in wrong direction         // Current line is done -- fixate         if(anchorStrength > 10) { // if line reached strength threshhold, but is now turning a corner            // line0 gets set first            if(follow->line0.isDefined == 0) {               if(decode && decode->plotPointCallback)                  (*(decode->plotPointCallback))(fStep[0], 2, 2, DMTX_DISPLAY_SQUARE);               // Update should build ray based on min/max points on the edge, NOT anchorVector               // XXXXXXXXX IMPORTANT: Revisit this... results should be adequate using anchorVector here               follow->line0.isDefined = 1;               dmtxVector2Sub(&vTmp, &(fStep[0]), &anchorStep);               dmtxVector2Norm(&vTmp);               follow->line0.v = vTmp;               follow->line0.p = anchorStep;               follow->line0.tMin = 0;               follow->line0.tMax = dmtxDistanceAlongRay2(&(follow->line0), &(fStep[0]));            }            // line1 gets set if line0 is already set            else {               if(decode && decode->plotPointCallback)                  (*(decode->plotPointCallback))(fStep[0], 3, 2, DMTX_DISPLAY_SQUARE);               // Update should build ray based on min/max points on the edge, NOT anchorVector               // XXXXXXXXX IMPORTANT: Revisit this... results should be adequate using anchorVector here               follow->line1.isDefined = 1;               dmtxVector2Sub(&vTmp, &(fStep[0]), &anchorStep);               dmtxVector2Norm(&vTmp);               follow->line1.v = vTmp;               follow->line1.p = anchorStep;               follow->line1.tMin = 0;               follow->line1.tMax = dmtxDistanceAlongRay2(&(follow->line1), &(fStep[0]));               return 0; // return "full"            }         }         else {            // line never reached strength threshhold            if(decode && decode->plotPointCallback)               (*(decode->plotPointCallback))(fStep[0], 4, 2, DMTX_DISPLAY_SQUARE);         }         rayAnchor = rayNext;         anchorStep = fStep[0];         anchorStrength = 0;      }   }   // return edge_lost condition (range/right/left)   if(decode && decode->plotPointCallback)      (*(decode->plotPointCallback))(EdgeFollowerGetLoc(follow), 5, 2, DMTX_DISPLAY_SQUARE);   return 0;}/** * XXX * * @param * @return XXX */static intEdgeFollowerIncrement(DmtxEdgeFollower *follow, DmtxDecode *decode){   int turnDir;   int increment;   int offset0, offset1, endOffset;   int dir;   float t0, t1;   float tmpOffset;   DmtxColor3 color0, color1;   // XXX this first calc of offset0 might be done smarter by extrapolating current "line"   offset0 = (int)(follow->perpOffset + 0.5);   if(((follow->dir & DmtxDirHorizontal) && (offset0 + 1 >= decode->image.height - 1)) ||         ((follow->dir & DmtxDirVertical) && (offset0 + 1 >= decode->image.width - 1)) ||         offset0 - 1 <= 0)      return DMTX_END_OF_RANGE;   increment = (follow->dir & DmtxDirRightUp) ? 1 : -1;   follow->paraOffset += increment;   if(((follow->dir & DmtxDirHorizontal) && (follow->paraOffset >= decode->image.width)) ||         ((follow->dir & DmtxDirVertical) && (follow->paraOffset >= decode->image.height)) ||         follow->paraOffset <= 0)      return DMTX_END_OF_RANGE;   if(follow->dir & DmtxDirVertical)      dmtxColor3FromPixel(&color0, &(decode->image.pxl[decode->image.width * follow->paraOffset + offset0]));   else      dmtxColor3FromPixel(&color0, &(decode->image.pxl[decode->image.width * offset0 + follow->paraOffset]));   t0 = dmtxDistanceAlongRay3(&(follow->ray), &color0);   dir = (follow->slope * (follow->tMid - t0) >= 0) ? 1 : -1;   // Find adjacent pixels whose values "surround" tMid   endOffset = offset0 + 3*dir;   for(offset1 = offset0; offset1 != endOffset; offset1 += dir) {      if(((follow->dir & DmtxDirHorizontal) && (offset1 + 1 >= decode->image.height - 1)) ||            ((follow->dir & DmtxDirVertical) && (offset1 + 1 >= decode->image.width - 1)) ||            offset1 - 1 <= 0)         return DMTX_END_OF_RANGE;      if(follow->dir & DmtxDirVertical)         dmtxColor3FromPixel(&color1, &(decode->image.pxl[decode->image.width * follow->paraOffset + offset1]));      else         dmtxColor3FromPixel(&color1, &(decode->image.pxl[decode->image.width * offset1 + follow->paraOffset]));      t1 = dmtxDistanceAlongRay3(&(follow->ray), &color1);      // Check that follower hasn't wandered off of edge following unlike colors      if(dmtxDistanceFromRay3(&(follow->ray), &color1) > DMTX_MAX_COLOR_DEVN) {         return DMTX_END_OF_RANGE; // XXX not really DMTX_END_OF_RANGE, but works for now      }      if(fabs(t1 - follow->tMid) < DMTX_ALMOST_ZERO ||            ((follow->tMid - t0) * (follow->tMid - t1) < 0)) {         if(fabs(t1 - follow->tMid) < DMTX_ALMOST_ZERO) {            follow->perpOffset = offset1;         }         else if(fabs(follow->tMid - t0) < fabs(follow->tMid - t1)) {            follow->perpOffset = offset0 + follow->slope * ((follow->tMid - t0)/fabs(t0 - t1));         }         else {            follow->perpOffset = offset1 + follow->slope * ((follow->tMid - t1)/fabs(t0 - t1));         }         if(decode && decode->followScanCallback)            (*(decode->followScanCallback))(follow);         return DMTX_EDGE_FOUND;      }      else {         offset0 = offset1;         t0 = t1;      }   }   tmpOffset = follow->paraOffset;   follow->paraOffset = follow->perpOffset;   follow->perpOffset = tmpOffset;   if(follow->dir & (DmtxDirUp | DmtxDirLeft))      turnDir = (dir > 0) ? DMTX_TURN_CW : DMTX_TURN_CCW;   else      turnDir = (dir > 0) ? DMTX_TURN_CCW : DMTX_TURN_CW;   // XXX Whoa, this one was hard to figure out   if(follow->dir & DmtxDirVertical && turnDir == DMTX_TURN_CW)      follow->slope *= -1;   else if(follow->dir & DmtxDirHorizontal && turnDir == DMTX_TURN_CCW)      follow->slope *= -1;   follow->turnCount++;   follow->dir = TurnCorner(follow->dir, turnDir);   return DMTX_EDGE_FOUND;}/** * XXX * * @param * @return XXX */static voidMatrixRegionInit(DmtxMatrixRegion *matrixRegion, DmtxGradient *gradient){   memset(matrixRegion, 0x00, sizeof(DmtxMatrixRegion));   matrixRegion->gradient = *gradient;   // XXX this stuff just became a lot less important since I'm initializing it locally in "chain" and then copying   matrixRegion->chain.tx = 0.0;   matrixRegion->chain.ty = 0.0;   matrixRegion->chain.phi = 0.0;   matrixRegion->chain.shx = 0.0;   matrixRegion->chain.scx = 1.0;   matrixRegion->chain.scy = 1.0;   matrixRegion->chain.bx0 = 100.0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -