1 /* Copyright (c) 2015, The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 
30 
31 #define ATRACE_TAG ATRACE_TAG_CAMERA
32 #define LOG_TAG "QCamera3CropRegionMapper"
33 
34 #include "QCamera3CropRegionMapper.h"
35 #include "QCamera3HWI.h"
36 
37 using namespace android;
38 
39 namespace qcamera {
40 
41 /*===========================================================================
42  * FUNCTION   : QCamera3CropRegionMapper
43  *
44  * DESCRIPTION: Constructor
45  *
46  * PARAMETERS : None
47  *
48  * RETURN     : None
49  *==========================================================================*/
QCamera3CropRegionMapper()50 QCamera3CropRegionMapper::QCamera3CropRegionMapper()
51         : mSensorW(0),
52           mSensorH(0),
53           mActiveArrayW(0),
54           mActiveArrayH(0)
55 {
56 }
57 
58 /*===========================================================================
59  * FUNCTION   : ~QCamera3CropRegionMapper
60  *
61  * DESCRIPTION: destructor
62  *
63  * PARAMETERS : none
64  *
65  * RETURN     : none
66  *==========================================================================*/
67 
~QCamera3CropRegionMapper()68 QCamera3CropRegionMapper::~QCamera3CropRegionMapper()
69 {
70 }
71 
72 /*===========================================================================
73  * FUNCTION   : update
74  *
75  * DESCRIPTION: update sensor active array size and sensor output size
76  *
77  * PARAMETERS :
78  *   @active_array_w : active array width
79  *   @active_array_h : active array height
80  *   @sensor_w       : sensor output width
81  *   @sensor_h       : sensor output height
82  *
83  * RETURN     : none
84  *==========================================================================*/
update(uint32_t active_array_w,uint32_t active_array_h,uint32_t sensor_w,uint32_t sensor_h)85 void QCamera3CropRegionMapper::update(uint32_t active_array_w,
86         uint32_t active_array_h, uint32_t sensor_w,
87         uint32_t sensor_h)
88 {
89     // Sanity check
90     if (active_array_w == 0 || active_array_h == 0 ||
91             sensor_w == 0 || sensor_h == 0) {
92         ALOGE("%s: active_array size and sensor output size must be non zero",
93                 __func__);
94         return;
95     }
96     if (active_array_w < sensor_w || active_array_h < sensor_h) {
97         ALOGE("%s: invalid input: active_array [%d, %d], sensor size [%d, %d]",
98                 __func__, active_array_w, active_array_h, sensor_w, sensor_h);
99         return;
100     }
101     mSensorW = sensor_w;
102     mSensorH = sensor_h;
103     mActiveArrayW = active_array_w;
104     mActiveArrayH = active_array_h;
105 
106     ALOGI("%s: active_array: %d x %d, sensor size %d x %d", __func__,
107             mActiveArrayW, mActiveArrayH, mSensorW, mSensorH);
108 }
109 
110 /*===========================================================================
111  * FUNCTION   : toActiveArray
112  *
113  * DESCRIPTION: Map crop rectangle from sensor output space to active array space
114  *
115  * PARAMETERS :
116  *   @crop_left   : x coordinate of top left corner of rectangle
117  *   @crop_top    : y coordinate of top left corner of rectangle
118  *   @crop_width  : width of rectangle
119  *   @crop_height : height of rectangle
120  *
121  * RETURN     : none
122  *==========================================================================*/
toActiveArray(int32_t & crop_left,int32_t & crop_top,int32_t & crop_width,int32_t & crop_height)123 void QCamera3CropRegionMapper::toActiveArray(int32_t& crop_left, int32_t& crop_top,
124         int32_t& crop_width, int32_t& crop_height)
125 {
126     if (mSensorW == 0 || mSensorH == 0 ||
127             mActiveArrayW == 0 || mActiveArrayH == 0) {
128         ALOGE("%s: sensor/active array sizes are not initialized!", __func__);
129         return;
130     }
131 
132     crop_left = crop_left * mActiveArrayW / mSensorW;
133     crop_top = crop_top * mActiveArrayH / mSensorH;
134     crop_width = crop_width * mActiveArrayW / mSensorW;
135     crop_height = crop_height * mActiveArrayH / mSensorH;
136 
137     boundToSize(crop_left, crop_top, crop_width, crop_height,
138             mActiveArrayW, mActiveArrayH);
139 }
140 
141 /*===========================================================================
142  * FUNCTION   : toSensor
143  *
144  * DESCRIPTION: Map crop rectangle from active array space to sensor output space
145  *
146  * PARAMETERS :
147  *   @crop_left   : x coordinate of top left corner of rectangle
148  *   @crop_top    : y coordinate of top left corner of rectangle
149  *   @crop_width  : width of rectangle
150  *   @crop_height : height of rectangle
151  *
152  * RETURN     : none
153  *==========================================================================*/
154 
toSensor(int32_t & crop_left,int32_t & crop_top,int32_t & crop_width,int32_t & crop_height)155 void QCamera3CropRegionMapper::toSensor(int32_t& crop_left, int32_t& crop_top,
156         int32_t& crop_width, int32_t& crop_height)
157 {
158     if (mSensorW == 0 || mSensorH == 0 ||
159             mActiveArrayW == 0 || mActiveArrayH == 0) {
160         ALOGE("%s: sensor/active array sizes are not initialized!", __func__);
161         return;
162     }
163 
164     crop_left = crop_left * mSensorW / mActiveArrayW;
165     crop_top = crop_top * mSensorH / mActiveArrayH;
166     crop_width = crop_width * mSensorW / mActiveArrayW;
167     crop_height = crop_height * mSensorH / mActiveArrayH;
168 
169     CDBG("%s: before bounding left %d, top %d, width %d, height %d",
170         __func__, crop_left, crop_top, crop_width, crop_height);
171     boundToSize(crop_left, crop_top, crop_width, crop_height,
172             mSensorW, mSensorH);
173     CDBG("%s: after bounding left %d, top %d, width %d, height %d",
174         __func__, crop_left, crop_top, crop_width, crop_height);
175 }
176 
177 /*===========================================================================
178  * FUNCTION   : boundToSize
179  *
180  * DESCRIPTION: Bound a particular rectangle inside a bounding box
181  *
182  * PARAMETERS :
183  *   @left    : x coordinate of top left corner of rectangle
184  *   @top     : y coordinate of top left corner of rectangle
185  *   @width   : width of rectangle
186  *   @height  : height of rectangle
187  *   @bound_w : width of bounding box
188  *   @bound_y : height of bounding box
189  *
190  * RETURN     : none
191  *==========================================================================*/
boundToSize(int32_t & left,int32_t & top,int32_t & width,int32_t & height,int32_t bound_w,int32_t bound_h)192 void QCamera3CropRegionMapper::boundToSize(int32_t& left, int32_t& top,
193             int32_t& width, int32_t& height, int32_t bound_w, int32_t bound_h)
194 {
195     if (left < 0) {
196         left = 0;
197     }
198     if (top < 0) {
199         top = 0;
200     }
201 
202     if ((left + width) > bound_w) {
203         width = bound_w - left;
204     }
205     if ((top + height) > bound_h) {
206         height = bound_h - top;
207     }
208 }
209 
210 /*===========================================================================
211  * FUNCTION   : toActiveArray
212  *
213  * DESCRIPTION: Map co-ordinate from sensor output space to active array space
214  *
215  * PARAMETERS :
216  *   @x   : x coordinate
217  *   @y   : y coordinate
218  *
219  * RETURN     : none
220  *==========================================================================*/
toActiveArray(uint32_t & x,uint32_t & y)221 void QCamera3CropRegionMapper::toActiveArray(uint32_t& x, uint32_t& y)
222 {
223     if (mSensorW == 0 || mSensorH == 0 ||
224             mActiveArrayW == 0 || mActiveArrayH == 0) {
225         ALOGE("%s: sensor/active array sizes are not initialized!", __func__);
226         return;
227     }
228     if ((x > static_cast<uint32_t>(mSensorW)) ||
229             (y > static_cast<uint32_t>(mSensorH))) {
230         ALOGE("%s: invalid co-ordinate (%d, %d) in (0, 0, %d, %d) space",
231                 __func__, x, y, mSensorW, mSensorH);
232         return;
233     }
234     x = x * mActiveArrayW / mSensorW;
235     y = y * mActiveArrayH / mSensorH;
236 }
237 
238 /*===========================================================================
239  * FUNCTION   : toSensor
240  *
241  * DESCRIPTION: Map co-ordinate from active array space to sensor output space
242  *
243  * PARAMETERS :
244  *   @x   : x coordinate
245  *   @y   : y coordinate
246  *
247  * RETURN     : none
248  *==========================================================================*/
249 
toSensor(uint32_t & x,uint32_t & y)250 void QCamera3CropRegionMapper::toSensor(uint32_t& x, uint32_t& y)
251 {
252     if (mSensorW == 0 || mSensorH == 0 ||
253             mActiveArrayW == 0 || mActiveArrayH == 0) {
254         ALOGE("%s: sensor/active array sizes are not initialized!", __func__);
255         return;
256     }
257 
258     if ((x > static_cast<uint32_t>(mActiveArrayW)) ||
259             (y > static_cast<uint32_t>(mActiveArrayH))) {
260         ALOGE("%s: invalid co-ordinate (%d, %d) in (0, 0, %d, %d) space",
261                 __func__, x, y, mSensorW, mSensorH);
262         return;
263     }
264     x = x * mSensorW / mActiveArrayW;
265     y = y * mSensorH / mActiveArrayH;
266 }
267 
268 }; //end namespace android
269