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

📄 dmtxregion.c

📁 Datamatrix二维码库和测试程序,运行于linux,仔细研究可以很容易转化成VC程序,有这就没必要化钱买个控件了,本人libdmtx-0.3版本转化过,的确可行,现在把找到该版本的libdmtx
💻 C
📖 第 1 页 / 共 4 页
字号:
   dmtxMatrix3MultiplyBy(m, mshx);   dmtxMatrix3Rotate(mphi, -phi);   dmtxMatrix3MultiplyBy(m, mphi);   dmtxMatrix3Translate(mtxy, -tx, -ty);   dmtxMatrix3Multiply(reg->fit2raw, m, mtxy);   return DMTX_SUCCESS;}/** * * */extern intdmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg){   double radians;   DmtxRay2 rLeft, rBottom, rTop, rRight;   DmtxVector2 p00, p10, p11, p01;   assert(reg->leftKnown != 0 && reg->bottomKnown != 0);   /* Build ray representing left edge */   rLeft.p.X = (double)reg->leftLoc.X;   rLeft.p.Y = (double)reg->leftLoc.Y;   radians = reg->leftAngle * (M_PI/DMTX_HOUGH_RES);   rLeft.v.X = cos(radians);   rLeft.v.Y = sin(radians);   rLeft.tMin = 0.0;   rLeft.tMax = dmtxVector2Norm(&rLeft.v);   /* Build ray representing bottom edge */   rBottom.p.X = (double)reg->bottomLoc.X;   rBottom.p.Y = (double)reg->bottomLoc.Y;   radians = reg->bottomAngle * (M_PI/DMTX_HOUGH_RES);   rBottom.v.X = cos(radians);   rBottom.v.Y = sin(radians);   rBottom.tMin = 0.0;   rBottom.tMax = dmtxVector2Norm(&rBottom.v);   /* Build ray representing top edge */   if(reg->topKnown != 0) {      rTop.p.X = (double)reg->topLoc.X;      rTop.p.Y = (double)reg->topLoc.Y;      radians = reg->topAngle * (M_PI/DMTX_HOUGH_RES);      rTop.v.X = cos(radians);      rTop.v.Y = sin(radians);      rTop.tMin = 0.0;      rTop.tMax = dmtxVector2Norm(&rTop.v);   }   else {      rTop.p.X = (double)reg->locT.X;      rTop.p.Y = (double)reg->locT.Y;      radians = reg->bottomAngle * (M_PI/DMTX_HOUGH_RES);      rTop.v.X = cos(radians);      rTop.v.Y = sin(radians);      rTop.tMin = 0.0;      rTop.tMax = rBottom.tMax;   }   /* Build ray representing right edge */   if(reg->rightKnown != 0) {      rRight.p.X = (double)reg->rightLoc.X;      rRight.p.Y = (double)reg->rightLoc.Y;      radians = reg->rightAngle * (M_PI/DMTX_HOUGH_RES);      rRight.v.X = cos(radians);      rRight.v.Y = sin(radians);      rRight.tMin = 0.0;      rRight.tMax = dmtxVector2Norm(&rRight.v);   }   else {      rRight.p.X = (double)reg->locR.X;      rRight.p.Y = (double)reg->locR.Y;      radians = reg->leftAngle * (M_PI/DMTX_HOUGH_RES);      rRight.v.X = cos(radians);      rRight.v.Y = sin(radians);      rRight.tMin = 0.0;      rRight.tMax = rLeft.tMax;   }   /* Calculate 4 corners, real or imagined */   if(dmtxRay2Intersect(&p00, &rLeft, &rBottom) == DMTX_FAILURE)      return DMTX_FAILURE;   if(dmtxRay2Intersect(&p10, &rBottom, &rRight) == DMTX_FAILURE)      return DMTX_FAILURE;   if(dmtxRay2Intersect(&p11, &rRight, &rTop) == DMTX_FAILURE)      return DMTX_FAILURE;   if(dmtxRay2Intersect(&p01, &rTop, &rLeft) == DMTX_FAILURE)      return DMTX_FAILURE;   if(dmtxRegionUpdateCorners(dec, reg, p00, p10, p11, p01) != DMTX_SUCCESS)      return DMTX_FAILURE;   return DMTX_SUCCESS;}/** * * */static doubleRightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle){   DmtxVector2 vA, vB;   DmtxMatrix3 m;   dmtxVector2Norm(dmtxVector2Sub(&vA, &c0, &c1));   dmtxVector2Norm(dmtxVector2Sub(&vB, &c2, &c1));   dmtxMatrix3Rotate(m, angle);   dmtxMatrix3VMultiplyBy(&vB, m);   return dmtxVector2Dot(&vA, &vB);}/** * @brief  Read color of Data Matrix module location * @param  image * @param  reg * @param  symbolRow * @param  symbolCol * @param  sizeIdx * @return Averaged module color */static intReadModuleColor(DmtxImage *img, DmtxRegion *reg, int symbolRow, int symbolCol, int sizeIdx){   int i;   int symbolRows, symbolCols;   int color;   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;   symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, sizeIdx);   symbolCols = dmtxGetSymbolAttribute(DmtxSymAttribSymbolCols, sizeIdx);   color = 0;   for(i = 0; i < 5; i++) {      p.X = (1.0/symbolCols) * (symbolCol + sampleX[i]);      p.Y = (1.0/symbolRows) * (symbolRow + sampleY[i]);      dmtxMatrix3VMultiplyBy(&p, reg->fit2raw);      color += dmtxImageGetColor(img, (int)(p.X + 0.5), (int)(p.Y + 0.5), reg->flowBegin.plane);   }   return color/5;}/** * @brief  Determine barcode size, expressed in modules * @param  image * @param  reg * @return DMTX_SUCCESS | DMTX_FAILURE */static intMatrixRegionFindSize(DmtxDecode *dec, DmtxRegion *reg){   int row, col;   int sizeIdxBeg, sizeIdxEnd;   int sizeIdx, bestSizeIdx;   int symbolRows, symbolCols;   int jumpCount, errors;   int color;   int colorOnAvg, bestColorOnAvg;   int colorOffAvg, bestColorOffAvg;   int contrast, bestContrast;   DmtxImage *img;   img = dec->image;   bestSizeIdx = -1;   bestContrast = 0;   bestColorOnAvg = bestColorOffAvg = 0;   if(dec->sizeIdxExpected == DmtxSymbolShapeAuto) {      sizeIdxBeg = 0;      sizeIdxEnd = DMTX_SYMBOL_SQUARE_COUNT + DMTX_SYMBOL_RECT_COUNT;   }   else if(dec->sizeIdxExpected == DmtxSymbolSquareAuto) {      sizeIdxBeg = 0;      sizeIdxEnd = DMTX_SYMBOL_SQUARE_COUNT;   }   else if(dec->sizeIdxExpected == DmtxSymbolRectAuto) {      sizeIdxBeg = DMTX_SYMBOL_SQUARE_COUNT;      sizeIdxEnd = DMTX_SYMBOL_SQUARE_COUNT + DMTX_SYMBOL_RECT_COUNT;   }   else {      sizeIdxBeg = dec->sizeIdxExpected;      sizeIdxEnd = dec->sizeIdxExpected + 1;   }   /* Test each barcode size to find best contrast in calibration modules */   for(sizeIdx = sizeIdxBeg; sizeIdx < sizeIdxEnd; sizeIdx++) {      symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, sizeIdx);      symbolCols = dmtxGetSymbolAttribute(DmtxSymAttribSymbolCols, sizeIdx);      colorOnAvg = colorOffAvg = 0;      /* Sum module colors along horizontal calibration bar */      row = symbolRows - 1;      for(col = 0; col < symbolCols; col++) {         color = ReadModuleColor(img, reg, row, col, sizeIdx);         if((col & 0x01) != 0x00)            colorOffAvg += color;         else            colorOnAvg += color;      }      /* Sum module colors along vertical calibration bar */      col = symbolCols - 1;      for(row = 0; row < symbolRows; row++) {         color = ReadModuleColor(img, reg, row, col, sizeIdx);         if((row & 0x01) != 0x00)            colorOffAvg += color;         else            colorOnAvg += color;      }      colorOnAvg = (colorOnAvg * 2)/(symbolRows + symbolCols);      colorOffAvg = (colorOffAvg * 2)/(symbolRows + symbolCols);      contrast = abs(colorOnAvg - colorOffAvg);      if(contrast < 20)         continue;      if(contrast > bestContrast) {         bestContrast = contrast;         bestSizeIdx = sizeIdx;         bestColorOnAvg = colorOnAvg;         bestColorOffAvg = colorOffAvg;      }   }   /* If no sizes produced acceptable contrast then call it quits */   if(bestSizeIdx == -1 || bestContrast < 20)      return DMTX_FAILURE;   reg->sizeIdx = bestSizeIdx;   reg->onColor = bestColorOnAvg;   reg->offColor = bestColorOffAvg;   reg->symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, reg->sizeIdx);   reg->symbolCols = dmtxGetSymbolAttribute(DmtxSymAttribSymbolCols, reg->sizeIdx);   reg->mappingRows = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixRows, reg->sizeIdx);   reg->mappingCols = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixCols, reg->sizeIdx);   /* Tally jumps on horizontal calibration bar to verify sizeIdx */   jumpCount = CountJumpTally(img, reg, 0, reg->symbolRows - 1, DmtxDirRight);   errors = abs(1 + jumpCount - reg->symbolCols);   if(jumpCount < 0 || errors > 2)      return DMTX_FAILURE;   /* Tally jumps on vertical calibration bar to verify sizeIdx */   jumpCount = CountJumpTally(img, reg, reg->symbolCols - 1, 0, DmtxDirUp);   errors = abs(1 + jumpCount - reg->symbolRows);   if(jumpCount < 0 || errors > 2)      return DMTX_FAILURE;   /* Tally jumps on horizontal finder bar to verify sizeIdx */   errors = CountJumpTally(img, reg, 0, 0, DmtxDirRight);   if(jumpCount < 0 || errors > 2)      return DMTX_FAILURE;   /* Tally jumps on vertical finder bar to verify sizeIdx */   errors = CountJumpTally(img, reg, 0, 0, DmtxDirUp);   if(errors < 0 || errors > 2)      return DMTX_FAILURE;   /* Tally jumps on surrounding whitespace, else fail */   errors = CountJumpTally(img, reg, 0, -1, DmtxDirRight);   if(errors < 0 || errors > 2)      return DMTX_FAILURE;   errors = CountJumpTally(img, reg, -1, 0, DmtxDirUp);   if(errors < 0 || errors > 2)      return DMTX_FAILURE;   errors = CountJumpTally(img, reg, 0, reg->symbolRows, DmtxDirRight);   if(errors < 0 || errors > 2)      return DMTX_FAILURE;   errors = CountJumpTally(img, reg, reg->symbolCols, 0, DmtxDirUp);   if(errors < 0 || errors > 2)      return DMTX_FAILURE;   return DMTX_SUCCESS;}/** * @brief  Count the number of number of transitions between light and dark * @param  img * @param  reg * @param  xStart * @param  yStart * @param  dir * @return Jump count */static intCountJumpTally(DmtxImage *img, DmtxRegion *reg, int xStart, int yStart, DmtxDirection dir){   int x, xInc = 0;   int y, yInc = 0;   int state = DMTX_MODULE_ON;   int jumpCount = 0;   int jumpThreshold;   int tModule, tPrev;   int darkOnLight;   int color;   assert(xStart == 0 || yStart == 0);   assert(dir == DmtxDirRight || dir == DmtxDirUp);   if(dir == DmtxDirRight)      xInc = 1;   else      yInc = 1;   if(xStart == -1 || xStart == reg->symbolCols ||         yStart == -1 || yStart == reg->symbolRows)      state = DMTX_MODULE_OFF;   darkOnLight = (int)(reg->offColor > reg->onColor);   jumpThreshold = abs((int)(0.4 * (reg->onColor - reg->offColor) + 0.5));   color = ReadModuleColor(img, reg, yStart, xStart, reg->sizeIdx);   tModule = (darkOnLight) ? reg->offColor - color : color - reg->offColor;   for(x = xStart + xInc, y = yStart + yInc;         (dir == DmtxDirRight && x < reg->symbolCols) ||         (dir == DmtxDirUp && y < reg->symbolRows);         x += xInc, y += yInc) {      tPrev = tModule;      color = ReadModuleColor(img, reg, y, x, reg->sizeIdx);      tModule = (darkOnLight) ? reg->offColor - color : color - reg->offColor;      if(state == DMTX_MODULE_OFF) {         if(tModule > tPrev + jumpThreshold) {            jumpCount++;            state = DMTX_MODULE_ON;         }      }      else {         if(tModule < tPrev - jumpThreshold) {            jumpCount++;            state = DMTX_MODULE_OFF;         }      }   }   return jumpCount;}/** * * */static DmtxPointFlowGetPointFlow(DmtxDecode *dec, int colorPlane, DmtxPixelLoc loc, int arrive){   static const int coefficient[] = {  0,  1,  2,  1,  0, -1, -2, -1 };   int patternIdx, coefficientIdx;   int compass, compassMax;   int mag[4] = { 0 };   int xAdjust, yAdjust;   int color, colorPattern[8];   DmtxPointFlow flow;   for(patternIdx = 0; patternIdx < 8; patternIdx++) {      xAdjust = loc.X + dmtxPatternX[patternIdx];      yAdjust = loc.Y + dmtxPatternY[patternIdx];      colorPattern[patternIdx] = dmtxImageGetColor(dec->image, xAdjust, yAdjust, colorPlane);      if(colorPattern[patternIdx] == -1)         return 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] += color;               /* Fall through */            case 1:               mag[compass] += color;               break;            case -2:               mag[compass] -= color;               /* Fall through */            case -1:               mag[compass] -= color;               break;         }      }      /* Identify strongest compass flow */      if(compass != 0 && abs(mag[compass]) > 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 = abs(mag[compassMax]);   flow.loc = loc;   return flow;}/** * * */static DmtxPointFlowFindStrongestNeighbor(DmtxDecode *dec, DmtxPointFlow center, int sign){   int i;   int offset;   int strongIdx;   int attempt, attemptDiff;   int occupied;   unsigned char *cache;   DmtxPixelLoc loc;   DmtxPointFlow flow[8];   attempt = (sign < 0) ? center.depart : (center.depart+4)%8;   occupied = 0;   strongIdx = -1;   for(i = 0; i < 8; i++) {      loc.X = center.loc.X + dmtxPatternX[i];      loc.Y = center.loc.Y + dmtxPatternY[i];      offset = dmtxImageGetOffset(dec->image, loc.X, loc.Y);      if(offset == DMTX_BAD_OFFSET) {         loc.status = DMTX_RANGE_BAD;         continue;      }      else {         loc.status = DMTX_RANGE_GOOD;      }      cache = &(dec->image->cache[offset]);      if((int)(*cache & 0x80) != 0x00) {         if(++occupied > 2)            return dmtxBlankEdge;         else            continue;      }      attemptDiff = abs(attempt - i);      if(attemptDiff > 4)         attemptDiff = 8 - attemptDiff;      if(attemptDiff > 1)         continue;      flow[i] = GetPointFlow(dec, center.plane, loc, i);      if(strongIdx == -1 || flow[i].mag > flow[strongIdx].mag ||            (flow[i].mag == flow[strongIdx].mag && ((i & 0x01) != 0))) {         strongIdx = i;      }   }   return (strongIdx == -1) ? dmtxBlankEdge : flow[strongIdx];}/** * * */static DmtxFollowFollowSeek(DmtxDecode *dec, DmtxRegion *reg, int seek)

⌨️ 快捷键说明

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