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

Side by Side Diff: xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.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 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 "xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.h"
24
25 #include <algorithm>
26 #include <memory>
27
28 #include "xfa/src/fxbarcode/BC_UtilCodingConvert.h"
29 #include "xfa/src/fxbarcode/common/BC_CommonByteArray.h"
30 #include "xfa/src/fxbarcode/common/BC_CommonByteMatrix.h"
31 #include "xfa/src/fxbarcode/common/reedsolomon/BC_ReedSolomon.h"
32 #include "xfa/src/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h"
33 #include "xfa/src/fxbarcode/qrcode/BC_QRCoder.h"
34 #include "xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.h"
35 #include "xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.h"
36 #include "xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.h"
37 #include "xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
38 #include "xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h"
39 #include "xfa/src/fxbarcode/qrcode/BC_QRCoderMode.h"
40 #include "xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.h"
41
42 const int32_t CBC_QRCoderEncoder::m_alphaNumbericTable[] = {
43 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
44 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
45 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
46 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
47 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
48 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1};
49
50 CBC_QRCoderEncoder::CBC_QRCoderEncoder() {}
51 CBC_QRCoderEncoder::~CBC_QRCoderEncoder() {}
52 class Make_Pair {
53 public:
54 CBC_QRCoderMode* m_mode;
55 CFX_ByteString m_string;
56
57 private:
58 Make_Pair(const Make_Pair& mode_string) {}
59 Make_Pair& operator=(Make_Pair& mode_string) {
60 if (this == &mode_string) {
61 return *this;
62 }
63 m_mode = mode_string.m_mode;
64 m_string = mode_string.m_string;
65 return *this;
66 }
67
68 public:
69 Make_Pair(CBC_QRCoderMode* mode, const CFX_ByteString& str)
70 : m_mode(mode), m_string(str) {}
71 ~Make_Pair() {}
72 };
73 void CBC_QRCoderEncoder::Encode(const CFX_ByteString& content,
74 CBC_QRCoderErrorCorrectionLevel* ecLevel,
75 CBC_QRCoder* qrCode,
76 int32_t& e,
77 int32_t versionSpecify) {
78 if (versionSpecify == 0) {
79 EncodeWithAutoVersion(content, ecLevel, qrCode, e);
80 BC_EXCEPTION_CHECK_ReturnVoid(e)
81 } else if (versionSpecify > 0 && versionSpecify <= 40) {
82 EncodeWithSpecifyVersion(content, ecLevel, qrCode, versionSpecify, e);
83 BC_EXCEPTION_CHECK_ReturnVoid(e);
84 } else {
85 e = BCExceptionVersionMust1_40;
86 BC_EXCEPTION_CHECK_ReturnVoid(e);
87 }
88 }
89 void CBC_QRCoderEncoder::AppendECI(CBC_QRCoderBitVector* bits) {}
90 void CBC_QRCoderEncoder::AppendDataModeLenghInfo(
91 CFX_PtrArray& splitResult,
92 CBC_QRCoderBitVector& headerAndDataBits,
93 CBC_QRCoderMode* tempMode,
94 CBC_QRCoder* qrCode,
95 CFX_ByteString& encoding,
96 int32_t& e) {
97 for (int32_t i = 0; i < splitResult.GetSize(); i++) {
98 tempMode = ((Make_Pair*)splitResult[i])->m_mode;
99 if (tempMode == CBC_QRCoderMode::sGBK) {
100 AppendModeInfo(tempMode, &headerAndDataBits, e);
101 BC_EXCEPTION_CHECK_ReturnVoid(e);
102 AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(),
103 qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
104 BC_EXCEPTION_CHECK_ReturnVoid(e);
105 AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode,
106 &headerAndDataBits, encoding, e);
107 BC_EXCEPTION_CHECK_ReturnVoid(e);
108 } else if (tempMode == CBC_QRCoderMode::sBYTE) {
109 CFX_ByteArray bytes;
110 CBC_UtilCodingConvert::LocaleToUtf8(
111 ((Make_Pair*)splitResult[i])->m_string, bytes);
112 AppendModeInfo(tempMode, &headerAndDataBits, e);
113 BC_EXCEPTION_CHECK_ReturnVoid(e);
114 AppendLengthInfo(bytes.GetSize(), qrCode->GetVersion(), tempMode,
115 &headerAndDataBits, e);
116 BC_EXCEPTION_CHECK_ReturnVoid(e);
117 Append8BitBytes(bytes, &headerAndDataBits, e);
118 BC_EXCEPTION_CHECK_ReturnVoid(e);
119 } else if (tempMode == CBC_QRCoderMode::sALPHANUMERIC) {
120 AppendModeInfo(tempMode, &headerAndDataBits, e);
121 BC_EXCEPTION_CHECK_ReturnVoid(e);
122 AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(),
123 qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
124 BC_EXCEPTION_CHECK_ReturnVoid(e);
125 AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode,
126 &headerAndDataBits, encoding, e);
127 BC_EXCEPTION_CHECK_ReturnVoid(e);
128 } else if (tempMode == CBC_QRCoderMode::sNUMERIC) {
129 AppendModeInfo(tempMode, &headerAndDataBits, e);
130 BC_EXCEPTION_CHECK_ReturnVoid(e);
131 AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(),
132 qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
133 BC_EXCEPTION_CHECK_ReturnVoid(e);
134 AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode,
135 &headerAndDataBits, encoding, e);
136 BC_EXCEPTION_CHECK_ReturnVoid(e);
137 } else {
138 e = BCExceptionUnknown;
139 BC_EXCEPTION_CHECK_ReturnVoid(e);
140 }
141 }
142 }
143 void CBC_QRCoderEncoder::SplitString(const CFX_ByteString& content,
144 CFX_PtrArray& result) {
145 int32_t index = 0, flag = 0;
146 while (
147 (((uint8_t)content[index] >= 0xA1 && (uint8_t)content[index] <= 0xAA) ||
148 ((uint8_t)content[index] >= 0xB0 && (uint8_t)content[index] <= 0xFA)) &&
149 (index < content.GetLength())) {
150 index += 2;
151 }
152 if (index != flag) {
153 result.Add(
154 new Make_Pair(CBC_QRCoderMode::sGBK, content.Mid(flag, index - flag)));
155 }
156 flag = index;
157 if (index >= content.GetLength()) {
158 return;
159 }
160 while (
161 GetAlphaNumericCode((uint8_t)content[index]) == -1 &&
162 !(((uint8_t)content[index] >= 0xA1 && (uint8_t)content[index] <= 0xAA) ||
163 ((uint8_t)content[index] >= 0xB0 && (uint8_t)content[index] <= 0xFA)) &&
164 (index < content.GetLength())) {
165 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
166 if (IsDBCSLeadByte((uint8_t)content[index]))
167 #else
168 if ((uint8_t)content[index] > 127)
169 #endif
170 {
171 index += 2;
172 } else {
173 index++;
174 }
175 }
176 if (index != flag) {
177 result.Add(
178 new Make_Pair(CBC_QRCoderMode::sBYTE, content.Mid(flag, index - flag)));
179 }
180 flag = index;
181 if (index >= content.GetLength()) {
182 return;
183 }
184 while (FXSYS_Isdigit((uint8_t)content[index]) &&
185 (index < content.GetLength())) {
186 index++;
187 }
188 if (index != flag) {
189 result.Add(new Make_Pair(CBC_QRCoderMode::sNUMERIC,
190 content.Mid(flag, index - flag)));
191 }
192 flag = index;
193 if (index >= content.GetLength()) {
194 return;
195 }
196 while (GetAlphaNumericCode((uint8_t)content[index]) != -1 &&
197 (index < content.GetLength())) {
198 index++;
199 }
200 if (index != flag) {
201 result.Add(new Make_Pair(CBC_QRCoderMode::sALPHANUMERIC,
202 content.Mid(flag, index - flag)));
203 }
204 flag = index;
205 if (index >= content.GetLength()) {
206 return;
207 }
208 SplitString(content.Mid(index, content.GetLength() - index), result);
209 }
210 int32_t CBC_QRCoderEncoder::GetSpanByVersion(CBC_QRCoderMode* modeFirst,
211 CBC_QRCoderMode* modeSecond,
212 int32_t versionNum,
213 int32_t& e) {
214 if (versionNum == 0) {
215 return 0;
216 }
217 if ((modeFirst == CBC_QRCoderMode::sALPHANUMERIC) &&
218 (modeSecond == CBC_QRCoderMode::sBYTE)) {
219 if (versionNum >= 1 && versionNum <= 9) {
220 return 11;
221 } else if (versionNum >= 10 && versionNum <= 26) {
222 return 15;
223 } else if (versionNum >= 27 && versionNum <= 40) {
224 return 16;
225 } else {
226 e = BCExceptionNoSuchVersion;
227 BC_EXCEPTION_CHECK_ReturnValue(e, 0);
228 }
229 } else if ((modeSecond == CBC_QRCoderMode::sALPHANUMERIC) &&
230 (modeFirst == CBC_QRCoderMode::sNUMERIC)) {
231 if (versionNum >= 1 && versionNum <= 9) {
232 return 13;
233 } else if (versionNum >= 10 && versionNum <= 26) {
234 return 15;
235 } else if (versionNum >= 27 && versionNum <= 40) {
236 return 17;
237 } else {
238 e = BCExceptionNoSuchVersion;
239 BC_EXCEPTION_CHECK_ReturnValue(e, 0);
240 }
241 } else if ((modeSecond == CBC_QRCoderMode::sBYTE) &&
242 (modeFirst == CBC_QRCoderMode::sNUMERIC)) {
243 if (versionNum >= 1 && versionNum <= 9) {
244 return 6;
245 } else if (versionNum >= 10 && versionNum <= 26) {
246 return 8;
247 } else if (versionNum >= 27 && versionNum <= 40) {
248 return 9;
249 } else {
250 e = BCExceptionNoSuchVersion;
251 BC_EXCEPTION_CHECK_ReturnValue(e, 0);
252 }
253 }
254 return -1;
255 }
256 void CBC_QRCoderEncoder::MergeString(CFX_PtrArray& result,
257 int32_t versionNum,
258 int32_t& e) {
259 Make_Pair* first = NULL;
260 Make_Pair* second = NULL;
261 size_t mergeNum = 0;
262 int32_t i;
263 for (i = 0; ((i < result.GetSize()) && (i + 1 < result.GetSize())); i++) {
264 first = (Make_Pair*)result[i];
265 second = (Make_Pair*)result[i + 1];
266 if (first->m_mode == CBC_QRCoderMode::sALPHANUMERIC) {
267 int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sALPHANUMERIC,
268 CBC_QRCoderMode::sBYTE, versionNum, e);
269 BC_EXCEPTION_CHECK_ReturnVoid(e);
270 if ((second->m_mode == CBC_QRCoderMode::sBYTE) &&
271 (first->m_string.GetLength() < tmp)) {
272 CFX_ByteString str = first->m_string + second->m_string;
273 second->m_string = str;
274 delete first;
275 result.RemoveAt(i);
276 i--;
277 mergeNum++;
278 }
279 } else if (first->m_mode == CBC_QRCoderMode::sBYTE) {
280 if (second->m_mode == CBC_QRCoderMode::sBYTE) {
281 first->m_string += second->m_string;
282 delete second;
283 result.RemoveAt(i + 1);
284 i--;
285 mergeNum++;
286 }
287 } else if (first->m_mode == CBC_QRCoderMode::sNUMERIC) {
288 int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC,
289 CBC_QRCoderMode::sBYTE, versionNum, e);
290 BC_EXCEPTION_CHECK_ReturnVoid(e);
291 if ((second->m_mode == CBC_QRCoderMode::sBYTE) &&
292 (first->m_string.GetLength() < tmp)) {
293 CFX_ByteString str = first->m_string + second->m_string;
294 second->m_string = str;
295 delete first;
296 result.RemoveAt(i);
297 i--;
298 mergeNum++;
299 }
300 tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC,
301 CBC_QRCoderMode::sALPHANUMERIC, versionNum, e);
302 BC_EXCEPTION_CHECK_ReturnVoid(e);
303 if ((second->m_mode == CBC_QRCoderMode::sALPHANUMERIC) &&
304 (first->m_string.GetLength() < tmp)) {
305 CFX_ByteString str = first->m_string + second->m_string;
306 second->m_string = str;
307 delete first;
308 result.RemoveAt(i);
309 i--;
310 mergeNum++;
311 }
312 }
313 }
314 if (mergeNum == 0) {
315 return;
316 }
317 MergeString(result, versionNum, e);
318 BC_EXCEPTION_CHECK_ReturnVoid(e);
319 }
320 void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes,
321 int32_t versionNumber,
322 CBC_QRCoderErrorCorrectionLevel* ecLevel,
323 CBC_QRCoderMode* mode,
324 CBC_QRCoder* qrCode,
325 int32_t& e) {
326 qrCode->SetECLevel(ecLevel);
327 qrCode->SetMode(mode);
328 CBC_QRCoderVersion* version =
329 CBC_QRCoderVersion::GetVersionForNumber(versionNumber, e);
330 BC_EXCEPTION_CHECK_ReturnVoid(e);
331 int32_t numBytes = version->GetTotalCodeWords();
332 CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
333 int32_t numEcBytes = ecBlocks->GetTotalECCodeWords();
334 int32_t numRSBlocks = ecBlocks->GetNumBlocks();
335 int32_t numDataBytes = numBytes - numEcBytes;
336 if (numDataBytes >= numInputBytes + 3) {
337 qrCode->SetVersion(versionNumber);
338 qrCode->SetNumTotalBytes(numBytes);
339 qrCode->SetNumDataBytes(numDataBytes);
340 qrCode->SetNumRSBlocks(numRSBlocks);
341 qrCode->SetNumECBytes(numEcBytes);
342 qrCode->SetMatrixWidth(version->GetDimensionForVersion());
343 return;
344 }
345 e = BCExceptionCannotFindBlockInfo;
346 BC_EXCEPTION_CHECK_ReturnVoid(e);
347 }
348 void CBC_QRCoderEncoder::EncodeWithSpecifyVersion(
349 const CFX_ByteString& content,
350 CBC_QRCoderErrorCorrectionLevel* ecLevel,
351 CBC_QRCoder* qrCode,
352 int32_t versionSpecify,
353 int32_t& e) {
354 CFX_ByteString encoding = "utf8";
355 CBC_QRCoderMode* mode = CBC_QRCoderMode::sBYTE;
356 CFX_PtrArray splitResult;
357 CBC_QRCoderBitVector dataBits;
358 dataBits.Init();
359 SplitString(content, splitResult);
360 MergeString(splitResult, versionSpecify, e);
361 BC_EXCEPTION_CHECK_ReturnVoid(e) CBC_QRCoderMode* tempMode = NULL;
362 for (int32_t i = 0; i < splitResult.GetSize(); i++) {
363 AppendBytes(((Make_Pair*)splitResult[i])->m_string,
364 ((Make_Pair*)splitResult[i])->m_mode, &dataBits, encoding, e);
365 if (e != BCExceptionNO) {
366 for (int32_t y = 0; y < splitResult.GetSize(); y++) {
367 delete (Make_Pair*)splitResult[y];
368 }
369 splitResult.RemoveAll();
370 return;
371 }
372 }
373 int32_t numInputBytes = dataBits.sizeInBytes();
374 CBC_QRCoderBitVector headerAndDataBits;
375 headerAndDataBits.Init();
376 InitQRCode(numInputBytes, versionSpecify, ecLevel, mode, qrCode, e);
377 if (e != BCExceptionNO) {
378 for (int32_t k = 0; k < splitResult.GetSize(); k++) {
379 delete (Make_Pair*)splitResult[k];
380 }
381 splitResult.RemoveAll();
382 return;
383 }
384 AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode,
385 encoding, e);
386 if (e != BCExceptionNO) {
387 for (int32_t k = 0; k < splitResult.GetSize(); k++) {
388 delete (Make_Pair*)splitResult[k];
389 }
390 splitResult.RemoveAll();
391 return;
392 }
393 numInputBytes = headerAndDataBits.sizeInBytes();
394 TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
395 if (e != BCExceptionNO) {
396 for (int32_t k = 0; k < splitResult.GetSize(); k++) {
397 delete (Make_Pair*)splitResult[k];
398 }
399 splitResult.RemoveAll();
400 return;
401 }
402 for (int32_t j = 0; j < splitResult.GetSize(); j++) {
403 delete (Make_Pair*)splitResult[j];
404 }
405 splitResult.RemoveAll();
406 CBC_QRCoderBitVector finalBits;
407 finalBits.Init();
408 InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
409 qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
410 &finalBits, e);
411 BC_EXCEPTION_CHECK_ReturnVoid(e);
412 std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix(
413 qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth()));
414 matrix->Init();
415 int32_t maskPattern = ChooseMaskPattern(
416 &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
417 BC_EXCEPTION_CHECK_ReturnVoid(e);
418 qrCode->SetMaskPattern(maskPattern);
419 CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
420 qrCode->GetVersion(),
421 qrCode->GetMaskPattern(), matrix.get(), e);
422 BC_EXCEPTION_CHECK_ReturnVoid(e);
423 qrCode->SetMatrix(matrix.release());
424 if (!qrCode->IsValid()) {
425 e = BCExceptionInvalidQRCode;
426 BC_EXCEPTION_CHECK_ReturnVoid(e);
427 }
428 }
429 void CBC_QRCoderEncoder::EncodeWithAutoVersion(
430 const CFX_ByteString& content,
431 CBC_QRCoderErrorCorrectionLevel* ecLevel,
432 CBC_QRCoder* qrCode,
433 int32_t& e) {
434 CFX_ByteString encoding = "utf8";
435 CBC_QRCoderMode* mode = CBC_QRCoderMode::sBYTE;
436 CFX_PtrArray splitResult;
437 CBC_QRCoderBitVector dataBits;
438 dataBits.Init();
439 SplitString(content, splitResult);
440 MergeString(splitResult, 8, e);
441 BC_EXCEPTION_CHECK_ReturnVoid(e);
442 CBC_QRCoderMode* tempMode = NULL;
443 for (int32_t i = 0; i < splitResult.GetSize(); i++) {
444 AppendBytes(((Make_Pair*)splitResult[i])->m_string,
445 ((Make_Pair*)splitResult[i])->m_mode, &dataBits, encoding, e);
446 if (e != BCExceptionNO) {
447 for (int32_t l = 0; l < splitResult.GetSize(); l++) {
448 delete (Make_Pair*)splitResult[l];
449 }
450 splitResult.RemoveAll();
451 return;
452 }
453 }
454 int32_t numInputBytes = dataBits.sizeInBytes();
455 InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
456 BC_EXCEPTION_CHECK_ReturnVoid(e) CBC_QRCoderBitVector headerAndDataBits;
457 headerAndDataBits.Init();
458 tempMode = NULL;
459 int32_t versionNum = qrCode->GetVersion();
460 sign:
461 AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode,
462 encoding, e);
463 if (e != BCExceptionNO) {
464 goto catchException;
465 }
466 numInputBytes = headerAndDataBits.sizeInBytes();
467 TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
468 if (e != BCExceptionNO) {
469 goto catchException;
470 }
471 catchException:
472 if (e != BCExceptionNO) {
473 int32_t e1 = BCExceptionNO;
474 InitQRCode(numInputBytes, ecLevel, mode, qrCode, e1);
475 if (e1 != BCExceptionNO) {
476 e = e1;
477 return;
478 }
479 versionNum++;
480 if (versionNum <= 40) {
481 headerAndDataBits.Clear();
482 e = BCExceptionNO;
483 goto sign;
484 } else {
485 for (int32_t j = 0; j < splitResult.GetSize(); j++) {
486 delete (Make_Pair*)splitResult[j];
487 }
488 splitResult.RemoveAll();
489 return;
490 }
491 }
492 for (int32_t k = 0; k < splitResult.GetSize(); k++) {
493 delete (Make_Pair*)splitResult[k];
494 }
495 splitResult.RemoveAll();
496 CBC_QRCoderBitVector finalBits;
497 finalBits.Init();
498 InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
499 qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
500 &finalBits, e);
501 BC_EXCEPTION_CHECK_ReturnVoid(e);
502 std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix(
503 qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth()));
504 matrix->Init();
505 int32_t maskPattern = ChooseMaskPattern(
506 &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
507 BC_EXCEPTION_CHECK_ReturnVoid(e);
508 qrCode->SetMaskPattern(maskPattern);
509 CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
510 qrCode->GetVersion(),
511 qrCode->GetMaskPattern(), matrix.get(), e);
512 BC_EXCEPTION_CHECK_ReturnVoid(e) qrCode->SetMatrix(matrix.release());
513 if (!qrCode->IsValid()) {
514 e = BCExceptionInvalidQRCode;
515 BC_EXCEPTION_CHECK_ReturnVoid(e);
516 }
517 }
518 void CBC_QRCoderEncoder::Encode(const CFX_WideString& content,
519 CBC_QRCoderErrorCorrectionLevel* ecLevel,
520 CBC_QRCoder* qrCode,
521 int32_t& e) {
522 CFX_ByteString encoding = "utf8";
523 CFX_ByteString utf8Data;
524 CBC_UtilCodingConvert::UnicodeToUTF8(content, utf8Data);
525 CBC_QRCoderMode* mode = ChooseMode(utf8Data, encoding);
526 CBC_QRCoderBitVector dataBits;
527 dataBits.Init();
528 AppendBytes(utf8Data, mode, &dataBits, encoding, e);
529 BC_EXCEPTION_CHECK_ReturnVoid(e);
530 int32_t numInputBytes = dataBits.sizeInBytes();
531 InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
532 BC_EXCEPTION_CHECK_ReturnVoid(e);
533 CBC_QRCoderBitVector headerAndDataBits;
534 headerAndDataBits.Init();
535 AppendModeInfo(mode, &headerAndDataBits, e);
536 BC_EXCEPTION_CHECK_ReturnVoid(e);
537 int32_t numLetters = mode == CBC_QRCoderMode::sBYTE ? dataBits.sizeInBytes()
538 : content.GetLength();
539 AppendLengthInfo(numLetters, qrCode->GetVersion(), mode, &headerAndDataBits,
540 e);
541 BC_EXCEPTION_CHECK_ReturnVoid(e);
542 headerAndDataBits.AppendBitVector(&dataBits, e);
543 BC_EXCEPTION_CHECK_ReturnVoid(e)
544 TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
545 BC_EXCEPTION_CHECK_ReturnVoid(e);
546 CBC_QRCoderBitVector finalBits;
547 finalBits.Init();
548 InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
549 qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
550 &finalBits, e);
551 BC_EXCEPTION_CHECK_ReturnVoid(e);
552 std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix(
553 qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth()));
554 matrix->Init();
555 int32_t maskPattern = ChooseMaskPattern(
556 &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
557 BC_EXCEPTION_CHECK_ReturnVoid(e);
558 qrCode->SetMaskPattern(maskPattern);
559 CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
560 qrCode->GetVersion(),
561 qrCode->GetMaskPattern(), matrix.get(), e);
562 BC_EXCEPTION_CHECK_ReturnVoid(e) qrCode->SetMatrix(matrix.release());
563 if (!qrCode->IsValid()) {
564 e = BCExceptionInvalidQRCode;
565 BC_EXCEPTION_CHECK_ReturnVoid(e);
566 }
567 }
568 void CBC_QRCoderEncoder::TerminateBits(int32_t numDataBytes,
569 CBC_QRCoderBitVector* bits,
570 int32_t& e) {
571 int32_t capacity = numDataBytes << 3;
572 if (bits->Size() > capacity) {
573 e = BCExceptionDataTooMany;
574 BC_EXCEPTION_CHECK_ReturnVoid(e);
575 }
576 for (int32_t i = 0; i < 4 && bits->Size() < capacity; ++i) {
577 bits->AppendBit(0, e);
578 BC_EXCEPTION_CHECK_ReturnVoid(e);
579 }
580 int32_t numBitsInLastByte = bits->Size() % 8;
581 if (numBitsInLastByte > 0) {
582 int32_t numPaddingBits = 8 - numBitsInLastByte;
583 for (int32_t j = 0; j < numPaddingBits; ++j) {
584 bits->AppendBit(0, e);
585 BC_EXCEPTION_CHECK_ReturnVoid(e)
586 }
587 }
588 if (bits->Size() % 8 != 0) {
589 e = BCExceptionDigitLengthMustBe8;
590 BC_EXCEPTION_CHECK_ReturnVoid(e);
591 }
592 int32_t numPaddingBytes = numDataBytes - bits->sizeInBytes();
593 for (int32_t k = 0; k < numPaddingBytes; ++k) {
594 if (k % 2 == 0) {
595 bits->AppendBits(0xec, 8, e);
596 BC_EXCEPTION_CHECK_ReturnVoid(e);
597 } else {
598 bits->AppendBits(0x11, 8, e);
599 BC_EXCEPTION_CHECK_ReturnVoid(e);
600 }
601 }
602 if (bits->Size() != capacity) {
603 e = BCExceptionBitsNotEqualCacity;
604 BC_EXCEPTION_CHECK_ReturnVoid(e);
605 }
606 }
607 int32_t CBC_QRCoderEncoder::ChooseMaskPattern(
608 CBC_QRCoderBitVector* bits,
609 CBC_QRCoderErrorCorrectionLevel* ecLevel,
610 int32_t version,
611 CBC_CommonByteMatrix* matrix,
612 int32_t& e) {
613 int32_t minPenalty = 65535;
614 int32_t bestMaskPattern = -1;
615 for (int32_t maskPattern = 0; maskPattern < CBC_QRCoder::NUM_MASK_PATTERNS;
616 maskPattern++) {
617 CBC_QRCoderMatrixUtil::BuildMatrix(bits, ecLevel, version, maskPattern,
618 matrix, e);
619 BC_EXCEPTION_CHECK_ReturnValue(e, 0);
620 int32_t penalty = CalculateMaskPenalty(matrix);
621 if (penalty < minPenalty) {
622 minPenalty = penalty;
623 bestMaskPattern = maskPattern;
624 }
625 }
626 return bestMaskPattern;
627 }
628 int32_t CBC_QRCoderEncoder::CalculateMaskPenalty(CBC_CommonByteMatrix* matrix) {
629 int32_t penalty = 0;
630 penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(matrix);
631 penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(matrix);
632 penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(matrix);
633 penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(matrix);
634 return penalty;
635 }
636 CBC_QRCoderMode* CBC_QRCoderEncoder::ChooseMode(const CFX_ByteString& content,
637 CFX_ByteString encoding) {
638 if (encoding.Compare("SHIFT_JIS") == 0) {
639 return CBC_QRCoderMode::sKANJI;
640 }
641 FX_BOOL hasNumeric = FALSE;
642 FX_BOOL hasAlphaNumeric = FALSE;
643 for (int32_t i = 0; i < content.GetLength(); i++) {
644 if (isdigit((uint8_t)content[i])) {
645 hasNumeric = TRUE;
646 } else if (GetAlphaNumericCode((uint8_t)content[i]) != -1) {
647 hasAlphaNumeric = TRUE;
648 } else {
649 return CBC_QRCoderMode::sBYTE;
650 }
651 }
652 if (hasAlphaNumeric) {
653 return CBC_QRCoderMode::sALPHANUMERIC;
654 } else if (hasNumeric) {
655 return CBC_QRCoderMode::sNUMERIC;
656 }
657 return CBC_QRCoderMode::sBYTE;
658 }
659 int32_t CBC_QRCoderEncoder::GetAlphaNumericCode(int32_t code) {
660 if (code < 96 && code >= 0) {
661 return m_alphaNumbericTable[code];
662 }
663 return -1;
664 }
665 void CBC_QRCoderEncoder::AppendBytes(const CFX_ByteString& content,
666 CBC_QRCoderMode* mode,
667 CBC_QRCoderBitVector* bits,
668 CFX_ByteString encoding,
669 int32_t& e) {
670 if (mode == CBC_QRCoderMode::sNUMERIC) {
671 AppendNumericBytes(content, bits, e);
672 BC_EXCEPTION_CHECK_ReturnVoid(e);
673 } else if (mode == CBC_QRCoderMode::sALPHANUMERIC) {
674 AppendAlphaNumericBytes(content, bits, e);
675 BC_EXCEPTION_CHECK_ReturnVoid(e);
676 } else if (mode == CBC_QRCoderMode::sBYTE) {
677 Append8BitBytes(content, bits, encoding, e);
678 BC_EXCEPTION_CHECK_ReturnVoid(e);
679 } else if (mode == CBC_QRCoderMode::sKANJI) {
680 AppendKanjiBytes(content, bits, e);
681 BC_EXCEPTION_CHECK_ReturnVoid(e);
682 } else if (mode == CBC_QRCoderMode::sGBK) {
683 AppendGBKBytes(content, bits, e);
684 BC_EXCEPTION_CHECK_ReturnVoid(e);
685 } else {
686 e = BCExceptionUnsupportedMode;
687 BC_EXCEPTION_CHECK_ReturnVoid(e);
688 }
689 }
690 void CBC_QRCoderEncoder::AppendNumericBytes(const CFX_ByteString& content,
691 CBC_QRCoderBitVector* bits,
692 int32_t& e) {
693 int32_t length = content.GetLength();
694 int32_t i = 0;
695 while (i < length) {
696 int32_t num1 = content[i] - '0';
697 if (i + 2 < length) {
698 int32_t num2 = content[i + 1] - '0';
699 int32_t num3 = content[i + 2] - '0';
700 bits->AppendBits(num1 * 100 + num2 * 10 + num3, 10, e);
701 BC_EXCEPTION_CHECK_ReturnVoid(e) i += 3;
702 } else if (i + 1 < length) {
703 int32_t num2 = content[i + 1] - '0';
704 bits->AppendBits(num1 * 10 + num2, 7, e);
705 BC_EXCEPTION_CHECK_ReturnVoid(e) i += 2;
706 } else {
707 bits->AppendBits(num1, 4, e);
708 BC_EXCEPTION_CHECK_ReturnVoid(e);
709 i++;
710 }
711 }
712 }
713 void CBC_QRCoderEncoder::AppendAlphaNumericBytes(const CFX_ByteString& content,
714 CBC_QRCoderBitVector* bits,
715 int32_t& e) {
716 int32_t length = content.GetLength();
717 int32_t i = 0;
718 while (i < length) {
719 int32_t code1 = GetAlphaNumericCode(content[i]);
720 if (code1 == -1) {
721 e = BCExceptionInvalidateCharacter;
722 BC_EXCEPTION_CHECK_ReturnVoid(e);
723 }
724 if (i + 1 < length) {
725 int32_t code2 = GetAlphaNumericCode(content[i + 1]);
726 if (code2 == -1) {
727 e = BCExceptionInvalidateCharacter;
728 BC_EXCEPTION_CHECK_ReturnVoid(e);
729 }
730 bits->AppendBits(code1 * 45 + code2, 11, e);
731 BC_EXCEPTION_CHECK_ReturnVoid(e);
732 i += 2;
733 } else {
734 bits->AppendBits(code1, 6, e);
735 BC_EXCEPTION_CHECK_ReturnVoid(e) i++;
736 }
737 }
738 }
739 void CBC_QRCoderEncoder::AppendGBKBytes(const CFX_ByteString& content,
740 CBC_QRCoderBitVector* bits,
741 int32_t& e) {
742 int32_t length = content.GetLength();
743 FX_DWORD value = 0;
744 for (int32_t i = 0; i < length; i += 2) {
745 value = (FX_DWORD)((uint8_t)content[i] << 8 | (uint8_t)content[i + 1]);
746 if (value <= 0xAAFE && value >= 0xA1A1) {
747 value -= 0xA1A1;
748 } else if (value <= 0xFAFE && value >= 0xB0A1) {
749 value -= 0xA6A1;
750 } else {
751 e = BCExceptionInvalidateCharacter;
752 BC_EXCEPTION_CHECK_ReturnVoid(e);
753 }
754 value = (FX_DWORD)((value >> 8) * 0x60) + (FX_DWORD)(value & 0xff);
755 bits->AppendBits(value, 13, e);
756 BC_EXCEPTION_CHECK_ReturnVoid(e);
757 }
758 }
759 void CBC_QRCoderEncoder::Append8BitBytes(const CFX_ByteString& content,
760 CBC_QRCoderBitVector* bits,
761 CFX_ByteString encoding,
762 int32_t& e) {
763 for (int32_t i = 0; i < content.GetLength(); i++) {
764 bits->AppendBits(content[i], 8, e);
765 BC_EXCEPTION_CHECK_ReturnVoid(e);
766 }
767 }
768 void CBC_QRCoderEncoder::Append8BitBytes(CFX_ByteArray& bytes,
769 CBC_QRCoderBitVector* bits,
770 int32_t& e) {
771 for (int32_t i = 0; i < bytes.GetSize(); i++) {
772 bits->AppendBits(bytes[i], 8, e);
773 BC_EXCEPTION_CHECK_ReturnVoid(e);
774 }
775 }
776 void CBC_QRCoderEncoder::AppendKanjiBytes(const CFX_ByteString& content,
777 CBC_QRCoderBitVector* bits,
778 int32_t& e) {
779 CFX_ByteArray bytes;
780 FX_DWORD value = 0;
781 for (int32_t i = 0; i < bytes.GetSize(); i += 2) {
782 value = (FX_DWORD)((uint8_t)(content[i] << 8) | (uint8_t)content[i + 1]);
783 if (value <= 0x9ffc && value >= 0x8140) {
784 value -= 0x8140;
785 } else if (value <= 0xebbf && value >= 0xe040) {
786 value -= 0xc140;
787 } else {
788 e = BCExceptionInvalidateCharacter;
789 BC_EXCEPTION_CHECK_ReturnVoid(e);
790 }
791 value = (FX_DWORD)((value >> 8) * 0xc0) + (FX_DWORD)(value & 0xff);
792 bits->AppendBits(value, 13, e);
793 BC_EXCEPTION_CHECK_ReturnVoid(e);
794 }
795 }
796 void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes,
797 CBC_QRCoderErrorCorrectionLevel* ecLevel,
798 CBC_QRCoderMode* mode,
799 CBC_QRCoder* qrCode,
800 int32_t& e) {
801 qrCode->SetECLevel(ecLevel);
802 qrCode->SetMode(mode);
803 for (int32_t versionNum = 1; versionNum <= 40; versionNum++) {
804 CBC_QRCoderVersion* version =
805 CBC_QRCoderVersion::GetVersionForNumber(versionNum, e);
806 BC_EXCEPTION_CHECK_ReturnVoid(e);
807 int32_t numBytes = version->GetTotalCodeWords();
808 CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
809 int32_t numEcBytes = ecBlocks->GetTotalECCodeWords();
810 int32_t numRSBlocks = ecBlocks->GetNumBlocks();
811 int32_t numDataBytes = numBytes - numEcBytes;
812 if (numDataBytes >= numInputBytes + 3) {
813 qrCode->SetVersion(versionNum);
814 qrCode->SetNumTotalBytes(numBytes);
815 qrCode->SetNumDataBytes(numDataBytes);
816 qrCode->SetNumRSBlocks(numRSBlocks);
817 qrCode->SetNumECBytes(numEcBytes);
818 qrCode->SetMatrixWidth(version->GetDimensionForVersion());
819 return;
820 }
821 }
822 e = BCExceptionCannotFindBlockInfo;
823 BC_EXCEPTION_CHECK_ReturnVoid(e);
824 }
825 void CBC_QRCoderEncoder::AppendModeInfo(CBC_QRCoderMode* mode,
826 CBC_QRCoderBitVector* bits,
827 int32_t& e) {
828 bits->AppendBits(mode->GetBits(), 4, e);
829 if (mode == CBC_QRCoderMode::sGBK) {
830 bits->AppendBits(1, 4, e);
831 BC_EXCEPTION_CHECK_ReturnVoid(e);
832 }
833 }
834 void CBC_QRCoderEncoder::AppendLengthInfo(int32_t numLetters,
835 int32_t version,
836 CBC_QRCoderMode* mode,
837 CBC_QRCoderBitVector* bits,
838 int32_t& e) {
839 CBC_QRCoderVersion* qcv = CBC_QRCoderVersion::GetVersionForNumber(version, e);
840 BC_EXCEPTION_CHECK_ReturnVoid(e);
841 int32_t numBits = mode->GetCharacterCountBits(qcv, e);
842 BC_EXCEPTION_CHECK_ReturnVoid(e);
843 if (numBits > ((1 << numBits) - 1)) {
844 return;
845 }
846 if (mode == CBC_QRCoderMode::sGBK) {
847 bits->AppendBits(numLetters / 2, numBits, e);
848 BC_EXCEPTION_CHECK_ReturnVoid(e);
849 }
850 bits->AppendBits(numLetters, numBits, e);
851 BC_EXCEPTION_CHECK_ReturnVoid(e);
852 }
853 void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits,
854 int32_t numTotalBytes,
855 int32_t numDataBytes,
856 int32_t numRSBlocks,
857 CBC_QRCoderBitVector* result,
858 int32_t& e) {
859 if (bits->sizeInBytes() != numDataBytes) {
860 e = BCExceptionBitsBytesNotMatch;
861 BC_EXCEPTION_CHECK_ReturnVoid(e);
862 }
863 int32_t dataBytesOffset = 0;
864 int32_t maxNumDataBytes = 0;
865 int32_t maxNumEcBytes = 0;
866 CFX_PtrArray blocks;
867 int32_t i;
868 for (i = 0; i < numRSBlocks; i++) {
869 int32_t numDataBytesInBlock;
870 int32_t numEcBytesInBlosk;
871 GetNumDataBytesAndNumECBytesForBlockID(numTotalBytes, numDataBytes,
872 numRSBlocks, i, numDataBytesInBlock,
873 numEcBytesInBlosk);
874 CBC_CommonByteArray* dataBytes = new CBC_CommonByteArray;
875 dataBytes->Set(bits->GetArray(), dataBytesOffset, numDataBytesInBlock);
876 CBC_CommonByteArray* ecBytes =
877 GenerateECBytes(dataBytes, numEcBytesInBlosk, e);
878 BC_EXCEPTION_CHECK_ReturnVoid(e);
879 blocks.Add(new CBC_QRCoderBlockPair(dataBytes, ecBytes));
880 maxNumDataBytes = std::max(maxNumDataBytes, dataBytes->Size());
881 maxNumEcBytes = std::max(maxNumEcBytes, ecBytes->Size());
882 dataBytesOffset += numDataBytesInBlock;
883 }
884 if (numDataBytes != dataBytesOffset) {
885 e = BCExceptionBytesNotMatchOffset;
886 BC_EXCEPTION_CHECK_ReturnVoid(e);
887 }
888 for (int32_t x = 0; x < maxNumDataBytes; x++) {
889 for (int32_t j = 0; j < blocks.GetSize(); j++) {
890 CBC_CommonByteArray* dataBytes =
891 ((CBC_QRCoderBlockPair*)blocks[j])->GetDataBytes();
892 if (x < dataBytes->Size()) {
893 result->AppendBits(dataBytes->At(x), 8, e);
894 BC_EXCEPTION_CHECK_ReturnVoid(e);
895 }
896 }
897 }
898 for (int32_t y = 0; y < maxNumEcBytes; y++) {
899 for (int32_t l = 0; l < blocks.GetSize(); l++) {
900 CBC_CommonByteArray* ecBytes =
901 ((CBC_QRCoderBlockPair*)blocks[l])->GetErrorCorrectionBytes();
902 if (y < ecBytes->Size()) {
903 result->AppendBits(ecBytes->At(y), 8, e);
904 BC_EXCEPTION_CHECK_ReturnVoid(e);
905 }
906 }
907 }
908 for (int32_t k = 0; k < blocks.GetSize(); k++) {
909 delete (CBC_QRCoderBlockPair*)blocks[k];
910 }
911 if (numTotalBytes != result->sizeInBytes()) {
912 e = BCExceptionSizeInBytesDiffer;
913 BC_EXCEPTION_CHECK_ReturnVoid(e);
914 }
915 }
916 void CBC_QRCoderEncoder::GetNumDataBytesAndNumECBytesForBlockID(
917 int32_t numTotalBytes,
918 int32_t numDataBytes,
919 int32_t numRSBlocks,
920 int32_t blockID,
921 int32_t& numDataBytesInBlock,
922 int32_t& numECBytesInBlock) {
923 if (blockID >= numRSBlocks) {
924 return;
925 }
926 int32_t numRsBlocksInGroup2 = numTotalBytes % numRSBlocks;
927 int32_t numRsBlocksInGroup1 = numRSBlocks - numRsBlocksInGroup2;
928 int32_t numTotalBytesInGroup1 = numTotalBytes / numRSBlocks;
929 int32_t numTotalBytesInGroup2 = numTotalBytesInGroup1 + 1;
930 int32_t numDataBytesInGroup1 = numDataBytes / numRSBlocks;
931 int32_t numDataBytesInGroup2 = numDataBytesInGroup1 + 1;
932 int32_t numEcBytesInGroup1 = numTotalBytesInGroup1 - numDataBytesInGroup1;
933 int32_t numEcBytesInGroup2 = numTotalBytesInGroup2 - numDataBytesInGroup2;
934 if (blockID < numRsBlocksInGroup1) {
935 numDataBytesInBlock = numDataBytesInGroup1;
936 numECBytesInBlock = numEcBytesInGroup1;
937 } else {
938 numDataBytesInBlock = numDataBytesInGroup2;
939 numECBytesInBlock = numEcBytesInGroup2;
940 }
941 }
942 CBC_CommonByteArray* CBC_QRCoderEncoder::GenerateECBytes(
943 CBC_CommonByteArray* dataBytes,
944 int32_t numEcBytesInBlock,
945 int32_t& e) {
946 int32_t numDataBytes = dataBytes->Size();
947 CFX_Int32Array toEncode;
948 toEncode.SetSize(numDataBytes + numEcBytesInBlock);
949 for (int32_t i = 0; i < numDataBytes; i++) {
950 toEncode[i] = (dataBytes->At(i));
951 }
952 CBC_ReedSolomonEncoder encode(CBC_ReedSolomonGF256::QRCodeFild);
953 encode.Init();
954 encode.Encode(&toEncode, numEcBytesInBlock, e);
955 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
956 CBC_CommonByteArray* ecBytes = new CBC_CommonByteArray(numEcBytesInBlock);
957 for (int32_t j = 0; j < numEcBytesInBlock; j++) {
958 ecBytes->Set(j, toEncode[numDataBytes + j]);
959 }
960 return ecBytes;
961 }
OLDNEW
« no previous file with comments | « xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.h ('k') | xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698