Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxbarcode / src / BC_QRGridSampler.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_CommonPerspectiveTransform.h"\r
9 #include "include/BC_CommonBitMatrix.h"\r
10 #include "include/BC_QRGridSampler.h"\r
11 CBC_QRGridSampler CBC_QRGridSampler::m_gridSampler;\r
12 CBC_QRGridSampler::CBC_QRGridSampler()\r
13 {\r
14 }\r
15 CBC_QRGridSampler::~CBC_QRGridSampler()\r
16 {\r
17 }\r
18 CBC_QRGridSampler &CBC_QRGridSampler::GetInstance()\r
19 {\r
20     return m_gridSampler;\r
21 }\r
22 void CBC_QRGridSampler::CheckAndNudgePoints(CBC_CommonBitMatrix *image, CFX_FloatArray *points, FX_INT32 &e)\r
23 {\r
24     FX_INT32 width = image->GetWidth();\r
25     FX_INT32 height = image->GetHeight();\r
26     FX_BOOL nudged = TRUE;\r
27     FX_INT32 offset;\r
28     for (offset = 0; offset < points->GetSize() && nudged; offset += 2) {\r
29         FX_INT32 x = (FX_INT32) (*points)[offset];\r
30         FX_INT32 y = (FX_INT32) (*points)[offset + 1];\r
31         if (x < -1 || x > width || y < -1 || y > height) {\r
32             e = BCExceptionRead;\r
33             BC_EXCEPTION_CHECK_ReturnVoid(e);\r
34         }\r
35         nudged = FALSE;\r
36         if (x == -1) {\r
37             (*points)[offset] = 0.0f;\r
38             nudged = TRUE;\r
39         } else if (x == width) {\r
40             (*points)[offset] = (FX_FLOAT)(width - 1);\r
41             nudged = TRUE;\r
42         }\r
43         if (y == -1) {\r
44             (*points)[offset + 1] = 0.0f;\r
45             nudged = TRUE;\r
46         } else if (y == height) {\r
47             (*points)[offset + 1] = (FX_FLOAT)(height - 1);\r
48             nudged = TRUE;\r
49         }\r
50     }\r
51     nudged = TRUE;\r
52     for (offset = (*points).GetSize() - 2; offset >= 0 && nudged; offset -= 2) {\r
53         FX_INT32 x = (FX_INT32) (*points)[offset];\r
54         FX_INT32 y = (FX_INT32) (*points)[offset + 1];\r
55         if (x < -1 || x > width || y < -1 || y > height) {\r
56             e = BCExceptionRead;\r
57             BC_EXCEPTION_CHECK_ReturnVoid(e);\r
58         }\r
59         nudged = FALSE;\r
60         if (x == -1) {\r
61             (*points)[offset] = 0.0f;\r
62             nudged = TRUE;\r
63         } else if (x == width) {\r
64             (*points)[offset] = (FX_FLOAT)(width - 1);\r
65             nudged = TRUE;\r
66         }\r
67         if (y == -1) {\r
68             (*points)[offset + 1] = 0.0f;\r
69             nudged = TRUE;\r
70         } else if (y == height) {\r
71             (*points)[offset + 1] = (FX_FLOAT)(height - 1);\r
72             nudged = TRUE;\r
73         }\r
74     }\r
75 }\r
76 CBC_CommonBitMatrix *CBC_QRGridSampler::SampleGrid(CBC_CommonBitMatrix *image, FX_INT32 dimensionX, FX_INT32 dimensionY,\r
77         FX_FLOAT p1ToX, FX_FLOAT p1ToY,\r
78         FX_FLOAT p2ToX, FX_FLOAT p2ToY,\r
79         FX_FLOAT p3ToX, FX_FLOAT p3ToY,\r
80         FX_FLOAT p4ToX, FX_FLOAT p4ToY,\r
81         FX_FLOAT p1FromX, FX_FLOAT p1FromY,\r
82         FX_FLOAT p2FromX, FX_FLOAT p2FromY,\r
83         FX_FLOAT p3FromX, FX_FLOAT p3FromY,\r
84         FX_FLOAT p4FromX, FX_FLOAT p4FromY, FX_INT32 &e)\r
85 {\r
86     CBC_AutoPtr<CBC_CommonPerspectiveTransform> transform(CBC_CommonPerspectiveTransform::QuadrilateralToQuadrilateral(\r
87                 p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,\r
88                 p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY));\r
89     CBC_CommonBitMatrix *tempBitM = FX_NEW CBC_CommonBitMatrix();\r
90     tempBitM->Init(dimensionX, dimensionY);\r
91     CBC_AutoPtr<CBC_CommonBitMatrix> bits(tempBitM);\r
92     CFX_FloatArray points;\r
93     points.SetSize(dimensionX << 1);\r
94     for (FX_INT32 y = 0; y < dimensionY; y++) {\r
95         FX_INT32 max = points.GetSize();\r
96         FX_FLOAT iValue = (FX_FLOAT) (y + 0.5f);\r
97         FX_INT32 x;\r
98         for (x = 0; x < max; x += 2) {\r
99             points[x] = (FX_FLOAT) ((x >> 1) + 0.5f);\r
100             points[x + 1] = iValue;\r
101         }\r
102         transform->TransformPoints(&points);\r
103         CheckAndNudgePoints(image, &points, e);\r
104         BC_EXCEPTION_CHECK_ReturnValue(e, NULL);\r
105         for (x = 0; x < max; x += 2) {\r
106             if (image->Get((FX_INT32) points[x], (FX_INT32) points[x + 1])) {\r
107                 bits->Set(x >> 1, y);\r
108             }\r
109         }\r
110     }\r
111     return bits.release();\r
112 }\r