rxing/pdf417/decoder/
pdf_417_codeword_decoder.rs1use crate::pdf417::pdf_417_common;
18
19static RATIOS_TABLE: [[f32; pdf_417_common::BARS_IN_MODULE as usize]; 2787] = {
25 let mut table =
26 [[0.0; pdf_417_common::BARS_IN_MODULE as usize]; pdf_417_common::SYMBOL_TABLE.len()];
27 let mut i = 0_usize;
29 while i < pdf_417_common::SYMBOL_TABLE.len() {
30 let mut currentSymbol = pdf_417_common::SYMBOL_TABLE[i];
32 let mut currentBit = currentSymbol & 0x1;
33 let mut j = 0_usize;
34 while j < pdf_417_common::BARS_IN_MODULE as usize {
35 let mut size = 0.0;
37 while (currentSymbol & 0x1) == currentBit {
38 size += 1.0;
39 currentSymbol >>= 1;
40 }
41 currentBit = currentSymbol & 0x1;
42 table[i][pdf_417_common::BARS_IN_MODULE as usize - j - 1] =
43 size / pdf_417_common::MODULES_IN_CODEWORD as f32;
44
45 j += 1;
46 }
47
48 i += 1;
49 }
50
51 table
52};
53
54pub fn getDecodedValue(moduleBitCount: &[u32]) -> u32 {
55 let decodedValue = getDecodedCodewordValue(&sampleBitCounts(moduleBitCount));
56 if decodedValue != -1 {
57 return decodedValue as u32;
58 }
59 getClosestDecodedValue(moduleBitCount) as u32
60}
61
62fn sampleBitCounts(moduleBitCount: &[u32]) -> [u32; 8] {
63 let bitCountSum: u32 = moduleBitCount.iter().sum(); let mut result = [0; pdf_417_common::BARS_IN_MODULE as usize];
65 let mut bitCountIndex = 0;
66 let mut sumPreviousBits = 0;
67 for i in 0..pdf_417_common::MODULES_IN_CODEWORD {
68 let sampleIndex: f32 = bitCountSum as f32
70 / (2.0 * pdf_417_common::MODULES_IN_CODEWORD as f32)
71 + (i as f32 * bitCountSum as f32) / pdf_417_common::MODULES_IN_CODEWORD as f32;
72 if sumPreviousBits as f32 + moduleBitCount[bitCountIndex] as f32 <= sampleIndex {
73 sumPreviousBits += moduleBitCount[bitCountIndex];
74 bitCountIndex += 1;
75 }
76 result[bitCountIndex] += 1;
77 }
78 result
79}
80
81fn getDecodedCodewordValue(moduleBitCount: &[u32]) -> i32 {
82 let decodedValue = getBitValue(moduleBitCount);
83 if pdf_417_common::getCodeword(decodedValue as u32) == -1 {
84 -1
85 } else {
86 decodedValue
87 }
88}
89
90fn getBitValue(moduleBitCount: &[u32]) -> i32 {
91 let mut result: u64 = 0;
92 for (i, mbc) in moduleBitCount.iter().enumerate() {
93 for _bit in 0..(*mbc) {
95 result = (result << 1) | u64::from(i % 2 == 0); }
98 }
99 result as i32
100}
101
102fn getClosestDecodedValue(moduleBitCount: &[u32]) -> i32 {
103 let bitCountSum: u32 = moduleBitCount.iter().sum(); let mut bitCountRatios = [0.0; pdf_417_common::BARS_IN_MODULE as usize];
105 if bitCountSum > 1 {
106 for i in 0..bitCountRatios.len() {
107 bitCountRatios[i] = moduleBitCount[i] as f32 / bitCountSum as f32;
109 }
110 }
111 let mut bestMatchError = f32::MAX;
112 let mut bestMatch = -1_i32;
113 for (j, ratioTableRow) in RATIOS_TABLE.iter().enumerate() {
114 let mut error = 0.0;
116 for k in 0..pdf_417_common::BARS_IN_MODULE as usize {
117 let diff = ratioTableRow[k] - bitCountRatios[k];
119 error += diff * diff;
120 if error >= bestMatchError {
121 break;
122 }
123 }
124 if error < bestMatchError {
125 bestMatchError = error;
126 bestMatch = pdf_417_common::SYMBOL_TABLE[j] as i32;
127 }
128 }
129 bestMatch
130}
131
132#[cfg(test)]
133mod test {
134 use crate::pdf417::decoder::pdf_417_codeword_decoder::getDecodedValue;
135
136 #[test]
137 fn test_cw_227() {
138 let sample_data = [2, 2, 3, 1, 6, 4, 3, 4];
139 assert_ne!(getDecodedValue(&sample_data), 110360);
140 assert_eq!(getDecodedValue(&sample_data), 93980);
141 }
142
143 #[test]
144 fn test_2() {
145 let sample = [2, 1, 4, 2, 5, 3, 7, 2];
146 assert_ne!(95134, getDecodedValue(&sample));
147 }
148
149 #[test]
150 fn test_128268() {
151 let sample = [7, 2, 1, 2, 2, 5, 3, 3];
152 assert_eq!(128268, getDecodedValue(&sample));
153 }
154
155 #[test]
156 fn test_125304() {
157 let sample = [6, 1, 2, 2, 2, 2, 6, 4];
158 assert_eq!(125304, getDecodedValue(&sample));
159 }
160
161 #[test]
162 fn test_125216() {
163 let sample = [6, 1, 2, 2, 2, 3, 2, 7];
164 assert_eq!(125216, getDecodedValue(&sample));
165 }
166
167 #[test]
168 fn test_83768() {
169 let sample = [1, 2, 1, 4, 5, 3, 5, 4];
170 assert_eq!(83768, getDecodedValue(&sample));
171 }
172
173 #[test]
174 fn test_96060() {
175 let sample = [2, 1, 4, 2, 5, 3, 7, 2];
176 assert_eq!(96060, getDecodedValue(&sample));
177 }
178
179 #[test]
180 fn test_97372() {
181 let sample = [3, 1, 7, 4, 2, 2, 4, 2];
182 assert_eq!(97372, getDecodedValue(&sample));
183 }
184}