1ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved.
2ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be
3ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// found in the LICENSE file.
4ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
5ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Original code is licensed as follows:
7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/*
8ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * Copyright 2010 ZXing authors
9ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *
10ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License");
11ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * you may not use this file except in compliance with the License.
12ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * You may obtain a copy of the License at
13ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *
14ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *      http://www.apache.org/licenses/LICENSE-2.0
15ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *
16ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * Unless required by applicable law or agreed to in writing, software
17ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS,
18ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * See the License for the specific language governing permissions and
20ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * limitations under the License.
21ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */
22ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
23ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "xfa/src/fxbarcode/barcode.h"
24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "xfa/src/fxbarcode/common/BC_WhiteRectangleDetector.h"
25ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h"
26ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "xfa/src/fxbarcode/BC_ResultPoint.h"
27ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst int32_t CBC_WhiteRectangleDetector::INIT_SIZE = 30;
28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannconst int32_t CBC_WhiteRectangleDetector::CORR = 1;
29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCBC_WhiteRectangleDetector::CBC_WhiteRectangleDetector(
30ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CBC_CommonBitMatrix* image) {
31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_image = image;
32ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_height = image->GetHeight();
33ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_width = image->GetWidth();
34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_leftInit = (m_width - INIT_SIZE) >> 1;
35ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_rightInit = (m_width + INIT_SIZE) >> 1;
36ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_upInit = (m_height - INIT_SIZE) >> 1;
37ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_downInit = (m_height + INIT_SIZE) >> 1;
38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
39ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CBC_WhiteRectangleDetector::Init(int32_t& e) {
40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (m_upInit < 0 || m_leftInit < 0 || m_downInit >= m_height ||
41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      m_rightInit >= m_width) {
42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    e = BCExceptionNotFound;
43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    BC_EXCEPTION_CHECK_ReturnVoid(e);
44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
45ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
46ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCBC_WhiteRectangleDetector::CBC_WhiteRectangleDetector(
47ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CBC_CommonBitMatrix* image,
48ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    int32_t initSize,
49ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    int32_t x,
50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    int32_t y) {
51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_image = image;
52ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_height = image->GetHeight();
53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_width = image->GetWidth();
54ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int32_t halfsize = initSize >> 1;
55ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_leftInit = x - halfsize;
56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_rightInit = x + halfsize;
57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_upInit = y - halfsize;
58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_downInit = y + halfsize;
59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCBC_WhiteRectangleDetector::~CBC_WhiteRectangleDetector() {}
61ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCFX_PtrArray* CBC_WhiteRectangleDetector::Detect(int32_t& e) {
62ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int32_t left = m_leftInit;
63ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int32_t right = m_rightInit;
64ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int32_t up = m_upInit;
65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int32_t down = m_downInit;
66ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  FX_BOOL sizeExceeded = FALSE;
67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  FX_BOOL aBlackPointFoundOnBorder = TRUE;
68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  FX_BOOL atLeastOneBlackPointFoundOnBorder = FALSE;
69ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  while (aBlackPointFoundOnBorder) {
70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    aBlackPointFoundOnBorder = FALSE;
71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FX_BOOL rightBorderNotWhite = TRUE;
72ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    while (rightBorderNotWhite && right < m_width) {
73ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      rightBorderNotWhite = ContainsBlackPoint(up, down, right, FALSE);
74ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (rightBorderNotWhite) {
75ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        right++;
76ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        aBlackPointFoundOnBorder = TRUE;
77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
78ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (right >= m_width) {
80ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      sizeExceeded = TRUE;
81ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      break;
82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FX_BOOL bottomBorderNotWhite = TRUE;
84ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    while (bottomBorderNotWhite && down < m_height) {
85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      bottomBorderNotWhite = ContainsBlackPoint(left, right, down, TRUE);
86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (bottomBorderNotWhite) {
87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        down++;
88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        aBlackPointFoundOnBorder = TRUE;
89ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (down >= m_height) {
92ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      sizeExceeded = TRUE;
93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      break;
94ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FX_BOOL leftBorderNotWhite = TRUE;
96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    while (leftBorderNotWhite && left >= 0) {
97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      leftBorderNotWhite = ContainsBlackPoint(up, down, left, FALSE);
98ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (leftBorderNotWhite) {
99ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        left--;
100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        aBlackPointFoundOnBorder = TRUE;
101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
102ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
103ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (left < 0) {
104ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      sizeExceeded = TRUE;
105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      break;
106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
107ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FX_BOOL topBorderNotWhite = TRUE;
108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    while (topBorderNotWhite && up >= 0) {
109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      topBorderNotWhite = ContainsBlackPoint(left, right, up, TRUE);
110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (topBorderNotWhite) {
111ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        up--;
112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        aBlackPointFoundOnBorder = TRUE;
113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (up < 0) {
116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      sizeExceeded = TRUE;
117ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      break;
118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (aBlackPointFoundOnBorder) {
120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      atLeastOneBlackPointFoundOnBorder = TRUE;
121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
122ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    int32_t maxSize = right - left;
125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CBC_AutoPtr<CBC_ResultPoint> z(NULL);
126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    for (int32_t i = 1; i < maxSize; i++) {
127ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      z = CBC_AutoPtr<CBC_ResultPoint>(
128ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann          GetBlackPointOnSegment((FX_FLOAT)left, (FX_FLOAT)(down - i),
129ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                 (FX_FLOAT)(left + i), (FX_FLOAT)(down)));
130ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (z.get() != NULL) {
131ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        break;
132ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
133ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
134ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (z.get() == NULL) {
135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      e = BCExceptionNotFound;
136ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
137ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
138ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CBC_AutoPtr<CBC_ResultPoint> t(NULL);
139ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    for (int32_t j = 1; j < maxSize; j++) {
140ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      t = CBC_AutoPtr<CBC_ResultPoint>(
141ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann          GetBlackPointOnSegment((FX_FLOAT)left, (FX_FLOAT)(up + j),
142ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                 (FX_FLOAT)(left + j), (FX_FLOAT)up));
143ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (t.get() != NULL) {
144ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        break;
145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
146ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
147ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (t.get() == NULL) {
148ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      e = BCExceptionNotFound;
149ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
150ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
151ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CBC_AutoPtr<CBC_ResultPoint> x(NULL);
152ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    for (int32_t k = 1; k < maxSize; k++) {
153ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      x = CBC_AutoPtr<CBC_ResultPoint>(
154ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann          GetBlackPointOnSegment((FX_FLOAT)right, (FX_FLOAT)(up + k),
155ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                 (FX_FLOAT)(right - k), (FX_FLOAT)up));
156ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (x.get() != NULL) {
157ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        break;
158ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
159ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
160ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (x.get() == NULL) {
161ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      e = BCExceptionNotFound;
162ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
163ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
164ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CBC_AutoPtr<CBC_ResultPoint> y(NULL);
165ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    for (int32_t m = 1; m < maxSize; m++) {
166ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      y = CBC_AutoPtr<CBC_ResultPoint>(
167ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann          GetBlackPointOnSegment((FX_FLOAT)right, (FX_FLOAT)(down - m),
168ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                 (FX_FLOAT)(right - m), (FX_FLOAT)down));
169ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (y.get() != NULL) {
170ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        break;
171ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
172ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
173ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (y.get() == NULL) {
174ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      e = BCExceptionNotFound;
175ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
176ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
177ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return CenterEdges(y.get(), z.get(), x.get(), t.get());
178ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  } else {
179ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    e = BCExceptionNotFound;
180ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
181ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
182ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  return NULL;
183ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
184ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannint32_t CBC_WhiteRectangleDetector::Round(FX_FLOAT d) {
185ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  return (int32_t)(d + 0.5f);
186ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
187ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCBC_ResultPoint* CBC_WhiteRectangleDetector::GetBlackPointOnSegment(
188ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FX_FLOAT aX,
189ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FX_FLOAT aY,
190ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FX_FLOAT bX,
191ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FX_FLOAT bY) {
192ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int32_t dist = DistanceL2(aX, aY, bX, bY);
193ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float xStep = (bX - aX) / dist;
194ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float yStep = (bY - aY) / dist;
195ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for (int32_t i = 0; i < dist; i++) {
196ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    int32_t x = Round(aX + i * xStep);
197ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    int32_t y = Round(aY + i * yStep);
198ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (m_image->Get(x, y)) {
199ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      return new CBC_ResultPoint((FX_FLOAT)x, (FX_FLOAT)y);
200ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
201ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
202ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  return NULL;
203ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
204ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannint32_t CBC_WhiteRectangleDetector::DistanceL2(FX_FLOAT aX,
205ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                               FX_FLOAT aY,
206ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                               FX_FLOAT bX,
207ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                               FX_FLOAT bY) {
208ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float xDiff = aX - bX;
209ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float yDiff = aY - bY;
210ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  return Round((float)sqrt(xDiff * xDiff + yDiff * yDiff));
211ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
212ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCFX_PtrArray* CBC_WhiteRectangleDetector::CenterEdges(CBC_ResultPoint* y,
213ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                      CBC_ResultPoint* z,
214ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                      CBC_ResultPoint* x,
215ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                      CBC_ResultPoint* t) {
216ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float yi = y->GetX();
217ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float yj = y->GetY();
218ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float zi = z->GetX();
219ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float zj = z->GetY();
220ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float xi = x->GetX();
221ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float xj = x->GetY();
222ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float ti = t->GetX();
223ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  float tj = t->GetY();
224ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (yi < m_width / 2) {
225ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CFX_PtrArray* result = new CFX_PtrArray;
226ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    result->SetSize(4);
227ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    (*result)[0] = new CBC_ResultPoint(ti - CORR, tj + CORR);
228ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    (*result)[1] = new CBC_ResultPoint(zi + CORR, zj + CORR);
229ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    (*result)[2] = new CBC_ResultPoint(xi - CORR, xj - CORR);
230ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    (*result)[3] = new CBC_ResultPoint(yi + CORR, yj - CORR);
231ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return result;
232ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  } else {
233ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CFX_PtrArray* result = new CFX_PtrArray;
234ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    result->SetSize(4);
235ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    (*result)[0] = new CBC_ResultPoint(ti + CORR, tj + CORR);
236ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    (*result)[1] = new CBC_ResultPoint(zi + CORR, zj - CORR);
237ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    (*result)[2] = new CBC_ResultPoint(xi - CORR, xj + CORR);
238ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    (*result)[3] = new CBC_ResultPoint(yi - CORR, yj - CORR);
239ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return result;
240ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
241ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
242ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannFX_BOOL CBC_WhiteRectangleDetector::ContainsBlackPoint(int32_t a,
243ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                       int32_t b,
244ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                       int32_t fixed,
245ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                       FX_BOOL horizontal) {
246ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (horizontal) {
247ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    for (int32_t x = a; x <= b; x++) {
248ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (m_image->Get(x, fixed)) {
249ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        return TRUE;
250ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
251ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
252ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  } else {
253ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    for (int32_t y = a; y <= b; y++) {
254ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (m_image->Get(fixed, y)) {
255ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        return TRUE;
256ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      }
257ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
258ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
259ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  return FALSE;
260ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
261