/** * pop off newest/last * used for edifact */ static DmtxByte StreamOutputChainRemoveLast(DmtxEncodeStream *stream) { DmtxByte value; DmtxPassFail passFail; if(stream->outputChainWordCount > 0) { value = dmtxByteListPop(stream->output, &passFail); stream->outputChainWordCount--; } else { value = 0; StreamMarkFatal(stream, DmtxErrorEmptyList); } return value; }
/** * remove first element from chain, shifting all following elements back by one * used for binary length changes end condition */ static void Base256OutputChainRemoveFirst(DmtxEncodeStream *stream) { DmtxByte value; DmtxPassFail passFail; int i, chainStart; chainStart = stream->output->length - stream->outputChainWordCount; for(i = chainStart; i < stream->output->length - 1; i++) { value = UnRandomize255State(stream->output->b[i+1], i+2); stream->output->b[i] = Randomize255State(value, i + 1); } dmtxByteListPop(stream->output, &passFail); if(passFail == DmtxPass) stream->outputChainWordCount--; else StreamMarkFatal(stream, DmtxErrorUnknown); }
static void ShiftValueListBy3(DmtxByteList *list, DmtxPassFail *passFail) { int i; /* Shift values */ for(i = 0; i < list->length - 3; i++) list->b[i] = list->b[i+3]; /* Shorten list by 3 (or less) */ for(i = 0; i < 3; i++) { dmtxByteListPop(list, passFail); if(*passFail == DmtxFail) return; if(list->length == 0) break; } *passFail = DmtxPass; }
DmtxPassFail RsDecode(unsigned char *code, int sizeIdx, int fix) { int i; int blockStride, blockIdx; int blockDataWords, blockErrorWords, blockTotalWords, blockMaxCorrectable; int symbolDataWords, symbolErrorWords, symbolTotalWords; DmtxBoolean error, repairable; DmtxPassFail passFail; unsigned char *word; DmtxByte elpStorage[MAX_ERROR_WORD_COUNT]; DmtxByte synStorage[MAX_ERROR_WORD_COUNT+1]; DmtxByte recStorage[NN]; DmtxByte locStorage[NN]; DmtxByteList elp = dmtxByteListBuild(elpStorage, sizeof(elpStorage)); DmtxByteList syn = dmtxByteListBuild(synStorage, sizeof(synStorage)); DmtxByteList rec = dmtxByteListBuild(recStorage, sizeof(recStorage)); DmtxByteList loc = dmtxByteListBuild(locStorage, sizeof(locStorage)); blockStride = dmtxGetSymbolAttribute(DmtxSymAttribInterleavedBlocks, sizeIdx); blockErrorWords = dmtxGetSymbolAttribute(DmtxSymAttribBlockErrorWords, sizeIdx); blockMaxCorrectable = dmtxGetSymbolAttribute(DmtxSymAttribBlockMaxCorrectable, sizeIdx); symbolDataWords = dmtxGetSymbolAttribute(DmtxSymAttribSymbolDataWords, sizeIdx); symbolErrorWords = dmtxGetSymbolAttribute(DmtxSymAttribSymbolErrorWords, sizeIdx); symbolTotalWords = symbolDataWords + symbolErrorWords; /* For each interleaved block */ for(blockIdx = 0; blockIdx < blockStride; blockIdx++) { /* Data word count depends on blockIdx due to special case at 144x144 */ blockDataWords = dmtxGetBlockDataSize(sizeIdx, blockIdx); blockTotalWords = blockErrorWords + blockDataWords; /* Populate received list (rec) with data and error codewords */ dmtxByteListInit(&rec, 0, 0, &passFail); CHKPASS; /* Start with final error word and work backward */ word = code + symbolTotalWords + blockIdx - blockStride; for(i = 0; i < blockErrorWords; i++) { dmtxByteListPush(&rec, *word, &passFail); CHKPASS; word -= blockStride; } /* Start with final data word and work backward */ word = code + blockIdx + (blockStride * (blockDataWords - 1)); for(i = 0; i < blockDataWords; i++) { dmtxByteListPush(&rec, *word, &passFail); CHKPASS; word -= blockStride; } /* Compute syndromes (syn) */ error = RsComputeSyndromes(&syn, &rec, blockErrorWords); /* Error(s) detected: Attempt repair */ if(error) { /* Find error locator polynomial (elp) */ repairable = RsFindErrorLocatorPoly(&elp, &syn, blockErrorWords, blockMaxCorrectable); if(!repairable) return DmtxFail; /* Find error positions (loc) */ repairable = RsFindErrorLocations(&loc, &elp); if(!repairable) return DmtxFail; /* Find error values and repair */ RsRepairErrors(&rec, &loc, &elp, &syn); } /* * Overwrite output with correct/corrected values */ /* Start with first data word and work forward */ word = code + blockIdx; for(i = 0; i < blockDataWords; i++) { *word = dmtxByteListPop(&rec, &passFail); CHKPASS; word += blockStride; } /* Start with first error word and work forward */ word = code + symbolDataWords + blockIdx; for(i = 0; i < blockErrorWords; i++) { *word = dmtxByteListPop(&rec, &passFail); CHKPASS; word += blockStride; } } return DmtxPass; }