int Code128Reader::decodeCode(Ref<BitArray> row, int counters[], int countersCount, int rowOffset) { if (!recordPattern(row, rowOffset, counters, countersCount)) { throw ReaderException(""); } unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept int bestMatch = -1; for (int d = 0; d < CODE_PATTERNS_LENGTH; d++) { int pattern[countersLength]; for(int ind = 0; ind< countersLength; ind++){ pattern[ind] = CODE_PATTERNS[d][ind]; } // memcpy(pattern, CODE_PATTERNS[d], countersLength); unsigned int variance = patternMatchVariance(counters, countersCount, pattern, MAX_INDIVIDUAL_VARIANCE); if (variance < bestVariance) { bestVariance = variance; bestMatch = d; } } // TODO We're overlooking the fact that the STOP pattern has 7 values, not 6. if (bestMatch >= 0) { return bestMatch; } else { throw ReaderException(""); } }
// int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, int** patterns/*[][]*/, int paterns1Len, int paterns2Len) int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, UPC_EAN_PATTERNS patternType){ recordPattern(row, rowOffset, counters, countersLen); unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept int bestMatch = -1; int max = 0; switch (patternType) { case UPC_EAN_PATTERNS_L_PATTERNS: max = L_PATTERNS_LEN; for (int i = 0; i < max; i++) { int pattern[countersLen]; for(int j = 0; j< countersLen; j++){ pattern[j] = L_PATTERNS[i][j]; } unsigned int variance = patternMatchVariance(counters, countersLen, pattern, MAX_INDIVIDUAL_VARIANCE); if (variance < bestVariance) { bestVariance = variance; bestMatch = i; } } break; case UPC_EAN_PATTERNS_L_AND_G_PATTERNS: max = L_AND_G_PATTERNS_LEN; for (int i = 0; i < max; i++) { int pattern[countersLen]; for(int j = 0; j< countersLen; j++){ pattern[j] = L_AND_G_PATTERNS[i][j]; } unsigned int variance = patternMatchVariance(counters, countersLen, pattern, MAX_INDIVIDUAL_VARIANCE); if (variance < bestVariance) { bestVariance = variance; bestMatch = i; } } break; default: break; } if (bestMatch >= 0) { return bestMatch; } else { throw ReaderException("UPCEANReader::decodeDigit: No best mach"); } }
Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) { int* start = NULL; try { start = findAsteriskPattern(row); int nextStart = start[1]; int end = row->getSize(); // Read off white space while (nextStart < end && !row->get(nextStart)) { nextStart++; } std::string tmpResultString; const int countersLen = 9; int counters[countersLen]; for (int i = 0; i < countersLen; i++) { counters[i] = 0; } char decodedChar; int lastStart; do { if (!recordPattern(row, nextStart, counters, countersLen)) { throw ReaderException(""); } int pattern = toNarrowWidePattern(counters, countersLen); if (pattern < 0) { throw ReaderException("pattern < 0"); } decodedChar = patternToChar(pattern); tmpResultString.append(1, decodedChar); lastStart = nextStart; for (int i = 0; i < countersLen; i++) { nextStart += counters[i]; } // Read off white space while (nextStart < end && !row->get(nextStart)) { nextStart++; } } while (decodedChar != '*'); tmpResultString.erase(tmpResultString.length()-1, 1);// remove asterisk // Look for whitespace after pattern: int lastPatternSize = 0; for (int i = 0; i < countersLen; i++) { lastPatternSize += counters[i]; } int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize; // If 50% of last pattern size, following last pattern, is not whitespace, // fail (but if it's whitespace to the very end of the image, that's OK) if (nextStart != end && whiteSpaceAfterEnd / 2 < lastPatternSize) { throw ReaderException("too short end white space"); } if (usingCheckDigit) { int max = tmpResultString.length() - 1; unsigned int total = 0; for (int i = 0; i < max; i++) { total += alphabet_string.find_first_of(tmpResultString[i], 0); } if (total % 43 != alphabet_string.find_first_of(tmpResultString[max], 0)) { throw ReaderException(""); } tmpResultString.erase(max, 1); } Ref<String> resultString(new String(tmpResultString)); if (extendedMode) { resultString = decodeExtended(tmpResultString); } if (tmpResultString.length() == 0) { // Almost surely a false positive throw ReaderException(""); } float left = (float) (start[1] + start[0]) / 2.0f; float right = (float) (nextStart + lastStart) / 2.0f; std::vector< Ref<ResultPoint> > resultPoints(2); Ref<OneDResultPoint> resultPoint1( new OneDResultPoint(left, (float) rowNumber)); Ref<OneDResultPoint> resultPoint2( new OneDResultPoint(right, (float) rowNumber)); resultPoints[0] = resultPoint1; resultPoints[1] = resultPoint2; ArrayRef<unsigned char> resultBytes(1); Ref<Result> res(new Result( resultString, resultBytes, resultPoints, BarcodeFormat_CODE_39)); delete [] start; return res; } catch (ReaderException const& re) { delete [] start; return Ref<Result>(); } }