Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / 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 \r
7 #include "barcode.h"\r
8 #include "include/BC_QRCoderECBlocks.h"\r
9 #include "include/BC_QRCoderECB.h"\r
10 #include "include/BC_QRDataBlock.h"\r
11 #include "include/BC_QRCoderVersion.h"\r
12 CBC_QRDataBlock::CBC_QRDataBlock(FX_INT32 numDataCodewords, CFX_ByteArray *codewords)\r
13     : m_numDataCodewords(numDataCodewords)\r
14     , m_codewords(codewords)\r
15 {\r
16 }\r
17 CBC_QRDataBlock::~CBC_QRDataBlock()\r
18 {\r
19     if(m_codewords != NULL) {\r
20         delete m_codewords;\r
21         m_codewords = NULL;\r
22     }\r
23 }\r
24 FX_INT32 CBC_QRDataBlock::GetNumDataCodewords()\r
25 {\r
26     return m_numDataCodewords;\r
27 }\r
28 CFX_ByteArray *CBC_QRDataBlock::GetCodewords()\r
29 {\r
30     return m_codewords;\r
31 }\r
32 CFX_PtrArray *CBC_QRDataBlock::GetDataBlocks(CFX_ByteArray* rawCodewords, CBC_QRCoderVersion *version, CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 &e)\r
33 {\r
34     if(rawCodewords->GetSize() != version->GetTotalCodeWords()) {\r
35         e = BCExceptionIllegalArgument;\r
36         BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
37     }\r
38     CBC_QRCoderECBlocks *ecBlocks = version->GetECBlocksForLevel(ecLevel);\r
39     FX_INT32 totalBlocks = 0;\r
40     CFX_PtrArray* ecBlockArray = ecBlocks->GetECBlocks();\r
41     FX_INT32 i = 0;\r
42     for(i = 0; i < ecBlockArray->GetSize(); i++) {\r
43         totalBlocks += ((CBC_QRCoderECB*)(*ecBlockArray)[i])->GetCount();\r
44     }\r
45     CFX_PtrArray *datablock = FX_NEW CFX_PtrArray();\r
46     datablock->SetSize(totalBlocks);\r
47     CBC_AutoPtr<CFX_PtrArray > result(datablock);\r
48     FX_INT32 numResultBlocks = 0;\r
49     for(FX_INT32 j = 0; j < ecBlockArray->GetSize(); j++) {\r
50         CBC_QRCoderECB *ecBlock = (CBC_QRCoderECB*)(*ecBlockArray)[j];\r
51         for(FX_INT32 k = 0; k < ecBlock->GetCount(); k++) {\r
52             FX_INT32 numDataCodewords = ecBlock->GetDataCodeWords();\r
53             FX_INT32 numBlockCodewords = ecBlocks->GetECCodeWordsPerBlock() + numDataCodewords;\r
54             CFX_ByteArray *bytearray = FX_NEW CFX_ByteArray();\r
55             bytearray->SetSize(numBlockCodewords);\r
56             (*result)[numResultBlocks++] = FX_NEW CBC_QRDataBlock(numDataCodewords, bytearray);\r
57         }\r
58     }\r
59     FX_INT32 shorterBlocksTotalCodewords = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();\r
60     FX_INT32 longerBlocksStartAt = result->GetSize() - 1;\r
61     while(longerBlocksStartAt >= 0) {\r
62         FX_INT32 numCodewords = ((CBC_QRDataBlock*)(*result)[longerBlocksStartAt])->m_codewords->GetSize();\r
63         if(numCodewords == shorterBlocksTotalCodewords) {\r
64             break;\r
65         }\r
66         longerBlocksStartAt--;\r
67     }\r
68     longerBlocksStartAt++;\r
69     FX_INT32 shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks->GetECCodeWordsPerBlock();\r
70     FX_INT32 rawCodewordsOffset = 0;\r
71     FX_INT32 x = 0;\r
72     for(FX_INT32 k = 0; k < shorterBlocksNumDataCodewords; k++) {\r
73         for(x = 0; x < numResultBlocks; x++) {\r
74             (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[k] = (*rawCodewords)[rawCodewordsOffset++];\r
75         }\r
76     }\r
77     for(x = longerBlocksStartAt; x < numResultBlocks; x++) {\r
78         (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[shorterBlocksNumDataCodewords] = (*rawCodewords)[rawCodewordsOffset++];\r
79     }\r
80     FX_INT32 max = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();\r
81     for(i = shorterBlocksNumDataCodewords; i < max; i++) {\r
82         for(FX_INT32 y = 0; y < numResultBlocks; y++) {\r
83             FX_INT32 iOffset = y < longerBlocksStartAt ? i : i + 1;\r
84             (*(((CBC_QRDataBlock*)(*result)[y])->m_codewords))[iOffset] = (*rawCodewords)[rawCodewordsOffset++];\r
85         }\r
86     }\r
87     return result.release();\r
88 }\r