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

📄 dmtxencode.c

📁 Datamatrix二维码库和测试程序,运行于linux,仔细研究可以很容易转化成VC程序,有这就没必要化钱买个控件了,本人libdmtx-0.3版本转化过,的确可行,现在把找到该版本的libdmtx
💻 C
📖 第 1 页 / 共 4 页
字号:
            inputWord = *(ptr++);            count = GetC40TextX12Words(outputWords, inputWord, channel->encScheme);            if(count == 0) {               channel->invalid = DMTX_CHANNEL_UNSUPPORTED_CHAR;               return;            }            for(i = 0; i < count; i++) {               buffer[tripletCount++] = outputWords[i];            }         }         /* Take the next 3 values from buffer to encode */         triplet.value[0] = buffer[0];         triplet.value[1] = buffer[1];         triplet.value[2] = buffer[2];         if(tripletCount >= 3) {            PushTriplet(channel, &triplet);            buffer[0] = buffer[3];            buffer[1] = buffer[4];            buffer[2] = buffer[5];            tripletCount -= 3;         }         /* If we reach the end of input and have not encountered a clean            break opportunity then complete the symbol here */         if(ptr == channel->inputStop) {            /* tripletCount represents the number of values in triplet waiting to be pushed               inputCount represents the number of values after inputPtr waiting to be pushed */            while(channel->currentLength < channel->encodedLength) {               IncrementProgress(channel, 8);               channel->inputPtr++;            }            /* If final triplet value was shift then InrementProgress will               overextend us .. hack it back a little.  Note that this means               this barcode is invalid unless one of the specific end-of-symbol               conditions explicitly allows it. */            if(channel->currentLength == channel->encodedLength + 8) {               channel->currentLength = channel->encodedLength;               channel->inputPtr--;            }            inputCount = channel->inputStop - channel->inputPtr;            ProcessEndOfSymbolTriplet(channel, &triplet, tripletCount, inputCount);            break;         }         /* If there are no triplet values remaining in the buffer then            break.  This guarantees that we will always stop encoding on a            clean "unshifted" break */         if(tripletCount == 0)            break;      }   }   /* Pre-encoded codeword is available for consumption */   if(channel->currentLength < channel->encodedLength) {      IncrementProgress(channel, 8);      channel->inputPtr++;   }}/** * @brief  Encode value using EDIFACT encodation * @param  channel * @return void */static voidEncodeEdifactCodeword(DmtxChannel *channel){   unsigned char inputValue;   assert(channel->encScheme == DmtxSchemeEncodeEdifact);   inputValue = *(channel->inputPtr);   if(inputValue < 32 || inputValue > 94) {      channel->invalid = DMTX_CHANNEL_UNSUPPORTED_CHAR;      return;   }   PushInputWord(channel, inputValue & 0x3f);   IncrementProgress(channel, 9);   channel->inputPtr++;   /* XXX rename this to CheckforEndOfSymbolEdifact() */   TestForEndOfSymbolEdifact(channel);}/** * @brief  Encode value using Base 256 encodation * @param  channel * @return void */static voidEncodeBase256Codeword(DmtxChannel *channel){   int i;   int newDataLength;   int headerByteCount;   unsigned char valueTmp;   unsigned char *firstBytePtr;   unsigned char headerByte[2];   assert(channel->encScheme == DmtxSchemeEncodeBase256);   firstBytePtr = &(channel->encodedWords[channel->firstCodeWord/12]);   headerByte[0] = UnRandomize255State(*firstBytePtr, channel->firstCodeWord/12 + 1);   /* newSchemeLength contains size byte(s) too */   if(headerByte[0] <= 249) {      newDataLength = headerByte[0];   }   else {      newDataLength = 250 * (headerByte[0] - 249);      newDataLength += UnRandomize255State(*(firstBytePtr+1), channel->firstCodeWord/12 + 2);   }   newDataLength++;   if(newDataLength <= 249) {      headerByteCount = 1;      headerByte[0] = newDataLength;      headerByte[1] = 0; /* unused */   }   else {      headerByteCount = 2;      headerByte[0] = newDataLength/250 + 249;      headerByte[1] = newDataLength%250;   }   /* newDataLength does not include header bytes */   assert(newDataLength > 0 && newDataLength <= 1555);   /* One time shift of codewords when passing the 250 byte size threshold */   if(newDataLength == 250) {      for(i = channel->currentLength/12 - 1; i > channel->firstCodeWord/12; i--) {         valueTmp = UnRandomize255State(channel->encodedWords[i], i+1);         channel->encodedWords[i+1] = Randomize255State(valueTmp, i+2);      }      IncrementProgress(channel, 12);      channel->encodedLength += 12; /* ugly */   }   /* Update scheme length in Base 256 header */   for(i = 0; i < headerByteCount; i++)      *(firstBytePtr+i) = Randomize255State(headerByte[i], channel->firstCodeWord/12 + i + 1);   PushInputWord(channel, Randomize255State(*(channel->inputPtr), channel->currentLength/12 + 1));   IncrementProgress(channel, 12);   channel->inputPtr++;   /* XXX will need to introduce an EndOfSymbolBase256() that recognizes      opportunity to encode headerLength of 0 if remaining Base 256 message      exactly matches symbol capacity */}/** * @brief  Change from one encodation scheme to another * @param  channel * @param  targetScheme * @param  unlatchType * @return void */static voidChangeEncScheme(DmtxChannel *channel, DmtxSchemeEncode targetScheme, int unlatchType){   int advance;   assert(channel->encScheme != targetScheme);   /* Unlatch to ASCII (base encodation scheme) */   switch(channel->encScheme) {      case DmtxSchemeEncodeAscii:         /* Nothing to do */         assert(channel->currentLength % 12 == 0);         break;      case DmtxSchemeEncodeC40:      case DmtxSchemeEncodeText:      case DmtxSchemeEncodeX12:         /* Can't unlatch unless currently at a byte boundary */         if((channel->currentLength % 12) != 0) {            channel->invalid = DMTX_CHANNEL_CANNOT_UNLATCH;            return;         }         /* Can't unlatch if last word in previous triplet is a shift */         if(channel->currentLength != channel->encodedLength) {            channel->invalid = DMTX_CHANNEL_CANNOT_UNLATCH;            return;         }         /* Unlatch to ASCII and increment progress */         if(unlatchType == DMTX_UNLATCH_EXPLICIT) {            PushInputWord(channel, DMTX_CHAR_TRIPLET_UNLATCH);            IncrementProgress(channel, 12);         }         break;      case DmtxSchemeEncodeEdifact:         /* must overwrite next 6 bits (after current) with 011111 (31) and            then fill remaining bits until next byte bounday with zeros            then set encodedLength, encodedTwothirdsbits, currentLength,            currentTwothirdsbits.  PushInputWord guarantees that remaining            bits are padded to 0, so just push the unlatch code and then            increment current and encoded length */         assert(channel->currentLength % 3 == 0);         if(unlatchType == DMTX_UNLATCH_EXPLICIT) {            PushInputWord(channel, DMTX_CHAR_EDIFACT_UNLATCH);            IncrementProgress(channel, 9);         }         /* Advance progress to next byte boundary */         advance = (channel->currentLength % 4) * 3;         channel->currentLength += advance;         channel->encodedLength += advance;         /* assert(remaining bits are zero); */         break;      case DmtxSchemeEncodeBase256:         /* since Base 256 stores the length value at the beginning of the            string instead of using an unlatch character, "unlatching" Base            256 involves going to the beginning of this stretch of Base 256            codewords and update the placeholder with the current length.            Note that the Base 256 length value can either be 1 or 2 bytes,            depending on the length of the current stretch of Base 256            chars.  However, this value will already have the correct            number of codewords allocated since this is checked every time            a new Base 256 codeword is pushed to the channel. */         break;      default:         break;   }   channel->encScheme = DmtxSchemeEncodeAscii;   /* Latch to new encodation scheme */   switch(targetScheme) {      case DmtxSchemeEncodeAscii:         /* Nothing to do */         break;      case DmtxSchemeEncodeC40:         PushInputWord(channel, DMTX_CHAR_C40_LATCH);         IncrementProgress(channel, 12);         break;      case DmtxSchemeEncodeText:         PushInputWord(channel, DMTX_CHAR_TEXT_LATCH);         IncrementProgress(channel, 12);         break;      case DmtxSchemeEncodeX12:         PushInputWord(channel, DMTX_CHAR_X12_LATCH);         IncrementProgress(channel, 12);         break;      case DmtxSchemeEncodeEdifact:         PushInputWord(channel, DMTX_CHAR_EDIFACT_LATCH);         IncrementProgress(channel, 12);         break;      case DmtxSchemeEncodeBase256:         PushInputWord(channel, DMTX_CHAR_BASE256_LATCH);         IncrementProgress(channel, 12);         /* Write temporary field length (0 indicates remainder of symbol) */         PushInputWord(channel, Randomize255State(0, 2));         IncrementProgress(channel, 12);         break;      default:         break;   }   channel->encScheme = targetScheme;   channel->firstCodeWord = channel->currentLength - 12;   assert(channel->firstCodeWord % 12 == 0);}/** * @brief  Push codeword onto channel and increment length * @param  channel * @param  codeword * @return void */static voidPushInputWord(DmtxChannel *channel, unsigned char codeword){   int i;   int startByte, pos;   DmtxQuadruplet quad;   /* XXX should this assertion actually be a legit runtime test? */   assert(channel->encodedLength/12 <= 3*1558); /* increased for Mosaic */   /* XXX this is currently pretty ugly, but can wait until the      rewrite. What is required is to go through and decide on a      consistent approach (probably that all encodation schemes use      currentLength except for triplet-based schemes which use      currentLength and encodedLength).  All encodation schemes should      maintain both currentLength and encodedLength though.  Perhaps      another approach would be to maintain currentLength and "extraLength" */   switch(channel->encScheme) {      case DmtxSchemeEncodeAscii:         channel->encodedWords[channel->currentLength/12] = codeword;         channel->encodedLength += 12;         break;      case DmtxSchemeEncodeC40:      case DmtxSchemeEncodeText:      case DmtxSchemeEncodeX12:         channel->encodedWords[channel->encodedLength/12] = codeword;         channel->encodedLength += 12;         break;      case DmtxSchemeEncodeEdifact:         /* EDIFACT is the only encodation scheme where we don't encode up to the            next byte boundary.  This is because EDIFACT can be unlatched at any            point, including mid-byte, so we can't guarantee what the next            codewords will be.  All other encodation schemes only unlatch on byte            boundaries, allowing us to encode to the next boundary knowing that            we have predicted the only codewords that could be used while in this            scheme. */         /* write codeword value to next 6 bits (might span codeword bytes) and            then pad any remaining bits until next byte boundary with zero bits. */         pos = channel->currentLength % 4;         startByte = ((channel->currentLength + 9) / 12) - pos;         quad = GetQuadrupletValues(channel->encodedWords[startByte],                                    channel->encodedWords[startByte+1],                                    channel->encodedWords[startByte+2]);         quad.value[pos] = codeword;         for(i = pos + 1; i < 4; i++)            quad.value[i] = 0;         /* Only write the necessary codewords */         switch(pos) {            case 3:            case 2:               channel->encodedWords[startByte+2] = ((quad.value[2] & 0x03) << 6) | quad.value[3];            case 1:               channel->encodedWords[startByte+1] = ((quad.value[1] & 0x0f) << 4) | (quad.value[2] >> 2);            case 0:               channel->encodedWords[startByte] = (quad.value[0] << 2) | (quad.value[1] >> 4);         }         channel->encodedLength += 9;         break;      case DmtxSchemeEncodeBase256:         channel->encodedWords[channel->currentLength/12] = codeword;         channel->encodedLength += 12;         break;      default:         break;   }}/** * @brief  Push triplet codeword onto channel * @param  channel * @param  triplet * @return void */static voidPushTriplet(DmtxChannel *channel, DmtxTriplet *triplet){   int tripletValue;   tripletValue = (1600 * triplet->value[0]) + (40 * triplet->value[1]) + triplet->value[2] + 1;   PushInputWord(channel, tripletValue / 256);   PushInputWord(channel, tripletValue % 256);}/** * @brief  Increment encoding progress tracking variables * @param  channel * @param  encodedUnits * @return void */static voidIncrementProgress(DmtxChannel *channel, int encodedUnits){   int startByte, pos;   DmtxTriplet triplet;   /* XXX this function became a misnomer when we started incrementing by    * an amount other than what was specified with the C40/Text exception.    * Maybe a new name/convention is in order.    */   /* In C40 and Text encodation schemes while we normally use 5 1/3 bits    * to encode a regular character, we also must account for the extra

⌨️ 快捷键说明

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