Project Ne10
An Open Optimized Software Library Project for the ARM Architecture
NE10_rotate.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 
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 
94 void ne10_img_rotate_get_quad_rangle_subpix_rgba_c (ne10_uint8_t *dst,
95  ne10_uint8_t *src,
96  ne10_int32_t srcw,
97  ne10_int32_t srch,
98  ne10_int32_t dstw,
99  ne10_int32_t dsth,
100  ne10_float32_t *matrix)
101 {
102  ne10_uint8_t* src_data = src;
103  ne10_uint8_t* dst_data = dst;
104 
105  ne10_int32_t x, y;
106  //ne10_float32_t dx = (dstw - 1) * 0.5;
107  //ne10_float32_t dy = (dsth - 1) * 0.5;
108  ne10_float32_t A11 = matrix[0], A12 = matrix[1], A13 = matrix[2];
109  ne10_float32_t A21 = matrix[3], A22 = matrix[4], A23 = matrix[5];
110 
111  ne10_int32_t src_step = srcw * 4;
112  ne10_int32_t dst_step = dstw * 4;
113  for (y = 0; y < dsth; y++, dst_data += dst_step)
114  {
115  ne10_float32_t xs = A12 * y + A13;
116  ne10_float32_t ys = A22 * y + A23;
117  ne10_float32_t xe = A11 * (dstw - 1) + A12 * y + A13;
118  ne10_float32_t ye = A21 * (dstw - 1) + A22 * y + A23;
119 
120  if ( (unsigned) ( (ne10_int32_t) (xs) - 1) < (unsigned) (srcw - 4) &&
121  (unsigned) ( (ne10_int32_t) (ys) - 1) < (unsigned) (srch - 4) &&
122  (unsigned) ( (ne10_int32_t) (xe) - 1) < (unsigned) (srcw - 4) &&
123  (unsigned) ( (ne10_int32_t) (ye) - 1) < (unsigned) (srch - 4))
124  {
125  for (x = 0; x < dstw; x++)
126  {
127  ne10_int32_t ixs = (ne10_int32_t) (xs);
128  ne10_int32_t iys = (ne10_int32_t) (ys);
129  const ne10_uint8_t *ptr = src_data + src_step * iys + ixs * 4;
130  //ne10_float32_t a = (xs - ixs), b = (ys - iys), a1 = (1.f - a);
131  ne10_int16_t a = NE10_F2I16_OP (xs - ixs);
132  ne10_int16_t b = NE10_F2I16_OP (ys - iys);
133  ne10_int16_t a1 = NE10_F2I16_OP (1.f - (xs - ixs));
134 
135  ne10_uint8_t p0, p1;
136  xs += A11;
137  ys += A21;
138 
139  p0 = NE10_F2I16_SROUND (ptr[0] * a1 + ptr[4] * a);
140  p1 = NE10_F2I16_SROUND (ptr[src_step] * a1 + ptr[src_step + 4] * a);
141  dst_data[x * 4] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
142 
143  p0 = NE10_F2I16_SROUND (ptr[1] * a1 + ptr[1] * a);
144  p1 = NE10_F2I16_SROUND (ptr[src_step + 1] * a1 + ptr[src_step + 4 + 1] * a);
145  dst_data[x * 4 + 1] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
146 
147  p0 = NE10_F2I16_SROUND (ptr[2] * a1 + ptr[4 + 2] * a);
148  p1 = NE10_F2I16_SROUND (ptr[src_step + 2] * a1 + ptr[src_step + 4 + 2] * a);
149  dst_data[x * 4 + 2] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
150 
151  p0 = NE10_F2I16_SROUND (ptr[3] * a1 + ptr[4 + 3] * a);
152  p1 = NE10_F2I16_SROUND (ptr[src_step + 3] * a1 + ptr[src_step + 4 + 3] * a);
153  dst_data[x * 4 + 3] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
154  }
155  }
156  else
157  {
158  for (x = 0; x < dstw; x++)
159  {
160  ne10_int32_t ixs = (ne10_int32_t) (xs), iys = (ne10_int32_t) (ys);
161  //ne10_float32_t a = xs - ixs, b = ys - iys;
162  //ne10_float32_t a1 = 1.f - a;
163  ne10_int16_t a = NE10_F2I16_OP (xs - ixs);
164  ne10_int16_t b = NE10_F2I16_OP (ys - iys);
165  ne10_int16_t a1 = NE10_F2I16_OP (1.f - (xs - ixs));
166  const ne10_uint8_t *ptr0, *ptr1;
167  xs += A11;
168  ys += A21;
169 
170  if ( (unsigned) iys < (unsigned) (srch - 1))
171  {
172  ptr0 = src_data + src_step * iys;
173  ptr1 = ptr0 + src_step;
174  }
175  else
176  {
177  continue;
178  }
179 
180  if ( (unsigned) ixs < (unsigned) (srcw - 1))
181  {
182 
183  ne10_uint8_t p0, p1;
184 
185  ptr0 += ixs * 4;
186  ptr1 += ixs * 4;
187 
188  p0 = NE10_F2I16_SROUND (ptr0[0] * a1 + ptr0[4] * a);
189  p1 = NE10_F2I16_SROUND (ptr1[0] * a1 + ptr1[4] * a);
190  dst_data[x * 4] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
191 
192  p0 = NE10_F2I16_SROUND (ptr0[1] * a1 + ptr0[4 + 1] * a);
193  p1 = NE10_F2I16_SROUND (ptr1[1] * a1 + ptr1[4 + 1] * a);
194  dst_data[x * 4 + 1] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
195 
196  p0 = NE10_F2I16_SROUND (ptr0[2] * a1 + ptr0[4 + 2] * a);
197  p1 = NE10_F2I16_SROUND (ptr1[2] * a1 + ptr1[4 + 2] * a);
198  dst_data[x * 4 + 2] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
199 
200  p0 = NE10_F2I16_SROUND (ptr0[3] * a1 + ptr0[4 + 3] * a);
201  p1 = NE10_F2I16_SROUND (ptr1[3] * a1 + ptr1[4 + 3] * a);
202  dst_data[x * 4 + 3] = NE10_F2I16_SROUND (p0 * NE10_F2I16_MAX + b * (p1 - p0));
203  }
204  }
205  }
206  }
207 }
208 
209 
231 void ne10_img_rotate_rgba_c (ne10_uint8_t* dst,
232  ne10_uint32_t* dst_width,
233  ne10_uint32_t* dst_height,
234  ne10_uint8_t* src,
235  ne10_uint32_t src_width,
236  ne10_uint32_t src_height,
237  ne10_int32_t angle)
238 {
239  ne10_float32_t radian = (angle * NE10_PI / 180.0);
240  ne10_float32_t a = sin (radian), b = cos (radian);
241  ne10_int32_t srcw = src_width;
242  ne10_int32_t srch = src_height;
243  ne10_int32_t dstw = (srch * fabs (a)) + (srcw * fabs (b)) + 1;
244  ne10_int32_t dsth = (srch * fabs (b)) + (srcw * fabs (a)) + 1;
245  ne10_float32_t m[6];
246  ne10_float32_t dx = (dstw - 1) * 0.5;
247  ne10_float32_t dy = (dsth - 1) * 0.5;
248 
249  m[0] = b;
250  m[1] = a;
251  m[3] = -m[1];
252  m[4] = m[0];
253  m[2] = srcw * 0.5f - m[0] * dx - m[1] * dy;
254  m[5] = srch * 0.5f - m[3] * dx - m[4] * dy;
255 
256  *dst_width = dstw;
257  *dst_height = dsth;
258  ne10_img_rotate_get_quad_rangle_subpix_rgba_c (dst, src, srcw, srch, dstw, dsth, m);
259 }
260 
261 #ifdef ENABLE_NE10_IMG_ROTATE_RGBA_NEON
262 extern void ne10_img_rotate_get_quad_rangle_subpix_rgba_neon (ne10_uint8_t *dst,
263  ne10_uint8_t *src,
264  ne10_int32_t srcw,
265  ne10_int32_t srch,
266  ne10_int32_t dstw,
267  ne10_int32_t dsth,
268  ne10_float32_t *matrix)
269  asm("ne10_img_rotate_get_quad_rangle_subpix_rgba_neon");
270 
283 void ne10_img_rotate_rgba_neon (ne10_uint8_t* dst,
284  ne10_uint32_t* dst_width,
285  ne10_uint32_t* dst_height,
286  ne10_uint8_t* src,
287  ne10_uint32_t src_width,
288  ne10_uint32_t src_height,
289  ne10_int32_t angle)
290 {
291  ne10_float32_t radian = (angle * NE10_PI / 180.0);
292  ne10_float32_t a = sin (radian), b = cos (radian);
293  ne10_int32_t srcw = src_width;
294  ne10_int32_t srch = src_height;
295  ne10_int32_t dstw = (srch * fabs (a)) + (srcw * fabs (b)) + 1;
296  ne10_int32_t dsth = (srch * fabs (b)) + (srcw * fabs (a)) + 1;
297  ne10_float32_t m[6];
298  ne10_float32_t dx = (dstw - 1) * 0.5;
299  ne10_float32_t dy = (dsth - 1) * 0.5;
300 
301  m[0] = b;
302  m[1] = a;
303  m[3] = -m[1];
304  m[4] = m[0];
305  m[2] = srcw * 0.5f - m[0] * dx - m[1] * dy;
306  m[5] = srch * 0.5f - m[3] * dx - m[4] * dy;
307 
308  *dst_width = dstw;
309  *dst_height = dsth;
310  ne10_img_rotate_get_quad_rangle_subpix_rgba_neon (dst, src, srcw, srch, dstw, dsth, m);
311 }
312 
316 #endif // ENABLE_NE10_IMG_ROTATE_RGBA_NEON
ne10_img_rotate_rgba_c
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)
image resize of 8-bit data.
Definition: NE10_rotate.c:231