Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_QRCoderMatrixUtil.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "barcode.h"\r
8 #include "include/BC_CommonByteMatrix.h"\r
9 #include "include/BC_QRCoderErrorCorrectionLevel.h"\r
10 #include "include/BC_QRCoder.h"\r
11 #include "include/BC_QRCoderMaskUtil.h"\r
12 #include "include/BC_QRCoderMatrixUtil.h"\r
13 #include "include/BC_QRCoderBitVector.h"\r
14 const FX_INT32 CBC_QRCoderMatrixUtil::POSITION_DETECTION_PATTERN[7][7] = {\r
15     1, 1, 1, 1, 1, 1, 1,\r
16     1, 0, 0, 0, 0, 0, 1,\r
17     1, 0, 1, 1, 1, 0, 1,\r
18     1, 0, 1, 1, 1, 0, 1,\r
19     1, 0, 1, 1, 1, 0, 1,\r
20     1, 0, 0, 0, 0, 0, 1,\r
21     1, 1, 1, 1, 1, 1, 1\r
22 };\r
23 const FX_INT32 CBC_QRCoderMatrixUtil::HORIZONTAL_SEPARATION_PATTERN[1][8] = {\r
24     0, 0, 0, 0, 0, 0, 0, 0\r
25 };\r
26 const FX_INT32 CBC_QRCoderMatrixUtil::VERTICAL_SEPARATION_PATTERN[7][1] = {\r
27     0, 0, 0, 0, 0, 0, 0\r
28 };\r
29 const FX_INT32 CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN[5][5] = {\r
30     1, 1, 1, 1, 1,\r
31     1, 0, 0, 0, 1,\r
32     1, 0, 1, 0, 1,\r
33     1, 0, 0, 0, 1,\r
34     1, 1, 1, 1, 1\r
35 };\r
36 const FX_INT32 CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7] = {\r
37     { -1, -1, -1, -1,  -1,  -1,  -1},\r
38     { 6, 18, -1, -1,  -1,  -1,  -1},\r
39     { 6, 22, -1, -1,  -1,  -1,  -1},\r
40     { 6, 26, -1, -1,  -1,  -1,  -1},\r
41     { 6, 30, -1, -1,  -1,  -1,  -1},\r
42     { 6, 34, -1, -1,  -1,  -1,  -1},\r
43     { 6, 22, 38, -1,  -1,  -1,  -1},\r
44     { 6, 24, 42, -1,  -1,  -1,  -1},\r
45     { 6, 26, 46, -1,  -1,  -1,  -1},\r
46     { 6, 28, 50, -1,  -1,  -1,  -1},\r
47     { 6, 30, 54, -1,  -1,  -1,  -1},\r
48     { 6, 32, 58, -1,  -1,  -1,  -1},\r
49     { 6, 34, 62, -1,  -1,  -1,  -1},\r
50     { 6, 26, 46, 66,  -1,  -1,  -1},\r
51     { 6, 26, 48, 70,  -1,  -1,  -1},\r
52     { 6, 26, 50, 74,  -1,  -1,  -1},\r
53     { 6, 30, 54, 78,  -1,  -1,  -1},\r
54     { 6, 30, 56, 82,  -1,  -1,  -1},\r
55     { 6, 30, 58, 86,  -1,  -1,  -1},\r
56     { 6, 34, 62, 90,  -1,  -1,  -1},\r
57     { 6, 28, 50, 72,  94,  -1,  -1},\r
58     { 6, 26, 50, 74,  98,  -1,  -1},\r
59     { 6, 30, 54, 78, 102,  -1,  -1},\r
60     { 6, 28, 54, 80, 106,  -1,  -1},\r
61     { 6, 32, 58, 84, 110,  -1,  -1},\r
62     { 6, 30, 58, 86, 114,  -1,  -1},\r
63     { 6, 34, 62, 90, 118,  -1,  -1},\r
64     { 6, 26, 50, 74,  98, 122,  -1},\r
65     { 6, 30, 54, 78, 102, 126,  -1},\r
66     { 6, 26, 52, 78, 104, 130,  -1},\r
67     { 6, 30, 56, 82, 108, 134,  -1},\r
68     { 6, 34, 60, 86, 112, 138,  -1},\r
69     { 6, 30, 58, 86, 114, 142,  -1},\r
70     { 6, 34, 62, 90, 118, 146,  -1},\r
71     { 6, 30, 54, 78, 102, 126, 150},\r
72     { 6, 24, 50, 76, 102, 128, 154},\r
73     { 6, 28, 54, 80, 106, 132, 158},\r
74     { 6, 32, 58, 84, 110, 136, 162},\r
75     { 6, 26, 54, 82, 110, 138, 166},\r
76     { 6, 30, 58, 86, 114, 142, 170},\r
77 };\r
78 const FX_INT32 CBC_QRCoderMatrixUtil::TYPE_INFO_COORDINATES[15][2] = {\r
79     {8, 0},\r
80     {8, 1},\r
81     {8, 2},\r
82     {8, 3},\r
83     {8, 4},\r
84     {8, 5},\r
85     {8, 7},\r
86     {8, 8},\r
87     {7, 8},\r
88     {5, 8},\r
89     {4, 8},\r
90     {3, 8},\r
91     {2, 8},\r
92     {1, 8},\r
93     {0, 8},\r
94 };\r
95 const FX_INT32 CBC_QRCoderMatrixUtil::VERSION_INFO_POLY = 0x1f25;\r
96 const FX_INT32 CBC_QRCoderMatrixUtil::TYPE_INFO_POLY = 0x0537;\r
97 const FX_INT32 CBC_QRCoderMatrixUtil::TYPE_INFO_MASK_PATTERN = 0x5412;\r
98 void CBC_QRCoderMatrixUtil::ClearMatrix(CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
99 {\r
100     if(matrix == NULL) {\r
101         e = BCExceptionNullPointer;\r
102         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
103     }\r
104     matrix->clear((FX_BYTE) - 1);\r
105 }\r
106 void CBC_QRCoderMatrixUtil::BuildMatrix(CBC_QRCoderBitVector* dataBits,\r
107                                         CBC_QRCoderErrorCorrectionLevel* ecLevel,\r
108                                         FX_INT32 version, FX_INT32 maskPattern,\r
109                                         CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
110 {\r
111     if(matrix == NULL) {\r
112         e = BCExceptionNullPointer;\r
113         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
114     }\r
115     ClearMatrix(matrix, e);\r
116     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
117     EmbedBasicPatterns(version, matrix, e);\r
118     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
119     EmbedTypeInfo(ecLevel, maskPattern, matrix, e);\r
120     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
121     MaybeEmbedVersionInfo(version, matrix, e);\r
122     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
123     EmbedDataBits(dataBits, maskPattern, matrix, e);\r
124     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
125 }\r
126 void CBC_QRCoderMatrixUtil::EmbedBasicPatterns(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
127 {\r
128     if(matrix == NULL) {\r
129         e = BCExceptionNullPointer;\r
130         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
131     }\r
132     EmbedPositionDetectionPatternsAndSeparators(matrix, e);\r
133     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
134     EmbedDarkDotAtLeftBottomCorner(matrix, e);\r
135     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
136     MaybeEmbedPositionAdjustmentPatterns(version, matrix, e);\r
137     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
138     EmbedTimingPatterns(matrix, e);\r
139     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
140 }\r
141 void CBC_QRCoderMatrixUtil::EmbedTypeInfo(CBC_QRCoderErrorCorrectionLevel* ecLevel,\r
142         FX_INT32 maskPattern, CBC_CommonByteMatrix *matrix, FX_INT32 &e)\r
143 {\r
144     if(matrix == NULL) {\r
145         e = BCExceptionNullPointer;\r
146         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
147     }\r
148     CBC_QRCoderBitVector typeInfoBits;\r
149     typeInfoBits.Init();\r
150     MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits, e);\r
151     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
152     for(FX_INT32 i = 0; i < typeInfoBits.Size(); i++) {\r
153         FX_INT32 bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e);\r
154         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
155         FX_INT32 x1 = TYPE_INFO_COORDINATES[i][0];\r
156         FX_INT32 y1 = TYPE_INFO_COORDINATES[i][1];\r
157         matrix->Set(x1, y1, bit);\r
158         if(i < 8) {\r
159             FX_INT32 x2 = matrix->GetWidth() - i - 1;\r
160             FX_INT32 y2 = 8;\r
161             matrix->Set(x2, y2, bit);\r
162         } else {\r
163             FX_INT32 x2 = 8;\r
164             FX_INT32 y2 = matrix->GetHeight() - 7 + (i - 8);\r
165             matrix->Set(x2, y2, bit);\r
166         }\r
167     }\r
168 }\r
169 void CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
170 {\r
171     if(matrix == NULL) {\r
172         e = BCExceptionNullPointer;\r
173         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
174     }\r
175     if(version < 7) {\r
176         return;\r
177     }\r
178     CBC_QRCoderBitVector versionInfoBits;\r
179     versionInfoBits.Init();\r
180     MakeVersionInfoBits(version, &versionInfoBits, e);\r
181     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
182     FX_INT32 bitIndex = 6 * 3 - 1;\r
183     for(FX_INT32 i = 0; i < 6; i++) {\r
184         for(FX_INT32 j = 0; j < 3; j++) {\r
185             FX_INT32 bit = versionInfoBits.At(bitIndex, e);\r
186             BC_EXCEPTION_CHECK_ReturnVoid(e);\r
187             bitIndex--;\r
188             matrix->Set(i, matrix->GetHeight() - 11 + j, bit);\r
189             matrix->Set(matrix->GetHeight() - 11 + j, i, bit);\r
190         }\r
191     }\r
192 }\r
193 void CBC_QRCoderMatrixUtil::EmbedDataBits(CBC_QRCoderBitVector* dataBits,\r
194         FX_INT32 maskPattern, CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
195 {\r
196     if(matrix == NULL || dataBits == NULL) {\r
197         e = BCExceptionNullPointer;\r
198         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
199     }\r
200     FX_INT32 bitIndex = 0;\r
201     FX_INT32 direction = -1;\r
202     FX_INT32 x = matrix->GetWidth() - 1;\r
203     FX_INT32 y = matrix->GetHeight() - 1;\r
204     while(x > 0) {\r
205         if (x == 6) {\r
206             x -= 1;\r
207         }\r
208         while(y >= 0 && y < matrix->GetHeight()) {\r
209             if (y == 6) {\r
210                 y += direction;\r
211                 continue;\r
212             }\r
213             for(FX_INT32 i = 0; i < 2; i++) {\r
214                 FX_INT32 xx = x - i;\r
215                 if(!IsEmpty(matrix->Get(xx, y))) {\r
216                     continue;\r
217                 }\r
218                 FX_INT32 bit;\r
219                 if(bitIndex < dataBits->Size()) {\r
220                     bit = dataBits->At(bitIndex, e);\r
221                     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
222                     bitIndex++;\r
223                 } else {\r
224                     bit = 0;\r
225                 }\r
226                 if( maskPattern != -1) {\r
227                     FX_BOOL bol = CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y, e);\r
228                     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
229                     if(bol) {\r
230                         bit ^= 0x01;\r
231                     }\r
232                 }\r
233                 matrix->Set(xx, y, bit);\r
234             }\r
235             y += direction;\r
236         }\r
237         direction = -direction;\r
238         y += direction;\r
239         x -= 2;\r
240     }\r
241     if(bitIndex != dataBits->Size()) {\r
242         return;\r
243     }\r
244 }\r
245 FX_INT32 CBC_QRCoderMatrixUtil::CalculateBCHCode(FX_INT32 value, FX_INT32 poly)\r
246 {\r
247     FX_INT32 msbSetInPoly = FindMSBSet(poly);\r
248     value <<= msbSetInPoly - 1;\r
249     while(FindMSBSet(value) >= msbSetInPoly) {\r
250         value ^= poly << (FindMSBSet(value) - msbSetInPoly);\r
251     }\r
252     return value;\r
253 }\r
254 void CBC_QRCoderMatrixUtil::MakeTypeInfoBits(CBC_QRCoderErrorCorrectionLevel* ecLevel,\r
255         FX_INT32 maskPattern, CBC_QRCoderBitVector* bits, FX_INT32 &e)\r
256 {\r
257     if(bits == NULL) {\r
258         e = BCExceptionNullPointer;\r
259         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
260     }\r
261     if(!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {\r
262         e = BCExceptionBadMask;\r
263         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
264     }\r
265     FX_INT32 typeInfo = (ecLevel->GetBits() << 3) | maskPattern;\r
266     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
267     bits->AppendBits(typeInfo, 5, e);\r
268     FX_INT32 bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY);\r
269     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
270     bits->AppendBits(bchCode, 10, e);\r
271     CBC_QRCoderBitVector maskBits;\r
272     maskBits.Init();\r
273     maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15, e);\r
274     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
275     bits->XOR(&maskBits, e);\r
276     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
277     if(bits->Size() != 15) {\r
278         e = BCExceptionBitSizeNot15;\r
279         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
280     }\r
281 }\r
282 void CBC_QRCoderMatrixUtil::MakeVersionInfoBits(FX_INT32 version, CBC_QRCoderBitVector* bits, FX_INT32 &e)\r
283 {\r
284     if(bits == NULL) {\r
285         e = BCExceptionNullPointer;\r
286         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
287     }\r
288     bits->AppendBits(version, 6, e);\r
289     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
290     FX_INT32 bchCode = CalculateBCHCode(version, VERSION_INFO_POLY);\r
291     bits->AppendBits(bchCode, 12, e);\r
292     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
293     if(bits->Size() != 18) {\r
294         e = BCExceptionBitSizeNot18;\r
295         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
296     }\r
297 }\r
298 FX_BOOL CBC_QRCoderMatrixUtil::IsEmpty(FX_INT32 value)\r
299 {\r
300     return (FX_BYTE)value == 0xff;\r
301 }\r
302 FX_BOOL CBC_QRCoderMatrixUtil::IsValidValue(FX_INT32 value)\r
303 {\r
304     return ((FX_BYTE)value == 0xff || (FX_BYTE)value == 0x00 || (FX_BYTE)value == 0x01);\r
305 }\r
306 void CBC_QRCoderMatrixUtil::EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
307 {\r
308     if(matrix == NULL) {\r
309         e = BCExceptionNullPointer;\r
310         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
311     }\r
312     for(FX_INT32 i = 8; i < matrix->GetWidth() - 8; i++) {\r
313         FX_INT32 bit = (i + 1) % 2;\r
314         if(!IsValidValue(matrix->Get(i, 6))) {\r
315             e = BCExceptionInvalidateImageData;\r
316             BC_EXCEPTION_CHECK_ReturnVoid(e);\r
317         }\r
318         if(IsEmpty(matrix->Get(i , 6))) {\r
319             matrix->Set(i, 6, bit);\r
320         }\r
321         if(!IsValidValue(matrix->Get(6, i))) {\r
322             e = BCExceptionInvalidateImageData;\r
323             BC_EXCEPTION_CHECK_ReturnVoid(e);\r
324         }\r
325         if(IsEmpty(matrix->Get(6, i))) {\r
326             matrix->Set(6, i, bit);\r
327         }\r
328     }\r
329 }\r
330 void CBC_QRCoderMatrixUtil::EmbedDarkDotAtLeftBottomCorner(CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
331 {\r
332     if(matrix == NULL) {\r
333         e = BCExceptionNullPointer;\r
334         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
335     }\r
336     if(matrix->Get(8, matrix->GetHeight() - 8) == 0) {\r
337         e = BCExceptionHeight_8BeZero;\r
338         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
339     }\r
340     matrix->Set(8, matrix->GetHeight() - 8, 1);\r
341 }\r
342 void CBC_QRCoderMatrixUtil::EmbedHorizontalSeparationPattern(FX_INT32 xStart, FX_INT32 yStart,\r
343         CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
344 {\r
345     if(matrix == NULL) {\r
346         e = BCExceptionNullPointer;\r
347         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
348     }\r
349     for(FX_INT32 x = 0; x < 8; x++) {\r
350         if(!IsEmpty(matrix->Get(xStart + x, yStart))) {\r
351             e = BCExceptionInvalidateData;\r
352             BC_EXCEPTION_CHECK_ReturnVoid(e)\r
353         }\r
354         matrix->Set(xStart + x, yStart, HORIZONTAL_SEPARATION_PATTERN[0][x]);\r
355     }\r
356 }\r
357 void CBC_QRCoderMatrixUtil::EmbedVerticalSeparationPattern(FX_INT32 xStart, FX_INT32 yStart,\r
358         CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
359 {\r
360     if(matrix == NULL) {\r
361         e = BCExceptionNullPointer;\r
362         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
363     }\r
364     for(FX_INT32 y = 0; y < 7; y++) {\r
365         if(!IsEmpty(matrix->Get(xStart, yStart + y))) {\r
366             e = BCExceptionInvalidateData;\r
367             BC_EXCEPTION_CHECK_ReturnVoid(e);\r
368         }\r
369         matrix->Set(xStart, yStart + y, VERTICAL_SEPARATION_PATTERN[y][0]);\r
370     }\r
371 }\r
372 void CBC_QRCoderMatrixUtil::EmbedPositionAdjustmentPattern(FX_INT32 xStart, FX_INT32 yStart,\r
373         CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
374 {\r
375     if(matrix == NULL) {\r
376         e  = BCExceptionNullPointer;\r
377         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
378     }\r
379     for(FX_INT32 y = 0; y < 5; y++) {\r
380         for(FX_INT32 x = 0; x < 5; x++) {\r
381             if(!IsEmpty(matrix->Get(xStart + x, y + yStart))) {\r
382                 e = BCExceptionInvalidateData;\r
383                 BC_EXCEPTION_CHECK_ReturnVoid(e);\r
384             }\r
385             matrix->Set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]);\r
386         }\r
387     }\r
388 }\r
389 void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPattern (FX_INT32 xStart, FX_INT32 yStart,\r
390         CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
391 {\r
392     if(matrix == NULL) {\r
393         e = BCExceptionNullPointer;\r
394         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
395     }\r
396     for(FX_INT32 y = 0; y < 7; y++) {\r
397         for(FX_INT32 x = 0; x < 7; x++) {\r
398             if(!IsEmpty(matrix->Get(xStart + x, yStart + y))) {\r
399                 e = BCExceptionInvalidateData;\r
400                 BC_EXCEPTION_CHECK_ReturnVoid(e);\r
401             }\r
402             matrix->Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);\r
403         }\r
404     }\r
405 }\r
406 void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPatternsAndSeparators(CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
407 {\r
408     if(matrix == NULL) {\r
409         e = BCExceptionNullPointer;\r
410         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
411     }\r
412     FX_INT32 pdpWidth = 7;\r
413     EmbedPositionDetectionPattern(0, 0, matrix, e);\r
414     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
415     EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix, e);\r
416     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
417     EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix, e);\r
418     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
419     FX_INT32 hspWidth = 8;\r
420     EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix, e);\r
421     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
422     EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth, hspWidth - 1, matrix, e);\r
423     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
424     EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth, matrix, e);\r
425     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
426     FX_INT32 vspSize = 7;\r
427     EmbedVerticalSeparationPattern(vspSize, 0, matrix, e);\r
428     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
429     EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0, matrix, e);\r
430     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
431     EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize, matrix, e);\r
432     BC_EXCEPTION_CHECK_ReturnVoid(e);\r
433 }\r
434 void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)\r
435 {\r
436     if(matrix == NULL) {\r
437         e = BCExceptionNullPointer;\r
438         BC_EXCEPTION_CHECK_ReturnVoid(e);\r
439     }\r
440     if(version < 2) {\r
441         return;\r
442     }\r
443     FX_INT32 index = version - 1;\r
444     FX_INT32 const* coordinates = &(POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][0]);\r
445     FX_INT32 numCoordinate = 7;\r
446     for(FX_INT32 i = 0; i < numCoordinate; i++) {\r
447         for(FX_INT32 j = 0; j < numCoordinate; j++) {\r
448             FX_INT32 y = coordinates[i];\r
449             FX_INT32 x = coordinates[j];\r
450             if(x == -1 || y == -1) {\r
451                 continue;\r
452             }\r
453             if(IsEmpty(matrix->Get(x, y))) {\r
454                 EmbedPositionAdjustmentPattern(x - 2, y - 2, matrix, e);\r
455                 BC_EXCEPTION_CHECK_ReturnVoid(e);\r
456             }\r
457         }\r
458     }\r
459 }\r
460 FX_INT32 CBC_QRCoderMatrixUtil::FindMSBSet(FX_INT32 value)\r
461 {\r
462     FX_INT32 numDigits = 0;\r
463     while(value != 0) {\r
464         value >>= 1;\r
465         ++numDigits;\r
466     }\r
467     return numDigits;\r
468 }\r
469 CBC_QRCoderMatrixUtil::CBC_QRCoderMatrixUtil()\r
470 {\r
471 }\r
472 CBC_QRCoderMatrixUtil::~CBC_QRCoderMatrixUtil()\r
473 {\r
474 }\r