Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / xfa / src / fxbarcode / qrcode / BC_QRDataBlock.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 // Original code is licensed as follows:\r
7 /*\r
8  * Copyright 2007 ZXing authors\r
9  *\r
10  * Licensed under the Apache License, Version 2.0 (the "License");\r
11  * you may not use this file except in compliance with the License.\r
12  * You may obtain a copy of the License at\r
13  *\r
14  *      http://www.apache.org/licenses/LICENSE-2.0\r
15  *\r
16  * Unless required by applicable law or agreed to in writing, software\r
17  * distributed under the License is distributed on an "AS IS" BASIS,\r
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
19  * See the License for the specific language governing permissions and\r
20  * limitations under the License.\r
21  */\r
22 \r
23 #include "../barcode.h"\r
24 #include "BC_QRCoderECBlocks.h"\r
25 #include "BC_QRCoderECB.h"\r
26 #include "BC_QRDataBlock.h"\r
27 #include "BC_QRCoderVersion.h"\r
28 CBC_QRDataBlock::CBC_QRDataBlock(int32_t numDataCodewords, CFX_ByteArray *codewords)\r
29     : m_numDataCodewords(numDataCodewords)\r
30     , m_codewords(codewords)\r
31 {\r
32 }\r
33 CBC_QRDataBlock::~CBC_QRDataBlock()\r
34 {\r
35     if(m_codewords != NULL) {\r
36         delete m_codewords;\r
37         m_codewords = NULL;\r
38     }\r
39 }\r
40 int32_t CBC_QRDataBlock::GetNumDataCodewords()\r
41 {\r
42     return m_numDataCodewords;\r
43 }\r
44 CFX_ByteArray *CBC_QRDataBlock::GetCodewords()\r
45 {\r
46     return m_codewords;\r
47 }\r
48 CFX_PtrArray *CBC_QRDataBlock::GetDataBlocks(CFX_ByteArray* rawCodewords, CBC_QRCoderVersion *version, CBC_QRCoderErrorCorrectionLevel* ecLevel, int32_t &e)\r
49 {\r
50     if(rawCodewords->GetSize() != version->GetTotalCodeWords()) {\r
51         e = BCExceptionIllegalArgument;\r
52         BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
53     }\r
54     CBC_QRCoderECBlocks *ecBlocks = version->GetECBlocksForLevel(ecLevel);\r
55     int32_t totalBlocks = 0;\r
56     CFX_PtrArray* ecBlockArray = ecBlocks->GetECBlocks();\r
57     int32_t i = 0;\r
58     for(i = 0; i < ecBlockArray->GetSize(); i++) {\r
59         totalBlocks += ((CBC_QRCoderECB*)(*ecBlockArray)[i])->GetCount();\r
60     }\r
61     CFX_PtrArray *datablock = FX_NEW CFX_PtrArray();\r
62     datablock->SetSize(totalBlocks);\r
63     CBC_AutoPtr<CFX_PtrArray > result(datablock);\r
64     int32_t numResultBlocks = 0;\r
65     for(int32_t j = 0; j < ecBlockArray->GetSize(); j++) {\r
66         CBC_QRCoderECB *ecBlock = (CBC_QRCoderECB*)(*ecBlockArray)[j];\r
67         for(int32_t k = 0; k < ecBlock->GetCount(); k++) {\r
68             int32_t numDataCodewords = ecBlock->GetDataCodeWords();\r
69             int32_t numBlockCodewords = ecBlocks->GetECCodeWordsPerBlock() + numDataCodewords;\r
70             CFX_ByteArray *bytearray = FX_NEW CFX_ByteArray();\r
71             bytearray->SetSize(numBlockCodewords);\r
72             (*result)[numResultBlocks++] = FX_NEW CBC_QRDataBlock(numDataCodewords, bytearray);\r
73         }\r
74     }\r
75     int32_t shorterBlocksTotalCodewords = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();\r
76     int32_t longerBlocksStartAt = result->GetSize() - 1;\r
77     while(longerBlocksStartAt >= 0) {\r
78         int32_t numCodewords = ((CBC_QRDataBlock*)(*result)[longerBlocksStartAt])->m_codewords->GetSize();\r
79         if(numCodewords == shorterBlocksTotalCodewords) {\r
80             break;\r
81         }\r
82         longerBlocksStartAt--;\r
83     }\r
84     longerBlocksStartAt++;\r
85     int32_t shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks->GetECCodeWordsPerBlock();\r
86     int32_t rawCodewordsOffset = 0;\r
87     int32_t x = 0;\r
88     for(int32_t k = 0; k < shorterBlocksNumDataCodewords; k++) {\r
89         for(x = 0; x < numResultBlocks; x++) {\r
90             (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[k] = (*rawCodewords)[rawCodewordsOffset++];\r
91         }\r
92     }\r
93     for(x = longerBlocksStartAt; x < numResultBlocks; x++) {\r
94         (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[shorterBlocksNumDataCodewords] = (*rawCodewords)[rawCodewordsOffset++];\r
95     }\r
96     int32_t max = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();\r
97     for(i = shorterBlocksNumDataCodewords; i < max; i++) {\r
98         for(int32_t y = 0; y < numResultBlocks; y++) {\r
99             int32_t iOffset = y < longerBlocksStartAt ? i : i + 1;\r
100             (*(((CBC_QRDataBlock*)(*result)[y])->m_codewords))[iOffset] = (*rawCodewords)[rawCodewordsOffset++];\r
101         }\r
102     }\r
103     return result.release();\r
104 }\r