Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_DataMatrixDecoder.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_DataMatrixDecoder.h"\r
9 #include "include/BC_ReedSolomonDecoder.h"\r
10 #include "include/BC_ReedSolomonGF256.h"\r
11 #include "include/BC_CommonBitMatrix.h"\r
12 #include "include/BC_DataMatrixBitMatrixParser.h"\r
13 #include "include/BC_DataMatrixVersion.h"\r
14 #include "include/BC_DataMatrixDataBlock.h"\r
15 #include "include/BC_DataMatrixDecodedBitStreamParser.h"\r
16 CBC_DataMatrixDecoder::CBC_DataMatrixDecoder()\r
17 {\r
18     m_rsDecoder = NULL;\r
19 }\r
20 void CBC_DataMatrixDecoder::Init()\r
21 {\r
22     m_rsDecoder = FX_NEW CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256::DataMatrixField);\r
23 }\r
24 CBC_DataMatrixDecoder::~CBC_DataMatrixDecoder()\r
25 {\r
26     if(m_rsDecoder != NULL) {\r
27         delete m_rsDecoder;\r
28     }\r
29     m_rsDecoder = NULL;\r
30 }\r
31 CBC_CommonDecoderResult *CBC_DataMatrixDecoder::Decode(CBC_CommonBitMatrix *bits, FX_INT32 &e)\r
32 {\r
33     CBC_DataMatrixBitMatrixParser parser;\r
34     parser.Init(bits, e);\r
35     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
36     CBC_DataMatrixVersion *version = parser.GetVersion();\r
37     CFX_ByteArray* byteTemp = parser.ReadCodewords(e);\r
38     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
39     CBC_AutoPtr<CFX_ByteArray> codewords(byteTemp);\r
40     CFX_PtrArray *dataBlocks = CBC_DataMatrixDataBlock::GetDataBlocks(codewords.get(), version, e);\r
41     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
42     FX_INT32 dataBlocksCount = dataBlocks->GetSize();\r
43     FX_INT32 totalBytes = 0;\r
44     FX_INT32 i, j;\r
45     for (i = 0; i < dataBlocksCount; i++) {\r
46         totalBytes += ((CBC_DataMatrixDataBlock*)(*dataBlocks)[i])->GetNumDataCodewords();\r
47     }\r
48     CFX_ByteArray resultBytes;\r
49     resultBytes.SetSize(totalBytes);\r
50     for (j = 0; j < dataBlocksCount; j++) {\r
51         CFX_ByteArray *codewordBytes = ((CBC_DataMatrixDataBlock*)(*dataBlocks)[j])->GetCodewords();\r
52         FX_INT32 numDataCodewords = ((CBC_DataMatrixDataBlock*)(*dataBlocks)[j])->GetNumDataCodewords();\r
53         CorrectErrors(*codewordBytes, numDataCodewords, e);\r
54         if (e != BCExceptionNO) {\r
55             for(FX_INT32 i = 0; i < dataBlocks->GetSize(); i++) {\r
56                 delete (CBC_DataMatrixDataBlock*)(*dataBlocks)[i];\r
57             }\r
58             delete dataBlocks;\r
59             dataBlocks = NULL;\r
60             return NULL;\r
61         }\r
62         FX_INT32 i;\r
63         for (i = 0; i < numDataCodewords; i++) {\r
64             resultBytes[i * dataBlocksCount + j] = (*codewordBytes)[i];\r
65         }\r
66     }\r
67     for(i = 0; i < (dataBlocks->GetSize()); i++) {\r
68         delete (CBC_DataMatrixDataBlock*)(*dataBlocks)[i];\r
69     }\r
70     delete dataBlocks;\r
71     dataBlocks = NULL;\r
72     CBC_CommonDecoderResult *resultR = CBC_DataMatrixDecodedBitStreamParser::Decode(resultBytes, e);\r
73     BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
74     return resultR;\r
75 }\r
76 void CBC_DataMatrixDecoder::CorrectErrors(CFX_ByteArray &codewordBytes, FX_INT32 numDataCodewords, FX_INT32 &e)\r
77 {\r
78     FX_INT32 numCodewords = codewordBytes.GetSize();\r
79     CFX_Int32Array codewordsInts;\r
80     codewordsInts.SetSize(numCodewords);\r
81     FX_INT32 i;\r
82     for (i = 0; i < numCodewords; i++) {\r
83         codewordsInts[i] = codewordBytes[i] & 0xFF;\r
84     }\r
85     FX_INT32 numECCodewords = codewordBytes.GetSize() - numDataCodewords;\r
86     m_rsDecoder->Decode(&codewordsInts, numECCodewords, e);\r
87     if (e != BCExceptionNO) {\r
88         e = BCExceptionChecksumException;\r
89         return ;\r
90     }\r
91     for (i = 0; i < numDataCodewords; i++) {\r
92         codewordBytes[i] = (FX_BYTE) codewordsInts[i];\r
93     }\r
94 }\r