您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ZXAbstractRSSReader.m 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright 2012 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "ZXAbstractRSSReader.h"
  17. #import "ZXIntArray.h"
  18. static float ZX_RSS_MAX_AVG_VARIANCE = 0.2f;
  19. static float ZX_RSS_MAX_INDIVIDUAL_VARIANCE = 0.45f;
  20. float const ZX_RSS_MIN_FINDER_PATTERN_RATIO = 9.5f / 12.0f;
  21. float const ZX_RSS_MAX_FINDER_PATTERN_RATIO = 12.5f / 14.0f;
  22. #define ZX_RSS14_FINDER_PATTERNS_LEN 9
  23. #define ZX_RSS14_FINDER_PATTERNS_SUB_LEN 4
  24. const int ZX_RSS14_FINDER_PATTERNS[ZX_RSS14_FINDER_PATTERNS_LEN][ZX_RSS14_FINDER_PATTERNS_SUB_LEN] = {
  25. {3,8,2,1},
  26. {3,5,5,1},
  27. {3,3,7,1},
  28. {3,1,9,1},
  29. {2,7,4,1},
  30. {2,5,6,1},
  31. {2,3,8,1},
  32. {1,5,7,1},
  33. {1,3,9,1},
  34. };
  35. #define ZX_RSS_EXPANDED_FINDER_PATTERNS_LEN 6
  36. #define ZX_RSS_EXPANDED_FINDER_PATTERNS_SUB_LEN 4
  37. const int ZX_RSS_EXPANDED_FINDER_PATTERNS[ZX_RSS_EXPANDED_FINDER_PATTERNS_LEN][ZX_RSS_EXPANDED_FINDER_PATTERNS_SUB_LEN] = {
  38. {1,8,4,1}, // A
  39. {3,6,4,1}, // B
  40. {3,4,6,1}, // C
  41. {3,2,8,1}, // D
  42. {2,6,5,1}, // E
  43. {2,2,9,1} // F
  44. };
  45. @implementation ZXAbstractRSSReader
  46. - (id)init {
  47. if (self = [super init]) {
  48. _decodeFinderCounters = [[ZXIntArray alloc] initWithLength:4];
  49. _dataCharacterCounters = [[ZXIntArray alloc] initWithLength:8];
  50. _oddRoundingErrorsLen = 4;
  51. _oddRoundingErrors = (float *)malloc(_oddRoundingErrorsLen * sizeof(float));
  52. memset(_oddRoundingErrors, 0, _oddRoundingErrorsLen * sizeof(float));
  53. _evenRoundingErrorsLen = 4;
  54. _evenRoundingErrors = (float *)malloc(_evenRoundingErrorsLen * sizeof(float));
  55. memset(_evenRoundingErrors, 0, _evenRoundingErrorsLen * sizeof(float));
  56. _oddCounts = [[ZXIntArray alloc] initWithLength:_dataCharacterCounters.length / 2];
  57. _evenCounts = [[ZXIntArray alloc] initWithLength:_dataCharacterCounters.length / 2];
  58. }
  59. return self;
  60. }
  61. - (void)dealloc {
  62. if (_oddRoundingErrors != NULL) {
  63. free(_oddRoundingErrors);
  64. _oddRoundingErrors = NULL;
  65. }
  66. if (_evenRoundingErrors != NULL) {
  67. free(_evenRoundingErrors);
  68. _evenRoundingErrors = NULL;
  69. }
  70. }
  71. + (int)parseFinderValue:(ZXIntArray *)counters finderPatternType:(ZX_RSS_PATTERNS)finderPatternType {
  72. switch (finderPatternType) {
  73. case ZX_RSS_PATTERNS_RSS14_PATTERNS:
  74. for (int value = 0; value < ZX_RSS14_FINDER_PATTERNS_LEN; value++) {
  75. if ([self patternMatchVariance:counters pattern:ZX_RSS14_FINDER_PATTERNS[value] maxIndividualVariance:ZX_RSS_MAX_INDIVIDUAL_VARIANCE] < ZX_RSS_MAX_AVG_VARIANCE) {
  76. return value;
  77. }
  78. }
  79. break;
  80. case ZX_RSS_PATTERNS_RSS_EXPANDED_PATTERNS:
  81. for (int value = 0; value < ZX_RSS_EXPANDED_FINDER_PATTERNS_LEN; value++) {
  82. if ([self patternMatchVariance:counters pattern:ZX_RSS_EXPANDED_FINDER_PATTERNS[value] maxIndividualVariance:ZX_RSS_MAX_INDIVIDUAL_VARIANCE] < ZX_RSS_MAX_AVG_VARIANCE) {
  83. return value;
  84. }
  85. }
  86. break;
  87. default:
  88. break;
  89. }
  90. return -1;
  91. }
  92. + (int)count:(ZXIntArray *)array {
  93. return [array sum];
  94. }
  95. + (void)increment:(ZXIntArray *)array errors:(float *)errors {
  96. int index = 0;
  97. float biggestError = errors[0];
  98. for (int i = 1; i < array.length; i++) {
  99. if (errors[i] > biggestError) {
  100. biggestError = errors[i];
  101. index = i;
  102. }
  103. }
  104. array.array[index]++;
  105. }
  106. + (void)decrement:(ZXIntArray *)array errors:(float *)errors {
  107. int index = 0;
  108. float biggestError = errors[0];
  109. for (int i = 1; i < array.length; i++) {
  110. if (errors[i] < biggestError) {
  111. biggestError = errors[i];
  112. index = i;
  113. }
  114. }
  115. array.array[index]--;
  116. }
  117. + (BOOL)isFinderPattern:(ZXIntArray *)counters {
  118. int32_t *array = counters.array;
  119. int firstTwoSum = array[0] + array[1];
  120. int sum = firstTwoSum + array[2] + array[3];
  121. float ratio = (float)firstTwoSum / (float)sum;
  122. if (ratio >= ZX_RSS_MIN_FINDER_PATTERN_RATIO && ratio <= ZX_RSS_MAX_FINDER_PATTERN_RATIO) {
  123. int minCounter = INT_MAX;
  124. int maxCounter = INT_MIN;
  125. for (int i = 0; i < counters.length; i++) {
  126. int counter = array[i];
  127. if (counter > maxCounter) {
  128. maxCounter = counter;
  129. }
  130. if (counter < minCounter) {
  131. minCounter = counter;
  132. }
  133. }
  134. return maxCounter < 10 * minCounter;
  135. }
  136. return NO;
  137. }
  138. @end