50 dec->squareDevn = cos(50 * (
M_PI / 180));
55 dec->xMax = width - 1;
57 dec->yMax = height - 1;
60 dec->cache = (
unsigned char *)calloc((
size_t)width * height,
sizeof(
unsigned char));
61 if (dec->cache == NULL) {
79 if (dec == NULL || *dec == NULL) {
83 if ((*dec)->cache != NULL) {
105 dec->edgeMin = value;
108 dec->edgeMax = value;
111 dec->scanGap = value;
117 dec->squareDevn = cos(value * (
M_PI / 180.0));
120 dec->sizeIdxExpected = value;
123 dec->edgeThresh = value;
127 dec->xMin = value / dec->scale;
130 dec->xMax = value / dec->scale;
133 dec->yMin = value / dec->scale;
136 dec->yMax = value / dec->scale;
142 if (dec->squareDevn <= 0.0 || dec->squareDevn >= 1.0) {
146 if (dec->scanGap < 1) {
150 if (dec->edgeThresh < 1 || dec->edgeThresh > 100) {
178 return (
int)(acos(dec->squareDevn) * 180.0 /
M_PI);
180 return dec->sizeIdxExpected;
182 return dec->edgeThresh;
223 if (x < 0 || x >= width || y < 0 || y >= height) {
227 return &(dec->cache[y * width + x]);
235 int xUnscaled, yUnscaled;
238 xUnscaled = x * dec->scale;
239 yUnscaled = y * dec->scale;
276 unsigned char *cache;
277 int *scanlineMin, *scanlineMax;
278 int minY, maxY, sizeY, posY, posX;
289 minY =
min(minY, p0.
y);
290 maxY =
max(maxY, p0.
y);
291 minY =
min(minY, p1.
y);
292 maxY =
max(maxY, p1.
y);
293 minY =
min(minY, p2.
y);
294 maxY =
max(maxY, p2.
y);
295 minY =
min(minY, p3.
y);
296 maxY =
max(maxY, p3.
y);
298 sizeY = maxY - minY + 1;
300 scanlineMin = (
int *)malloc(sizeY *
sizeof(
int));
301 scanlineMax = (
int *)calloc(sizeY,
sizeof(
int));
306 for (i = 0; i < sizeY; i++) {
307 scanlineMin[i] = dec->xMax;
310 for (i = 0; i < 4; i++) {
311 while (lines[i].loc.x != lines[i].loc1.x || lines[i].loc.y != lines[i].loc1.y) {
312 idx = lines[i].loc.y - minY;
313 scanlineMin[idx] =
min(scanlineMin[idx], lines[i].loc.x);
314 scanlineMax[idx] =
max(scanlineMax[idx], lines[i].loc.x);
319 for (posY = minY; posY < maxY && posY < dec->yMax; posY++) {
321 for (posX = scanlineMin[idx]; posX < scanlineMax[idx] && posX < dec->xMax; posX++) {
351 msg->
fnc1 = dec->fnc1;
354 DmtxVector2 topLeft, topRight, bottomLeft, bottomRight;
355 DmtxPixelLoc pxTopLeft, pxTopRight, pxBottomLeft, pxBottomRight;
357 topLeft.
x = bottomLeft.
x = topLeft.
y = topRight.
y = -0.1;
358 topRight.
x = bottomRight.
x = bottomLeft.
y = bottomRight.
y = 1.1;
365 pxTopLeft.
x = (int)(0.5 + topLeft.
x);
366 pxTopLeft.
y = (int)(0.5 + topLeft.
y);
367 pxBottomLeft.
x = (int)(0.5 + bottomLeft.
x);
368 pxBottomLeft.
y = (int)(0.5 + bottomLeft.
y);
369 pxTopRight.
x = (int)(0.5 + topRight.
x);
370 pxTopRight.
y = (int)(0.5 + topRight.
y);
371 pxBottomRight.
x = (int)(0.5 + bottomRight.
x);
372 pxBottomRight.
y = (int)(0.5 + bottomRight.
y);
374 cacheFillQuad(dec, pxTopLeft, pxTopRight, pxBottomRight, pxBottomLeft);
470 if (oMsg == NULL || rMsg == NULL || gMsg == NULL || bMsg == NULL) {
503 int widthDigits, heightDigits;
504 int count, channelCount;
507 unsigned char *pnm, *output, *cache;
516 for (widthDigits = 0, i = width; i > 0; i /= 10) {
521 for (heightDigits = 0, i = height; i > 0; i /= 10) {
525 *headerBytes = widthDigits + heightDigits + 9;
526 *totalBytes = *headerBytes + width * height * 3;
528 pnm = (
unsigned char *)malloc(*totalBytes);
533#if defined(_MSC_VER) && (_MSC_VER < 1700)
534 count = sprintf_s((
char *)pnm, *headerBytes + 1,
"P6\n%d %d\n255\n", width, height);
536 count = snprintf((
char *)pnm, *headerBytes + 1,
"P6\n%d %d\n255\n", width, height);
539 if (count != *headerBytes) {
544 output = pnm + (*headerBytes);
545 for (row = height - 1; row >= 0; row--) {
546 for (col = 0; col < width; col++) {
552 }
else if (*cache & 0x40) {
557 shade = (*cache & 0x80) ? 0.0 : 0.7;
558 for (i = 0; i < 3; i++) {
559 if (i < channelCount) {
565 rgb[i] += (int)(shade * (
double)(255 - rgb[i]) + 0.5);
571 *(output++) = (
unsigned char)rgb[0];
572 *(output++) = (
unsigned char)rgb[1];
573 *(output++) = (
unsigned char)rgb[2];
601 int symbolRow, symbolCol;
603 int lineStart, lineStop;
604 int travelStart, travelStop;
609 int statusPrev, statusModule;
623 lineStop = yOrigin + mapHeight;
624 travelStart = (travelStep == 1) ? xOrigin - 1 : xOrigin + mapWidth;
625 travelStop = (travelStep == 1) ? xOrigin + mapWidth : xOrigin - 1;
632 lineStop = xOrigin + mapWidth;
633 travelStart = (travelStep == 1) ? yOrigin - 1 : yOrigin + mapHeight;
634 travelStop = (travelStep == 1) ? yOrigin + mapHeight : yOrigin - 1;
638 jumpThreshold = abs((
int)(0.4 * (reg->
offColor - reg->
onColor) + 0.5));
642 for (*line = lineStart; *line < lineStop; (*line)++) {
646 *travel = travelStart;
654 while ((*travel += travelStep) != travelStop) {
656 statusPrev = statusModule;
666 if (tModule < tPrev - jumpThreshold) {
672 if (tModule > tPrev + jumpThreshold) {
679 mapRow = symbolRow - yOrigin;
680 mapCol = symbolCol - xOrigin;
684 tally[mapRow][mapCol] += (2 * weight);
709 int mapWidth, mapHeight;
710 int xRegionTotal, yRegionTotal;
711 int xRegionCount, yRegionCount;
712 int xOrigin, yOrigin;
714 int colTmp, rowTmp, idx;
727 weightFactor = 2 * (mapHeight + mapWidth + 2);
751 for (yRegionCount = 0; yRegionCount < yRegionTotal; yRegionCount++) {
753 yOrigin = yRegionCount * (mapHeight + 2) + 1;
755 for (xRegionCount = 0; xRegionCount < xRegionTotal; xRegionCount++) {
757 xOrigin = xRegionCount * (mapWidth + 2) + 1;
780 memset(tally, 0x00,
sizeof(
int) * 24 * 24);
787 for (mapRow = 0; mapRow < mapHeight; mapRow++) {
789 for (mapCol = 0; mapCol < mapWidth; mapCol++) {
790 rowTmp = (yRegionCount * mapHeight) + mapRow;
791 rowTmp = yRegionTotal * mapHeight - rowTmp - 1;
792 colTmp = (xRegionCount * mapWidth) + mapCol;
793 idx = (rowTmp * xRegionTotal * mapWidth) + colTmp;
796 if (tally[mapRow][mapCol] / (
double)weightFactor >= 0.5) {
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
@ DmtxPropXmax
ROI X坐标最大值(如果未设置则为图像宽度-1)
@ DmtxPropXmin
ROI X坐标最小值(如果未设置则为0)
@ DmtxPropYmin
ROI Y坐标最小值(如果未设置则为0)
@ DmtxPropChannelCount
图像通道数
@ DmtxPropYmax
ROI Y坐标最大值(如果未设置则为图像高度-1)
int dmtxGetSymbolAttribute(int attribute, int sizeIdx)
根据规格索引返回二维码规格各个参数
#define DmtxModuleAssigned
已分配
enum DmtxDirection_enum DmtxDirection
DmtxPassFail dmtxMessageDestroy(DmtxMessage **msg)
Free memory previously allocated for message.
@ DmtxSymAttribHorizDataRegions
水平方向区块个数
@ DmtxSymAttribVertDataRegions
垂直方向区块个数
@ DmtxSymAttribDataRegionCols
单区块二维码数据区码元列数(不包括L形框和点线)
@ DmtxSymAttribDataRegionRows
单区块二维码数据区码元行数(不包括L形框和点线)
#define DmtxModuleOnBlue
蓝
#define DmtxModuleOnRGB
OnRed | OnGreen | OnBlue.
DmtxPassFail dmtxMatrix3VMultiplyBy(INOUT DmtxVector2 *v, DmtxMatrix3 m)
将向量与矩阵相乘
DmtxMessage * dmtxMessageCreate(int sizeIdx, int symbolFormat)
Allocate memory for message.
int dmtxImageGetProp(DmtxImage *img, int prop)
获取图像属性
DmtxPassFail dmtxImageGetPixelValue(DmtxImage *img, int x, int y, int channel, OUT int *value)
#define DmtxModuleOnGreen
绿
#define DmtxModuleOff
bit0
unsigned char * dmtxDecodeCreateDiagnostic(DmtxDecode *dec, int *totalBytes, int *headerBytes, int style)
static void tallyModuleJumps(DmtxDecode *dec, DmtxRegion *reg, INOUT int tally[][24], int xOrigin, int yOrigin, int mapWidth, int mapHeight, DmtxDirection dir)
通过指定方向对判断bit为1的码元位置记录对应的值
unsigned char * dmtxDecodeGetCache(DmtxDecode *dec, int x, int y)
Returns xxx.
DmtxDecode * dmtxDecodeCreate(DmtxImage *img, int scale)
Initialize decode struct with default values.
static DmtxPassFail populateArrayFromMatrix(DmtxDecode *dec, DmtxRegion *reg, OUT DmtxMessage *msg)
根据模块颜色填充数组以确定码字值。
DmtxMessage * dmtxDecodeMosaicRegion(DmtxDecode *dec, DmtxRegion *reg, int fix)
Convert fitted Data Mosaic region into a decoded message.
DmtxPassFail dmtxDecodeGetPixelValue(DmtxDecode *dec, int x, int y, int channel, OUT int *value)
获取图像像素
DmtxPassFail dmtxDecodeDestroy(DmtxDecode **dec)
Deinitialize decode struct.
DmtxMessage * dmtxDecodePopulatedArray(int sizeIdx, INOUT DmtxMessage *msg, int fix)
从DataMatrix数据区二进制矩阵解码,并将结果写入msg->output
DmtxPassFail dmtxDecodeSetProp(DmtxDecode *dec, int prop, int value)
Set decoding behavior property.
static void cacheFillQuad(DmtxDecode *dec, DmtxPixelLoc p0, DmtxPixelLoc p1, DmtxPixelLoc p2, DmtxPixelLoc p3)
Fill the region covered by the quadrilateral given by (p0,p1,p2,p3) in the cache.
int dmtxDecodeGetProp(DmtxDecode *dec, int prop)
Get decoding behavior property.
DmtxMessage * dmtxDecodeMatrixRegion(DmtxDecode *dec, DmtxRegion *reg, int fix)
解码拟合的二维码区域
DmtxPassFail decodeDataStream(DmtxMessage *msg, int sizeIdx, unsigned char *outputStart)
Translate encoded data stream into final output.
static int modulePlacementEcc200(INOUT unsigned char *modules, OUT unsigned char *codewords, int sizeIdx, int moduleOnColor)
通过DataMatrix数据区的二进制矩阵,根据DataMatrix的排列规则,得到码字(codewords)
static DmtxPassFail rsDecode(unsigned char *code, int sizeIdx, int fix)
Decode xyz.
static DmtxPassFail bresLineStep(DmtxBresLine *line, int travel, int outward)
static int readModuleColor(DmtxDecode *dec, DmtxRegion *reg, int symbolRow, int symbolCol, int sizeIdx, int colorPlane)
读取模块(码元)颜色值
static DmtxBresLine bresLineInit(DmtxPixelLoc loc0, DmtxPixelLoc loc1, DmtxPixelLoc locInside)
static DmtxScanGrid initScanGrid(DmtxDecode *dec)
初始化扫描网格
libdmtx - Data Matrix Encoding/Decoding Library Copyright 2008, 2009 Mike Laughton.
int outputIdx
Internal index used to store output progress.
int fnc1
表示FNC1或DmtxUndefined的字符
unsigned char * output
指向二维码码值的指针
int sizeIdx
二维码类型索引,总共有 DmtxSymbolSquareCount + DmtxSymbolRectCount 种
DmtxPointFlow flowBegin
搜索起点,十字搜索抛出的点
DmtxMatrix3 fit2raw
3x3 变换矩阵,从二维码坐标系到图像坐标系