| /* |
| * Copyright (C) 2015-2017 Intel Corporation |
| * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "Window" |
| |
| #include <math.h> |
| #include "CameraWindow.h" |
| #include "UtilityMacros.h" |
| #include "LogHelper.h" |
| |
| NAMESPACE_DECLARATION { |
| |
| /****************************************************************************** |
| * CAMERA WINDOW OPERATIONS |
| *****************************************************************************/ |
| |
| /** |
| * Default constructor |
| */ |
| CameraWindow::CameraWindow() : |
| mXleft(0), |
| mXright(0), |
| mYtop(0), |
| mYbottom(0), |
| mWeight(0), |
| mWidth(0), |
| mHeight(0) |
| { |
| CLEAR(mMeteringRectangle); |
| CLEAR(mCenter); |
| } |
| |
| void CameraWindow::init(ia_coordinate topLeft,ia_coordinate bottomRight, int aWeight) |
| { |
| mXleft = topLeft.x; |
| mYtop = topLeft.y; |
| mXright = bottomRight.x; |
| mYbottom = bottomRight.y; |
| |
| mWeight = aWeight; |
| mWidth = mXright - mXleft; |
| mHeight = mYbottom - mYtop; |
| |
| _calculateCenter(); |
| |
| } |
| |
| void CameraWindow::init(ia_coordinate topLeft,int width, int height, int aWeight) |
| { |
| mXleft = topLeft.x; |
| mYtop = topLeft.y; |
| mWidth = width; |
| mHeight = height; |
| mXright = mXleft + mWidth; |
| mYbottom = mYtop + mHeight; |
| mWeight = aWeight; |
| _calculateCenter(); |
| |
| } |
| |
| void CameraWindow::init(int aWeight) |
| { |
| mWeight = aWeight; |
| |
| mXleft = 0; |
| mYtop = 0; |
| mXright = 0; |
| mYbottom = 0; |
| mWidth = 0; |
| mHeight = 0; |
| _calculateCenter(); |
| } |
| |
| void CameraWindow::_calculateCenter() |
| { |
| mCenter.x = mXleft + mWidth/2; |
| mCenter.y = mYtop + mHeight/2; |
| } |
| |
| /** |
| * isValid |
| * Check whethe the structure is initialized correctly or not |
| * a valid CameraWindow has coordinates such that xmin<xmax and ymin<ymax |
| */ |
| bool CameraWindow::isValid() |
| { |
| return mXleft >= 0 && mYtop >= 0 && // top left corner is >= (0,0) |
| mXleft < mXright && // bottom right corner point is bigger than |
| mYtop < mYbottom; |
| } |
| |
| /** |
| * clip |
| * This method modifies the CameraWindow to fit inside the clipping region. |
| * This is effectively an intersection operation |
| * It is assumed that both windows are using the same coordinate system |
| * |
| * Three scenarios are possible |
| * -Scenario A: |
| * clipping region does not overlap with this window. In this case the window |
| * is modified to be empty and therefore invalid. |
| * - Scenario B: |
| * clipping region partially intersects with this window. In this case the |
| * window will be modified to be the intersection. |
| * - Scenario C: the clipping region is fully contained in this window. |
| * In this case the window will be changed to be the same as the clipping |
| * region |
| * |
| * \param clippingRegion [IN]: regions used to intersect with this window |
| */ |
| void CameraWindow::clip(CameraWindow &clippingRegion) |
| { |
| Range x_range, y_range; |
| Range x_clipping_range, y_clipping_range; |
| Range x_intersect_range, y_intersect_range; |
| ia_coordinate newTopLeft, newBottomRight; |
| |
| INIT_RANGE(x_range, mXleft, mXright); |
| INIT_RANGE(y_range, mYtop, mYbottom); |
| |
| INIT_RANGE(x_clipping_range, clippingRegion.mXleft, clippingRegion.mXright); |
| INIT_RANGE(y_clipping_range, clippingRegion.mYtop, clippingRegion.mYbottom); |
| |
| x_intersect_range = _intersect(x_range, x_clipping_range); |
| y_intersect_range = _intersect(y_range, y_clipping_range); |
| |
| if (x_intersect_range.isEmpty() || y_intersect_range.isEmpty()) { |
| //Scenario A |
| INIT_COORDINATE(newTopLeft,0, 0); |
| INIT_COORDINATE(newBottomRight,0, 0); |
| |
| } else { |
| //Scenario B and C |
| INIT_COORDINATE(newTopLeft, x_intersect_range.start, |
| y_intersect_range.start); |
| INIT_COORDINATE(newBottomRight, x_intersect_range.end, |
| y_intersect_range.end); |
| |
| } |
| |
| init(newTopLeft, newBottomRight, mWeight); |
| return; |
| } |
| /* |
| * _intersect |
| * |
| * calculates the intersection of 2 ranges. |
| * |
| * |-----1------| |------2------| |
| * There are 6 possible scenarios that we can group in 3 types |
| * Type 1: do not overlap (scenarios 1 and 2) |
| * |-----1------| |------2------| |
| * |-----2------| |------1------| |
| * Type 2: partial overlap (scenarios 3 and 4) |
| * |-----1------| |
| * |-----2------| |
| * |-----2------| |
| * |-----1------| |
| * Type 3: inclusion (scenarios 5 and 6) |
| * |-----1------| |
| * |---2---| |
| * |-----2------| |
| * |---1---| |
| * |
| * This method returns the range of the intersection in each case |
| * |
| */ |
| Range CameraWindow::_intersect(Range range1, Range range2) |
| { |
| Range intersect; |
| // detect type 1 |
| if ((range1.start < range2.start && range1.end <= range2.start) || |
| (range2.start < range1.start && range2.end <= range1.start)) { |
| intersect.start = 0; |
| intersect.end = 0; |
| return intersect; |
| } |
| |
| // detect type 2 - scenario 3 |
| if ((range1.start <= range2.start && range1.end <= range2.end)){ |
| intersect.start = range2.start; |
| intersect.end = range1.end; |
| return intersect; |
| } |
| // detect type 2 - scenario 4 |
| if ((range2.start <= range1.start && range2.end <= range1.end)){ |
| intersect.start = range1.start; |
| intersect.end = range2.end; |
| return intersect; |
| } |
| // detect type 3 |
| if ((range1.start <= range2.start && range1.end >= range2.end)){ |
| return range2; |
| } else { |
| return range1; |
| } |
| |
| } |
| |
| CameraWindow CameraWindow::scale(float widthRatio, float heightRatio) |
| { |
| CameraWindow ret; |
| ia_coordinate topLeft; |
| topLeft.x = mXleft; |
| topLeft.y = mYtop; |
| |
| int newWidth = mWidth*widthRatio; |
| int newHeight = mHeight*heightRatio; |
| |
| ret.init(topLeft,newWidth, newHeight, mWeight); |
| return ret; |
| } |
| |
| /** |
| * meteringRectangle |
| * |
| * Helper method to use the CameraWindow as a metering rectangle defined |
| * like Android metadata type. This is as an array of 5 int in this order |
| * [xmin, ymin, xmax, ymax, weight] |
| */ |
| int* CameraWindow::meteringRectangle() |
| { |
| mMeteringRectangle[0] = mXleft; |
| mMeteringRectangle[1] = mYtop; |
| mMeteringRectangle[2] = mXright; |
| mMeteringRectangle[3] = mYbottom; |
| mMeteringRectangle[4] = mWeight; |
| return mMeteringRectangle; |
| } |
| void CameraWindow::dump() |
| { |
| LOGD("Window: TL(%d,%d) BR(%d,%d), width %d height %d, center (%d,%d), weight %d", |
| mXleft, mYtop, mXright, mYbottom, mWidth, mHeight, |
| mCenter.x, mCenter.y, mWeight); |
| } |
| } NAMESPACE_DECLARATION_END |