OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 // Original code is licensed as follows: | |
7 /* | |
8 * Copyright 2008 ZXing authors | |
9 * | |
10 * Licensed under the Apache License, Version 2.0 (the "License"); | |
11 * you may not use this file except in compliance with the License. | |
12 * You may obtain a copy of the License at | |
13 * | |
14 * http://www.apache.org/licenses/LICENSE-2.0 | |
15 * | |
16 * Unless required by applicable law or agreed to in writing, software | |
17 * distributed under the License is distributed on an "AS IS" BASIS, | |
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
19 * See the License for the specific language governing permissions and | |
20 * limitations under the License. | |
21 */ | |
22 | |
23 #include "barcode.h" | |
24 #include "include/BC_Reader.h" | |
25 #include "include/BC_OneDReader.h" | |
26 #include "include/BC_BinaryBitmap.h" | |
27 #include "include/BC_CommonBitArray.h" | |
28 const FX_INT32 CBC_OneDReader::INTEGER_MATH_SHIFT = 8; | |
29 const FX_INT32 CBC_OneDReader::PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << 8; | |
30 CBC_OneDReader::CBC_OneDReader() | |
31 { | |
32 } | |
33 CBC_OneDReader::~CBC_OneDReader() | |
34 { | |
35 } | |
36 CFX_ByteString CBC_OneDReader::Decode(CBC_BinaryBitmap *image, FX_INT32 &e) | |
37 { | |
38 CFX_ByteString strtemp = Decode(image, 0, e); | |
39 BC_EXCEPTION_CHECK_ReturnValue(e, ""); | |
40 return strtemp; | |
41 } | |
42 CFX_ByteString CBC_OneDReader::Decode(CBC_BinaryBitmap *image, FX_INT32 hints, F
X_INT32 &e) | |
43 { | |
44 CFX_ByteString strtemp = DeDecode(image, hints, e); | |
45 BC_EXCEPTION_CHECK_ReturnValue(e, ""); | |
46 return strtemp; | |
47 } | |
48 CFX_ByteString CBC_OneDReader::DeDecode(CBC_BinaryBitmap *image, FX_INT32 hints,
FX_INT32 &e) | |
49 { | |
50 FX_INT32 width = image->GetWidth(); | |
51 FX_INT32 height = image->GetHeight(); | |
52 CBC_CommonBitArray *row = NULL; | |
53 FX_INT32 middle = height >> 1; | |
54 FX_BOOL tryHarder = FALSE; | |
55 FX_INT32 rowStep = FX_MAX(1, height >> (tryHarder ? 8 : 5)); | |
56 FX_INT32 maxLines; | |
57 if (tryHarder) { | |
58 maxLines = height; | |
59 } else { | |
60 maxLines = 15; | |
61 } | |
62 for (FX_INT32 x = 0; x < maxLines; x++) { | |
63 FX_INT32 rowStepsAboveOrBelow = (x + 1) >> 1; | |
64 FX_BOOL isAbove = (x & 0x01) == 0; | |
65 FX_INT32 rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow
: -rowStepsAboveOrBelow); | |
66 if (rowNumber < 0 || rowNumber >= height) { | |
67 break; | |
68 } | |
69 row = image->GetBlackRow(rowNumber, NULL, e); | |
70 if (e != BCExceptionNO) { | |
71 e = BCExceptionNO; | |
72 if(row != NULL) { | |
73 delete row; | |
74 row = NULL; | |
75 } | |
76 continue; | |
77 } | |
78 for (FX_INT32 attempt = 0; attempt < 2; attempt++) { | |
79 if (attempt == 1) { | |
80 row->Reverse(); | |
81 } | |
82 CFX_ByteString result = DecodeRow(rowNumber, row, hints, e); | |
83 if (e != BCExceptionNO) { | |
84 e = BCExceptionNO; | |
85 continue; | |
86 } | |
87 if(row != NULL) { | |
88 delete row; | |
89 row = NULL; | |
90 } | |
91 return result; | |
92 } | |
93 if(row != NULL) { | |
94 delete row; | |
95 row = NULL; | |
96 } | |
97 } | |
98 e = BCExceptionNotFound; | |
99 return ""; | |
100 } | |
101 void CBC_OneDReader::RecordPattern(CBC_CommonBitArray *row, FX_INT32 start, CFX_
Int32Array *counters, FX_INT32 &e) | |
102 { | |
103 FX_INT32 numCounters = counters->GetSize(); | |
104 for (FX_INT32 i = 0; i < numCounters; i++) { | |
105 (*counters)[i] = 0; | |
106 } | |
107 FX_INT32 end = row->GetSize(); | |
108 if (start >= end) { | |
109 e = BCExceptionNotFound; | |
110 return; | |
111 } | |
112 FX_BOOL isWhite = !row->Get(start); | |
113 FX_INT32 counterPosition = 0; | |
114 FX_INT32 j = start; | |
115 while (j < end) { | |
116 FX_BOOL pixel = row->Get(j); | |
117 if (pixel ^ isWhite) { | |
118 (*counters)[counterPosition]++; | |
119 } else { | |
120 counterPosition++; | |
121 if (counterPosition == numCounters) { | |
122 break; | |
123 } else { | |
124 (*counters)[counterPosition] = 1; | |
125 isWhite = !isWhite; | |
126 } | |
127 } | |
128 j++; | |
129 } | |
130 if (!(counterPosition == numCounters || (counterPosition == numCounters - 1
&& j == end))) { | |
131 e = BCExceptionNotFound; | |
132 return; | |
133 } | |
134 } | |
135 void CBC_OneDReader::RecordPatternInReverse(CBC_CommonBitArray *row, FX_INT32 st
art, CFX_Int32Array *counters, FX_INT32 &e) | |
136 { | |
137 FX_INT32 numTransitionsLeft = counters->GetSize(); | |
138 FX_BOOL last = row->Get(start); | |
139 while (start > 0 && numTransitionsLeft >= 0) { | |
140 if (row->Get(--start) != last) { | |
141 numTransitionsLeft--; | |
142 last = !last; | |
143 } | |
144 } | |
145 if (numTransitionsLeft >= 0) { | |
146 e = BCExceptionNotFound; | |
147 return; | |
148 } | |
149 RecordPattern(row, start + 1, counters, e); | |
150 BC_EXCEPTION_CHECK_ReturnVoid(e); | |
151 } | |
152 FX_INT32 CBC_OneDReader::PatternMatchVariance(CFX_Int32Array *counters, const FX
_INT32 *pattern, FX_INT32 maxIndividualVariance) | |
153 { | |
154 FX_INT32 numCounters = counters->GetSize(); | |
155 FX_INT32 total = 0; | |
156 FX_INT32 patternLength = 0; | |
157 for (FX_INT32 i = 0; i < numCounters; i++) { | |
158 total += (*counters)[i]; | |
159 patternLength += pattern[i]; | |
160 } | |
161 if (total < patternLength) { | |
162 #undef max | |
163 return FXSYS_IntMax; | |
164 } | |
165 FX_INT32 unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength; | |
166 maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MA
TH_SHIFT; | |
167 FX_INT32 totalVariance = 0; | |
168 for (FX_INT32 x = 0; x < numCounters; x++) { | |
169 FX_INT32 counter = (*counters)[x] << INTEGER_MATH_SHIFT; | |
170 FX_INT32 scaledPattern = pattern[x] * unitBarWidth; | |
171 FX_INT32 variance = counter > scaledPattern ? counter - scaledPattern :
scaledPattern - counter; | |
172 if (variance > maxIndividualVariance) { | |
173 #undef max | |
174 return FXSYS_IntMax; | |
175 } | |
176 totalVariance += variance; | |
177 } | |
178 return totalVariance / total; | |
179 } | |
OLD | NEW |