Line data Source code
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, int dst_width, int x, \
24 : 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, dst_width & MASK, x + n * dx, dx); \
30 : }
31 :
32 : #ifdef HAS_SCALEFILTERCOLS_NEON
33 : CANY(ScaleFilterCols_Any_NEON, ScaleFilterCols_NEON, ScaleFilterCols_C, 1, 7)
34 : #endif
35 : #ifdef HAS_SCALEARGBCOLS_NEON
36 : CANY(ScaleARGBCols_Any_NEON, ScaleARGBCols_NEON, ScaleARGBCols_C, 4, 7)
37 : #endif
38 : #ifdef HAS_SCALEARGBFILTERCOLS_NEON
39 : CANY(ScaleARGBFilterCols_Any_NEON,
40 : ScaleARGBFilterCols_NEON,
41 : ScaleARGBFilterCols_C,
42 : 4,
43 : 3)
44 : #endif
45 : #undef CANY
46 :
47 : // Fixed scale down.
48 : #define SDANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \
49 : void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride, uint8* dst_ptr, \
50 : int dst_width) { \
51 : int r = (int)((unsigned int)dst_width % (MASK + 1)); \
52 : int n = dst_width - r; \
53 : if (n > 0) { \
54 : SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n); \
55 : } \
56 : SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride, \
57 : dst_ptr + n * BPP, r); \
58 : }
59 :
60 : // Fixed scale down for odd source width. Used by I420Blend subsampling.
61 : // Since dst_width is (width + 1) / 2, this function scales one less pixel
62 : // and copies the last pixel.
63 : #define SDODD(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \
64 : void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride, uint8* dst_ptr, \
65 : int dst_width) { \
66 : int r = (int)((unsigned int)(dst_width - 1) % (MASK + 1)); \
67 : int n = dst_width - r; \
68 : if (n > 0) { \
69 : SCALEROWDOWN_SIMD(src_ptr, src_stride, dst_ptr, n); \
70 : } \
71 : SCALEROWDOWN_C(src_ptr + (n * FACTOR) * BPP, src_stride, \
72 : dst_ptr + n * BPP, r); \
73 : }
74 :
75 : #ifdef HAS_SCALEROWDOWN2_SSSE3
76 0 : SDANY(ScaleRowDown2_Any_SSSE3, ScaleRowDown2_SSSE3, ScaleRowDown2_C, 2, 1, 15)
77 0 : SDANY(ScaleRowDown2Linear_Any_SSSE3,
78 : ScaleRowDown2Linear_SSSE3,
79 : ScaleRowDown2Linear_C,
80 : 2,
81 : 1,
82 : 15)
83 0 : SDANY(ScaleRowDown2Box_Any_SSSE3,
84 : ScaleRowDown2Box_SSSE3,
85 : ScaleRowDown2Box_C,
86 : 2,
87 : 1,
88 : 15)
89 0 : SDODD(ScaleRowDown2Box_Odd_SSSE3,
90 : ScaleRowDown2Box_SSSE3,
91 : ScaleRowDown2Box_Odd_C,
92 : 2,
93 : 1,
94 : 15)
95 : #endif
96 : #ifdef HAS_SCALEROWDOWN2_AVX2
97 0 : SDANY(ScaleRowDown2_Any_AVX2, ScaleRowDown2_AVX2, ScaleRowDown2_C, 2, 1, 31)
98 0 : SDANY(ScaleRowDown2Linear_Any_AVX2,
99 : ScaleRowDown2Linear_AVX2,
100 : ScaleRowDown2Linear_C,
101 : 2,
102 : 1,
103 : 31)
104 0 : SDANY(ScaleRowDown2Box_Any_AVX2,
105 : ScaleRowDown2Box_AVX2,
106 : ScaleRowDown2Box_C,
107 : 2,
108 : 1,
109 : 31)
110 0 : SDODD(ScaleRowDown2Box_Odd_AVX2,
111 : ScaleRowDown2Box_AVX2,
112 : ScaleRowDown2Box_Odd_C,
113 : 2,
114 : 1,
115 : 31)
116 : #endif
117 : #ifdef HAS_SCALEROWDOWN2_NEON
118 : SDANY(ScaleRowDown2_Any_NEON, ScaleRowDown2_NEON, ScaleRowDown2_C, 2, 1, 15)
119 : SDANY(ScaleRowDown2Linear_Any_NEON,
120 : ScaleRowDown2Linear_NEON,
121 : ScaleRowDown2Linear_C,
122 : 2,
123 : 1,
124 : 15)
125 : SDANY(ScaleRowDown2Box_Any_NEON,
126 : ScaleRowDown2Box_NEON,
127 : ScaleRowDown2Box_C,
128 : 2,
129 : 1,
130 : 15)
131 : SDODD(ScaleRowDown2Box_Odd_NEON,
132 : ScaleRowDown2Box_NEON,
133 : ScaleRowDown2Box_Odd_C,
134 : 2,
135 : 1,
136 : 15)
137 : #endif
138 : #ifdef HAS_SCALEROWDOWN2_MSA
139 : SDANY(ScaleRowDown2_Any_MSA, ScaleRowDown2_MSA, ScaleRowDown2_C, 2, 1, 31)
140 : SDANY(ScaleRowDown2Linear_Any_MSA,
141 : ScaleRowDown2Linear_MSA,
142 : ScaleRowDown2Linear_C,
143 : 2,
144 : 1,
145 : 31)
146 : SDANY(ScaleRowDown2Box_Any_MSA,
147 : ScaleRowDown2Box_MSA,
148 : ScaleRowDown2Box_C,
149 : 2,
150 : 1,
151 : 31)
152 : #endif
153 : #ifdef HAS_SCALEROWDOWN4_SSSE3
154 0 : SDANY(ScaleRowDown4_Any_SSSE3, ScaleRowDown4_SSSE3, ScaleRowDown4_C, 4, 1, 7)
155 0 : SDANY(ScaleRowDown4Box_Any_SSSE3,
156 : ScaleRowDown4Box_SSSE3,
157 : ScaleRowDown4Box_C,
158 : 4,
159 : 1,
160 : 7)
161 : #endif
162 : #ifdef HAS_SCALEROWDOWN4_AVX2
163 0 : SDANY(ScaleRowDown4_Any_AVX2, ScaleRowDown4_AVX2, ScaleRowDown4_C, 4, 1, 15)
164 0 : SDANY(ScaleRowDown4Box_Any_AVX2,
165 : ScaleRowDown4Box_AVX2,
166 : ScaleRowDown4Box_C,
167 : 4,
168 : 1,
169 : 15)
170 : #endif
171 : #ifdef HAS_SCALEROWDOWN4_NEON
172 : SDANY(ScaleRowDown4_Any_NEON, ScaleRowDown4_NEON, ScaleRowDown4_C, 4, 1, 7)
173 : SDANY(ScaleRowDown4Box_Any_NEON,
174 : ScaleRowDown4Box_NEON,
175 : ScaleRowDown4Box_C,
176 : 4,
177 : 1,
178 : 7)
179 : #endif
180 : #ifdef HAS_SCALEROWDOWN4_MSA
181 : SDANY(ScaleRowDown4_Any_MSA, ScaleRowDown4_MSA, ScaleRowDown4_C, 4, 1, 15)
182 : SDANY(ScaleRowDown4Box_Any_MSA,
183 : ScaleRowDown4Box_MSA,
184 : ScaleRowDown4Box_C,
185 : 4,
186 : 1,
187 : 15)
188 : #endif
189 : #ifdef HAS_SCALEROWDOWN34_SSSE3
190 0 : SDANY(ScaleRowDown34_Any_SSSE3,
191 : ScaleRowDown34_SSSE3,
192 : ScaleRowDown34_C,
193 : 4 / 3,
194 : 1,
195 : 23)
196 0 : SDANY(ScaleRowDown34_0_Box_Any_SSSE3,
197 : ScaleRowDown34_0_Box_SSSE3,
198 : ScaleRowDown34_0_Box_C,
199 : 4 / 3,
200 : 1,
201 : 23)
202 0 : SDANY(ScaleRowDown34_1_Box_Any_SSSE3,
203 : ScaleRowDown34_1_Box_SSSE3,
204 : ScaleRowDown34_1_Box_C,
205 : 4 / 3,
206 : 1,
207 : 23)
208 : #endif
209 : #ifdef HAS_SCALEROWDOWN34_NEON
210 : SDANY(ScaleRowDown34_Any_NEON,
211 : ScaleRowDown34_NEON,
212 : ScaleRowDown34_C,
213 : 4 / 3,
214 : 1,
215 : 23)
216 : SDANY(ScaleRowDown34_0_Box_Any_NEON,
217 : ScaleRowDown34_0_Box_NEON,
218 : ScaleRowDown34_0_Box_C,
219 : 4 / 3,
220 : 1,
221 : 23)
222 : SDANY(ScaleRowDown34_1_Box_Any_NEON,
223 : ScaleRowDown34_1_Box_NEON,
224 : ScaleRowDown34_1_Box_C,
225 : 4 / 3,
226 : 1,
227 : 23)
228 : #endif
229 : #ifdef HAS_SCALEROWDOWN38_SSSE3
230 0 : SDANY(ScaleRowDown38_Any_SSSE3,
231 : ScaleRowDown38_SSSE3,
232 : ScaleRowDown38_C,
233 : 8 / 3,
234 : 1,
235 : 11)
236 0 : SDANY(ScaleRowDown38_3_Box_Any_SSSE3,
237 : ScaleRowDown38_3_Box_SSSE3,
238 : ScaleRowDown38_3_Box_C,
239 : 8 / 3,
240 : 1,
241 : 5)
242 0 : SDANY(ScaleRowDown38_2_Box_Any_SSSE3,
243 : ScaleRowDown38_2_Box_SSSE3,
244 : ScaleRowDown38_2_Box_C,
245 : 8 / 3,
246 : 1,
247 : 5)
248 : #endif
249 : #ifdef HAS_SCALEROWDOWN38_NEON
250 : SDANY(ScaleRowDown38_Any_NEON,
251 : ScaleRowDown38_NEON,
252 : ScaleRowDown38_C,
253 : 8 / 3,
254 : 1,
255 : 11)
256 : SDANY(ScaleRowDown38_3_Box_Any_NEON,
257 : ScaleRowDown38_3_Box_NEON,
258 : ScaleRowDown38_3_Box_C,
259 : 8 / 3,
260 : 1,
261 : 11)
262 : SDANY(ScaleRowDown38_2_Box_Any_NEON,
263 : ScaleRowDown38_2_Box_NEON,
264 : ScaleRowDown38_2_Box_C,
265 : 8 / 3,
266 : 1,
267 : 11)
268 : #endif
269 : #ifdef HAS_SCALEROWDOWN38_MSA
270 : SDANY(ScaleRowDown38_Any_MSA,
271 : ScaleRowDown38_MSA,
272 : ScaleRowDown38_C,
273 : 8 / 3,
274 : 1,
275 : 11)
276 : SDANY(ScaleRowDown38_3_Box_Any_MSA,
277 : ScaleRowDown38_3_Box_MSA,
278 : ScaleRowDown38_3_Box_C,
279 : 8 / 3,
280 : 1,
281 : 11)
282 : SDANY(ScaleRowDown38_2_Box_Any_MSA,
283 : ScaleRowDown38_2_Box_MSA,
284 : ScaleRowDown38_2_Box_C,
285 : 8 / 3,
286 : 1,
287 : 11)
288 : #endif
289 :
290 : #ifdef HAS_SCALEARGBROWDOWN2_SSE2
291 0 : SDANY(ScaleARGBRowDown2_Any_SSE2,
292 : ScaleARGBRowDown2_SSE2,
293 : ScaleARGBRowDown2_C,
294 : 2,
295 : 4,
296 : 3)
297 0 : SDANY(ScaleARGBRowDown2Linear_Any_SSE2,
298 : ScaleARGBRowDown2Linear_SSE2,
299 : ScaleARGBRowDown2Linear_C,
300 : 2,
301 : 4,
302 : 3)
303 0 : SDANY(ScaleARGBRowDown2Box_Any_SSE2,
304 : ScaleARGBRowDown2Box_SSE2,
305 : ScaleARGBRowDown2Box_C,
306 : 2,
307 : 4,
308 : 3)
309 : #endif
310 : #ifdef HAS_SCALEARGBROWDOWN2_NEON
311 : SDANY(ScaleARGBRowDown2_Any_NEON,
312 : ScaleARGBRowDown2_NEON,
313 : ScaleARGBRowDown2_C,
314 : 2,
315 : 4,
316 : 7)
317 : SDANY(ScaleARGBRowDown2Linear_Any_NEON,
318 : ScaleARGBRowDown2Linear_NEON,
319 : ScaleARGBRowDown2Linear_C,
320 : 2,
321 : 4,
322 : 7)
323 : SDANY(ScaleARGBRowDown2Box_Any_NEON,
324 : ScaleARGBRowDown2Box_NEON,
325 : ScaleARGBRowDown2Box_C,
326 : 2,
327 : 4,
328 : 7)
329 : #endif
330 : #ifdef HAS_SCALEARGBROWDOWN2_MSA
331 : SDANY(ScaleARGBRowDown2_Any_MSA,
332 : ScaleARGBRowDown2_MSA,
333 : ScaleARGBRowDown2_C,
334 : 2,
335 : 4,
336 : 3)
337 : SDANY(ScaleARGBRowDown2Linear_Any_MSA,
338 : ScaleARGBRowDown2Linear_MSA,
339 : ScaleARGBRowDown2Linear_C,
340 : 2,
341 : 4,
342 : 3)
343 : SDANY(ScaleARGBRowDown2Box_Any_MSA,
344 : ScaleARGBRowDown2Box_MSA,
345 : ScaleARGBRowDown2Box_C,
346 : 2,
347 : 4,
348 : 3)
349 : #endif
350 : #undef SDANY
351 :
352 : // Scale down by even scale factor.
353 : #define SDAANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, BPP, MASK) \
354 : void NAMEANY(const uint8* src_ptr, ptrdiff_t src_stride, int src_stepx, \
355 : uint8* dst_ptr, int dst_width) { \
356 : int r = (int)((unsigned int)dst_width % (MASK + 1)); \
357 : int n = dst_width - r; \
358 : if (n > 0) { \
359 : SCALEROWDOWN_SIMD(src_ptr, src_stride, src_stepx, dst_ptr, n); \
360 : } \
361 : SCALEROWDOWN_C(src_ptr + (n * src_stepx) * BPP, src_stride, src_stepx, \
362 : dst_ptr + n * BPP, r); \
363 : }
364 :
365 : #ifdef HAS_SCALEARGBROWDOWNEVEN_SSE2
366 0 : SDAANY(ScaleARGBRowDownEven_Any_SSE2,
367 : ScaleARGBRowDownEven_SSE2,
368 : ScaleARGBRowDownEven_C,
369 : 4,
370 : 3)
371 0 : SDAANY(ScaleARGBRowDownEvenBox_Any_SSE2,
372 : ScaleARGBRowDownEvenBox_SSE2,
373 : ScaleARGBRowDownEvenBox_C,
374 : 4,
375 : 3)
376 : #endif
377 : #ifdef HAS_SCALEARGBROWDOWNEVEN_NEON
378 : SDAANY(ScaleARGBRowDownEven_Any_NEON,
379 : ScaleARGBRowDownEven_NEON,
380 : ScaleARGBRowDownEven_C,
381 : 4,
382 : 3)
383 : SDAANY(ScaleARGBRowDownEvenBox_Any_NEON,
384 : ScaleARGBRowDownEvenBox_NEON,
385 : ScaleARGBRowDownEvenBox_C,
386 : 4,
387 : 3)
388 : #endif
389 : #ifdef HAS_SCALEARGBROWDOWNEVEN_MSA
390 : SDAANY(ScaleARGBRowDownEven_Any_MSA,
391 : ScaleARGBRowDownEven_MSA,
392 : ScaleARGBRowDownEven_C,
393 : 4,
394 : 3)
395 : SDAANY(ScaleARGBRowDownEvenBox_Any_MSA,
396 : ScaleARGBRowDownEvenBox_MSA,
397 : ScaleARGBRowDownEvenBox_C,
398 : 4,
399 : 3)
400 : #endif
401 :
402 : // Add rows box filter scale down.
403 : #define SAANY(NAMEANY, SCALEADDROW_SIMD, SCALEADDROW_C, MASK) \
404 : void NAMEANY(const uint8* src_ptr, uint16* dst_ptr, int src_width) { \
405 : int n = src_width & ~MASK; \
406 : if (n > 0) { \
407 : SCALEADDROW_SIMD(src_ptr, dst_ptr, n); \
408 : } \
409 : SCALEADDROW_C(src_ptr + n, dst_ptr + n, src_width & MASK); \
410 : }
411 :
412 : #ifdef HAS_SCALEADDROW_SSE2
413 0 : SAANY(ScaleAddRow_Any_SSE2, ScaleAddRow_SSE2, ScaleAddRow_C, 15)
414 : #endif
415 : #ifdef HAS_SCALEADDROW_AVX2
416 0 : SAANY(ScaleAddRow_Any_AVX2, ScaleAddRow_AVX2, ScaleAddRow_C, 31)
417 : #endif
418 : #ifdef HAS_SCALEADDROW_NEON
419 : SAANY(ScaleAddRow_Any_NEON, ScaleAddRow_NEON, ScaleAddRow_C, 15)
420 : #endif
421 : #ifdef HAS_SCALEADDROW_MSA
422 : SAANY(ScaleAddRow_Any_MSA, ScaleAddRow_MSA, ScaleAddRow_C, 15)
423 : #endif
424 : #ifdef HAS_SCALEADDROW_DSPR2
425 : SAANY(ScaleAddRow_Any_DSPR2, ScaleAddRow_DSPR2, ScaleAddRow_C, 15)
426 : #endif
427 : #undef SAANY
428 :
429 : #ifdef __cplusplus
430 : } // extern "C"
431 : } // namespace libyuv
432 : #endif
|