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