1 /* Copyright (c) 2015-2016, The Linux Foundation. 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 // Camera dependencies
35 #include "QCamera3CropRegionMapper.h"
36 #include "QCamera3HWI.h"
37 
38 extern "C" {
39 #include "mm_camera_dbg.h"
40 }
41 
42 using namespace android;
43 
44 namespace qcamera {
45 
46 /*===========================================================================
47  * FUNCTION   : QCamera3CropRegionMapper
48  *
49  * DESCRIPTION: Constructor
50  *
51  * PARAMETERS : None
52  *
53  * RETURN     : None
54  *==========================================================================*/
QCamera3CropRegionMapper()55 QCamera3CropRegionMapper::QCamera3CropRegionMapper()
56         : mSensorW(0),
57           mSensorH(0),
58           mActiveArrayW(0),
59           mActiveArrayH(0)
60 {
61 }
62 
63 /*===========================================================================
64  * FUNCTION   : ~QCamera3CropRegionMapper
65  *
66  * DESCRIPTION: destructor
67  *
68  * PARAMETERS : none
69  *
70  * RETURN     : none
71  *==========================================================================*/
72 
~QCamera3CropRegionMapper()73 QCamera3CropRegionMapper::~QCamera3CropRegionMapper()
74 {
75 }
76 
77 /*===========================================================================
78  * FUNCTION   : update
79  *
80  * DESCRIPTION: update sensor active array size and sensor output size
81  *
82  * PARAMETERS :
83  *   @active_array_w : active array width
84  *   @active_array_h : active array height
85  *   @sensor_w       : sensor output width
86  *   @sensor_h       : sensor output height
87  *
88  * RETURN     : none
89  *==========================================================================*/
update(uint32_t active_array_w,uint32_t active_array_h,uint32_t sensor_w,uint32_t sensor_h)90 void QCamera3CropRegionMapper::update(uint32_t active_array_w,
91         uint32_t active_array_h, uint32_t sensor_w,
92         uint32_t sensor_h)
93 {
94     // Sanity check
95     if (active_array_w == 0 || active_array_h == 0 ||
96             sensor_w == 0 || sensor_h == 0) {
97         LOGE("active_array size and sensor output size must be non zero");
98         return;
99     }
100     if (active_array_w < sensor_w || active_array_h < sensor_h) {
101         LOGE("invalid input: active_array [%d, %d], sensor size [%d, %d]",
102                  active_array_w, active_array_h, sensor_w, sensor_h);
103         return;
104     }
105     mSensorW = sensor_w;
106     mSensorH = sensor_h;
107     mActiveArrayW = active_array_w;
108     mActiveArrayH = active_array_h;
109 
110     LOGH("active_array: %d x %d, sensor size %d x %d",
111             mActiveArrayW, mActiveArrayH, mSensorW, mSensorH);
112 }
113 
114 /*===========================================================================
115  * FUNCTION   : toActiveArray
116  *
117  * DESCRIPTION: Map crop rectangle from sensor output space to active array space
118  *
119  * PARAMETERS :
120  *   @crop_left   : x coordinate of top left corner of rectangle
121  *   @crop_top    : y coordinate of top left corner of rectangle
122  *   @crop_width  : width of rectangle
123  *   @crop_height : height of rectangle
124  *
125  * RETURN     : none
126  *==========================================================================*/
toActiveArray(int32_t & crop_left,int32_t & crop_top,int32_t & crop_width,int32_t & crop_height)127 void QCamera3CropRegionMapper::toActiveArray(int32_t& crop_left, int32_t& crop_top,
128         int32_t& crop_width, int32_t& crop_height)
129 {
130     if (mSensorW == 0 || mSensorH == 0 ||
131             mActiveArrayW == 0 || mActiveArrayH == 0) {
132         LOGE("sensor/active array sizes are not initialized!");
133         return;
134     }
135 
136     crop_left = crop_left * mActiveArrayW / mSensorW;
137     crop_top = crop_top * mActiveArrayH / mSensorH;
138     crop_width = crop_width * mActiveArrayW / mSensorW;
139     crop_height = crop_height * mActiveArrayH / mSensorH;
140 
141     boundToSize(crop_left, crop_top, crop_width, crop_height,
142             mActiveArrayW, mActiveArrayH);
143 }
144 
145 /*===========================================================================
146  * FUNCTION   : toSensor
147  *
148  * DESCRIPTION: Map crop rectangle from active array space to sensor output space
149  *
150  * PARAMETERS :
151  *   @crop_left   : x coordinate of top left corner of rectangle
152  *   @crop_top    : y coordinate of top left corner of rectangle
153  *   @crop_width  : width of rectangle
154  *   @crop_height : height of rectangle
155  *
156  * RETURN     : none
157  *==========================================================================*/
158 
toSensor(int32_t & crop_left,int32_t & crop_top,int32_t & crop_width,int32_t & crop_height)159 void QCamera3CropRegionMapper::toSensor(int32_t& crop_left, int32_t& crop_top,
160         int32_t& crop_width, int32_t& crop_height)
161 {
162     if (mSensorW == 0 || mSensorH == 0 ||
163             mActiveArrayW == 0 || mActiveArrayH == 0) {
164         LOGE("sensor/active array sizes are not initialized!");
165         return;
166     }
167 
168     crop_left = crop_left * mSensorW / mActiveArrayW;
169     crop_top = crop_top * mSensorH / mActiveArrayH;
170     crop_width = crop_width * mSensorW / mActiveArrayW;
171     crop_height = crop_height * mSensorH / mActiveArrayH;
172 
173     LOGD("before bounding left %d, top %d, width %d, height %d",
174          crop_left, crop_top, crop_width, crop_height);
175     boundToSize(crop_left, crop_top, crop_width, crop_height,
176             mSensorW, mSensorH);
177     LOGD("after bounding left %d, top %d, width %d, height %d",
178          crop_left, crop_top, crop_width, crop_height);
179 }
180 
181 /*===========================================================================
182  * FUNCTION   : boundToSize
183  *
184  * DESCRIPTION: Bound a particular rectangle inside a bounding box
185  *
186  * PARAMETERS :
187  *   @left    : x coordinate of top left corner of rectangle
188  *   @top     : y coordinate of top left corner of rectangle
189  *   @width   : width of rectangle
190  *   @height  : height of rectangle
191  *   @bound_w : width of bounding box
192  *   @bound_y : height of bounding box
193  *
194  * RETURN     : none
195  *==========================================================================*/
boundToSize(int32_t & left,int32_t & top,int32_t & width,int32_t & height,int32_t bound_w,int32_t bound_h)196 void QCamera3CropRegionMapper::boundToSize(int32_t& left, int32_t& top,
197             int32_t& width, int32_t& height, int32_t bound_w, int32_t bound_h)
198 {
199     if (left < 0) {
200         left = 0;
201     }
202     if (top < 0) {
203         top = 0;
204     }
205 
206     if ((left + width) > bound_w) {
207         width = bound_w - left;
208     }
209     if ((top + height) > bound_h) {
210         height = bound_h - top;
211     }
212 }
213 
214 /*===========================================================================
215  * FUNCTION   : toActiveArray
216  *
217  * DESCRIPTION: Map co-ordinate from sensor output space to active array space
218  *
219  * PARAMETERS :
220  *   @x   : x coordinate
221  *   @y   : y coordinate
222  *
223  * RETURN     : none
224  *==========================================================================*/
toActiveArray(uint32_t & x,uint32_t & y)225 void QCamera3CropRegionMapper::toActiveArray(uint32_t& x, uint32_t& y)
226 {
227     if (mSensorW == 0 || mSensorH == 0 ||
228             mActiveArrayW == 0 || mActiveArrayH == 0) {
229         LOGE("sensor/active array sizes are not initialized!");
230         return;
231     }
232     if ((x > static_cast<uint32_t>(mSensorW)) ||
233             (y > static_cast<uint32_t>(mSensorH))) {
234         LOGE("invalid co-ordinate (%d, %d) in (0, 0, %d, %d) space",
235                  x, y, mSensorW, mSensorH);
236         return;
237     }
238     x = x * mActiveArrayW / mSensorW;
239     y = y * mActiveArrayH / mSensorH;
240 }
241 
242 /*===========================================================================
243  * FUNCTION   : toSensor
244  *
245  * DESCRIPTION: Map co-ordinate from active array space to sensor output space
246  *
247  * PARAMETERS :
248  *   @x   : x coordinate
249  *   @y   : y coordinate
250  *
251  * RETURN     : none
252  *==========================================================================*/
253 
toSensor(uint32_t & x,uint32_t & y)254 void QCamera3CropRegionMapper::toSensor(uint32_t& x, uint32_t& y)
255 {
256     if (mSensorW == 0 || mSensorH == 0 ||
257             mActiveArrayW == 0 || mActiveArrayH == 0) {
258         LOGE("sensor/active array sizes are not initialized!");
259         return;
260     }
261 
262     if ((x > static_cast<uint32_t>(mActiveArrayW)) ||
263             (y > static_cast<uint32_t>(mActiveArrayH))) {
264         LOGE("invalid co-ordinate (%d, %d) in (0, 0, %d, %d) space",
265                  x, y, mSensorW, mSensorH);
266         return;
267     }
268     x = x * mSensorW / mActiveArrayW;
269     y = y * mSensorH / mActiveArrayH;
270 }
271 
272 }; //end namespace android
273