DmtxBoolean RsFindErrorLocations(DmtxByteList *loc, const DmtxByteList *elp) { int i, j; int lambda = elp->length - 1; DmtxPassFail passFail; DmtxByte q, regStorage[MAX_ERROR_WORD_COUNT]; DmtxByteList reg = dmtxByteListBuild(regStorage, sizeof(regStorage)); dmtxByteListCopy(®, elp, &passFail); CHKPASS; dmtxByteListInit(loc, 0, 0, &passFail); CHKPASS; for(i = 1; i <= NN; i++) { for(q = 1, j = 1; j <= lambda; j++) { reg.b[j] = GfMultAntilog(reg.b[j], j); q = GfAdd(q, reg.b[j]); } if(q == 0) { dmtxByteListPush(loc, NN - i, &passFail); CHKPASS; } } return (loc->length == lambda) ? DmtxTrue : DmtxFalse; }
static void StreamCopy(DmtxEncodeStream *dst, DmtxEncodeStream *src) { DmtxPassFail passFail; dst->currentScheme = src->currentScheme; dst->inputNext = src->inputNext; dst->outputChainValueCount = src->outputChainValueCount; dst->outputChainWordCount = src->outputChainWordCount; dst->reason = src->reason; dst->sizeIdx = src->sizeIdx; dst->status = src->status; dst->input = src->input; dmtxByteListCopy(dst->output, src->output, &passFail); }
DmtxBoolean RsFindErrorLocatorPoly(DmtxByteList *elpOut, const DmtxByteList *syn, int errorWordCount, int maxCorrectable) { int i, iNext, j; int m, mCmp, lambda; DmtxByte disTmp, disStorage[MAX_ERROR_WORD_COUNT+1]; DmtxByte elpStorage[MAX_ERROR_WORD_COUNT+2][MAX_ERROR_WORD_COUNT]; DmtxByteList dis, elp[MAX_ERROR_WORD_COUNT+2]; DmtxPassFail passFail; dis = dmtxByteListBuild(disStorage, sizeof(disStorage)); dmtxByteListInit(&dis, 0, 0, &passFail); CHKPASS; for(i = 0; i < MAX_ERROR_WORD_COUNT + 2; i++) { elp[i] = dmtxByteListBuild(elpStorage[i], sizeof(elpStorage[i])); dmtxByteListInit(&elp[i], 0, 0, &passFail); CHKPASS; } /* iNext = 0 */ dmtxByteListPush(&elp[0], 1, &passFail); CHKPASS; dmtxByteListPush(&dis, 1, &passFail); CHKPASS; /* iNext = 1 */ dmtxByteListPush(&elp[1], 1, &passFail); CHKPASS; dmtxByteListPush(&dis, syn->b[1], &passFail); CHKPASS; for(iNext = 2, i = 1; /* explicit break */; i = iNext++) { if(dis.b[i] == 0) { /* Simple case: Copy directly from previous iteration */ dmtxByteListCopy(&elp[iNext], &elp[i], &passFail); CHKPASS; } else { /* Find earlier iteration (m) that provides maximal (m - lambda) */ for(m = 0, mCmp = 1; mCmp < i; mCmp++) if(dis.b[mCmp] != 0 && (mCmp - elp[mCmp].length) >= (m - elp[m].length)) m = mCmp; /* Calculate error location polynomial elp[i] (set 1st term) */ for(lambda = elp[m].length - 1, j = 0; j <= lambda; j++) elp[iNext].b[j+i-m] = antilog301[(NN - log301[dis.b[m]] + log301[dis.b[i]] + log301[elp[m].b[j]]) % NN]; /* Calculate error location polynomial elp[i] (add 2nd term) */ for(lambda = elp[i].length - 1, j = 0; j <= lambda; j++) elp[iNext].b[j] = GfAdd(elp[iNext].b[j], elp[i].b[j]); elp[iNext].length = max(elp[i].length, elp[m].length + i - m); } lambda = elp[iNext].length - 1; if(i == errorWordCount || i >= lambda + maxCorrectable) break; /* Calculate discrepancy dis.b[i] */ for(disTmp = syn->b[iNext], j = 1; j <= lambda; j++) disTmp = GfAdd(disTmp, GfMult(syn->b[iNext-j], elp[iNext].b[j])); assert(dis.length == iNext); dmtxByteListPush(&dis, disTmp, &passFail); CHKPASS; } dmtxByteListCopy(elpOut, &elp[iNext], &passFail); CHKPASS; return (lambda <= maxCorrectable) ? DmtxTrue : DmtxFalse; }
static int EncodeOptimizeBest(DmtxByteList *input, DmtxByteList *output, int sizeIdxRequest, int fnc1) { enum SchemeState state; int inputNext, c40ValueCount, textValueCount, x12ValueCount; int sizeIdx; DmtxEncodeStream *winner; DmtxPassFail passFail; DmtxEncodeStream streamsBest[SchemeStateCount]; DmtxEncodeStream streamsTemp[SchemeStateCount]; DmtxByte outputsBestStorage[SchemeStateCount][4096]; DmtxByte outputsTempStorage[SchemeStateCount][4096]; DmtxByte ctxTempStorage[4]; DmtxByteList outputsBest[SchemeStateCount]; DmtxByteList outputsTemp[SchemeStateCount]; DmtxByteList ctxTemp = dmtxByteListBuild(ctxTempStorage, sizeof(ctxTempStorage)); /* Initialize all streams with their own output storage */ for(state = 0; state < SchemeStateCount; state++) { outputsBest[state] = dmtxByteListBuild(outputsBestStorage[state], sizeof(outputsBestStorage[state])); outputsTemp[state] = dmtxByteListBuild(outputsTempStorage[state], sizeof(outputsTempStorage[state])); streamsBest[state] = StreamInit(input, &(outputsBest[state])); streamsTemp[state] = StreamInit(input, &(outputsTemp[state])); streamsBest[state].fnc1 = fnc1; streamsTemp[state].fnc1 = fnc1; } c40ValueCount = textValueCount = x12ValueCount = 0; for(inputNext = 0; inputNext < input->length; inputNext++) { StreamAdvanceFromBest(streamsTemp, streamsBest, AsciiFull, sizeIdxRequest); AdvanceAsciiCompact(streamsTemp, streamsBest, AsciiCompactOffset0, inputNext, sizeIdxRequest); AdvanceAsciiCompact(streamsTemp, streamsBest, AsciiCompactOffset1, inputNext, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, C40Offset0, inputNext, c40ValueCount, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, C40Offset1, inputNext, c40ValueCount, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, C40Offset2, inputNext, c40ValueCount, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, TextOffset0, inputNext, textValueCount, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, TextOffset1, inputNext, textValueCount, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, TextOffset2, inputNext, textValueCount, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, X12Offset0, inputNext, x12ValueCount, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, X12Offset1, inputNext, x12ValueCount, sizeIdxRequest); AdvanceCTX(streamsTemp, streamsBest, X12Offset2, inputNext, x12ValueCount, sizeIdxRequest); AdvanceEdifact(streamsTemp, streamsBest, EdifactOffset0, inputNext, sizeIdxRequest); AdvanceEdifact(streamsTemp, streamsBest, EdifactOffset1, inputNext, sizeIdxRequest); AdvanceEdifact(streamsTemp, streamsBest, EdifactOffset2, inputNext, sizeIdxRequest); AdvanceEdifact(streamsTemp, streamsBest, EdifactOffset3, inputNext, sizeIdxRequest); StreamAdvanceFromBest(streamsTemp, streamsBest, Base256, sizeIdxRequest); /* Overwrite best streams with new results */ for(state = 0; state < SchemeStateCount; state++) { if(streamsBest[state].status != DmtxStatusComplete) StreamCopy(&(streamsBest[state]), &(streamsTemp[state])); } dmtxByteListClear(&ctxTemp); PushCTXValues(&ctxTemp, input->b[inputNext], DmtxSchemeC40, &passFail, fnc1); c40ValueCount += ((passFail == DmtxPass) ? ctxTemp.length : 1); dmtxByteListClear(&ctxTemp); PushCTXValues(&ctxTemp, input->b[inputNext], DmtxSchemeText, &passFail, fnc1); textValueCount += ((passFail == DmtxPass) ? ctxTemp.length : 1); dmtxByteListClear(&ctxTemp); PushCTXValues(&ctxTemp, input->b[inputNext], DmtxSchemeX12, &passFail, fnc1); x12ValueCount += ((passFail == DmtxPass) ? ctxTemp.length : 1); #if DUMPSTREAMS DumpStreams(streamsBest); #endif } /* Choose the overall winner */ winner = NULL; for(state = 0; state < SchemeStateCount; state++) { if(streamsBest[state].status == DmtxStatusComplete) { if(winner == NULL || streamsBest[state].output->length < winner->output->length) winner = &(streamsBest[state]); } } /* Copy winner to output */ if(winner == NULL) { sizeIdx = DmtxUndefined; } else { dmtxByteListCopy(output, winner->output, &passFail); sizeIdx = (passFail == DmtxPass) ? winner->sizeIdx : DmtxUndefined; } return sizeIdx; }