• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * soft_image.h - soft image class
3  *
4  *  Copyright (c) 2017 Intel Corporation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Author: Wind Yuan <feng.yuan@intel.com>
19  */
20 
21 #ifndef XCAM_SOFT_IMAGE_H
22 #define XCAM_SOFT_IMAGE_H
23 
24 #include <xcam_std.h>
25 #include <video_buffer.h>
26 #include <vec_mat.h>
27 #include <file_handle.h>
28 
29 namespace XCam {
30 
31 typedef uint8_t Uchar;
32 typedef int8_t Char;
33 typedef Vector2<uint8_t> Uchar2;
34 typedef Vector2<int8_t> Char2;
35 typedef Vector2<float> Float2;
36 typedef Vector2<int> Int2;
37 
38 enum BorderType {
39     BorderTypeNearest,
40     BorderTypeConst,
41     BorderTypeRewind,
42 };
43 
44 template <typename T>
45 class SoftImage
46 {
47 public:
48     typedef T Type;
49 private:
50     uint8_t    *_buf_ptr;
51     uint32_t    _width;
52     uint32_t    _height;
53     uint32_t    _pitch;
54 
55     SmartPtr<VideoBuffer> _bind;
56 
57 public:
58     explicit SoftImage (const SmartPtr<VideoBuffer> &buf, const uint32_t plane);
59     explicit SoftImage (
60         const uint32_t width, const uint32_t height,
61         uint32_t aligned_width = 0);
62     explicit SoftImage (
63         const SmartPtr<VideoBuffer> &buf,
64         const uint32_t width, const uint32_t height, const uint32_t pictch, const uint32_t offset = 0);
65 
~SoftImage()66     ~SoftImage () {
67         if (!_bind.ptr ()) {
68             xcam_free (_buf_ptr);
69         }
70     }
71 
pixel_size()72     uint32_t pixel_size () const {
73         return sizeof (T);
74     }
75 
get_width()76     uint32_t get_width () const {
77         return _width;
78     }
get_height()79     uint32_t get_height () const {
80         return _height;
81     }
get_pitch()82     uint32_t get_pitch () const {
83         return _pitch;
84     }
is_valid()85     bool is_valid () const {
86         return (_buf_ptr && _width && _height);
87     }
88 
get_bind_buf()89     const SmartPtr<VideoBuffer> &get_bind_buf () const {
90         return _bind;
91     }
get_buf_ptr(int32_t x,int32_t y)92     T *get_buf_ptr (int32_t x, int32_t y) {
93         return (T *)(_buf_ptr + y * _pitch) + x;
94     }
get_buf_ptr(int32_t x,int32_t y)95     const T *get_buf_ptr (int32_t x, int32_t y) const {
96         return (const T *)(_buf_ptr + y * _pitch) + x;
97     }
98 
read_data_no_check(int32_t x,int32_t y)99     inline T read_data_no_check (int32_t x, int32_t y) const {
100         const T *t_ptr = (const T *)(_buf_ptr + y * _pitch);
101         return t_ptr[x];
102     }
103 
read_data(int32_t x,int32_t y)104     inline T read_data (int32_t x, int32_t y) const {
105         border_check (x, y);
106         return read_data_no_check (x, y);
107     }
108 
109     template<typename O>
110     inline O read_interpolate_data (float x, float y) const;
111 
112     template<typename O, uint32_t N>
113     inline void read_interpolate_array (Float2 *pos, O *array) const;
114 
115     template<uint32_t N>
read_array_no_check(const int32_t x,const int32_t y,T * array)116     inline void read_array_no_check (const int32_t x, const int32_t y, T *array) const {
117         XCAM_ASSERT (N <= 8);
118         const T *t_ptr = ((const T *)(_buf_ptr + y * _pitch)) + x;
119         memcpy (array, t_ptr, sizeof (T) * N);
120     }
121 
122     template<typename O, uint32_t N>
read_array_no_check(const int32_t x,const int32_t y,O * array)123     inline void read_array_no_check (const int32_t x, const int32_t y, O *array) const {
124         XCAM_ASSERT (N <= 8);
125         const T *t_ptr = ((const T *)(_buf_ptr + y * _pitch)) + x;
126         for (uint32_t i = 0; i < N; ++i) {
127             array[i] = t_ptr[i];
128         }
129     }
130 
131     template<uint32_t N>
read_array(int32_t x,int32_t y,T * array)132     inline void read_array (int32_t x, int32_t y, T *array) const {
133         XCAM_ASSERT (N <= 8);
134         border_check_y (y);
135         if (x + N < _width) {
136             read_array_no_check<N> (x, y, array);
137         } else {
138             const T *t_ptr = ((const T *)(_buf_ptr + y * _pitch));
139             for (uint32_t i = 0; i < N; ++i, ++x) {
140                 border_check_x (x);
141                 array[i] = t_ptr[x];
142             }
143         }
144     }
145 
146     template<typename O, uint32_t N>
read_array(int32_t x,int32_t y,O * array)147     inline void read_array (int32_t x, int32_t y, O *array) const {
148         XCAM_ASSERT (N <= 8);
149         border_check_y (y);
150         const T *t_ptr = ((const T *)(_buf_ptr + y * _pitch));
151         for (uint32_t i = 0; i < N; ++i, ++x) {
152             border_check_x (x);
153             array[i] = t_ptr[x];
154         }
155     }
156 
write_data(int32_t x,int32_t y,const T & v)157     inline void write_data (int32_t x, int32_t y, const T &v) {
158         if (x < 0 || x >= (int32_t)_width)
159             return;
160         if (y < 0 || y >= (int32_t)_height)
161             return;
162         write_data_no_check (x, y, v);
163     }
164 
write_data_no_check(int32_t x,int32_t y,const T & v)165     inline void write_data_no_check (int32_t x, int32_t y, const T &v) {
166         T *t_ptr = (T *)(_buf_ptr + y * _pitch);
167         t_ptr[x] = v;
168     }
169 
170     template<uint32_t N>
write_array_no_check(int32_t x,int32_t y,const T * array)171     inline void write_array_no_check (int32_t x, int32_t y, const T *array) {
172         T *t_ptr = (T *)(_buf_ptr + y * _pitch);
173         memcpy (t_ptr + x, array, sizeof (T) * N);
174     }
175 
176     template<uint32_t N>
write_array(int32_t x,int32_t y,const T * array)177     inline void write_array (int32_t x, int32_t y, const T *array) {
178         if (y < 0 || y >= (int32_t)_height)
179             return;
180 
181         if (x >= 0 && x + N <= _width) {
182             write_array_no_check<N> (x, y, array);
183         } else {
184             T *t_ptr = ((T *)(_buf_ptr + y * _pitch));
185             for (uint32_t i = 0; i < N; ++i, ++x) {
186                 if (x < 0 || x >= (int32_t)_width) continue;
187                 t_ptr[x] = array[i];
188             }
189         }
190     }
191 
192 private:
border_check_x(int32_t & x)193     inline void border_check_x (int32_t &x) const {
194         if (x < 0) x = 0;
195         else if (x >= (int32_t)_width) x = (int32_t)(_width - 1);
196     }
197 
border_check_y(int32_t & y)198     inline void border_check_y (int32_t &y) const {
199         if (y < 0) y = 0;
200         else if (y >= (int32_t)_height) y = (int32_t)(_height - 1);
201     }
202 
border_check(int32_t & x,int32_t & y)203     inline void border_check (int32_t &x, int32_t &y) const {
204         border_check_x (x);
205         border_check_y (y);
206     }
207 };
208 
209 
210 template <typename T>
SoftImage(const SmartPtr<VideoBuffer> & buf,const uint32_t plane)211 SoftImage<T>::SoftImage (const SmartPtr<VideoBuffer> &buf, const uint32_t plane)
212     : _buf_ptr (NULL)
213     , _width (0) , _height (0) , _pitch (0)
214 {
215     XCAM_ASSERT (buf.ptr ());
216     const VideoBufferInfo &info = buf->get_video_info ();
217     VideoBufferPlanarInfo planar;
218     if (!info.get_planar_info(planar, plane)) {
219         XCAM_LOG_ERROR (
220             "videobuf to soft image failed. buf format:%s, plane:%d", xcam_fourcc_to_string (info.format), plane);
221         return;
222     }
223     _buf_ptr = buf->map () + info.offsets[plane];
224     XCAM_ASSERT (_buf_ptr);
225     _pitch = info.strides[plane];
226     _height = planar.height;
227     _width = planar.pixel_bytes * planar.width / sizeof (T);
228     XCAM_ASSERT (_width * sizeof(T) == planar.pixel_bytes * planar.width);
229     _bind = buf;
230 }
231 
232 template <typename T>
SoftImage(const uint32_t width,const uint32_t height,uint32_t aligned_width)233 SoftImage<T>::SoftImage (
234     const uint32_t width, const uint32_t height, uint32_t aligned_width)
235     : _buf_ptr (NULL)
236     , _width (0) , _height (0) , _pitch (0)
237 {
238     if (!aligned_width)
239         aligned_width = width;
240 
241     XCAM_ASSERT (aligned_width >= width);
242     XCAM_ASSERT (width > 0 && height > 0);
243     _pitch = aligned_width * sizeof (T);
244     _buf_ptr = (uint8_t *)xcam_malloc (_pitch * height);
245     XCAM_ASSERT (_buf_ptr);
246     _width = width;
247     _height = height;
248 }
249 
250 template <typename T>
SoftImage(const SmartPtr<VideoBuffer> & buf,const uint32_t width,const uint32_t height,const uint32_t pictch,const uint32_t offset)251 SoftImage<T>::SoftImage (
252     const SmartPtr<VideoBuffer> &buf,
253     const uint32_t width, const uint32_t height, const uint32_t pictch, const uint32_t offset)
254     : _buf_ptr (NULL)
255     , _width (width) , _height (height)
256     , _pitch (pictch)
257     , _bind (buf)
258 {
259     XCAM_ASSERT (buf.ptr ());
260     XCAM_ASSERT (buf->map ());
261     _buf_ptr = buf->map () + offset;
262 }
263 
264 template <typename T>
convert_to_uchar(const T & v)265 inline Uchar convert_to_uchar (const T& v) {
266     if (v < 0.0f) return 0;
267     else if (v > 255.0f) return 255;
268     return (Uchar)(v + 0.5f);
269 }
270 
271 template <typename T, uint32_t N>
convert_to_uchar_N(const T * in,Uchar * out)272 inline void convert_to_uchar_N (const T *in, Uchar *out) {
273     for (uint32_t i = 0; i < N; ++i) {
274         out[i] = convert_to_uchar<T> (in[i]);
275     }
276 }
277 
278 template <typename Vec2>
convert_to_uchar2(const Vec2 & v)279 inline Uchar2 convert_to_uchar2 (const Vec2& v) {
280     return Uchar2 (convert_to_uchar(v.x), convert_to_uchar(v.y));
281 }
282 
283 template <typename Vec2, uint32_t N>
convert_to_uchar2_N(const Vec2 * in,Uchar2 * out)284 inline void convert_to_uchar2_N (const Vec2 *in, Uchar2 *out) {
285     for (uint32_t i = 0; i < N; ++i) {
286         out[i].x = convert_to_uchar (in[i].x);
287         out[i].y = convert_to_uchar (in[i].y);
288     }
289 }
290 
291 typedef SoftImage<Uchar> UcharImage;
292 typedef SoftImage<Uchar2> Uchar2Image;
293 typedef SoftImage<float> FloatImage;
294 typedef SoftImage<Float2> Float2Image;
295 
296 template <class SoftImageT>
297 class SoftImageFile
298     : public FileHandle
299 {
300 public:
SoftImageFile()301     SoftImageFile () {}
SoftImageFile(const char * name,const char * option)302     explicit SoftImageFile (const char *name, const char *option)
303         : FileHandle (name, option)
304     {}
305 
306     inline XCamReturn read_buf (const SmartPtr<SoftImageT> &buf);
307     inline XCamReturn write_buf (const SmartPtr<SoftImageT> &buf);
308 };
309 
310 template <class SoftImageT>
311 inline XCamReturn
read_buf(const SmartPtr<SoftImageT> & buf)312 SoftImageFile<SoftImageT>::read_buf (const SmartPtr<SoftImageT> &buf)
313 {
314     XCAM_FAIL_RETURN (
315         WARNING, is_valid (), XCAM_RETURN_ERROR_PARAM,
316         "soft image file(%s) read buf failed, file is not open", XCAM_STR (get_file_name ()));
317 
318     XCAM_FAIL_RETURN (
319         WARNING, buf->is_valid (), XCAM_RETURN_ERROR_PARAM,
320         "soft image file(%s) read buf failed, buf is not valid", XCAM_STR (get_file_name ()));
321 
322     XCAM_ASSERT (is_valid ());
323     uint32_t height = buf->get_height ();
324     uint32_t line_bytes = buf->get_width () * buf->pixel_size ();
325 
326     for (uint32_t index = 0; index < height; index++) {
327         uint8_t *line_ptr = buf->get_buf_ptr (0, index);
328         XCAM_FAIL_RETURN (
329             WARNING, fread (line_ptr, 1, line_bytes, _fp) == line_bytes, XCAM_RETURN_ERROR_FILE,
330             "soft image file(%s) read buf failed, image_line:%d", XCAM_STR (get_file_name ()), index);
331     }
332     return XCAM_RETURN_NO_ERROR;
333 }
334 
335 template <class SoftImageT>
336 inline XCamReturn
write_buf(const SmartPtr<SoftImageT> & buf)337 SoftImageFile<SoftImageT>::write_buf (const SmartPtr<SoftImageT> &buf)
338 {
339     XCAM_FAIL_RETURN (
340         WARNING, is_valid (), XCAM_RETURN_ERROR_PARAM,
341         "soft image file(%s) write buf failed, file is not open", XCAM_STR (get_file_name ()));
342 
343     XCAM_FAIL_RETURN (
344         WARNING, buf->is_valid (), XCAM_RETURN_ERROR_PARAM,
345         "soft image file(%s) write buf failed, buf is not valid", XCAM_STR (get_file_name ()));
346 
347     XCAM_ASSERT (is_valid ());
348     uint32_t height = buf->get_height ();
349     uint32_t line_bytes = buf->get_width () * buf->pixel_size ();
350 
351     for (uint32_t index = 0; index < height; index++) {
352         uint8_t *line_ptr = buf->get_buf_ptr (0, index);
353         XCAM_FAIL_RETURN (
354             WARNING, fwrite (line_ptr, 1, line_bytes, _fp) == line_bytes, XCAM_RETURN_ERROR_FILE,
355             "soft image file(%s) write buf failed, image_line:%d", XCAM_STR (get_file_name ()), index);
356     }
357     return XCAM_RETURN_NO_ERROR;
358 }
359 
360 template <typename T> template <typename O>
361 O
read_interpolate_data(float x,float y)362 SoftImage<T>::read_interpolate_data (float x, float y) const
363 {
364     int32_t x0 = (int32_t)(x), y0 = (int32_t)(y);
365     float a = x - x0, b = y - y0;
366     O l0[2], l1[2];
367     read_array<O, 2> (x0, y0, l0);
368     read_array<O, 2> (x0, y0 + 1, l1);
369 
370     return l1[1] * (a * b) + l0[0] * ((1 - a) * (1 - b)) +
371            l1[0] * ((1 - a) * b) + l0[1] * (a * (1 - b));
372 }
373 
374 template <typename T> template<typename O, uint32_t N>
375 void
read_interpolate_array(Float2 * pos,O * array)376 SoftImage<T>::read_interpolate_array (Float2 *pos, O *array) const
377 {
378     for (uint32_t i = 0; i < N; ++i) {
379         array[i] = read_interpolate_data<O> (pos[i].x, pos[i].y);
380     }
381 }
382 
383 }
384 #endif //XCAM_SOFT_IMAGE_H
385