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

Side by Side Diff: xfa/src/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 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 2006 Jeremias Maerki in part, and ZXing Authors in part
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 "xfa/src/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h"
24
25 #include "third_party/bigint/BigIntegerLibrary.hh"
26 #include "xfa/src/fxbarcode/BC_UtilCodingConvert.h"
27 #include "xfa/src/fxbarcode/pdf417/BC_PDF417Compaction.h"
28 #include "xfa/src/fxbarcode/utils.h"
29
30 #define SUBMODE_ALPHA 0
31 #define SUBMODE_LOWER 1
32 #define SUBMODE_MIXED 2
33
34 int32_t CBC_PDF417HighLevelEncoder::TEXT_COMPACTION = 0;
35 int32_t CBC_PDF417HighLevelEncoder::BYTE_COMPACTION = 1;
36 int32_t CBC_PDF417HighLevelEncoder::NUMERIC_COMPACTION = 2;
37 int32_t CBC_PDF417HighLevelEncoder::SUBMODE_PUNCTUATION = 3;
38 int32_t CBC_PDF417HighLevelEncoder::LATCH_TO_TEXT = 900;
39 int32_t CBC_PDF417HighLevelEncoder::LATCH_TO_BYTE_PADDED = 901;
40 int32_t CBC_PDF417HighLevelEncoder::LATCH_TO_NUMERIC = 902;
41 int32_t CBC_PDF417HighLevelEncoder::SHIFT_TO_BYTE = 913;
42 int32_t CBC_PDF417HighLevelEncoder::LATCH_TO_BYTE = 924;
43 uint8_t CBC_PDF417HighLevelEncoder::TEXT_MIXED_RAW[] = {
44 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 38, 13, 9, 44, 58,
45 35, 45, 46, 36, 47, 43, 37, 42, 61, 94, 0, 32, 0, 0, 0};
46 uint8_t CBC_PDF417HighLevelEncoder::TEXT_PUNCTUATION_RAW[] = {
47 59, 60, 62, 64, 91, 92, 93, 95, 96, 126, 33, 13, 9, 44, 58,
48 10, 45, 46, 36, 47, 34, 124, 42, 40, 41, 63, 123, 125, 39, 0};
49 int32_t CBC_PDF417HighLevelEncoder::MIXED[128] = {0};
50 int32_t CBC_PDF417HighLevelEncoder::PUNCTUATION[128] = {0};
51
52 void CBC_PDF417HighLevelEncoder::Initialize() {
53 Inverse();
54 }
55 void CBC_PDF417HighLevelEncoder::Finalize() {}
56 CFX_WideString CBC_PDF417HighLevelEncoder::encodeHighLevel(
57 CFX_WideString wideMsg,
58 Compaction compaction,
59 int32_t& e) {
60 CFX_ByteString bytes;
61 CBC_UtilCodingConvert::UnicodeToUTF8(wideMsg, bytes);
62 CFX_WideString msg;
63 int32_t len = bytes.GetLength();
64 for (int32_t i = 0; i < len; i++) {
65 FX_WCHAR ch = (FX_WCHAR)(bytes.GetAt(i) & 0xff);
66 if (ch == '?' && bytes.GetAt(i) != '?') {
67 e = BCExceptionCharactersOutsideISO88591Encoding;
68 return (FX_WCHAR*)"";
69 }
70 msg += ch;
71 }
72 CFX_ByteArray byteArr;
73 for (int32_t k = 0; k < bytes.GetLength(); k++) {
74 byteArr.Add(bytes.GetAt(k));
75 }
76 CFX_WideString sb;
77 len = msg.GetLength();
78 int32_t p = 0;
79 int32_t textSubMode = SUBMODE_ALPHA;
80 if (compaction == TEXT) {
81 encodeText(msg, p, len, sb, textSubMode);
82 } else if (compaction == BYTES) {
83 encodeBinary(&byteArr, p, byteArr.GetSize(), BYTE_COMPACTION, sb);
84 } else if (compaction == NUMERIC) {
85 sb += (FX_WCHAR)LATCH_TO_NUMERIC;
86 encodeNumeric(msg, p, len, sb);
87 } else {
88 int32_t encodingMode = LATCH_TO_TEXT;
89 while (p < len) {
90 int32_t n = determineConsecutiveDigitCount(msg, p);
91 if (n >= 13) {
92 sb += (FX_WCHAR)LATCH_TO_NUMERIC;
93 encodingMode = NUMERIC_COMPACTION;
94 textSubMode = SUBMODE_ALPHA;
95 encodeNumeric(msg, p, n, sb);
96 p += n;
97 } else {
98 int32_t t = determineConsecutiveTextCount(msg, p);
99 if (t >= 5 || n == len) {
100 if (encodingMode != TEXT_COMPACTION) {
101 sb += (FX_WCHAR)LATCH_TO_TEXT;
102 encodingMode = TEXT_COMPACTION;
103 textSubMode = SUBMODE_ALPHA;
104 }
105 textSubMode = encodeText(msg, p, t, sb, textSubMode);
106 p += t;
107 } else {
108 int32_t b = determineConsecutiveBinaryCount(msg, &byteArr, p, e);
109 BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR)' ');
110 if (b == 0) {
111 b = 1;
112 }
113 if (b == 1 && encodingMode == TEXT_COMPACTION) {
114 encodeBinary(&byteArr, p, 1, TEXT_COMPACTION, sb);
115 } else {
116 encodeBinary(&byteArr, p, b, encodingMode, sb);
117 encodingMode = BYTE_COMPACTION;
118 textSubMode = SUBMODE_ALPHA;
119 }
120 p += b;
121 }
122 }
123 }
124 }
125 return sb;
126 }
127
128 void CBC_PDF417HighLevelEncoder::Inverse() {
129 for (size_t l = 0; l < FX_ArraySize(MIXED); ++l)
130 MIXED[l] = -1;
131
132 for (uint8_t i = 0; i < FX_ArraySize(TEXT_MIXED_RAW); ++i) {
133 uint8_t b = TEXT_MIXED_RAW[i];
134 if (b != 0)
135 MIXED[b] = i;
136 }
137
138 for (size_t l = 0; l < FX_ArraySize(PUNCTUATION); ++l)
139 PUNCTUATION[l] = -1;
140
141 for (uint8_t i = 0; i < FX_ArraySize(TEXT_PUNCTUATION_RAW); ++i) {
142 uint8_t b = TEXT_PUNCTUATION_RAW[i];
143 if (b != 0)
144 PUNCTUATION[b] = i;
145 }
146 }
147
148 int32_t CBC_PDF417HighLevelEncoder::encodeText(CFX_WideString msg,
149 int32_t startpos,
150 int32_t count,
151 CFX_WideString& sb,
152 int32_t initialSubmode) {
153 CFX_WideString tmp;
154 int32_t submode = initialSubmode;
155 int32_t idx = 0;
156 while (TRUE) {
157 FX_WCHAR ch = msg.GetAt(startpos + idx);
158 switch (submode) {
159 case SUBMODE_ALPHA:
160 if (isAlphaUpper(ch)) {
161 if (ch == ' ') {
162 tmp += (FX_WCHAR)26;
163 } else {
164 tmp += (FX_WCHAR)(ch - 65);
165 }
166 } else {
167 if (isAlphaLower(ch)) {
168 submode = SUBMODE_LOWER;
169 tmp += (FX_WCHAR)27;
170 continue;
171 } else if (isMixed(ch)) {
172 submode = SUBMODE_MIXED;
173 tmp += (FX_WCHAR)28;
174 continue;
175 } else {
176 tmp += (FX_WCHAR)29;
177 tmp += PUNCTUATION[ch];
178 break;
179 }
180 }
181 break;
182 case SUBMODE_LOWER:
183 if (isAlphaLower(ch)) {
184 if (ch == ' ') {
185 tmp += (FX_WCHAR)26;
186 } else {
187 tmp += (FX_WCHAR)(ch - 97);
188 }
189 } else {
190 if (isAlphaUpper(ch)) {
191 tmp += (FX_WCHAR)27;
192 tmp += (FX_WCHAR)(ch - 65);
193 break;
194 } else if (isMixed(ch)) {
195 submode = SUBMODE_MIXED;
196 tmp += (FX_WCHAR)28;
197 continue;
198 } else {
199 tmp += (FX_WCHAR)29;
200 tmp += PUNCTUATION[ch];
201 break;
202 }
203 }
204 break;
205 case SUBMODE_MIXED:
206 if (isMixed(ch)) {
207 tmp += MIXED[ch];
208 } else {
209 if (isAlphaUpper(ch)) {
210 submode = SUBMODE_ALPHA;
211 tmp += (FX_WCHAR)28;
212 continue;
213 } else if (isAlphaLower(ch)) {
214 submode = SUBMODE_LOWER;
215 tmp += (FX_WCHAR)27;
216 continue;
217 } else {
218 if (startpos + idx + 1 < count) {
219 FX_WCHAR next = msg.GetAt(startpos + idx + 1);
220 if (isPunctuation(next)) {
221 submode = SUBMODE_PUNCTUATION;
222 tmp += (FX_WCHAR)25;
223 continue;
224 }
225 }
226 tmp += (FX_WCHAR)29;
227 tmp += PUNCTUATION[ch];
228 }
229 }
230 break;
231 default:
232 if (isPunctuation(ch)) {
233 tmp += PUNCTUATION[ch];
234 } else {
235 submode = SUBMODE_ALPHA;
236 tmp += (FX_WCHAR)29;
237 continue;
238 }
239 }
240 idx++;
241 if (idx >= count) {
242 break;
243 }
244 }
245 FX_WCHAR h = 0;
246 int32_t len = tmp.GetLength();
247 for (int32_t i = 0; i < len; i++) {
248 FX_BOOL odd = (i % 2) != 0;
249 if (odd) {
250 h = (FX_WCHAR)((h * 30) + tmp.GetAt(i));
251 sb += h;
252 } else {
253 h = tmp.GetAt(i);
254 }
255 }
256 if ((len % 2) != 0) {
257 sb += (FX_WCHAR)((h * 30) + 29);
258 }
259 return submode;
260 }
261 void CBC_PDF417HighLevelEncoder::encodeBinary(CFX_ByteArray* bytes,
262 int32_t startpos,
263 int32_t count,
264 int32_t startmode,
265 CFX_WideString& sb) {
266 if (count == 1 && startmode == TEXT_COMPACTION) {
267 sb += (FX_WCHAR)SHIFT_TO_BYTE;
268 }
269 int32_t idx = startpos;
270 int32_t i = 0;
271 if (count >= 6) {
272 sb += (FX_WCHAR)LATCH_TO_BYTE;
273 FX_WCHAR chars[5];
274 while ((startpos + count - idx) >= 6) {
275 int64_t t = 0;
276 for (i = 0; i < 6; i++) {
277 t <<= 8;
278 t += bytes->GetAt(idx + i) & 0xff;
279 }
280 for (i = 0; i < 5; i++) {
281 chars[i] = (FX_WCHAR)(t % 900);
282 t /= 900;
283 }
284 for (i = 4; i >= 0; i--) {
285 sb += (chars[i]);
286 }
287 idx += 6;
288 }
289 }
290 if (idx < startpos + count) {
291 sb += (FX_WCHAR)LATCH_TO_BYTE_PADDED;
292 }
293 for (i = idx; i < startpos + count; i++) {
294 int32_t ch = bytes->GetAt(i) & 0xff;
295 sb += (FX_WCHAR)ch;
296 }
297 }
298 void CBC_PDF417HighLevelEncoder::encodeNumeric(CFX_WideString msg,
299 int32_t startpos,
300 int32_t count,
301 CFX_WideString& sb) {
302 int32_t idx = 0;
303 BigInteger num900 = 900;
304 while (idx < count) {
305 CFX_WideString tmp;
306 int32_t len = 44 < count - idx ? 44 : count - idx;
307 CFX_ByteString part =
308 ((FX_WCHAR)'1' + msg.Mid(startpos + idx, len)).UTF8Encode();
309 BigInteger bigint = stringToBigInteger(part.c_str());
310 do {
311 int32_t c = (bigint % num900).toInt();
312 tmp += (FX_WCHAR)(c);
313 bigint = bigint / num900;
314 } while (!bigint.isZero());
315 for (int32_t i = tmp.GetLength() - 1; i >= 0; i--) {
316 sb += tmp.GetAt(i);
317 }
318 idx += len;
319 }
320 }
321 FX_BOOL CBC_PDF417HighLevelEncoder::isDigit(FX_WCHAR ch) {
322 return ch >= '0' && ch <= '9';
323 }
324 FX_BOOL CBC_PDF417HighLevelEncoder::isAlphaUpper(FX_WCHAR ch) {
325 return ch == ' ' || (ch >= 'A' && ch <= 'Z');
326 }
327 FX_BOOL CBC_PDF417HighLevelEncoder::isAlphaLower(FX_WCHAR ch) {
328 return ch == ' ' || (ch >= 'a' && ch <= 'z');
329 }
330 FX_BOOL CBC_PDF417HighLevelEncoder::isMixed(FX_WCHAR ch) {
331 return MIXED[ch] != -1;
332 }
333 FX_BOOL CBC_PDF417HighLevelEncoder::isPunctuation(FX_WCHAR ch) {
334 return PUNCTUATION[ch] != -1;
335 }
336 FX_BOOL CBC_PDF417HighLevelEncoder::isText(FX_WCHAR ch) {
337 return ch == '\t' || ch == '\n' || ch == '\r' || (ch >= 32 && ch <= 126);
338 }
339 int32_t CBC_PDF417HighLevelEncoder::determineConsecutiveDigitCount(
340 CFX_WideString msg,
341 int32_t startpos) {
342 int32_t count = 0;
343 int32_t len = msg.GetLength();
344 int32_t idx = startpos;
345 if (idx < len) {
346 FX_WCHAR ch = msg.GetAt(idx);
347 while (isDigit(ch) && idx < len) {
348 count++;
349 idx++;
350 if (idx < len) {
351 ch = msg.GetAt(idx);
352 }
353 }
354 }
355 return count;
356 }
357 int32_t CBC_PDF417HighLevelEncoder::determineConsecutiveTextCount(
358 CFX_WideString msg,
359 int32_t startpos) {
360 int32_t len = msg.GetLength();
361 int32_t idx = startpos;
362 while (idx < len) {
363 FX_WCHAR ch = msg.GetAt(idx);
364 int32_t numericCount = 0;
365 while (numericCount < 13 && isDigit(ch) && idx < len) {
366 numericCount++;
367 idx++;
368 if (idx < len) {
369 ch = msg.GetAt(idx);
370 }
371 }
372 if (numericCount >= 13) {
373 return idx - startpos - numericCount;
374 }
375 if (numericCount > 0) {
376 continue;
377 }
378 ch = msg.GetAt(idx);
379 if (!isText(ch)) {
380 break;
381 }
382 idx++;
383 }
384 return idx - startpos;
385 }
386 int32_t CBC_PDF417HighLevelEncoder::determineConsecutiveBinaryCount(
387 CFX_WideString msg,
388 CFX_ByteArray* bytes,
389 int32_t startpos,
390 int32_t& e) {
391 int32_t len = msg.GetLength();
392 int32_t idx = startpos;
393 while (idx < len) {
394 FX_WCHAR ch = msg.GetAt(idx);
395 int32_t numericCount = 0;
396 while (numericCount < 13 && isDigit(ch)) {
397 numericCount++;
398 int32_t i = idx + numericCount;
399 if (i >= len) {
400 break;
401 }
402 ch = msg.GetAt(i);
403 }
404 if (numericCount >= 13) {
405 return idx - startpos;
406 }
407 int32_t textCount = 0;
408 while (textCount < 5 && isText(ch)) {
409 textCount++;
410 int32_t i = idx + textCount;
411 if (i >= len) {
412 break;
413 }
414 ch = msg.GetAt(i);
415 }
416 if (textCount >= 5) {
417 return idx - startpos;
418 }
419 ch = msg.GetAt(idx);
420 if (bytes->GetAt(idx) == 63 && ch != '?') {
421 e = BCExceptionNonEncodableCharacterDetected;
422 return -1;
423 }
424 idx++;
425 }
426 return idx - startpos;
427 }
OLDNEW
« no previous file with comments | « xfa/src/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h ('k') | xfa/src/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698