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