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

📄 dmtxdecode.c

📁 Datamatrix二维码库和测试程序,运行于linux,仔细研究可以很容易转化成VC程序,有这就没必要化钱买个控件了,本人libdmtx-0.3版本转化过,的确可行,现在把找到该版本的libdmtx
💻 C
📖 第 1 页 / 共 2 页
字号:
               fprintf(stdout, "Upper Shift (?)"); /* Upper Shift (eh?) */            shift = 0;         }         else if(shift == 3) { /* Shift 3 set */            if(encScheme == DmtxSchemeDecodeC40) {               msg->output[msg->outputIdx++] = c40Values[i] + 96;            }            else if(encScheme == DmtxSchemeDecodeText) {               if(c40Values[i] == 0)                  msg->output[msg->outputIdx++] = c40Values[i] + 96;               else if(c40Values[i] <= 26)                  msg->output[msg->outputIdx++] = c40Values[i] - 26 + 'Z'; /* A-Z */               else                  msg->output[msg->outputIdx++] = c40Values[i] - 31 + 127; /* { | } ~ DEL */            }            shift = 0;         }      }      /* Unlatch if codeword 254 follows 2 codewords in C40/Text encodation */      if(*ptr == 254)         return ptr + 1;      /* Unlatch is implied if only one codeword remains */      if(dataEnd - ptr == 1)         return ptr;   }   return ptr;}/** * @brief  Decode stream assuming X12 encodation * @param  msg * @param  ptr * @param  dataEnd * @return Pointer to next undecoded codeword */static unsigned char *DecodeSchemeX12(DmtxMessage *msg, unsigned char *ptr, unsigned char *dataEnd){   int i;   int packed;   unsigned char x12Values[3];   while(ptr < dataEnd) {      /* FIXME Also check that ptr+1 is safe to access */      packed = (*ptr << 8) | *(ptr+1);      x12Values[0] = ((packed - 1)/1600);      x12Values[1] = ((packed - 1)/40) % 40;      x12Values[2] =  (packed - 1) % 40;      ptr += 2;      for(i = 0; i < 3; i++) {         if(x12Values[i] == 0)            msg->output[msg->outputIdx++] = 13;         else if(x12Values[i] == 1)            msg->output[msg->outputIdx++] = 42;         else if(x12Values[i] == 2)            msg->output[msg->outputIdx++] = 62;         else if(x12Values[i] == 3)            msg->output[msg->outputIdx++] = 32;         else if(x12Values[i] <= 13)            msg->output[msg->outputIdx++] = x12Values[i] + 44;         else if(x12Values[i] <= 90)            msg->output[msg->outputIdx++] = x12Values[i] + 51;      }      /* Unlatch if codeword 254 follows 2 codewords in C40/Text encodation */      if(*ptr == 254)         return ptr + 1;      /* Unlatch is implied if only one codeword remains */      if(dataEnd - ptr == 1)         return ptr;   }   return ptr;}/** * @brief  Decode stream assuming EDIFACT encodation * @param  msg * @param  ptr * @param  dataEnd * @return Pointer to next undecoded codeword */static unsigned char *DecodeSchemeEdifact(DmtxMessage *msg, unsigned char *ptr, unsigned char *dataEnd){   int i;   unsigned char unpacked[4];   while(ptr < dataEnd) {      /* FIXME Also check that ptr+2 is safe to access -- shouldn't be a         problem because I'm guessing you can guarantee there will always         be at least 3 error codewords */      unpacked[0] = (*ptr & 0xfc) >> 2;      unpacked[1] = (*ptr & 0x03) << 4 | (*(ptr+1) & 0xf0) >> 4;      unpacked[2] = (*(ptr+1) & 0x0f) << 2 | (*(ptr+2) & 0xc0) >> 6;      unpacked[3] = *(ptr+2) & 0x3f;      for(i = 0; i < 4; i++) {         /* Advance input ptr (4th value comes from already-read 3rd byte) */         if(i < 3)            ptr++;         /* Test for unlatch condition */         if(unpacked[i] == 0x1f) {            assert(msg->output[msg->outputIdx] == 0); /* XXX dirty why? */            return ptr;         }         msg->output[msg->outputIdx++] = unpacked[i] ^ (((unpacked[i] & 0x20) ^ 0x20) << 1);      }      /* Unlatch is implied if fewer than 3 codewords remain */      if(dataEnd - ptr < 3) {         return ptr;      }   }   return ptr;/* XXX the following version should be safer, but requires testing before replacing the old version   int bits = 0;   int bitCount = 0;   int value;   while(ptr < dataEnd) {      if(bitCount < 6) {         bits = (bits << 8) | *(ptr++);         bitCount += 8;      }      value = bits >> (bitCount - 6);      bits -= (value << (bitCount - 6));      bitCount -= 6;      if(value == 0x1f) {         assert(bits == 0); // should be padded with zero-value bits         return ptr;      }      msg->output[msg->outputIdx++] = value ^ (((value & 0x20) ^ 0x20) << 1);      // Unlatch implied if just completed triplet and 1 or 2 words are left      if(bitCount == 0 && dataEnd - ptr - 1 > 0 && dataEnd - ptr - 1 < 3)         return ptr;   }   assert(bits == 0); // should be padded with zero-value bits   assert(bitCount == 0); // should be padded with zero-value bits   return ptr;*/}/** * @brief  Decode stream assuming Base 256 encodation * @param  msg * @param  ptr * @param  dataEnd * @return Pointer to next undecoded codeword */static unsigned char *DecodeSchemeBase256(DmtxMessage *msg, unsigned char *ptr, unsigned char *dataEnd){   int d0, d1;   int i;   unsigned char *ptrEnd;   /* XXX i is the positional index used for unrandomizing */   i = ptr - msg->code + 1;   d0 = UnRandomize255State(*(ptr++), i++);   if(d0 == 0) {      ptrEnd = dataEnd;   }   else if(d0 <= 249) {      ptrEnd = ptr + d0;   }   else {      d1 = UnRandomize255State(*(ptr++), i++);      ptrEnd = ptr + (d0 - 249) * 250 + d1;   }   if(ptrEnd > dataEnd) {      exit(40); /* XXX needs cleaner error handling */   }   while(ptr < ptrEnd) {      msg->output[msg->outputIdx++] = UnRandomize255State(*(ptr++), i++);   }   return ptr;}/** * @brief  Unrandomize 253 state * @param  codewordValue * @return codewordPosition *//**static unsigned charUnRandomize253State(unsigned char codewordValue, int codewordPosition){   int pseudoRandom;   int tmp;   pseudoRandom = ((149 * codewordPosition) % 253) + 1;   tmp = codewordValue - pseudoRandom;   return (tmp >= 1) ? tmp : tmp + 254;}*//** * @brief  Unrandomize 255 state * @param  value * @param  idx * @return Unrandomized value */static unsigned charUnRandomize255State(unsigned char value, int idx){   int pseudoRandom;   int tmp;   pseudoRandom = ((149 * idx) % 255) + 1;   tmp = value - pseudoRandom;   return (tmp >= 0) ? tmp : tmp + 256;}/** * @brief  Populate array with codeword values based on module colors * @param  msg * @param  img * @param  reg * @return DMTX_SUCCESS | DMTX_FAILURE */static intPopulateArrayFromMatrix(DmtxMessage *msg, DmtxImage *img, DmtxRegion *reg){   int weightFactor;   int mapWidth, mapHeight;   int xRegionTotal, yRegionTotal;   int xRegionCount, yRegionCount;   int xOrigin, yOrigin;   int mapCol, mapRow;   int colTmp, rowTmp, idx;   int tally[24][24]; /* Large enough to map largest single region *//* memset(msg->array, 0x00, msg->arraySize); */   /* Capture number of regions present in barcode */   xRegionTotal = dmtxGetSymbolAttribute(DmtxSymAttribHorizDataRegions, reg->sizeIdx);   yRegionTotal = dmtxGetSymbolAttribute(DmtxSymAttribVertDataRegions, reg->sizeIdx);   /* Capture region dimensions (not including border modules) */   mapWidth = dmtxGetSymbolAttribute(DmtxSymAttribDataRegionCols, reg->sizeIdx);   mapHeight = dmtxGetSymbolAttribute(DmtxSymAttribDataRegionRows, reg->sizeIdx);   weightFactor = 2 * (mapHeight + mapWidth + 2);   assert(weightFactor > 0);   /* Tally module changes for each region in each direction */   for(yRegionCount = 0; yRegionCount < yRegionTotal; yRegionCount++) {      /* Y location of mapping region origin in symbol coordinates */      yOrigin = yRegionCount * (mapHeight + 2) + 1;      for(xRegionCount = 0; xRegionCount < xRegionTotal; xRegionCount++) {         /* X location of mapping region origin in symbol coordinates */         xOrigin = xRegionCount * (mapWidth + 2) + 1;         memset(tally, 0x00, 24 * 24 * sizeof(int));         TallyModuleJumps(img, reg, tally, xOrigin, yOrigin, mapWidth, mapHeight, DmtxDirUp);         TallyModuleJumps(img, reg, tally, xOrigin, yOrigin, mapWidth, mapHeight, DmtxDirLeft);         TallyModuleJumps(img, reg, tally, xOrigin, yOrigin, mapWidth, mapHeight, DmtxDirDown);         TallyModuleJumps(img, reg, tally, xOrigin, yOrigin, mapWidth, mapHeight, DmtxDirRight);         /* Decide module status based on final tallies */         for(mapRow = 0; mapRow < mapHeight; mapRow++) {            for(mapCol = 0; mapCol < mapWidth; mapCol++) {               rowTmp = (yRegionCount * mapHeight) + mapRow;               rowTmp = yRegionTotal * mapHeight - rowTmp - 1;               colTmp = (xRegionCount * mapWidth) + mapCol;               idx = (rowTmp * xRegionTotal * mapWidth) + colTmp;               if(tally[mapRow][mapCol]/(double)weightFactor >= 0.5)                  msg->array[idx] = DMTX_MODULE_ON_RGB;               else                  msg->array[idx] = DMTX_MODULE_OFF;               msg->array[idx] |= DMTX_MODULE_ASSIGNED;            }         }      }   }   return DMTX_SUCCESS;}/** * @brief  Increment counters used to determine module values * @param  img * @param  reg * @param  tally * @param  xOrigin * @param  yOrigin * @param  mapWidth * @param  mapHeight * @param  dir * @return void */static voidTallyModuleJumps(DmtxImage *img, DmtxRegion *reg, int tally[][24], int xOrigin, int yOrigin, int mapWidth, int mapHeight, DmtxDirection dir){   int extent, weight;   int travelStep;   int symbolRow, symbolCol;   int mapRow, mapCol;   int lineStart, lineStop;   int travelStart, travelStop;   int *line, *travel;   int jumpThreshold;   int darkOnLight;   int color;   int statusPrev, statusModule;   int tPrev, tModule;   assert(dir == DmtxDirUp || dir == DmtxDirLeft || dir == DmtxDirDown || dir == DmtxDirRight);   travelStep = (dir == DmtxDirUp || dir == DmtxDirRight) ? 1 : -1;   /* Abstract row and column progress using pointers to allow grid      traversal in all 4 directions using same logic */   if((dir & DmtxDirHorizontal) != 0x00) {      line = &symbolRow;      travel = &symbolCol;      extent = mapWidth;      lineStart = yOrigin;      lineStop = yOrigin + mapHeight;      travelStart = (travelStep == 1) ? xOrigin - 1 : xOrigin + mapWidth;      travelStop = (travelStep == 1) ? xOrigin + mapWidth : xOrigin - 1;   }   else {      assert(dir & DmtxDirVertical);      line = &symbolCol;      travel = &symbolRow;      extent = mapHeight;      lineStart = xOrigin;      lineStop = xOrigin + mapWidth;      travelStart = (travelStep == 1) ? yOrigin - 1: yOrigin + mapHeight;      travelStop = (travelStep == 1) ? yOrigin + mapHeight : yOrigin - 1;   }   darkOnLight = (int)(reg->offColor > reg->onColor);   jumpThreshold = abs((int)(0.4 * (reg->offColor - reg->onColor) + 0.5));   assert(jumpThreshold >= 0);   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;      color = ReadModuleColor(img, reg, symbolRow, symbolCol, reg->sizeIdx);      tModule = (darkOnLight) ? reg->offColor - color : color - reg->offColor;      statusModule = (travelStep == 1 || (*line & 0x01) == 0) ? DMTX_MODULE_ON_RGB : DMTX_MODULE_OFF;      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 */         color = ReadModuleColor(img, reg, symbolRow, symbolCol, reg->sizeIdx);         tModule = (darkOnLight) ? reg->offColor - color : color - reg->offColor;         if(statusPrev == DMTX_MODULE_ON_RGB) {            if(tModule < tPrev - jumpThreshold)               statusModule = DMTX_MODULE_OFF;            else               statusModule = DMTX_MODULE_ON_RGB;         }         else if(statusPrev == DMTX_MODULE_OFF) {            if(tModule > tPrev + jumpThreshold)               statusModule = DMTX_MODULE_ON_RGB;            else               statusModule = DMTX_MODULE_OFF;         }         mapRow = symbolRow - yOrigin;         mapCol = symbolCol - xOrigin;         assert(mapRow < 24 && mapCol < 24);         if(statusModule == DMTX_MODULE_ON_RGB)            tally[mapRow][mapCol] += (2 * weight);         weight--;      }      assert(weight == 0);   }}/** * @brief  Populate array with codeword values based on module colors * @param  msg * @param  img * @param  reg * @return DMTX_SUCCESS | DMTX_FAILURE */static intPopulateArrayFromMosaic(DmtxMessage *msg, DmtxImage *img, DmtxRegion *reg){   int col, row, rowTmp;   int symbolRow, symbolCol;   int dataRegionRows, dataRegionCols;   int color;   dataRegionRows = dmtxGetSymbolAttribute(DmtxSymAttribDataRegionRows, reg->sizeIdx);   dataRegionCols = dmtxGetSymbolAttribute(DmtxSymAttribDataRegionCols, reg->sizeIdx);   memset(msg->array, 0x00, msg->arraySize);   for(row = 0; row < reg->mappingRows; row++) {      /* Transform mapping row to symbol row (Swap because the array's         origin is top-left and everything else is bottom-left) */      rowTmp = reg->mappingRows - row - 1;      symbolRow = rowTmp + 2 * (rowTmp / dataRegionRows) + 1;      for(col = 0; col < reg->mappingCols; col++) {         /* Transform mapping col to symbol col */         symbolCol = col + 2 * (col / dataRegionCols) + 1;/* to fix this function, add rColor, gColor, bColor, and change ReadModuleColor() to accept plane as a parameter */         color = ReadModuleColor(img, reg, symbolRow, symbolCol, reg->sizeIdx);         /* Value has been assigned, but not visited *//*       if(color.R < 50) this is broken for the moment */         if(color < 50)            msg->array[row*reg->mappingCols+col] |= DMTX_MODULE_ON_RED;/*       if(color.G < 50) this is broken for the moment */         if(color < 50)            msg->array[row*reg->mappingCols+col] |= DMTX_MODULE_ON_GREEN;/*       if(color.B < 50) this is broken for the moment */         if(color < 50)            msg->array[row*reg->mappingCols+col] |= DMTX_MODULE_ON_BLUE;         msg->array[row*reg->mappingCols+col] |= DMTX_MODULE_ASSIGNED;      }   }   /* Ideal barcode drawn in lower-right (final) window pane *//* CALLBACK_DECODE_FUNC2(finalCallback, dec, dec, reg); */   return DMTX_SUCCESS;}

⌨️ 快捷键说明

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