Example #1
0
static BitArray::Range
FindFinderPattern(const BitArray& row, bool rightFinderPattern, FinderCounters& counters)
{
	return RowReader::FindPattern(
	    // Will encounter white first when searching for right finder pattern
	    row.getNextSetTo(row.begin(), !rightFinderPattern), row.end(), counters,
	    [](BitArray::Iterator, BitArray::Iterator, const FinderCounters& counters) {
		    return RSS::ReaderHelper::IsFinderPattern(counters);
	    });
}
Example #2
0
static RSS::DataCharacter
DecodeDataCharacter(const BitArray& row, const RSS::FinderPattern& pattern, bool outsideChar)
{
	std::array<int, 8> counters = {};

	if (outsideChar) {
		if (!RowReader::RecordPatternInReverse(row.begin(), row.iterAt(pattern.startPos()), counters))
			return {};
	}
	else {
		if (!RowReader::RecordPattern(row.iterAt(pattern.endPos() + 1), row.end(), counters))
			return {};
		std::reverse(counters.begin(), counters.end());
	}

	int numModules = outsideChar ? 16 : 15;
	float elementWidth = static_cast<float>(std::accumulate(counters.begin(), counters.end(), 0)) / static_cast<float>(numModules);

	std::array<int, 4> oddCounts;
	std::array<int, 4> evenCounts;
	std::array<float, 4> oddRoundingErrors;
	std::array<float, 4> evenRoundingErrors;

	for (int i = 0; i < 8; i++) {
		float value = (float)counters[i] / elementWidth;
		int count = (int)(value + 0.5f); // Round
		if (count < 1) {
			count = 1;
		}
		else if (count > 8) {
			count = 8;
		}
		int offset = i / 2;
		if ((i & 0x01) == 0) {
			oddCounts[offset] = count;
			oddRoundingErrors[offset] = value - count;
		}
		else {
			evenCounts[offset] = count;
			evenRoundingErrors[offset] = value - count;
		}
	}

	if (!AdjustOddEvenCounts(outsideChar, numModules, oddCounts, evenCounts, oddRoundingErrors, evenRoundingErrors)) {
		return {};
	}

	int oddSum = 0;
	int oddChecksumPortion = 0;
	for (auto it = oddCounts.rbegin(); it != oddCounts.rend(); ++it) {
		oddChecksumPortion *= 9;
		oddChecksumPortion += *it;
		oddSum += *it;
	}
	int evenChecksumPortion = 0;
	int evenSum = 0;
	for (auto it = evenCounts.rbegin(); it != evenCounts.rend(); ++it) {
		evenChecksumPortion *= 9;
		evenChecksumPortion += *it;
		evenSum += *it;
	}
	int checksumPortion = oddChecksumPortion + 3 * evenChecksumPortion;

	if (outsideChar) {
		if ((oddSum & 0x01) != 0 || oddSum > 12 || oddSum < 4) {
			return {};
		}
		int group = (12 - oddSum) / 2;
		int oddWidest = OUTSIDE_ODD_WIDEST[group];
		int evenWidest = 9 - oddWidest;
		int vOdd = RSS::ReaderHelper::GetRSSvalue(oddCounts, oddWidest, false);
		int vEven = RSS::ReaderHelper::GetRSSvalue(evenCounts, evenWidest, true);
		int tEven = OUTSIDE_EVEN_TOTAL_SUBSET[group];
		int gSum = OUTSIDE_GSUM[group];
		return {vOdd * tEven + vEven + gSum, checksumPortion};
	}
	else {
		if ((evenSum & 0x01) != 0 || evenSum > 10 || evenSum < 4) {
			return {};
		}
		int group = (10 - evenSum) / 2;
		int oddWidest = INSIDE_ODD_WIDEST[group];
		int evenWidest = 9 - oddWidest;
		int vOdd = RSS::ReaderHelper::GetRSSvalue(oddCounts, oddWidest, true);
		int vEven = RSS::ReaderHelper::GetRSSvalue(evenCounts, evenWidest, false);
		int tOdd = INSIDE_ODD_TOTAL_SUBSET[group];
		int gSum = INSIDE_GSUM[group];
		return {vEven * tOdd + vOdd + gSum, checksumPortion};
	}

}