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

📄 dmtxencode.c

📁 Datamatrix二维码库和测试程序,运行于linux,仔细研究可以很容易转化成VC程序,有这就没必要化钱买个控件了,本人libdmtx-0.3版本转化过,的确可行,现在把找到该版本的libdmtx
💻 C
📖 第 1 页 / 共 4 页
字号:
    * 5 1/3 bits (for a total of 10 2/3 bits that gets used for a shifted    * character.    */   if(channel->encScheme == DmtxSchemeEncodeC40 ||         channel->encScheme == DmtxSchemeEncodeText) {      pos = (channel->currentLength % 6) / 2;      startByte = (channel->currentLength / 12) - (pos >> 1);      triplet = GetTripletValues(channel->encodedWords[startByte], channel->encodedWords[startByte+1]);      /* Note that we will alway increment progress according to a whole         input codeword, so the value at "pos" is guaranteed to not be in         a shifted state. */      if(triplet.value[pos] <= 2)         channel->currentLength += 8;   }   channel->currentLength += encodedUnits;}/** * @brief  Special end-of-symbol encoding for triplet-based schemes * @param  channel * @param  triplet * @param  tripletCount * @param  inputCount * @return void */static voidProcessEndOfSymbolTriplet(DmtxChannel *channel, DmtxTriplet *triplet, int tripletCount, int inputCount){   int sizeIdx;   int currentByte;   int remainingCodewords;   int inputAdjust;   /* In this function we process some special cases from the Data Matrix    * standard, and as such we circumvent the normal functions for    * accomplishing certain tasks.  This breaks our internal counts, but this    * function always marks the end of processing so it will not affect    * anything downstream.  This approach allows the normal encoding functions    * to be built with very strict checks and assertions.    *    * EXIT CONDITIONS:    *    *   triplet  symbol  action    *   -------  ------  -------------------    *         1       0  need bigger symbol    *         1       1  special case (d)    *         1       2  special case (c)    *         1       3  unlatch ascii pad    *         1       4  unlatch ascii pad pad    *         2       0  need bigger symbol    *         2       1  need bigger symbol    *         2       2  special case (b)    *         2       3  unlatch ascii ascii    *         2       4  unlatch ascii ascii pad    *         3       0  need bigger symbol    *         3       1  need bigger symbol    *         3       2  special case (a)    *         3       3  c40 c40 unlatch    *         3       4  c40 c40 unlatch pad    */   /* We should always reach this point on a byte boundary */   assert(channel->currentLength % 12 == 0);   /* XXX Capture how many extra input values will be counted ... for later adjustment */   inputAdjust = tripletCount - inputCount;   /* Find minimum symbol size big enough to accomodate remaining codewords */   currentByte = channel->currentLength/12;/* XXX this is broken -- what if someone asks for DmtxSymbolRectAuto or a specific sizeIdx? */   sizeIdx = FindCorrectSymbolSize(currentByte + ((inputCount == 3) ? 2 : inputCount),         DmtxSymbolSquareAuto);   /* XXX test for sizeIdx == -1 here */   remainingCodewords = dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx) - currentByte;   /* XXX the big problem with all of these special cases is what if one of      these last words requires multiple bytes in ASCII (like upper shift?).      We probably need to add a test against this and then just force an      unlatch if we see this coming. */   /* Special case (d): Unlatch is implied (switch manually) */   if(inputCount == 1 && remainingCodewords == 1) {      ChangeEncScheme(channel, DmtxSchemeEncodeAscii, DMTX_UNLATCH_IMPLICIT);      EncodeNextWord(channel, DmtxSchemeEncodeAscii);      assert(channel->invalid == 0);      assert(channel->inputPtr == channel->inputStop);   }   else if(remainingCodewords == 2) {      /* Special case (a): Unlatch is implied */      if(tripletCount == 3) {         PushTriplet(channel, triplet);         IncrementProgress(channel, 24);         channel->encScheme = DmtxSchemeEncodeAscii;         channel->inputPtr += 3;         channel->inputPtr -= inputAdjust;      }      /* Special case (b): Unlatch is implied */      else if(tripletCount == 2) {/*       assert(2nd C40 is not a shift character); */         triplet->value[2] = 0;         PushTriplet(channel, triplet);         IncrementProgress(channel, 24);         channel->encScheme = DmtxSchemeEncodeAscii;         channel->inputPtr += 2;         channel->inputPtr -= inputAdjust;      }      /* Special case (c) */      else if(tripletCount == 1) {         ChangeEncScheme(channel, DmtxSchemeEncodeAscii, DMTX_UNLATCH_EXPLICIT);         EncodeNextWord(channel, DmtxSchemeEncodeAscii);         assert(channel->invalid == 0);         /* XXX I can still think of a case that looks ugly here.  What if            the final 2 C40 codewords are a Shift word and a non-Shift            word.  This special case will unlatch after the shift ... which            is probably legal but I'm not loving it.  Give it more thought. */      }   }   else {/*    assert(remainingCodewords == 0 || remainingCodewords >= 3); */      currentByte = channel->currentLength/12;      remainingCodewords = dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx) - currentByte;      if(remainingCodewords > 0) {         ChangeEncScheme(channel, DmtxSchemeEncodeAscii, DMTX_UNLATCH_EXPLICIT);         while(channel->inputPtr < channel->inputStop) {            EncodeNextWord(channel, DmtxSchemeEncodeAscii);            assert(channel->invalid == 0);         }      }   }   assert(channel->inputPtr == channel->inputStop);}/** * @brief  Determine if end-of-symbol condition is met for EDIFACT-based schemes * @param  channel * @return void */static voidTestForEndOfSymbolEdifact(DmtxChannel *channel){   int edifactValues;   int currentByte;   int sizeIdx;   int symbolCodewords;   int asciiCodewords;   int i;   /* This function tests if the remaining input values can be completed using    * one of the valid end-of-symbol cases, and finishes encodation if possible.    *    * This function must exit in ASCII encodation.  EDIFACT must always be    * unlatched, although implicit Unlatch is possible.    *    * End   Symbol  ASCII  EDIFACT  End        Codeword    * Case  Words   Words  Values   Condition  Sequence    * ----  ------  -----  -------  ---------  -------------------------------    * (a)        1      0           Special    PAD    * (b)        1      1           Special    ASCII (could be 2 digits)    * (c)        1   >= 2           Continue   Need larger symbol    * (d)        2      0           Special    PAD PAD    * (e)        2      1           Special    ASCII PAD    * (f)        2      2           Special    ASCII ASCII    * (g)        2   >= 3           Continue   Need larger symbol    * (h)      N/A    N/A        0  Normal     UNLATCH    * (i)      N/A    N/A     >= 1  Continue   Not end of symbol    *    * Note: All "Special" cases (a,b,d,e,f) require clean byte boundary to start    */   /* Count remaining input values assuming EDIFACT encodation */   edifactValues = channel->inputStop - channel->inputPtr;   /* Can't end symbol right now if there are 5+ values remaining      (noting that '9999' can still terminate in case (f)) */   if(edifactValues > 4) /* subset of (i) -- performance only */      return;   /* Find minimum symbol size big enough to accomodate remaining codewords */   /* XXX broken -- what if someone asks for DmtxSymbolRectAuto or specific sizeIdx? */   currentByte = channel->currentLength/12;   sizeIdx = FindCorrectSymbolSize(currentByte, DmtxSymbolSquareAuto);   /* XXX test for sizeIdx == -1 here */   symbolCodewords = dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx) - currentByte;   /* Test for special case condition */   if(channel->currentLength % 12 == 0 &&         (symbolCodewords == 1 || symbolCodewords == 2)) {      /* Count number of codewords left to write (assuming ASCII) */      /* XXX temporary hack ... later create function that knows about shifts and digits */      asciiCodewords = edifactValues;      if(asciiCodewords <= symbolCodewords) { /* (a,b,d,e,f) */         ChangeEncScheme(channel, DmtxSchemeEncodeAscii, DMTX_UNLATCH_IMPLICIT);         /* XXX this loop should produce exactly asciiWords codewords ... assert somehow? */         for(i = 0; i < edifactValues; i++) {            EncodeNextWord(channel, DmtxSchemeEncodeAscii);            assert(channel->invalid == 0);         }      }      /* else (c,g) -- do nothing */   }   else if(edifactValues == 0) { /* (h) */      ChangeEncScheme(channel, DmtxSchemeEncodeAscii, DMTX_UNLATCH_EXPLICIT);   }   /* else (i) -- do nothing */}/** * @brief  Convert 3 input values into 2 codewords for triplet-based schemes * @param  outputWords * @param  inputWord * @param  encScheme * @return Codeword count */static intGetC40TextX12Words(int *outputWords, int inputWord, DmtxSchemeEncode encScheme){   int count;   assert(encScheme == DmtxSchemeEncodeC40 ||         encScheme == DmtxSchemeEncodeText ||         encScheme == DmtxSchemeEncodeX12);   count = 0;   /* Handle extended ASCII with Upper Shift character */   if(inputWord > 127) {      if(encScheme == DmtxSchemeEncodeX12) {         return 0;      }      else {         outputWords[count++] = 1;         outputWords[count++] = 30;         inputWord -= 128;      }   }   /* Handle all other characters according to encodation scheme */   if(encScheme == DmtxSchemeEncodeX12) {      if(inputWord == 13)         outputWords[count++] = 0;      else if(inputWord == 42)         outputWords[count++] = 1;      else if(inputWord == 62)         outputWords[count++] = 2;      else if(inputWord == 32)         outputWords[count++] = 3;      else if(inputWord >= 48 && inputWord <= 57)         outputWords[count++] = inputWord - 44;      else if(inputWord >= 65 && inputWord <= 90)         outputWords[count++] = inputWord - 51;   }   else { /* encScheme is C40 or Text */      if(inputWord <= 31) {         outputWords[count++] = DMTX_CHAR_TRIPLET_SHIFT_1;         outputWords[count++] = inputWord;      }      else if(inputWord == 32) {         outputWords[count++] = 3;      }      else if(inputWord <= 47) {         outputWords[count++] = DMTX_CHAR_TRIPLET_SHIFT_2;         outputWords[count++] = inputWord - 33;      }      else if(inputWord <= 57) {         outputWords[count++] = inputWord - 44;      }      else if(inputWord <= 64) {         outputWords[count++] = DMTX_CHAR_TRIPLET_SHIFT_2;         outputWords[count++] = inputWord - 43;      }      else if(inputWord <= 90 && encScheme == DmtxSchemeEncodeC40) {         outputWords[count++] = inputWord - 51;      }      else if(inputWord <= 90 && encScheme == DmtxSchemeEncodeText) {         outputWords[count++] = DMTX_CHAR_TRIPLET_SHIFT_3;         outputWords[count++] = inputWord - 64;      }      else if(inputWord <= 95) {         outputWords[count++] = DMTX_CHAR_TRIPLET_SHIFT_2;         outputWords[count++] = inputWord - 69;      }      else if(inputWord == 96 && encScheme == DmtxSchemeEncodeText) {         outputWords[count++] = DMTX_CHAR_TRIPLET_SHIFT_3;         outputWords[count++] = 0;      }      else if(inputWord <= 122 && encScheme == DmtxSchemeEncodeText) {         outputWords[count++] = inputWord - 83;      }      else if(inputWord <= 127) {         outputWords[count++] = DMTX_CHAR_TRIPLET_SHIFT_3;         outputWords[count++] = inputWord - 96;      }   }   return count;}/** * @brief  Convert 2 codewords into 3 values for triplet-based schemes * @param  cw1 * @param  cw2 * @return Triplet data */static DmtxTripletGetTripletValues(unsigned char cw1, unsigned char cw2){   int compact;   DmtxTriplet triplet;   /* XXX this really belongs with the decode functions */   compact = (cw1 << 8) | cw2;   triplet.value[0] = ((compact - 1)/1600);   triplet.value[1] = ((compact - 1)/40) % 40;   triplet.value[2] =  (compact - 1) % 40;   return triplet;}/** * @brief  Convert 3 codewords into 4 values for quadrulplet-based schemes * @param  cw1 * @param  cw2 * @param  cw3 * @return Quadruplet data */static DmtxQuadrupletGetQuadrupletValues(unsigned char cw1, unsigned char cw2, unsigned char cw3){   DmtxQuadruplet quad;   /* XXX this really belongs with the decode functions */   quad.value[0] = cw1 >> 2;   quad.value[1] = ((cw1 & 0x03) << 4) | ((cw2 & 0xf0) >> 4);   quad.value[2] = ((cw2 & 0x0f) << 2) | ((cw3 & 0xc0) >> 6);   quad.value[3] = cw3 & 0x3f;   return quad;}/** * @brief  Write channel contents to standard output * @param  channel * @return void *//**static voidDumpChannel(DmtxChannel *channel){   int j;   for(j = 0; j < channel->currentLength / 12; j++)      fprintf(stdout, "%3d ", channel->encodedWords[j]);   if(channel->currentLength % 12)      fprintf(stdout, "%3d-", channel->encodedWords[j]);   if(channel->invalid & DMTX_CHANNEL_CANNOT_UNLATCH)      fprintf(stdout, "(can't unlatch right now)");   else if(channel->invalid & DMTX_CHANNEL_UNSUPPORTED_CHAR)      fprintf(stdout, "(unsupported character)");   fprintf(stdout, "\n");}*//** * @brief  Write all channels' contents to standard output * @param  group * @param  encTarget * @return void *//**static voidDumpChannelGroup(DmtxChannelGroup *group, int encTarget){   int encScheme, i;   char *encNames[] = { "ASCII", "C40", "Text", "X12", "EDIFACT", "Base256" };   DmtxChannel *channel;   fprintf(stdout, "\n");   for(encScheme = DmtxSchemeEncodeAscii; encScheme <= DmtxSchemeEncodeBase256; encScheme++) {      channel = &(group->channel[encScheme]);      fprintf(stdout, "%s from %s: ", encNames[encTarget], encNames[encScheme]);      for(i = 8 + strlen(encNames[encTarget]) + strlen(encNames[encScheme]); i < 24; i++)         fprintf(stdout, " ");      DumpChannel(channel);      fflush(stdout);   }}*/

⌨️ 快捷键说明

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