Project Ne10
An open, optimized software library for the ARM architecture.
NE10_rotate.c
Go to the documentation of this file.
1 /*
2  * Copyright 2013-16 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 
28 /* license of OpenCV */
29 /*M///////////////////////////////////////////////////////////////////////////////////////
30 //
31 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
32 //
33 // By downloading, copying, installing or using the software you agree to this license.
34 // If you do not agree to this license, do not download, install,
35 // copy or use the software.
36 //
37 //
38 // License Agreement
39 // For Open Source Computer Vision Library
40 //
41 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
42 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
43 // Third party copyrights are property of their respective owners.
44 //
45 // Redistribution and use in source and binary forms, with or without modification,
46 // are permitted provided that the following conditions are met:
47 //
48 // * Redistribution's of source code must retain the above copyright notice,
49 // this list of conditions and the following disclaimer.
50 //
51 // * Redistribution's in binary form must reproduce the above copyright notice,
52 // this list of conditions and the following disclaimer in the documentation
53 // and/or other materials provided with the distribution.
54 //
55 // * The name of the copyright holders may not be used to endorse or promote products
56 // derived from this software without specific prior written permission.
57 //
58 // This software is provided by the copyright holders and contributors "as is" and
59 // any express or implied warranties, including, but not limited to, the implied
60 // warranties of merchantability and fitness for a particular purpose are disclaimed.
61 // In no event shall the Intel Corporation or contributors be liable for any direct,
62 // indirect, incidental, special, exemplary, or consequential damages
63 // (including, but not limited to, procurement of substitute goods or services;
64 // loss of use, data, or profits; or business interruption) however caused
65 // and on any theory of liability, whether in contract, strict liability,
66 // or tort (including negligence or otherwise) arising in any way out of
67 // the use of this software, even if advised of the possibility of such damage.
68 //
69 //M*/
70 
71 /*
72  * NE10 Library : imgproc/NE10_rotate.c
73  */
74 
75 //#include <math.h>
76 #include "NE10.h"
77 
78 
93  ne10_uint8_t *src,
94  ne10_int32_t srcw,
95  ne10_int32_t srch,
96  ne10_int32_t dstw,
97  ne10_int32_t dsth,
98  ne10_float32_t *matrix)
99 {
100  ne10_uint8_t* src_data = src;
101  ne10_uint8_t* dst_data = dst;
102 
103  ne10_int32_t x, y;
104  //ne10_float32_t dx = (dstw - 1) * 0.5;
105  //ne10_float32_t dy = (dsth - 1) * 0.5;
106  ne10_float32_t A11 = matrix[0], A12 = matrix[1], A13 = matrix[2];
107  ne10_float32_t A21 = matrix[3], A22 = matrix[4], A23 = matrix[5];
108 
109  ne10_int32_t src_step = srcw * 4;
110  ne10_int32_t dst_step = dstw * 4;
111  for (y = 0; y < dsth; y++, dst_data += dst_step)
112  {
113  ne10_float32_t xs = A12 * y + A13;
114  ne10_float32_t ys = A22 * y + A23;
115  ne10_float32_t xe = A11 * (dstw - 1) + A12 * y + A13;
116  ne10_float32_t ye = A21 * (dstw - 1) + A22 * y + A23;
117 
118  if ( (unsigned) ( (ne10_int32_t) (xs) - 1) < (unsigned) (srcw - 4) &&
119  (unsigned) ( (ne10_int32_t) (ys) - 1) < (unsigned) (srch - 4) &&
120  (unsigned) ( (ne10_int32_t) (xe) - 1) < (unsigned) (srcw - 4) &&
121  (unsigned) ( (ne10_int32_t) (ye) - 1) < (unsigned) (srch - 4))
122  {
123  for (x = 0; x < dstw; x++)
124  {
125  ne10_int32_t ixs = (ne10_int32_t) (xs);
126  ne10_int32_t iys = (ne10_int32_t) (ys);
127  const ne10_uint8_t *ptr = src_data + src_step * iys + ixs * 4;
128  //ne10_float32_t a = (xs - ixs), b = (ys - iys), a1 = (1.f - a);
129  ne10_int16_t a = NE10_F2I16_OP (xs - ixs);
130  ne10_int16_t b = NE10_F2I16_OP (ys - iys);
131  ne10_int16_t a1 = NE10_F2I16_OP (1.f - (xs - ixs));
132 
133  ne10_uint8_t p0, p1;
134  xs += A11;
135  ys += A21;
136 
137  p0 = NE10_F2I16_SROUND (ptr[0] * a1 + ptr[4] * a);
138  p1 = NE10_F2I16_SROUND (ptr[src_step] * a1 + ptr[src_step + 4] * a);
139  dst_data[x * 4] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
140 
141  p0 = NE10_F2I16_SROUND (ptr[1] * a1 + ptr[1] * a);
142  p1 = NE10_F2I16_SROUND (ptr[src_step + 1] * a1 + ptr[src_step + 4 + 1] * a);
143  dst_data[x * 4 + 1] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
144 
145  p0 = NE10_F2I16_SROUND (ptr[2] * a1 + ptr[4 + 2] * a);
146  p1 = NE10_F2I16_SROUND (ptr[src_step + 2] * a1 + ptr[src_step + 4 + 2] * a);
147  dst_data[x * 4 + 2] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
148 
149  p0 = NE10_F2I16_SROUND (ptr[3] * a1 + ptr[4 + 3] * a);
150  p1 = NE10_F2I16_SROUND (ptr[src_step + 3] * a1 + ptr[src_step + 4 + 3] * a);
151  dst_data[x * 4 + 3] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
152  }
153  }
154  else
155  {
156  for (x = 0; x < dstw; x++)
157  {
158  ne10_int32_t ixs = (ne10_int32_t) (xs), iys = (ne10_int32_t) (ys);
159  //ne10_float32_t a = xs - ixs, b = ys - iys;
160  //ne10_float32_t a1 = 1.f - a;
161  ne10_int16_t a = NE10_F2I16_OP (xs - ixs);
162  ne10_int16_t b = NE10_F2I16_OP (ys - iys);
163  ne10_int16_t a1 = NE10_F2I16_OP (1.f - (xs - ixs));
164  const ne10_uint8_t *ptr0, *ptr1;
165  xs += A11;
166  ys += A21;
167 
168  if ( (unsigned) iys < (unsigned) (srch - 1))
169  {
170  ptr0 = src_data + src_step * iys;
171  ptr1 = ptr0 + src_step;
172  }
173  else
174  {
175  continue;
176  }
177 
178  if ( (unsigned) ixs < (unsigned) (srcw - 1))
179  {
180 
181  ne10_uint8_t p0, p1;
182 
183  ptr0 += ixs * 4;
184  ptr1 += ixs * 4;
185 
186  p0 = NE10_F2I16_SROUND (ptr0[0] * a1 + ptr0[4] * a);
187  p1 = NE10_F2I16_SROUND (ptr1[0] * a1 + ptr1[4] * a);
188  dst_data[x * 4] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
189 
190  p0 = NE10_F2I16_SROUND (ptr0[1] * a1 + ptr0[4 + 1] * a);
191  p1 = NE10_F2I16_SROUND (ptr1[1] * a1 + ptr1[4 + 1] * a);
192  dst_data[x * 4 + 1] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
193 
194  p0 = NE10_F2I16_SROUND (ptr0[2] * a1 + ptr0[4 + 2] * a);
195  p1 = NE10_F2I16_SROUND (ptr1[2] * a1 + ptr1[4 + 2] * a);
196  dst_data[x * 4 + 2] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
197 
198  p0 = NE10_F2I16_SROUND (ptr0[3] * a1 + ptr0[4 + 3] * a);
199  p1 = NE10_F2I16_SROUND (ptr1[3] * a1 + ptr1[4 + 3] * a);
200  dst_data[x * 4 + 3] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
201  }
202  }
203  }
204  }
205 }
206 
207 
213  ne10_uint32_t* dst_width,
214  ne10_uint32_t* dst_height,
215  ne10_uint8_t* src,
216  ne10_uint32_t src_width,
217  ne10_uint32_t src_height,
218  ne10_int32_t angle)
219 {
220  ne10_float32_t radian = (angle * NE10_PI / 180.0);
221  ne10_float32_t a = sin (radian), b = cos (radian);
222  ne10_int32_t srcw = src_width;
223  ne10_int32_t srch = src_height;
224  ne10_int32_t dstw = (srch * fabs (a)) + (srcw * fabs (b)) + 1;
225  ne10_int32_t dsth = (srch * fabs (b)) + (srcw * fabs (a)) + 1;
226  ne10_float32_t m[6];
227  ne10_float32_t dx = (dstw - 1) * 0.5;
228  ne10_float32_t dy = (dsth - 1) * 0.5;
229 
230  m[0] = b;
231  m[1] = a;
232  m[3] = -m[1];
233  m[4] = m[0];
234  m[2] = srcw * 0.5f - m[0] * dx - m[1] * dy;
235  m[5] = srch * 0.5f - m[3] * dx - m[4] * dy;
236 
237  *dst_width = dstw;
238  *dst_height = dsth;
239  ne10_img_rotate_get_quad_rangle_subpix_rgba_c (dst, src, srcw, srch, dstw, dsth, m);
240 }
241 
242 #ifdef ENABLE_NE10_IMG_ROTATE_RGBA_NEON
244  ne10_uint8_t *src,
245  ne10_int32_t srcw,
246  ne10_int32_t srch,
247  ne10_int32_t dstw,
248  ne10_int32_t dsth,
249  ne10_float32_t *matrix)
250  asm("ne10_img_rotate_get_quad_rangle_subpix_rgba_neon");
251 
257  ne10_uint32_t* dst_width,
258  ne10_uint32_t* dst_height,
259  ne10_uint8_t* src,
260  ne10_uint32_t src_width,
261  ne10_uint32_t src_height,
262  ne10_int32_t angle)
263 {
264  ne10_float32_t radian = (angle * NE10_PI / 180.0);
265  ne10_float32_t a = sin (radian), b = cos (radian);
266  ne10_int32_t srcw = src_width;
267  ne10_int32_t srch = src_height;
268  ne10_int32_t dstw = (srch * fabs (a)) + (srcw * fabs (b)) + 1;
269  ne10_int32_t dsth = (srch * fabs (b)) + (srcw * fabs (a)) + 1;
270  ne10_float32_t m[6];
271  ne10_float32_t dx = (dstw - 1) * 0.5;
272  ne10_float32_t dy = (dsth - 1) * 0.5;
273 
274  m[0] = b;
275  m[1] = a;
276  m[3] = -m[1];
277  m[4] = m[0];
278  m[2] = srcw * 0.5f - m[0] * dx - m[1] * dy;
279  m[5] = srch * 0.5f - m[3] * dx - m[4] * dy;
280 
281  *dst_width = dstw;
282  *dst_height = dsth;
283  ne10_img_rotate_get_quad_rangle_subpix_rgba_neon (dst, src, srcw, srch, dstw, dsth, m);
284 }
285 #endif // ENABLE_NE10_IMG_ROTATE_RGBA_NEON
#define NE10_F2I16_MAX
Definition: NE10_macros.h:71
uint8_t ne10_uint8_t
Definition: NE10_types.h:73
int32_t ne10_int32_t
Definition: NE10_types.h:76
float ne10_float32_t
Definition: NE10_types.h:80
#define NE10_F2I16_SROUND(x)
Definition: NE10_macros.h:75
void ne10_img_rotate_get_quad_rangle_subpix_rgba_c(ne10_uint8_t *dst, ne10_uint8_t *src, ne10_int32_t srcw, ne10_int32_t srch, ne10_int32_t dstw, ne10_int32_t dsth, ne10_float32_t *matrix)
Definition: NE10_rotate.c:92
uint32_t ne10_uint32_t
Definition: NE10_types.h:77
#define NE10_PI
NE10 defines a number of macros for use in its function signatures.
Definition: NE10_macros.h:47
void ne10_img_rotate_rgba_neon(ne10_uint8_t *dst, ne10_uint32_t *dst_width, ne10_uint32_t *dst_height, ne10_uint8_t *src, ne10_uint32_t src_width, ne10_uint32_t src_height, ne10_int32_t angle)
Specific implementation of ne10_img_rotate_rgba using NEON SIMD capabilities.
Definition: NE10_rotate.c:256
#define NE10_F2I16_OP(x)
Definition: NE10_macros.h:74
void ne10_img_rotate_rgba_c(ne10_uint8_t *dst, ne10_uint32_t *dst_width, ne10_uint32_t *dst_height, ne10_uint8_t *src, ne10_uint32_t src_width, ne10_uint32_t src_height, ne10_int32_t angle)
Specific implementation of ne10_img_rotate_rgba using plain C.
Definition: NE10_rotate.c:212
int16_t ne10_int16_t
Definition: NE10_types.h:74
void ne10_img_rotate_get_quad_rangle_subpix_rgba_neon(ne10_uint8_t *dst, ne10_uint8_t *src, ne10_int32_t srcw, ne10_int32_t srch, ne10_int32_t dstw, ne10_int32_t dsth, ne10_float32_t *matrix) asm("ne10_img_rotate_get_quad_rangle_subpix_rgba_neon")