Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: xfa/src/fxbarcode/src/BC_PDF417DecodedBitStreamParser.cpp

Issue 842043002: Organize barcode codes into modules. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@xfa
Patch Set: rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 2009 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 <stdlib.h>
24 #include "barcode.h"
25 #include "include/BC_DecoderResult.h"
26 #include "include/BC_PDF417ResultMetadata.h"
27 #include "include/BC_CommonDecoderResult.h"
28 #include "include/BC_PDF417DecodedBitStreamParser.h"
29 #include "../../../../third_party/bigint/BigIntegerLibrary.hh"
30 #define TEXT_COMPACTION_MODE_LATCH 900
31 #define BYTE_COMPACTION_MODE_LATCH 901
32 #define NUMERIC_COMPACTION_MODE_LATCH 902
33 #define BYTE_COMPACTION_MODE_LATCH_6 924
34 #define BEGIN_MACRO_PDF417_CONTROL_BLOCK 928
35 #define BEGIN_MACRO_PDF417_OPTIONAL_FIELD 923
36 #define MACRO_PDF417_TERMINATOR 922
37 #define MODE_SHIFT_TO_BYTE_COMPACTION_MODE 913
38
39 FX_INT32 CBC_DecodedBitStreamPaser::MAX_NUMERIC_CODEWORDS = 15;
40 FX_INT32 CBC_DecodedBitStreamPaser::NUMBER_OF_SEQUENCE_CODEWORDS = 2;
41 FX_INT32 CBC_DecodedBitStreamPaser::PL = 25;
42 FX_INT32 CBC_DecodedBitStreamPaser::LL = 27;
43 FX_INT32 CBC_DecodedBitStreamPaser::AS = 27;
44 FX_INT32 CBC_DecodedBitStreamPaser::ML = 28;
45 FX_INT32 CBC_DecodedBitStreamPaser::AL = 28;
46 FX_INT32 CBC_DecodedBitStreamPaser::PS = 29;
47 FX_INT32 CBC_DecodedBitStreamPaser::PAL = 29;
48 FX_CHAR CBC_DecodedBitStreamPaser::PUNCT_CHARS[29] = {
49 ';', '<', '>', '@', '[', '\\', '}', '_', '`', '~', '!',
50 '\r', '\t', ',', ':', '\n', '-', '.', '$', '/', '"', '|', '*',
51 '(', ')', '?', '{', '}', '\''
52 };
53 FX_CHAR CBC_DecodedBitStreamPaser::MIXED_CHARS[30] = {
54 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '&',
55 '\r', '\t', ',', ':', '#', '-', '.', '$', '/', '+', '%', '*',
56 '=', '^'
57 };
58 void CBC_DecodedBitStreamPaser::Initialize()
59 {
60 }
61 void CBC_DecodedBitStreamPaser::Finalize()
62 {
63 }
64 CBC_DecodedBitStreamPaser::CBC_DecodedBitStreamPaser()
65 {
66 }
67 CBC_DecodedBitStreamPaser::~CBC_DecodedBitStreamPaser()
68 {
69 }
70 CBC_CommonDecoderResult* CBC_DecodedBitStreamPaser::decode(CFX_Int32Array &codew ords, CFX_ByteString ecLevel, FX_INT32 &e)
71 {
72 CFX_ByteString result;
73 FX_INT32 codeIndex = 1;
74 FX_INT32 code = codewords.GetAt(codeIndex);
75 codeIndex++;
76 CBC_PDF417ResultMetadata* resultMetadata = FX_NEW CBC_PDF417ResultMetadata;
77 while (codeIndex < codewords[0]) {
78 switch (code) {
79 case TEXT_COMPACTION_MODE_LATCH:
80 codeIndex = textCompaction(codewords, codeIndex, result);
81 break;
82 case BYTE_COMPACTION_MODE_LATCH:
83 codeIndex = byteCompaction(code, codewords, codeIndex, result);
84 break;
85 case NUMERIC_COMPACTION_MODE_LATCH:
86 codeIndex = numericCompaction(codewords, codeIndex, result, e);
87 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
88 break;
89 case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
90 codeIndex = byteCompaction(code, codewords, codeIndex, result);
91 break;
92 case BYTE_COMPACTION_MODE_LATCH_6:
93 codeIndex = byteCompaction(code, codewords, codeIndex, result);
94 break;
95 case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
96 codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadat a, e);
97 if (e != BCExceptionNO) {
98 delete resultMetadata;
99 return NULL;
100 }
101 break;
102 default:
103 codeIndex--;
104 codeIndex = textCompaction(codewords, codeIndex, result);
105 break;
106 }
107 if (codeIndex < codewords.GetSize()) {
108 code = codewords[codeIndex++];
109 } else {
110 e = BCExceptionFormatInstance;
111 delete resultMetadata;
112 return NULL;
113 }
114 }
115 if (result.GetLength() == 0) {
116 e = BCExceptionFormatInstance;
117 delete resultMetadata;
118 return NULL;
119 }
120 CFX_ByteArray rawBytes;
121 CFX_PtrArray byteSegments;
122 CBC_CommonDecoderResult *tempCd = FX_NEW CBC_CommonDecoderResult();
123 tempCd->Init(rawBytes, result, byteSegments, ecLevel, e);
124 if (e != BCExceptionNO) {
125 delete resultMetadata;
126 return NULL;
127 }
128 tempCd->setOther(resultMetadata);
129 return tempCd;
130 }
131 FX_INT32 CBC_DecodedBitStreamPaser::decodeMacroBlock(CFX_Int32Array &codewords, FX_INT32 codeIndex, CBC_PDF417ResultMetadata* resultMetadata, FX_INT32 &e)
132 {
133 if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) {
134 e = BCExceptionFormatInstance;
135 return -1;
136 }
137 CFX_Int32Array segmentIndexArray;
138 segmentIndexArray.SetSize(NUMBER_OF_SEQUENCE_CODEWORDS);
139 for (FX_INT32 i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
140 segmentIndexArray.SetAt(i, codewords[codeIndex]);
141 }
142 CFX_ByteString str = decodeBase900toBase10(segmentIndexArray, NUMBER_OF_SEQU ENCE_CODEWORDS, e);
143 BC_EXCEPTION_CHECK_ReturnValue(e, -1);
144 resultMetadata->setSegmentIndex(atoi(str.GetBuffer(str.GetLength())));
145 CFX_ByteString fileId;
146 codeIndex = textCompaction(codewords, codeIndex, fileId);
147 resultMetadata->setFileId(fileId);
148 if (codewords[codeIndex] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
149 codeIndex++;
150 CFX_Int32Array additionalOptionCodeWords;
151 additionalOptionCodeWords.SetSize(codewords[0] - codeIndex);
152 FX_INT32 additionalOptionCodeWordsIndex = 0;
153 FX_BOOL end = FALSE;
154 while ((codeIndex < codewords[0]) && !end) {
155 FX_INT32 code = codewords[codeIndex++];
156 if (code < TEXT_COMPACTION_MODE_LATCH) {
157 additionalOptionCodeWords[additionalOptionCodeWordsIndex++] = co de;
158 } else {
159 switch (code) {
160 case MACRO_PDF417_TERMINATOR:
161 resultMetadata->setLastSegment(TRUE);
162 codeIndex++;
163 end = TRUE;
164 break;
165 default:
166 e = BCExceptionFormatInstance;
167 return -1;
168 }
169 }
170 }
171 CFX_Int32Array array;
172 array.SetSize(additionalOptionCodeWordsIndex);
173 array.Copy(additionalOptionCodeWords);
174 resultMetadata->setOptionalData(array);
175 } else if (codewords[codeIndex] == MACRO_PDF417_TERMINATOR) {
176 resultMetadata->setLastSegment(TRUE);
177 codeIndex++;
178 }
179 return codeIndex;
180 }
181 FX_INT32 CBC_DecodedBitStreamPaser::textCompaction(CFX_Int32Array &codewords, FX _INT32 codeIndex, CFX_ByteString &result)
182 {
183 CFX_Int32Array textCompactionData;
184 textCompactionData.SetSize((codewords[0] - codeIndex) << 1);
185 CFX_Int32Array byteCompactionData;
186 byteCompactionData.SetSize((codewords[0] - codeIndex) << 1);
187 FX_INT32 index = 0;
188 FX_BOOL end = FALSE;
189 while ((codeIndex < codewords[0]) && !end) {
190 FX_INT32 code = codewords[codeIndex++];
191 if (code < TEXT_COMPACTION_MODE_LATCH) {
192 textCompactionData[index] = code / 30;
193 textCompactionData[index + 1] = code % 30;
194 index += 2;
195 } else {
196 switch (code) {
197 case TEXT_COMPACTION_MODE_LATCH:
198 textCompactionData[index++] = TEXT_COMPACTION_MODE_LATCH;
199 break;
200 case BYTE_COMPACTION_MODE_LATCH:
201 codeIndex--;
202 end = TRUE;
203 break;
204 case NUMERIC_COMPACTION_MODE_LATCH:
205 codeIndex--;
206 end = TRUE;
207 break;
208 case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
209 codeIndex--;
210 end = TRUE;
211 break;
212 case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
213 codeIndex--;
214 end = TRUE;
215 break;
216 case MACRO_PDF417_TERMINATOR:
217 codeIndex--;
218 end = TRUE;
219 break;
220 case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
221 textCompactionData[index] = MODE_SHIFT_TO_BYTE_COMPACTION_MO DE;
222 code = codewords[codeIndex++];
223 byteCompactionData[index] = code;
224 index++;
225 break;
226 case BYTE_COMPACTION_MODE_LATCH_6:
227 codeIndex--;
228 end = TRUE;
229 break;
230 }
231 }
232 }
233 decodeTextCompaction(textCompactionData, byteCompactionData, index, result);
234 return codeIndex;
235 }
236 void CBC_DecodedBitStreamPaser::decodeTextCompaction(CFX_Int32Array &textCompact ionData, CFX_Int32Array &byteCompactionData, FX_INT32 length, CFX_ByteString &re sult)
237 {
238 Mode subMode = ALPHA;
239 Mode priorToShiftMode = ALPHA;
240 FX_INT32 i = 0;
241 while (i < length) {
242 FX_INT32 subModeCh = textCompactionData[i];
243 FX_CHAR ch = 0;
244 switch (subMode) {
245 case ALPHA:
246 if (subModeCh < 26) {
247 ch = (FX_CHAR) ('A' + subModeCh);
248 } else {
249 if (subModeCh == 26) {
250 ch = ' ';
251 } else if (subModeCh == LL) {
252 subMode = LOWER;
253 } else if (subModeCh == ML) {
254 subMode = MIXED;
255 } else if (subModeCh == PS) {
256 priorToShiftMode = subMode;
257 subMode = PUNCT_SHIFT;
258 } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
259 result += (FX_CHAR) byteCompactionData[i];
260 } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
261 subMode = ALPHA;
262 }
263 }
264 break;
265 case LOWER:
266 if (subModeCh < 26) {
267 ch = (FX_CHAR) ('a' + subModeCh);
268 } else {
269 if (subModeCh == 26) {
270 ch = ' ';
271 } else if (subModeCh == AS) {
272 priorToShiftMode = subMode;
273 subMode = ALPHA_SHIFT;
274 } else if (subModeCh == ML) {
275 subMode = MIXED;
276 } else if (subModeCh == PS) {
277 priorToShiftMode = subMode;
278 subMode = PUNCT_SHIFT;
279 } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
280 result += (FX_CHAR) byteCompactionData[i];
281 } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
282 subMode = ALPHA;
283 }
284 }
285 break;
286 case MIXED:
287 if (subModeCh < PL) {
288 ch = MIXED_CHARS[subModeCh];
289 } else {
290 if (subModeCh == PL) {
291 subMode = PUNCT;
292 } else if (subModeCh == 26) {
293 ch = ' ';
294 } else if (subModeCh == LL) {
295 subMode = LOWER;
296 } else if (subModeCh == AL) {
297 subMode = ALPHA;
298 } else if (subModeCh == PS) {
299 priorToShiftMode = subMode;
300 subMode = PUNCT_SHIFT;
301 } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
302 result += (FX_CHAR) byteCompactionData[i];
303 } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
304 subMode = ALPHA;
305 }
306 }
307 break;
308 case PUNCT:
309 if (subModeCh < PAL) {
310 ch = PUNCT_CHARS[subModeCh];
311 } else {
312 if (subModeCh == PAL) {
313 subMode = ALPHA;
314 } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
315 result += (FX_CHAR) byteCompactionData[i];
316 } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
317 subMode = ALPHA;
318 }
319 }
320 break;
321 case ALPHA_SHIFT:
322 subMode = priorToShiftMode;
323 if (subModeCh < 26) {
324 ch = (FX_CHAR) ('A' + subModeCh);
325 } else {
326 if (subModeCh == 26) {
327 ch = ' ';
328 } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
329 subMode = ALPHA;
330 }
331 }
332 break;
333 case PUNCT_SHIFT:
334 subMode = priorToShiftMode;
335 if (subModeCh < PAL) {
336 ch = PUNCT_CHARS[subModeCh];
337 } else {
338 if (subModeCh == PAL) {
339 subMode = ALPHA;
340 } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
341 result += (FX_CHAR) byteCompactionData[i];
342 } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
343 subMode = ALPHA;
344 }
345 }
346 break;
347 }
348 if (ch != 0) {
349 result += ch;
350 }
351 i++;
352 }
353 }
354 FX_INT32 CBC_DecodedBitStreamPaser::byteCompaction(FX_INT32 mode, CFX_Int32Array &codewords, FX_INT32 codeIndex, CFX_ByteString &result)
355 {
356 if (mode == BYTE_COMPACTION_MODE_LATCH) {
357 FX_INT32 count = 0;
358 FX_INT64 value = 0;
359 FX_WORD* decodedData = FX_Alloc(FX_WORD, 6 * sizeof(FX_WORD));
360 CFX_Int32Array byteCompactedCodewords;
361 byteCompactedCodewords.SetSize(6);
362 FX_BOOL end = FALSE;
363 FX_INT32 nextCode = codewords[codeIndex++];
364 while ((codeIndex < codewords[0]) && !end) {
365 byteCompactedCodewords[count++] = nextCode;
366 value = 900 * value + nextCode;
367 nextCode = codewords[codeIndex++];
368 if (nextCode == TEXT_COMPACTION_MODE_LATCH ||
369 nextCode == BYTE_COMPACTION_MODE_LATCH ||
370 nextCode == NUMERIC_COMPACTION_MODE_LATCH ||
371 nextCode == BYTE_COMPACTION_MODE_LATCH_6 ||
372 nextCode == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
373 nextCode == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
374 nextCode == MACRO_PDF417_TERMINATOR) {
375 codeIndex--;
376 end = TRUE;
377 } else {
378 if ((count % 5 == 0) && (count > 0)) {
379 FX_INT32 j = 0;
380 for (; j < 6; ++j) {
381 decodedData[5 - j] = (FX_WORD) (value % 256);
382 value >>= 8;
383 }
384 for (j = 0; j < 6; ++j) {
385 result += (FX_CHAR)decodedData[j];
386 }
387 count = 0;
388 }
389 }
390 }
391 FX_Free(decodedData);
392 if (codeIndex == codewords[0] && nextCode < TEXT_COMPACTION_MODE_LATCH) {
393 byteCompactedCodewords[count++] = nextCode;
394 }
395 for (FX_INT32 i = 0; i < count; i++) {
396 result += (FX_CHAR)(FX_WORD) byteCompactedCodewords[i];
397 }
398 } else if (mode == BYTE_COMPACTION_MODE_LATCH_6) {
399 FX_INT32 count = 0;
400 FX_INT64 value = 0;
401 FX_BOOL end = FALSE;
402 while (codeIndex < codewords[0] && !end) {
403 FX_INT32 code = codewords[codeIndex++];
404 if (code < TEXT_COMPACTION_MODE_LATCH) {
405 count++;
406 value = 900 * value + code;
407 } else {
408 if (code == TEXT_COMPACTION_MODE_LATCH ||
409 code == BYTE_COMPACTION_MODE_LATCH ||
410 code == NUMERIC_COMPACTION_MODE_LATCH ||
411 code == BYTE_COMPACTION_MODE_LATCH_6 ||
412 code == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
413 code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
414 code == MACRO_PDF417_TERMINATOR) {
415 codeIndex--;
416 end = TRUE;
417 }
418 }
419 if ((count % 5 == 0) && (count > 0)) {
420 FX_WORD* decodedData = FX_Alloc(FX_WORD, 6 * sizeof(FX_WORD));
421 FX_INT32 j = 0;
422 for (; j < 6; ++j) {
423 decodedData[5 - j] = (FX_WORD) (value & 0xFF);
424 value >>= 8;
425 }
426 for (j = 0; j < 6; ++j) {
427 result += (FX_CHAR)decodedData[j];
428 }
429 count = 0;
430 FX_Free(decodedData);
431 }
432 }
433 }
434 return codeIndex;
435 }
436 FX_INT32 CBC_DecodedBitStreamPaser::numericCompaction(CFX_Int32Array &codewords, FX_INT32 codeIndex, CFX_ByteString &result, FX_INT32 &e)
437 {
438 FX_INT32 count = 0;
439 FX_BOOL end = FALSE;
440 CFX_Int32Array numericCodewords;
441 numericCodewords.SetSize(MAX_NUMERIC_CODEWORDS);
442 while (codeIndex < codewords[0] && !end) {
443 FX_INT32 code = codewords[codeIndex++];
444 if (codeIndex == codewords[0]) {
445 end = TRUE;
446 }
447 if (code < TEXT_COMPACTION_MODE_LATCH) {
448 numericCodewords[count] = code;
449 count++;
450 } else {
451 if (code == TEXT_COMPACTION_MODE_LATCH ||
452 code == BYTE_COMPACTION_MODE_LATCH ||
453 code == BYTE_COMPACTION_MODE_LATCH_6 ||
454 code == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
455 code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
456 code == MACRO_PDF417_TERMINATOR) {
457 codeIndex--;
458 end = TRUE;
459 }
460 }
461 if (count % MAX_NUMERIC_CODEWORDS == 0 ||
462 code == NUMERIC_COMPACTION_MODE_LATCH ||
463 end) {
464 CFX_ByteString s = decodeBase900toBase10(numericCodewords, count, e) ;
465 BC_EXCEPTION_CHECK_ReturnValue(e, -1);
466 result += s;
467 count = 0;
468 }
469 }
470 return codeIndex;
471 }
472 CFX_ByteString CBC_DecodedBitStreamPaser::decodeBase900toBase10(CFX_Int32Array & codewords, FX_INT32 count, FX_INT32 &e)
473 {
474 BigInteger result = 0;
475 BigInteger nineHundred(900);
476 for (FX_INT32 i = 0; i < count; i++) {
477 result = result * nineHundred + BigInteger(codewords[i]);
478 }
479 CFX_ByteString resultString(bigIntegerToString(result).c_str());
480 if (resultString.GetAt(0) != '1') {
481 e = BCExceptionFormatInstance;
482 return ' ';
483 }
484 return resultString.Mid(1, resultString.GetLength() - 1);
485 }
OLDNEW
« no previous file with comments | « xfa/src/fxbarcode/src/BC_PDF417Compaction.cpp ('k') | xfa/src/fxbarcode/src/BC_PDF417DetectionResult.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698