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

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

Powered by Google App Engine
This is Rietveld 408576698