• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2015 The LibYuv Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS. All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "libyuv/scale.h"
12 #include "libyuv/scale_row.h"
13 
14 #include "libyuv/basic_types.h"
15 
16 #ifdef __cplusplus
17 namespace libyuv {
18 extern "C" {
19 #endif
20 
21 // Definition for ScaleFilterCols, ScaleARGBCols and ScaleARGBFilterCols
22 #define CANY(NAMEANY, TERP_SIMD, TERP_C, BPP, MASK)                            \
23     void NAMEANY(uint8* dst_ptr, const uint8* src_ptr,                         \
24                  int dst_width, int x, int dx) {                               \
25       int n = dst_width & ~MASK;                                               \
26       if (n > 0) {                                                             \
27         TERP_SIMD(dst_ptr, src_ptr, n, x, dx);                                 \
28       }                                                                        \
29       TERP_C(dst_ptr + n * BPP, src_ptr,                                       \
30              dst_width & MASK, x + n * dx, dx);                                \
31     }
32 
33 #ifdef HAS_SCALEFILTERCOLS_NEON
34 CANY(ScaleFilterCols_Any_NEON, ScaleFilterCols_NEON, ScaleFilterCols_C, 1, 7)
35 #endif
36 #ifdef HAS_SCALEARGBCOLS_NEON
37 CANY(ScaleARGBCols_Any_NEON, ScaleARGBCols_NEON, ScaleARGBCols_C, 4, 7)
38 #endif
39 #ifdef HAS_SCALEARGBFILTERCOLS_NEON
40 CANY(ScaleARGBFilterCols_Any_NEON, ScaleARGBFilterCols_NEON,
41      ScaleARGBFilterCols_C, 4, 3)
42 #endif
43 #undef CANY
44 
45 // Fixed scale down.
46 #define SDANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK)   \
47     void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride,                   \
48                  uint8* dst_ptr, int dst_width) {                              \
49       int r = (int)((unsigned int)dst_width % (MASK + 1));                     \
50       int n = dst_width - r;                                                   \
51       if (n > 0) {                                                             \
52         SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n);                    \
53       }                                                                        \
54       SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride,                 \
55                      dst_ptr + n * BPP, r);                                    \
56     }
57 
58 // Fixed scale down for odd source width.  Used by I420Blend subsampling.
59 // Since dst_width is (width + 1) / 2, this function scales one less pixel
60 // and copies the last pixel.
61 #define SDODD(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK)   \
62     void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride,                   \
63                  uint8* dst_ptr, int dst_width) {                              \
64       int r = (int)((unsigned int)(dst_width - 1) % (MASK + 1));               \
65       int n = dst_width - r;                                                   \
66       if (n > 0) {                                                             \
67         SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n);                    \
68       }                                                                        \
69       SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride,                 \
70                      dst_ptr + n * BPP, r);                                    \
71     }
72 
73 #ifdef HAS_SCALEROWDOWN2_SSSE3
74 SDANY(ScaleRowDown2_Any_SSSE3, ScaleRowDown2_SSSE3, ScaleRowDown2_C, 2, 1, 15)
75 SDANY(ScaleRowDown2Linear_Any_SSSE3, ScaleRowDown2Linear_SSSE3,
76       ScaleRowDown2Linear_C, 2, 1, 15)
77 SDANY(ScaleRowDown2Box_Any_SSSE3, ScaleRowDown2Box_SSSE3, ScaleRowDown2Box_C,
78       2, 1, 15)
79 SDODD(ScaleRowDown2Box_Odd_SSSE3, ScaleRowDown2Box_SSSE3,
80       ScaleRowDown2Box_Odd_C, 2, 1, 15)
81 #endif
82 #ifdef HAS_SCALEROWDOWN2_AVX2
83 SDANY(ScaleRowDown2_Any_AVX2, ScaleRowDown2_AVX2, ScaleRowDown2_C, 2, 1, 31)
84 SDANY(ScaleRowDown2Linear_Any_AVX2, ScaleRowDown2Linear_AVX2,
85       ScaleRowDown2Linear_C, 2, 1, 31)
86 SDANY(ScaleRowDown2Box_Any_AVX2, ScaleRowDown2Box_AVX2, ScaleRowDown2Box_C,
87       2, 1, 31)
88 SDODD(ScaleRowDown2Box_Odd_AVX2, ScaleRowDown2Box_AVX2, ScaleRowDown2Box_Odd_C,
89       2, 1, 31)
90 #endif
91 #ifdef HAS_SCALEROWDOWN2_NEON
92 SDANY(ScaleRowDown2_Any_NEON, ScaleRowDown2_NEON, ScaleRowDown2_C, 2, 1, 15)
93 SDANY(ScaleRowDown2Linear_Any_NEON, ScaleRowDown2Linear_NEON,
94       ScaleRowDown2Linear_C, 2, 1, 15)
95 SDANY(ScaleRowDown2Box_Any_NEON, ScaleRowDown2Box_NEON,
96       ScaleRowDown2Box_C, 2, 1, 15)
97 SDODD(ScaleRowDown2Box_Odd_NEON, ScaleRowDown2Box_NEON,
98       ScaleRowDown2Box_Odd_C, 2, 1, 15)
99 #endif
100 #ifdef HAS_SCALEROWDOWN4_SSSE3
101 SDANY(ScaleRowDown4_Any_SSSE3, ScaleRowDown4_SSSE3, ScaleRowDown4_C, 4, 1, 7)
102 SDANY(ScaleRowDown4Box_Any_SSSE3, ScaleRowDown4Box_SSSE3, ScaleRowDown4Box_C,
103       4, 1, 7)
104 #endif
105 #ifdef HAS_SCALEROWDOWN4_AVX2
106 SDANY(ScaleRowDown4_Any_AVX2, ScaleRowDown4_AVX2, ScaleRowDown4_C, 4, 1, 15)
107 SDANY(ScaleRowDown4Box_Any_AVX2, ScaleRowDown4Box_AVX2, ScaleRowDown4Box_C,
108       4, 1, 15)
109 #endif
110 #ifdef HAS_SCALEROWDOWN4_NEON
111 SDANY(ScaleRowDown4_Any_NEON, ScaleRowDown4_NEON, ScaleRowDown4_C, 4, 1, 7)
112 SDANY(ScaleRowDown4Box_Any_NEON, ScaleRowDown4Box_NEON, ScaleRowDown4Box_C,
113       4, 1, 7)
114 #endif
115 #ifdef HAS_SCALEROWDOWN34_SSSE3
116 SDANY(ScaleRowDown34_Any_SSSE3, ScaleRowDown34_SSSE3,
117       ScaleRowDown34_C, 4 / 3, 1, 23)
118 SDANY(ScaleRowDown34_0_Box_Any_SSSE3, ScaleRowDown34_0_Box_SSSE3,
119       ScaleRowDown34_0_Box_C, 4 / 3, 1, 23)
120 SDANY(ScaleRowDown34_1_Box_Any_SSSE3, ScaleRowDown34_1_Box_SSSE3,
121       ScaleRowDown34_1_Box_C, 4 / 3, 1, 23)
122 #endif
123 #ifdef HAS_SCALEROWDOWN34_NEON
124 SDANY(ScaleRowDown34_Any_NEON, ScaleRowDown34_NEON,
125       ScaleRowDown34_C, 4 / 3, 1, 23)
126 SDANY(ScaleRowDown34_0_Box_Any_NEON, ScaleRowDown34_0_Box_NEON,
127       ScaleRowDown34_0_Box_C, 4 / 3, 1, 23)
128 SDANY(ScaleRowDown34_1_Box_Any_NEON, ScaleRowDown34_1_Box_NEON,
129       ScaleRowDown34_1_Box_C, 4 / 3, 1, 23)
130 #endif
131 #ifdef HAS_SCALEROWDOWN38_SSSE3
132 SDANY(ScaleRowDown38_Any_SSSE3, ScaleRowDown38_SSSE3,
133       ScaleRowDown38_C, 8 / 3, 1, 11)
134 SDANY(ScaleRowDown38_3_Box_Any_SSSE3, ScaleRowDown38_3_Box_SSSE3,
135       ScaleRowDown38_3_Box_C, 8 / 3, 1, 5)
136 SDANY(ScaleRowDown38_2_Box_Any_SSSE3, ScaleRowDown38_2_Box_SSSE3,
137       ScaleRowDown38_2_Box_C, 8 / 3, 1, 5)
138 #endif
139 #ifdef HAS_SCALEROWDOWN38_NEON
140 SDANY(ScaleRowDown38_Any_NEON, ScaleRowDown38_NEON,
141       ScaleRowDown38_C, 8 / 3, 1, 11)
142 SDANY(ScaleRowDown38_3_Box_Any_NEON, ScaleRowDown38_3_Box_NEON,
143       ScaleRowDown38_3_Box_C, 8 / 3, 1, 11)
144 SDANY(ScaleRowDown38_2_Box_Any_NEON, ScaleRowDown38_2_Box_NEON,
145       ScaleRowDown38_2_Box_C, 8 / 3, 1, 11)
146 #endif
147 
148 #ifdef HAS_SCALEARGBROWDOWN2_SSE2
149 SDANY(ScaleARGBRowDown2_Any_SSE2, ScaleARGBRowDown2_SSE2,
150       ScaleARGBRowDown2_C, 2, 4, 3)
151 SDANY(ScaleARGBRowDown2Linear_Any_SSE2, ScaleARGBRowDown2Linear_SSE2,
152       ScaleARGBRowDown2Linear_C, 2, 4, 3)
153 SDANY(ScaleARGBRowDown2Box_Any_SSE2, ScaleARGBRowDown2Box_SSE2,
154       ScaleARGBRowDown2Box_C, 2, 4, 3)
155 #endif
156 #ifdef HAS_SCALEARGBROWDOWN2_NEON
157 SDANY(ScaleARGBRowDown2_Any_NEON, ScaleARGBRowDown2_NEON,
158       ScaleARGBRowDown2_C, 2, 4, 7)
159 SDANY(ScaleARGBRowDown2Linear_Any_NEON, ScaleARGBRowDown2Linear_NEON,
160       ScaleARGBRowDown2Linear_C, 2, 4, 7)
161 SDANY(ScaleARGBRowDown2Box_Any_NEON, ScaleARGBRowDown2Box_NEON,
162       ScaleARGBRowDown2Box_C, 2, 4, 7)
163 #endif
164 #undef SDANY
165 
166 // Scale down by even scale factor.
167 #define SDAANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, BPP, MASK)          \
168     void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride, int src_stepx,    \
169                  uint8* dst_ptr, int dst_width) {                              \
170       int r = (int)((unsigned int)dst_width % (MASK + 1));                     \
171       int n = dst_width - r;                                                   \
172       if (n > 0) {                                                             \
173         SCALEROWDOWN_SIMD(src_ptr, src_stride, src_stepx, dst_ptr, n);         \
174       }                                                                        \
175       SCALEROWDOWN_C(src_ptr + (n * src_stepx) * BPP, src_stride,              \
176                      src_stepx, dst_ptr + n * BPP, r);                         \
177     }
178 
179 #ifdef HAS_SCALEARGBROWDOWNEVEN_SSE2
180 SDAANY(ScaleARGBRowDownEven_Any_SSE2, ScaleARGBRowDownEven_SSE2,
181        ScaleARGBRowDownEven_C, 4, 3)
182 SDAANY(ScaleARGBRowDownEvenBox_Any_SSE2, ScaleARGBRowDownEvenBox_SSE2,
183        ScaleARGBRowDownEvenBox_C, 4, 3)
184 #endif
185 #ifdef HAS_SCALEARGBROWDOWNEVEN_NEON
186 SDAANY(ScaleARGBRowDownEven_Any_NEON, ScaleARGBRowDownEven_NEON,
187        ScaleARGBRowDownEven_C, 4, 3)
188 SDAANY(ScaleARGBRowDownEvenBox_Any_NEON, ScaleARGBRowDownEvenBox_NEON,
189        ScaleARGBRowDownEvenBox_C, 4, 3)
190 #endif
191 
192 // Add rows box filter scale down.
193 #define SAANY(NAMEANY, SCALEADDROW_SIMD, SCALEADDROW_C, MASK)                  \
194   void NAMEANY(const uint8* src_ptr, uint16* dst_ptr, int src_width) {         \
195       int n = src_width & ~MASK;                                               \
196       if (n > 0) {                                                             \
197         SCALEADDROW_SIMD(src_ptr, dst_ptr, n);                                 \
198       }                                                                        \
199       SCALEADDROW_C(src_ptr + n, dst_ptr + n, src_width & MASK);               \
200     }
201 
202 #ifdef HAS_SCALEADDROW_SSE2
203 SAANY(ScaleAddRow_Any_SSE2, ScaleAddRow_SSE2, ScaleAddRow_C, 15)
204 #endif
205 #ifdef HAS_SCALEADDROW_AVX2
206 SAANY(ScaleAddRow_Any_AVX2, ScaleAddRow_AVX2, ScaleAddRow_C, 31)
207 #endif
208 #ifdef HAS_SCALEADDROW_NEON
209 SAANY(ScaleAddRow_Any_NEON, ScaleAddRow_NEON, ScaleAddRow_C, 15)
210 #endif
211 #undef SAANY
212 
213 #ifdef __cplusplus
214 }  // extern "C"
215 }  // namespace libyuv
216 #endif
217 
218 
219 
220 
221 
222