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

📄 dmtxencode.c

📁 Datamatrix二维码库和测试程序,运行于linux,仔细研究可以很容易转化成VC程序,有这就没必要化钱买个控件了,本人libdmtx-0.3版本转化过,的确可行,现在把找到该版本的libdmtx
💻 C
📖 第 1 页 / 共 4 页
字号:
/*libdmtx - Data Matrix Encoding/Decoding LibraryCopyright (c) 2008 Mike LaughtonThis library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2.1 of the License, or (at your option) any later version.This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USAContact: mike@dragonflylogic.com*//* $Id: dmtxencode.c 514 2008-11-19 17:10:44Z mblaughton $ *//** * @file dmtxencode.c * @brief Encode messages *//* TODO rewrite this logic to use a push/stack approach. Do not track mid-   byte progress. Encode triplet-based schemes pre-encoding as necessary   like before, but only track how far up we had to go. Only rule channel   loss when unlatch is possible, or at end of channel. Make sure that   "remaining words in this schema" works accounts for shift characters,   and is used by all terminating conditions. Also see the rewrite comments   in EncodeAsciiCodeword().*/#define DMTX_CHAR_ASCII_PAD            129#define DMTX_CHAR_ASCII_UPPER_SHIFT    235#define DMTX_CHAR_C40_LATCH            230#define DMTX_CHAR_TEXT_LATCH           239#define DMTX_CHAR_X12_LATCH            238#define DMTX_CHAR_TRIPLET_UNLATCH      254#define DMTX_CHAR_TRIPLET_SHIFT_1        0#define DMTX_CHAR_TRIPLET_SHIFT_2        1#define DMTX_CHAR_TRIPLET_SHIFT_3        2#define DMTX_CHAR_EDIFACT_LATCH        240#define DMTX_CHAR_EDIFACT_UNLATCH       31#define DMTX_CHAR_BASE256_LATCH        231#define DMTX_CHAR_FNC1                 232#define DMTX_CHAR_STRUCTURED_APPEND    233#define DMTX_CHAR_ECI                  241#define DMTX_CHAR_05MACRO              236#define DMTX_CHAR_06MACRO              237#define DMTX_CHANNEL_VALID            0x00#define DMTX_CHANNEL_UNSUPPORTED_CHAR 0x01 << 0#define DMTX_CHANNEL_CANNOT_UNLATCH   0x01 << 1#define DMTX_UNLATCH_EXPLICIT            0#define DMTX_UNLATCH_IMPLICIT            1/** * @brief  Initialize encode struct with default values * @return Initialized DmtxEncode struct */extern DmtxEncodedmtxEncodeStructInit(void){   DmtxEncode enc;   memset(&enc, 0x00, sizeof(DmtxEncode));   enc.scheme = DmtxSchemeEncodeAscii;   enc.moduleSize = 5;   enc.marginSize = 10;   /* Initialize background color to white *//* enc.region.gradient.ray.p.R = 255.0;   enc.region.gradient.ray.p.G = 255.0;   enc.region.gradient.ray.p.B = 255.0; */   /* Initialize foreground color to black *//* enc.region.gradient.tMin = 0.0;   enc.region.gradient.tMax = dmtxColor3Mag(&(enc.region.gradient.ray.p)); *//* dmtxColor3Scale(&(enc.region.gradient.ray.c),         &(enc.region.gradient.ray.p), -1.0/enc.region.gradient.tMax); */   dmtxMatrix3Identity(enc.xfrm);   return enc;}/** * @brief  Deinitialize encode struct * @param  enc * @return void */extern voiddmtxEncodeStructDeInit(DmtxEncode *enc){   if(enc == NULL)      return;   dmtxImageFree(&(enc->image));   dmtxMessageFree(&(enc->message));   memset(enc, 0x00, sizeof(DmtxEncode));}/** * @brief  Convert message into Data Matrix image * @param  enc * @param  inputSize * @param  inputString * @param  sizeIdxRequest * @return DMTX_SUCCESS | DMTX_FAILURE */extern intdmtxEncodeDataMatrix(DmtxEncode *enc, int inputSize, unsigned char *inputString, int sizeIdxRequest){   int dataWordCount;   int sizeIdx;   unsigned char buf[4096];   /* Encode input string into data codewords */   sizeIdx = sizeIdxRequest;   dataWordCount = EncodeDataCodewords(buf, inputString, inputSize, enc->scheme, &sizeIdx);   if(dataWordCount <= 0)      return(DMTX_FAILURE);   /* EncodeDataCodewords() should have updated any auto sizeIdx to a real one */   assert(sizeIdx != DmtxSymbolSquareAuto && sizeIdx != DmtxSymbolRectAuto);   /* Add pad characters to match a standard symbol size (whether smallest or requested) */   AddPadChars(buf, &dataWordCount, dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx));   /* XXX we can remove a lot of this redundant data */   enc->region.sizeIdx = sizeIdx;   enc->region.symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, sizeIdx);   enc->region.symbolCols = dmtxGetSymbolAttribute(DmtxSymAttribSymbolCols, sizeIdx);   enc->region.mappingRows = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixRows, sizeIdx);   enc->region.mappingCols = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixCols, sizeIdx);   /* Allocate memory for message and array */   enc->message = dmtxMessageMalloc(sizeIdx, DMTX_FORMAT_MATRIX);   memcpy(enc->message->code, buf, dataWordCount);/* fprintf(stdout, "\n\nsize:    %dx%d w/ %d error codewords\n", rows, cols, errorWordLength(enc->region.sizeIdx)); */   /* Generate error correction codewords */   GenReedSolEcc(enc->message, enc->region.sizeIdx);   /* Module placement in region */   ModulePlacementEcc200(enc->message->array, enc->message->code, enc->region.sizeIdx, DMTX_MODULE_ON_RGB);   /* Allocate memory for the image to be generated */   enc->image = dmtxImageMalloc(         2 * enc->marginSize + (enc->region.symbolCols * enc->moduleSize),         2 * enc->marginSize + (enc->region.symbolRows * enc->moduleSize));   if(enc->image == NULL) {      perror("image malloc error");      return DMTX_FAILURE;   }   /* Insert finder and aligment pattern modules */   PrintPattern(enc);   return DMTX_SUCCESS;}/** * @brief  Convert message into Data Mosaic image * @param  enc * @param  inputSize * @param  inputString * @param  sizeIdxRequest * @return DMTX_SUCCESS | DMTX_FAILURE */extern intdmtxEncodeDataMosaic(DmtxEncode *enc, int inputSize, unsigned char *inputString, int sizeIdxRequest){   int dataWordCount;   int tmpInputSize;   unsigned char *inputStart;   int splitInputSize[3];   int sizeIdx;   int splitSizeIdxAttempt, splitSizeIdxFirst, splitSizeIdxLast;   unsigned char buf[3][4096];   DmtxEncode encGreen, encBlue;   int row, col, mappingRows, mappingCols;   /* 1) count how many codewords it would take to encode the whole thing    * 2) take ceiling N of codeword count divided by 3    * 3) using minimum symbol size that can accomodate N codewords:    * 4) create several barcodes over iterations of increasing numbers of    *    input codewords until you go one too far    * 5) if codewords remain after filling R, G, and B barcodes then go back    *    to 3 and try with next larger size    * 6) take the 3 different images you created and write out a new barcode    */   /* XXX we're going to force ascii until we fix the problem with C40/Text termination */   enc->scheme = DmtxSchemeEncodeAscii;   /* Encode full input string to establish baseline data codeword count */   sizeIdx = sizeIdxRequest;   /* XXX buf can be changed here to use all 3 buffers' length */   dataWordCount = EncodeDataCodewords(buf[0], inputString, inputSize, enc->scheme, &sizeIdx);   if(dataWordCount <= 0)      return DMTX_FAILURE;   /* Use 1/3 (ceiling) of inputSize establish input size target */   tmpInputSize = (inputSize + 2) / 3;   splitInputSize[0] = tmpInputSize;   splitInputSize[1] = tmpInputSize;   splitInputSize[2] = inputSize - (splitInputSize[0] + splitInputSize[1]);   /* XXX clean up above lines later for corner cases */   /* Use 1/3 (floor) of dataWordCount establish first symbol size attempt */   splitSizeIdxFirst = FindCorrectSymbolSize(tmpInputSize, sizeIdxRequest);   if(splitSizeIdxFirst == -1)      return DMTX_FAILURE;   /* Set the last possible symbol size for this symbol shape or specific size request */   if(sizeIdxRequest == DmtxSymbolSquareAuto)      splitSizeIdxLast = DMTX_SYMBOL_SQUARE_COUNT - 1;   else if(sizeIdxRequest == DmtxSymbolRectAuto)      splitSizeIdxLast = DMTX_SYMBOL_SQUARE_COUNT + DMTX_SYMBOL_RECT_COUNT - 1;   else      splitSizeIdxLast = splitSizeIdxFirst;   /* XXX would be nice if we could choose a size and then fill up each      layer as we go, but this can cause problems with all data fits on      first 2 layers.  Revisit this later after things look a bit cleaner. */   /* Try increasing symbol sizes until 3 of them can hold all input values */   for(splitSizeIdxAttempt = splitSizeIdxFirst; splitSizeIdxAttempt <= splitSizeIdxLast; splitSizeIdxAttempt++) {      assert(splitSizeIdxAttempt >= 0);      /* RED LAYER */      sizeIdx = splitSizeIdxAttempt;      inputStart = inputString;      EncodeDataCodewords(buf[0], inputStart, splitInputSize[0], enc->scheme, &sizeIdx);      if(sizeIdx != splitSizeIdxAttempt)         continue;      /* GREEN LAYER */      sizeIdx = splitSizeIdxAttempt;      inputStart += splitInputSize[0];      EncodeDataCodewords(buf[1], inputStart, splitInputSize[1], enc->scheme, &sizeIdx);      if(sizeIdx != splitSizeIdxAttempt)         continue;      /* BLUE LAYER */      sizeIdx = splitSizeIdxAttempt;      inputStart += splitInputSize[1];      EncodeDataCodewords(buf[2], inputStart, splitInputSize[2], enc->scheme, &sizeIdx);      if(sizeIdx != splitSizeIdxAttempt)         continue;      break;   }   /* Now we have the correct lengths for splitInputSize, and they all fit into the desired size */   encGreen = *enc;   encBlue = *enc;   /* First encode red to the main encode struct (image portion will be overwritten) */   inputStart = inputString;   dmtxEncodeDataMatrix(enc, splitInputSize[0], inputStart, splitSizeIdxAttempt);   inputStart += splitInputSize[0];   dmtxEncodeDataMatrix(&encGreen, splitInputSize[1], inputStart, splitSizeIdxAttempt);   inputStart += splitInputSize[1];   dmtxEncodeDataMatrix(&encBlue, splitInputSize[2], inputStart, splitSizeIdxAttempt);   mappingRows = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixRows, splitSizeIdxAttempt);   mappingCols = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixCols, splitSizeIdxAttempt);   memset(enc->message->array, 0x00, sizeof(unsigned char) * enc->region.mappingRows * enc->region.mappingCols);   ModulePlacementEcc200(enc->message->array, enc->message->code, enc->region.sizeIdx, DMTX_MODULE_ON_RED);   /* Data Mosaic will traverse this array multiple times -- reset      DMTX_MODULE_ASSIGNED and DMX_MODULE_VISITED bits before starting */   for(row = 0; row < mappingRows; row++) {      for(col = 0; col < mappingCols; col++) {         enc->message->array[row*mappingCols+col] &= (0xff ^ (DMTX_MODULE_ASSIGNED | DMTX_MODULE_VISITED));      }   }   ModulePlacementEcc200(enc->message->array, encGreen.message->code, enc->region.sizeIdx, DMTX_MODULE_ON_GREEN);   /* Data Mosaic will traverse this array multiple times -- reset      DMTX_MODULE_ASSIGNED and DMX_MODULE_VISITED bits before starting */   for(row = 0; row < mappingRows; row++) {      for(col = 0; col < mappingCols; col++) {         enc->message->array[row*mappingCols+col] &= (0xff ^ (DMTX_MODULE_ASSIGNED | DMTX_MODULE_VISITED));      }   }   ModulePlacementEcc200(enc->message->array, encBlue.message->code, enc->region.sizeIdx, DMTX_MODULE_ON_BLUE);/* dmtxEncodeStructDeInit(&encGreen);   dmtxEncodeStructDeInit(&encBlue); */   PrintPattern(enc);   return DMTX_SUCCESS;}/** * @brief  Convert input into message using specific encodation scheme * @param  buf * @param  inputString * @param  inputSize * @param  scheme * @param  sizeIdx * @return Count of encoded data words */static intEncodeDataCodewords(unsigned char *buf, unsigned char *inputString,      int inputSize, DmtxSchemeEncode scheme, int *sizeIdx){   int dataWordCount;   /*    * This function needs to take both dataWordCount and sizeIdx into account    * because symbol size is tied to an encodation. That is, a data stream    * might be different from one symbol size to another    */   /* Encode input string into data codewords */   switch(scheme) {      case DmtxSchemeEncodeAutoBest:         dataWordCount = EncodeAutoBest(buf, inputString, inputSize);         break;      case DmtxSchemeEncodeAutoFast:         dataWordCount = 0;         /* dataWordCount = EncodeAutoFast(buf, inputString, inputSize); */         break;      default:         dataWordCount = EncodeSingleScheme(buf, inputString, inputSize, scheme);         break;   }   /* XXX must fix ... will need to handle sizeIdx requests here because it is      needed by Encode...() for triplet termination */   /* parameter sizeIdx is requested value, returned sizeIdx is decision */   *sizeIdx = FindCorrectSymbolSize(dataWordCount, *sizeIdx);   if(*sizeIdx == -1)      return 0;   return dataWordCount;}/** * @brief  Add necessary padding codewords to message * @param  buf * @param  bufSize * @param  paddedSize * @return void */static voidAddPadChars(unsigned char *buf,  int *bufSize, int paddedSize){   /* First pad character is not randomized */   if(*bufSize < paddedSize)      buf[(*bufSize)++] = DMTX_CHAR_ASCII_PAD;   /* All remaining pad characters are randomized based on character position */   while(*bufSize < paddedSize) {      buf[*bufSize] = Randomize253State(DMTX_CHAR_ASCII_PAD, *bufSize + 1);      (*bufSize)++;   }}/** * @brief  Randomize 253 state * @param  codewordValue * @param  codewordPosition * @return Randomized value */static unsigned charRandomize253State(unsigned char codewordValue, int codewordPosition){   int pseudoRandom;   int tmp;   pseudoRandom = ((149 * codewordPosition) % 253) + 1;   tmp = codewordValue + pseudoRandom;   return (tmp <= 254) ? tmp : tmp - 254;}/** * @brief  Randomize 255 state * @param  codewordValue

⌨️ 快捷键说明

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