Project Ne10
An Open Optimized Software Library Project for the ARM Architecture
Loading...
Searching...
No Matches
NE10_boxfilter.c
1/*
2 * Copyright 2013-15 ARM Limited and Contributors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of ARM Limited nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY ARM LIMITED AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL ARM LIMITED AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/* license of OpenCV */
28/*M///////////////////////////////////////////////////////////////////////////////////////
29//
30// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
31//
32// By downloading, copying, installing or using the software you agree to this license.
33// If you do not agree to this license, do not download, install,
34// copy or use the software.
35//
36//
37// License Agreement
38// For Open Source Computer Vision Library
39//
40// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
41// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
42// Third party copyrights are property of their respective owners.
43//
44// Redistribution and use in source and binary forms, with or without modification,
45// are permitted provided that the following conditions are met:
46//
47// * Redistribution's of source code must retain the above copyright notice,
48// this list of conditions and the following disclaimer.
49//
50// * Redistribution's in binary form must reproduce the above copyright notice,
51// this list of conditions and the following disclaimer in the documentation
52// and/or other materials provided with the distribution.
53//
54// * The name of the copyright holders may not be used to endorse or promote products
55// derived from this software without specific prior written permission.
56//
57// This software is provided by the copyright holders and contributors "as is" and
58// any express or implied warranties, including, but not limited to, the implied
59// warranties of merchantability and fitness for a particular purpose are disclaimed.
60// In no event shall the Intel Corporation or contributors be liable for any direct,
61// indirect, incidental, special, exemplary, or consequential damages
62// (including, but not limited to, procurement of substitute goods or services;
63// loss of use, data, or profits; or business interruption) however caused
64// and on any theory of liability, whether in contract, strict liability,
65// or tort (including negligence or otherwise) arising in any way out of
66// the use of this software, even if advised of the possibility of such damage.
67//
68//M*/
69
70/*
71 * NE10 Library : imgproc/NE10_boxfilter.c
72 */
73
74#include "NE10.h"
75#include <stdlib.h>
76
77/* RGBA CHANNEL number is 4 */
78#define RGBA_CH 4
79
80/*
81 * compute destination image's row border.
82 */
83void ne10_img_boxfilter_row_border (const ne10_uint8_t* src,
84 ne10_uint8_t* dst,
85 ne10_size_t src_sz,
86 ne10_int32_t src_stride,
87 ne10_int32_t dst_stride,
88 ne10_size_t kernel,
89 ne10_point_t anchor,
90 ne10_int32_t *border_l_p,
91 ne10_int32_t *border_r_p)
92{
93 assert (kernel.x <= src_sz.x);
94 assert (src != dst);
95
96 *border_l_p = anchor.x;
97 *border_r_p = kernel.x - (anchor.x + 1);
98
99 ne10_int32_t x, y, k;
100
101 const ne10_uint8_t *src_row;
102 ne10_uint8_t *dst_row;
103
104 for (y = 0; y < src_sz.y; y++)
105 {
106 src_row = src + y * src_stride;
107 dst_row = dst + y * dst_stride;
108 ne10_float32_t sum[RGBA_CH];
109
110 /* compute left border */
111 ne10_int32_t offset = kernel.x - *border_l_p - 1;
112 for (k = 0; k < RGBA_CH; k++)
113 {
114 sum[k] = 0;
115 for (x = 0; x < offset; x++)
116 {
117 sum[k] += * (src_row + x * RGBA_CH + k);
118 }
119 }
120
121 for (k = 0; k < RGBA_CH; k++)
122 {
123 for (x = 0; x < *border_l_p; x++)
124 {
125 sum[k] += * (src_row + (offset + x) *
126 RGBA_CH + k);
127 * (dst_row + x * RGBA_CH + k) = sum[k] /
128 kernel.x;
129 }
130 }
131
132 /* compute right border */
133 for (k = 0; k < RGBA_CH; k++)
134 {
135 sum[k] = 0;
136 for (x = 0; x < kernel.x; x++)
137 {
138 sum[k] += * (src_row + (src_sz.x - kernel.x + x) *
139 RGBA_CH + k);
140 }
141 }
142
143 for (k = 0; k < RGBA_CH; k++)
144 {
145 for (x = 0; x < *border_r_p; x++)
146 {
147 sum[k] -= * (src_row + (src_sz.x - kernel.x + x) *
148 RGBA_CH + k);
149 * (dst_row + (src_sz.x - *border_r_p + x) *
150 RGBA_CH + k) = sum[k] / kernel.x;
151 }
152 }
153 }
154}
155
156void ne10_img_boxfilter_row_c (const ne10_uint8_t *src,
157 ne10_uint8_t *dst,
158 ne10_size_t src_sz,
159 ne10_int32_t src_stride,
160 ne10_int32_t dst_stride,
161 ne10_size_t kernel,
162 ne10_point_t anchor,
163 ne10_int32_t border_l,
164 ne10_int32_t border_r)
165{
166 assert (src != dst);
167 assert ( (kernel.x > 0) && (kernel.x < (1 << 16)));
168 assert (kernel.x <= src_sz.x);
169
170 ne10_int32_t x, y, k;
171
172 for (y = 0; y < src_sz.y; y++)
173 {
174 const ne10_uint8_t *src_row = src + y * src_stride;
175 ne10_uint8_t *dst_row = dst + y * dst_stride;
176 ne10_float32_t sum[RGBA_CH];
177
178 for (k = 0; k < RGBA_CH; k++)
179 {
180 sum[k] = 0;
181
182 for (x = 0; x < kernel.x; x++)
183 {
184 sum[k] += * (src_row + x * RGBA_CH + k);
185 }
186
187 * (dst_row + border_l * RGBA_CH + k) = sum[k] /
188 kernel.x;
189 }
190
191 ne10_uint32_t prev = (anchor.x + 1) * RGBA_CH;
192 ne10_uint32_t next = (kernel.x - anchor.x - 1) * RGBA_CH;
193 const ne10_uint8_t *src_pixel = src_row + (1 + border_l) * RGBA_CH;
194 const ne10_uint8_t *src_pixel_end = src_row + (src_sz.x - border_r) *
195 RGBA_CH;
196 ne10_uint8_t *dst_pixel = dst_row + (1 + border_l) * RGBA_CH;
197
198 for (k = 0; src_pixel < src_pixel_end; src_pixel++, dst_pixel++)
199 {
200 sum[k] += src_pixel[next] - * (src_pixel - prev);
201 *dst_pixel = sum[k] / kernel.x;
202 k++;
203 k &= 3;
204 }
205 }
206}
207
208void ne10_img_boxfilter_col_border (const ne10_uint8_t *src,
209 ne10_uint8_t *dst,
210 ne10_size_t src_sz,
211 ne10_int32_t src_stride,
212 ne10_int32_t dst_stride,
213 ne10_size_t kernel,
214 ne10_point_t anchor,
215 ne10_int32_t *border_t_p,
216 ne10_int32_t *border_b_p)
217{
218 assert (kernel.y <= src_sz.y);
219 assert (src != dst);
220
221 *border_t_p = anchor.y;
222 *border_b_p = kernel.y - (anchor.y + 1);
223
224 ne10_int32_t x, y, k;
225 const ne10_uint8_t *src_col;
226 ne10_uint8_t *dst_col;
227
228 for (x = 0; x < src_sz.x; x++)
229 {
230 src_col = src + x * RGBA_CH;
231 dst_col = dst + x * RGBA_CH;
232 ne10_float32_t sum[RGBA_CH];
233
234 /* compute top border */
235 ne10_int32_t offset = kernel.y - *border_t_p - 1;
236 for (k = 0; k < RGBA_CH; k++)
237 {
238 sum[k] = 0;
239
240 for (y = 0; y < offset; y++)
241 {
242 sum[k] += * (src_col + y * src_stride + k);
243 }
244 }
245
246 for (k = 0; k < RGBA_CH; k++)
247 {
248 for (y = 0; y < *border_t_p; y++)
249 {
250 sum[k] += * (src_col + (offset + y) *
251 src_stride + k);
252 * (dst_col + y * dst_stride + k) = sum[k] /
253 kernel.y;
254 }
255 }
256
257 /* compute the bottom border */
258 for (k = 0; k < RGBA_CH; k++)
259 {
260 sum[k] = 0;
261 for (y = 0; y < kernel.y; y++)
262 {
263 sum[k] += * (src_col + (src_sz.y - kernel.y + y) *
264 src_stride + k);
265 }
266 }
267
268 for (k = 0; k < RGBA_CH; k++)
269 {
270 for (y = 0; y < *border_b_p; y++)
271 {
272 sum[k] -= * (src_col + (src_sz.y - kernel.y + y) *
273 src_stride + k);
274 * (dst_col + (src_sz.y - *border_b_p + y) * dst_stride + k) =
275 sum[k] / kernel.y;
276 }
277 }
278 }
279}
280
281void ne10_img_boxfilter_col_c (const ne10_uint8_t *src,
282 ne10_uint8_t *dst,
283 ne10_size_t src_sz,
284 ne10_int32_t src_stride,
285 ne10_int32_t dst_stride,
286 ne10_size_t kernel,
287 ne10_point_t anchor,
288 ne10_int32_t border_t,
289 ne10_int32_t border_b)
290{
291 assert (src != dst);
292 assert ( (kernel.y > 0) && (kernel.y < (1 << 16)));
293 assert (kernel.y <= src_sz.y);
294
295 ne10_int32_t x, y, k;
296
297 for (x = 0; x < src_sz.x; x++)
298 {
299 const ne10_uint8_t *src_col = src + x * RGBA_CH;
300 ne10_uint8_t *dst_col = dst + x * RGBA_CH;
301 ne10_float32_t sum[RGBA_CH];
302
303 for (k = 0; k < RGBA_CH; k++)
304 {
305 sum[k] = 0;
306
307 for (y = 0; y < kernel.y; y++)
308 {
309 sum[k] += * (src_col + y * src_stride + k);
310 }
311
312 * (dst_col + border_t * dst_stride + k) = sum[k] / kernel.y;
313 }
314
315 ne10_uint32_t prev = (anchor.y + 1) * src_stride;
316 ne10_uint32_t next = (kernel.y - anchor.y - 1) * src_stride;
317 const ne10_uint8_t *src_pixel = src_col + (1 + border_t) * src_stride;
318 const ne10_uint8_t *src_end = src_col + (src_sz.y - border_b) *
319 src_stride;
320 ne10_uint8_t *dst_pixel = dst_col + (1 + border_t) * dst_stride;
321
322 while (src_pixel < src_end)
323 {
324 for (k = 0; k < RGBA_CH; k++)
325 {
326 sum[k] += src_pixel[next + k] - * (src_pixel - prev + k);
327 * (dst_pixel + k) = sum[k] / kernel.y;
328 }
329 dst_pixel += dst_stride;
330 src_pixel += src_stride;
331 }
332 }
333}
334
354void ne10_img_boxfilter_rgba8888_c (const ne10_uint8_t *src,
355 ne10_uint8_t *dst,
356 ne10_size_t src_sz,
357 ne10_int32_t src_stride,
358 ne10_int32_t dst_stride,
359 ne10_size_t kernel)
360{
361 ne10_int32_t border_l, border_r, border_t, border_b;
362 ne10_point_t anchor;
363
364 assert (src != 0 && dst != 0);
365 assert (src_sz.x > 0 && src_sz.y > 0);
366 assert (src_stride > 0 && dst_stride > 0);
367 assert (kernel.x > 0 && kernel.x <= src_sz.x
368 && kernel.y > 0 && kernel.y <= src_sz.y);
369
370 anchor.x = kernel.x / 2;
371 anchor.y = kernel.y / 2;
372
373 ne10_uint8_t *dst_buf = (ne10_uint8_t *) malloc (sizeof (ne10_uint8_t) *
374 src_sz.x *
375 src_sz.y *
376 RGBA_CH);
377
378 if (!dst_buf)
379 {
380 fprintf (stderr,
381 "ERROR: buffer allocation fails!\nallocation size: %d\n",
382 sizeof (ne10_uint8_t) *
383 src_sz.x *
384 src_sz.y *
385 RGBA_CH);
386 return;
387 }
388
389 ne10_int32_t dst_buf_stride = src_sz.x * RGBA_CH;
390
391 /* compute the row border of dst image */
392 ne10_img_boxfilter_row_border (src,
393 dst_buf,
394 src_sz,
395 src_stride,
396 dst_buf_stride,
397 kernel,
398 anchor,
399 &border_l,
400 &border_r);
401 /* boxfilter is separable filter, and then can be apply row filter and
402 * column filter sequentially. here apply boxfilter's row part to image
403 */
404 ne10_img_boxfilter_row_c (src,
405 dst_buf,
406 src_sz,
407 src_stride,
408 dst_buf_stride,
409 kernel,
410 anchor,
411 border_l,
412 border_r);
413
414 /* compute the column border of dst image,
415 * which is based on previous row filter result.
416 */
417 ne10_img_boxfilter_col_border (dst_buf,
418 dst,
419 src_sz,
420 dst_buf_stride,
421 dst_stride,
422 kernel,
423 anchor,
424 &border_t,
425 &border_b);
426
427 /* apply boxfilter column filter to image */
428 ne10_img_boxfilter_col_c (dst_buf,
429 dst,
430 src_sz,
431 dst_buf_stride,
432 dst_stride,
433 kernel,
434 anchor,
435 border_t,
436 border_b);
437
438 free (dst_buf);
439}
440
void ne10_img_boxfilter_rgba8888_c(const ne10_uint8_t *src, ne10_uint8_t *dst, ne10_size_t src_sz, ne10_int32_t src_stride, ne10_int32_t dst_stride, ne10_size_t kernel)
box filter
Structure for point in image.
Definition NE10_types.h:435