123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- /*
- * Copyright 2013 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #import "ZXPDF417CodewordDecoder.h"
- #import "ZXPDF417Common.h"
-
- static float ZX_PDF417_RATIOS_TABLE[ZX_PDF417_SYMBOL_TABLE_LEN][ZX_PDF417_BARS_IN_MODULE];
-
- @implementation ZXPDF417CodewordDecoder
-
- + (void)initialize {
- if ([self class] != [ZXPDF417CodewordDecoder class]) return;
-
- // Pre-computes the symbol ratio table.
- for (int i = 0; i < ZX_PDF417_SYMBOL_TABLE_LEN; i++) {
- int currentSymbol = ZX_PDF417_SYMBOL_TABLE[i];
- int currentBit = currentSymbol & 0x1;
- for (int j = 0; j < ZX_PDF417_BARS_IN_MODULE; j++) {
- float size = 0.0f;
- while ((currentSymbol & 0x1) == currentBit) {
- size += 1.0f;
- currentSymbol >>= 1;
- }
- currentBit = currentSymbol & 0x1;
- ZX_PDF417_RATIOS_TABLE[i][ZX_PDF417_BARS_IN_MODULE - j - 1] = size / ZX_PDF417_MODULES_IN_CODEWORD;
- }
- }
- }
-
- + (int)decodedValue:(NSArray *)moduleBitCount {
- int decodedValue = [self decodedCodewordValue:[self sampleBitCounts:moduleBitCount]];
- if (decodedValue != -1) {
- return decodedValue;
- }
- return [self closestDecodedValue:moduleBitCount];
- }
-
- + (NSArray *)sampleBitCounts:(NSArray *)moduleBitCount {
- float bitCountSum = [ZXPDF417Common bitCountSum:moduleBitCount];
- NSMutableArray *result = [NSMutableArray arrayWithCapacity:ZX_PDF417_BARS_IN_MODULE];
- for (int i = 0; i < ZX_PDF417_BARS_IN_MODULE; i++) {
- [result addObject:@0];
- }
-
- int bitCountIndex = 0;
- int sumPreviousBits = 0;
- for (int i = 0; i < ZX_PDF417_MODULES_IN_CODEWORD; i++) {
- float sampleIndex =
- bitCountSum / (2 * ZX_PDF417_MODULES_IN_CODEWORD) +
- (i * bitCountSum) / ZX_PDF417_MODULES_IN_CODEWORD;
- if (sumPreviousBits + [moduleBitCount[bitCountIndex] intValue] <= sampleIndex) {
- sumPreviousBits += [moduleBitCount[bitCountIndex] intValue];
- bitCountIndex++;
- }
- result[bitCountIndex] = @([result[bitCountIndex] intValue] + 1);
- }
- return result;
- }
-
- + (int)decodedCodewordValue:(NSArray *)moduleBitCount {
- int decodedValue = [self bitValue:moduleBitCount];
- return [ZXPDF417Common codeword:decodedValue] == -1 ? -1 : decodedValue;
- }
-
- + (int)bitValue:(NSArray *)moduleBitCount {
- long result = 0;
- for (int i = 0; i < [moduleBitCount count]; i++) {
- for (int bit = 0; bit < [moduleBitCount[i] intValue]; bit++) {
- result = (result << 1) | (i % 2 == 0 ? 1 : 0);
- }
- }
- return (int) result;
- }
-
- + (int)closestDecodedValue:(NSArray *)moduleBitCount {
- int bitCountSum = [ZXPDF417Common bitCountSum:moduleBitCount];
- float bitCountRatios[ZX_PDF417_BARS_IN_MODULE];
- for (int i = 0; i < ZX_PDF417_BARS_IN_MODULE; i++) {
- bitCountRatios[i] = [moduleBitCount[i] intValue] / (float) bitCountSum;
- }
- float bestMatchError = MAXFLOAT;
- int bestMatch = -1;
- for (int j = 0; j < ZX_PDF417_SYMBOL_TABLE_LEN; j++) {
- float error = 0.0f;
- float *ratioTableRow = ZX_PDF417_RATIOS_TABLE[j];
- for (int k = 0; k < ZX_PDF417_BARS_IN_MODULE; k++) {
- float diff = ratioTableRow[k] - bitCountRatios[k];
- error += diff * diff;
- if (error >= bestMatchError) {
- break;
- }
- }
- if (error < bestMatchError) {
- bestMatchError = error;
- bestMatch = ZX_PDF417_SYMBOL_TABLE[j];
- }
- }
- return bestMatch;
- }
-
- @end
|