1 /*
2  *  Copyright 2013 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 #ifndef INCLUDE_LIBYUV_SCALE_ROW_H_
12 #define INCLUDE_LIBYUV_SCALE_ROW_H_
13 
14 #include "libyuv/basic_types.h"
15 #include "libyuv/scale.h"
16 
17 #ifdef __cplusplus
18 namespace libyuv {
19 extern "C" {
20 #endif
21 
22 #if defined(__pnacl__) || defined(__CLR_VER) ||            \
23     (defined(__native_client__) && defined(__x86_64__)) || \
24     (defined(__i386__) && !defined(__SSE__) && !defined(__clang__))
25 #define LIBYUV_DISABLE_X86
26 #endif
27 #if defined(__native_client__)
28 #define LIBYUV_DISABLE_NEON
29 #endif
30 // MemorySanitizer does not support assembly code yet. http://crbug.com/344505
31 #if defined(__has_feature)
32 #if __has_feature(memory_sanitizer)
33 #define LIBYUV_DISABLE_X86
34 #endif
35 #endif
36 // GCC >= 4.7.0 required for AVX2.
37 #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
38 #if (__GNUC__ > 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 7))
39 #define GCC_HAS_AVX2 1
40 #endif  // GNUC >= 4.7
41 #endif  // __GNUC__
42 
43 // clang >= 3.4.0 required for AVX2.
44 #if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
45 #if (__clang_major__ > 3) || (__clang_major__ == 3 && (__clang_minor__ >= 4))
46 #define CLANG_HAS_AVX2 1
47 #endif  // clang >= 3.4
48 #endif  // __clang__
49 
50 // Visual C 2012 required for AVX2.
51 #if defined(_M_IX86) && !defined(__clang__) && defined(_MSC_VER) && \
52     _MSC_VER >= 1700
53 #define VISUALC_HAS_AVX2 1
54 #endif  // VisualStudio >= 2012
55 
56 // The following are available on all x86 platforms:
57 #if !defined(LIBYUV_DISABLE_X86) && \
58     (defined(_M_IX86) || defined(__x86_64__) || defined(__i386__))
59 #define HAS_FIXEDDIV1_X86
60 #define HAS_FIXEDDIV_X86
61 #define HAS_SCALEARGBCOLS_SSE2
62 #define HAS_SCALEARGBCOLSUP2_SSE2
63 #define HAS_SCALEARGBFILTERCOLS_SSSE3
64 #define HAS_SCALEARGBROWDOWN2_SSE2
65 #define HAS_SCALEARGBROWDOWNEVEN_SSE2
66 #define HAS_SCALECOLSUP2_SSE2
67 #define HAS_SCALEFILTERCOLS_SSSE3
68 #define HAS_SCALEROWDOWN2_SSSE3
69 #define HAS_SCALEROWDOWN34_SSSE3
70 #define HAS_SCALEROWDOWN38_SSSE3
71 #define HAS_SCALEROWDOWN4_SSSE3
72 #define HAS_SCALEADDROW_SSE2
73 #endif
74 
75 // The following are available on all x86 platforms, but
76 // require VS2012, clang 3.4 or gcc 4.7.
77 // The code supports NaCL but requires a new compiler and validator.
78 #if !defined(LIBYUV_DISABLE_X86) &&                          \
79     (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2) || \
80      defined(GCC_HAS_AVX2))
81 #define HAS_SCALEADDROW_AVX2
82 #define HAS_SCALEROWDOWN2_AVX2
83 #define HAS_SCALEROWDOWN4_AVX2
84 #endif
85 
86 // The following are available on Neon platforms:
87 #if !defined(LIBYUV_DISABLE_NEON) && \
88     (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__))
89 #define HAS_SCALEARGBCOLS_NEON
90 #define HAS_SCALEARGBROWDOWN2_NEON
91 #define HAS_SCALEARGBROWDOWNEVEN_NEON
92 #define HAS_SCALEFILTERCOLS_NEON
93 #define HAS_SCALEROWDOWN2_NEON
94 #define HAS_SCALEROWDOWN34_NEON
95 #define HAS_SCALEROWDOWN38_NEON
96 #define HAS_SCALEROWDOWN4_NEON
97 #define HAS_SCALEARGBFILTERCOLS_NEON
98 #endif
99 
100 #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
101 #define HAS_SCALEADDROW_MSA
102 #define HAS_SCALEARGBCOLS_MSA
103 #define HAS_SCALEARGBFILTERCOLS_MSA
104 #define HAS_SCALEARGBROWDOWN2_MSA
105 #define HAS_SCALEARGBROWDOWNEVEN_MSA
106 #define HAS_SCALEFILTERCOLS_MSA
107 #define HAS_SCALEROWDOWN2_MSA
108 #define HAS_SCALEROWDOWN34_MSA
109 #define HAS_SCALEROWDOWN38_MSA
110 #define HAS_SCALEROWDOWN4_MSA
111 #endif
112 
113 // Scale ARGB vertically with bilinear interpolation.
114 void ScalePlaneVertical(int src_height,
115                         int dst_width,
116                         int dst_height,
117                         int src_stride,
118                         int dst_stride,
119                         const uint8_t* src_argb,
120                         uint8_t* dst_argb,
121                         int x,
122                         int y,
123                         int dy,
124                         int bpp,
125                         enum FilterMode filtering);
126 
127 void ScalePlaneVertical_16(int src_height,
128                            int dst_width,
129                            int dst_height,
130                            int src_stride,
131                            int dst_stride,
132                            const uint16_t* src_argb,
133                            uint16_t* dst_argb,
134                            int x,
135                            int y,
136                            int dy,
137                            int wpp,
138                            enum FilterMode filtering);
139 
140 // Simplify the filtering based on scale factors.
141 enum FilterMode ScaleFilterReduce(int src_width,
142                                   int src_height,
143                                   int dst_width,
144                                   int dst_height,
145                                   enum FilterMode filtering);
146 
147 // Divide num by div and return as 16.16 fixed point result.
148 int FixedDiv_C(int num, int div);
149 int FixedDiv_X86(int num, int div);
150 // Divide num - 1 by div - 1 and return as 16.16 fixed point result.
151 int FixedDiv1_C(int num, int div);
152 int FixedDiv1_X86(int num, int div);
153 #ifdef HAS_FIXEDDIV_X86
154 #define FixedDiv FixedDiv_X86
155 #define FixedDiv1 FixedDiv1_X86
156 #else
157 #define FixedDiv FixedDiv_C
158 #define FixedDiv1 FixedDiv1_C
159 #endif
160 
161 // Compute slope values for stepping.
162 void ScaleSlope(int src_width,
163                 int src_height,
164                 int dst_width,
165                 int dst_height,
166                 enum FilterMode filtering,
167                 int* x,
168                 int* y,
169                 int* dx,
170                 int* dy);
171 
172 void ScaleRowDown2_C(const uint8_t* src_ptr,
173                      ptrdiff_t src_stride,
174                      uint8_t* dst,
175                      int dst_width);
176 void ScaleRowDown2_16_C(const uint16_t* src_ptr,
177                         ptrdiff_t src_stride,
178                         uint16_t* dst,
179                         int dst_width);
180 void ScaleRowDown2Linear_C(const uint8_t* src_ptr,
181                            ptrdiff_t src_stride,
182                            uint8_t* dst,
183                            int dst_width);
184 void ScaleRowDown2Linear_16_C(const uint16_t* src_ptr,
185                               ptrdiff_t src_stride,
186                               uint16_t* dst,
187                               int dst_width);
188 void ScaleRowDown2Box_C(const uint8_t* src_ptr,
189                         ptrdiff_t src_stride,
190                         uint8_t* dst,
191                         int dst_width);
192 void ScaleRowDown2Box_Odd_C(const uint8_t* src_ptr,
193                             ptrdiff_t src_stride,
194                             uint8_t* dst,
195                             int dst_width);
196 void ScaleRowDown2Box_16_C(const uint16_t* src_ptr,
197                            ptrdiff_t src_stride,
198                            uint16_t* dst,
199                            int dst_width);
200 void ScaleRowDown4_C(const uint8_t* src_ptr,
201                      ptrdiff_t src_stride,
202                      uint8_t* dst,
203                      int dst_width);
204 void ScaleRowDown4_16_C(const uint16_t* src_ptr,
205                         ptrdiff_t src_stride,
206                         uint16_t* dst,
207                         int dst_width);
208 void ScaleRowDown4Box_C(const uint8_t* src_ptr,
209                         ptrdiff_t src_stride,
210                         uint8_t* dst,
211                         int dst_width);
212 void ScaleRowDown4Box_16_C(const uint16_t* src_ptr,
213                            ptrdiff_t src_stride,
214                            uint16_t* dst,
215                            int dst_width);
216 void ScaleRowDown34_C(const uint8_t* src_ptr,
217                       ptrdiff_t src_stride,
218                       uint8_t* dst,
219                       int dst_width);
220 void ScaleRowDown34_16_C(const uint16_t* src_ptr,
221                          ptrdiff_t src_stride,
222                          uint16_t* dst,
223                          int dst_width);
224 void ScaleRowDown34_0_Box_C(const uint8_t* src_ptr,
225                             ptrdiff_t src_stride,
226                             uint8_t* d,
227                             int dst_width);
228 void ScaleRowDown34_0_Box_16_C(const uint16_t* src_ptr,
229                                ptrdiff_t src_stride,
230                                uint16_t* d,
231                                int dst_width);
232 void ScaleRowDown34_1_Box_C(const uint8_t* src_ptr,
233                             ptrdiff_t src_stride,
234                             uint8_t* d,
235                             int dst_width);
236 void ScaleRowDown34_1_Box_16_C(const uint16_t* src_ptr,
237                                ptrdiff_t src_stride,
238                                uint16_t* d,
239                                int dst_width);
240 void ScaleCols_C(uint8_t* dst_ptr,
241                  const uint8_t* src_ptr,
242                  int dst_width,
243                  int x,
244                  int dx);
245 void ScaleCols_16_C(uint16_t* dst_ptr,
246                     const uint16_t* src_ptr,
247                     int dst_width,
248                     int x,
249                     int dx);
250 void ScaleColsUp2_C(uint8_t* dst_ptr,
251                     const uint8_t* src_ptr,
252                     int dst_width,
253                     int,
254                     int);
255 void ScaleColsUp2_16_C(uint16_t* dst_ptr,
256                        const uint16_t* src_ptr,
257                        int dst_width,
258                        int,
259                        int);
260 void ScaleFilterCols_C(uint8_t* dst_ptr,
261                        const uint8_t* src_ptr,
262                        int dst_width,
263                        int x,
264                        int dx);
265 void ScaleFilterCols_16_C(uint16_t* dst_ptr,
266                           const uint16_t* src_ptr,
267                           int dst_width,
268                           int x,
269                           int dx);
270 void ScaleFilterCols64_C(uint8_t* dst_ptr,
271                          const uint8_t* src_ptr,
272                          int dst_width,
273                          int x32,
274                          int dx);
275 void ScaleFilterCols64_16_C(uint16_t* dst_ptr,
276                             const uint16_t* src_ptr,
277                             int dst_width,
278                             int x32,
279                             int dx);
280 void ScaleRowDown38_C(const uint8_t* src_ptr,
281                       ptrdiff_t src_stride,
282                       uint8_t* dst,
283                       int dst_width);
284 void ScaleRowDown38_16_C(const uint16_t* src_ptr,
285                          ptrdiff_t src_stride,
286                          uint16_t* dst,
287                          int dst_width);
288 void ScaleRowDown38_3_Box_C(const uint8_t* src_ptr,
289                             ptrdiff_t src_stride,
290                             uint8_t* dst_ptr,
291                             int dst_width);
292 void ScaleRowDown38_3_Box_16_C(const uint16_t* src_ptr,
293                                ptrdiff_t src_stride,
294                                uint16_t* dst_ptr,
295                                int dst_width);
296 void ScaleRowDown38_2_Box_C(const uint8_t* src_ptr,
297                             ptrdiff_t src_stride,
298                             uint8_t* dst_ptr,
299                             int dst_width);
300 void ScaleRowDown38_2_Box_16_C(const uint16_t* src_ptr,
301                                ptrdiff_t src_stride,
302                                uint16_t* dst_ptr,
303                                int dst_width);
304 void ScaleAddRow_C(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width);
305 void ScaleAddRow_16_C(const uint16_t* src_ptr,
306                       uint32_t* dst_ptr,
307                       int src_width);
308 void ScaleARGBRowDown2_C(const uint8_t* src_argb,
309                          ptrdiff_t src_stride,
310                          uint8_t* dst_argb,
311                          int dst_width);
312 void ScaleARGBRowDown2Linear_C(const uint8_t* src_argb,
313                                ptrdiff_t src_stride,
314                                uint8_t* dst_argb,
315                                int dst_width);
316 void ScaleARGBRowDown2Box_C(const uint8_t* src_argb,
317                             ptrdiff_t src_stride,
318                             uint8_t* dst_argb,
319                             int dst_width);
320 void ScaleARGBRowDownEven_C(const uint8_t* src_argb,
321                             ptrdiff_t src_stride,
322                             int src_stepx,
323                             uint8_t* dst_argb,
324                             int dst_width);
325 void ScaleARGBRowDownEvenBox_C(const uint8_t* src_argb,
326                                ptrdiff_t src_stride,
327                                int src_stepx,
328                                uint8_t* dst_argb,
329                                int dst_width);
330 void ScaleARGBCols_C(uint8_t* dst_argb,
331                      const uint8_t* src_argb,
332                      int dst_width,
333                      int x,
334                      int dx);
335 void ScaleARGBCols64_C(uint8_t* dst_argb,
336                        const uint8_t* src_argb,
337                        int dst_width,
338                        int x32,
339                        int dx);
340 void ScaleARGBColsUp2_C(uint8_t* dst_argb,
341                         const uint8_t* src_argb,
342                         int dst_width,
343                         int,
344                         int);
345 void ScaleARGBFilterCols_C(uint8_t* dst_argb,
346                            const uint8_t* src_argb,
347                            int dst_width,
348                            int x,
349                            int dx);
350 void ScaleARGBFilterCols64_C(uint8_t* dst_argb,
351                              const uint8_t* src_argb,
352                              int dst_width,
353                              int x32,
354                              int dx);
355 
356 // Specialized scalers for x86.
357 void ScaleRowDown2_SSSE3(const uint8_t* src_ptr,
358                          ptrdiff_t src_stride,
359                          uint8_t* dst_ptr,
360                          int dst_width);
361 void ScaleRowDown2Linear_SSSE3(const uint8_t* src_ptr,
362                                ptrdiff_t src_stride,
363                                uint8_t* dst_ptr,
364                                int dst_width);
365 void ScaleRowDown2Box_SSSE3(const uint8_t* src_ptr,
366                             ptrdiff_t src_stride,
367                             uint8_t* dst_ptr,
368                             int dst_width);
369 void ScaleRowDown2_AVX2(const uint8_t* src_ptr,
370                         ptrdiff_t src_stride,
371                         uint8_t* dst_ptr,
372                         int dst_width);
373 void ScaleRowDown2Linear_AVX2(const uint8_t* src_ptr,
374                               ptrdiff_t src_stride,
375                               uint8_t* dst_ptr,
376                               int dst_width);
377 void ScaleRowDown2Box_AVX2(const uint8_t* src_ptr,
378                            ptrdiff_t src_stride,
379                            uint8_t* dst_ptr,
380                            int dst_width);
381 void ScaleRowDown4_SSSE3(const uint8_t* src_ptr,
382                          ptrdiff_t src_stride,
383                          uint8_t* dst_ptr,
384                          int dst_width);
385 void ScaleRowDown4Box_SSSE3(const uint8_t* src_ptr,
386                             ptrdiff_t src_stride,
387                             uint8_t* dst_ptr,
388                             int dst_width);
389 void ScaleRowDown4_AVX2(const uint8_t* src_ptr,
390                         ptrdiff_t src_stride,
391                         uint8_t* dst_ptr,
392                         int dst_width);
393 void ScaleRowDown4Box_AVX2(const uint8_t* src_ptr,
394                            ptrdiff_t src_stride,
395                            uint8_t* dst_ptr,
396                            int dst_width);
397 
398 void ScaleRowDown34_SSSE3(const uint8_t* src_ptr,
399                           ptrdiff_t src_stride,
400                           uint8_t* dst_ptr,
401                           int dst_width);
402 void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr,
403                                 ptrdiff_t src_stride,
404                                 uint8_t* dst_ptr,
405                                 int dst_width);
406 void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr,
407                                 ptrdiff_t src_stride,
408                                 uint8_t* dst_ptr,
409                                 int dst_width);
410 void ScaleRowDown38_SSSE3(const uint8_t* src_ptr,
411                           ptrdiff_t src_stride,
412                           uint8_t* dst_ptr,
413                           int dst_width);
414 void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr,
415                                 ptrdiff_t src_stride,
416                                 uint8_t* dst_ptr,
417                                 int dst_width);
418 void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr,
419                                 ptrdiff_t src_stride,
420                                 uint8_t* dst_ptr,
421                                 int dst_width);
422 void ScaleRowDown2_Any_SSSE3(const uint8_t* src_ptr,
423                              ptrdiff_t src_stride,
424                              uint8_t* dst_ptr,
425                              int dst_width);
426 void ScaleRowDown2Linear_Any_SSSE3(const uint8_t* src_ptr,
427                                    ptrdiff_t src_stride,
428                                    uint8_t* dst_ptr,
429                                    int dst_width);
430 void ScaleRowDown2Box_Any_SSSE3(const uint8_t* src_ptr,
431                                 ptrdiff_t src_stride,
432                                 uint8_t* dst_ptr,
433                                 int dst_width);
434 void ScaleRowDown2Box_Odd_SSSE3(const uint8_t* src_ptr,
435                                 ptrdiff_t src_stride,
436                                 uint8_t* dst_ptr,
437                                 int dst_width);
438 void ScaleRowDown2_Any_AVX2(const uint8_t* src_ptr,
439                             ptrdiff_t src_stride,
440                             uint8_t* dst_ptr,
441                             int dst_width);
442 void ScaleRowDown2Linear_Any_AVX2(const uint8_t* src_ptr,
443                                   ptrdiff_t src_stride,
444                                   uint8_t* dst_ptr,
445                                   int dst_width);
446 void ScaleRowDown2Box_Any_AVX2(const uint8_t* src_ptr,
447                                ptrdiff_t src_stride,
448                                uint8_t* dst_ptr,
449                                int dst_width);
450 void ScaleRowDown2Box_Odd_AVX2(const uint8_t* src_ptr,
451                                ptrdiff_t src_stride,
452                                uint8_t* dst_ptr,
453                                int dst_width);
454 void ScaleRowDown4_Any_SSSE3(const uint8_t* src_ptr,
455                              ptrdiff_t src_stride,
456                              uint8_t* dst_ptr,
457                              int dst_width);
458 void ScaleRowDown4Box_Any_SSSE3(const uint8_t* src_ptr,
459                                 ptrdiff_t src_stride,
460                                 uint8_t* dst_ptr,
461                                 int dst_width);
462 void ScaleRowDown4_Any_AVX2(const uint8_t* src_ptr,
463                             ptrdiff_t src_stride,
464                             uint8_t* dst_ptr,
465                             int dst_width);
466 void ScaleRowDown4Box_Any_AVX2(const uint8_t* src_ptr,
467                                ptrdiff_t src_stride,
468                                uint8_t* dst_ptr,
469                                int dst_width);
470 
471 void ScaleRowDown34_Any_SSSE3(const uint8_t* src_ptr,
472                               ptrdiff_t src_stride,
473                               uint8_t* dst_ptr,
474                               int dst_width);
475 void ScaleRowDown34_1_Box_Any_SSSE3(const uint8_t* src_ptr,
476                                     ptrdiff_t src_stride,
477                                     uint8_t* dst_ptr,
478                                     int dst_width);
479 void ScaleRowDown34_0_Box_Any_SSSE3(const uint8_t* src_ptr,
480                                     ptrdiff_t src_stride,
481                                     uint8_t* dst_ptr,
482                                     int dst_width);
483 void ScaleRowDown38_Any_SSSE3(const uint8_t* src_ptr,
484                               ptrdiff_t src_stride,
485                               uint8_t* dst_ptr,
486                               int dst_width);
487 void ScaleRowDown38_3_Box_Any_SSSE3(const uint8_t* src_ptr,
488                                     ptrdiff_t src_stride,
489                                     uint8_t* dst_ptr,
490                                     int dst_width);
491 void ScaleRowDown38_2_Box_Any_SSSE3(const uint8_t* src_ptr,
492                                     ptrdiff_t src_stride,
493                                     uint8_t* dst_ptr,
494                                     int dst_width);
495 
496 void ScaleAddRow_SSE2(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width);
497 void ScaleAddRow_AVX2(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width);
498 void ScaleAddRow_Any_SSE2(const uint8_t* src_ptr,
499                           uint16_t* dst_ptr,
500                           int src_width);
501 void ScaleAddRow_Any_AVX2(const uint8_t* src_ptr,
502                           uint16_t* dst_ptr,
503                           int src_width);
504 
505 void ScaleFilterCols_SSSE3(uint8_t* dst_ptr,
506                            const uint8_t* src_ptr,
507                            int dst_width,
508                            int x,
509                            int dx);
510 void ScaleColsUp2_SSE2(uint8_t* dst_ptr,
511                        const uint8_t* src_ptr,
512                        int dst_width,
513                        int x,
514                        int dx);
515 
516 // ARGB Column functions
517 void ScaleARGBCols_SSE2(uint8_t* dst_argb,
518                         const uint8_t* src_argb,
519                         int dst_width,
520                         int x,
521                         int dx);
522 void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb,
523                                const uint8_t* src_argb,
524                                int dst_width,
525                                int x,
526                                int dx);
527 void ScaleARGBColsUp2_SSE2(uint8_t* dst_argb,
528                            const uint8_t* src_argb,
529                            int dst_width,
530                            int x,
531                            int dx);
532 void ScaleARGBFilterCols_NEON(uint8_t* dst_argb,
533                               const uint8_t* src_argb,
534                               int dst_width,
535                               int x,
536                               int dx);
537 void ScaleARGBCols_NEON(uint8_t* dst_argb,
538                         const uint8_t* src_argb,
539                         int dst_width,
540                         int x,
541                         int dx);
542 void ScaleARGBFilterCols_Any_NEON(uint8_t* dst_ptr,
543                                   const uint8_t* src_ptr,
544                                   int dst_width,
545                                   int x,
546                                   int dx);
547 void ScaleARGBCols_Any_NEON(uint8_t* dst_ptr,
548                             const uint8_t* src_ptr,
549                             int dst_width,
550                             int x,
551                             int dx);
552 void ScaleARGBFilterCols_MSA(uint8_t* dst_argb,
553                              const uint8_t* src_argb,
554                              int dst_width,
555                              int x,
556                              int dx);
557 void ScaleARGBCols_MSA(uint8_t* dst_argb,
558                        const uint8_t* src_argb,
559                        int dst_width,
560                        int x,
561                        int dx);
562 void ScaleARGBFilterCols_Any_MSA(uint8_t* dst_ptr,
563                                  const uint8_t* src_ptr,
564                                  int dst_width,
565                                  int x,
566                                  int dx);
567 void ScaleARGBCols_Any_MSA(uint8_t* dst_ptr,
568                            const uint8_t* src_ptr,
569                            int dst_width,
570                            int x,
571                            int dx);
572 
573 // ARGB Row functions
574 void ScaleARGBRowDown2_SSE2(const uint8_t* src_argb,
575                             ptrdiff_t src_stride,
576                             uint8_t* dst_argb,
577                             int dst_width);
578 void ScaleARGBRowDown2Linear_SSE2(const uint8_t* src_argb,
579                                   ptrdiff_t src_stride,
580                                   uint8_t* dst_argb,
581                                   int dst_width);
582 void ScaleARGBRowDown2Box_SSE2(const uint8_t* src_argb,
583                                ptrdiff_t src_stride,
584                                uint8_t* dst_argb,
585                                int dst_width);
586 void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr,
587                             ptrdiff_t src_stride,
588                             uint8_t* dst,
589                             int dst_width);
590 void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb,
591                                   ptrdiff_t src_stride,
592                                   uint8_t* dst_argb,
593                                   int dst_width);
594 void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr,
595                                ptrdiff_t src_stride,
596                                uint8_t* dst,
597                                int dst_width);
598 void ScaleARGBRowDown2_MSA(const uint8_t* src_argb,
599                            ptrdiff_t src_stride,
600                            uint8_t* dst_argb,
601                            int dst_width);
602 void ScaleARGBRowDown2Linear_MSA(const uint8_t* src_argb,
603                                  ptrdiff_t src_stride,
604                                  uint8_t* dst_argb,
605                                  int dst_width);
606 void ScaleARGBRowDown2Box_MSA(const uint8_t* src_argb,
607                               ptrdiff_t src_stride,
608                               uint8_t* dst_argb,
609                               int dst_width);
610 void ScaleARGBRowDown2_Any_SSE2(const uint8_t* src_ptr,
611                                 ptrdiff_t src_stride,
612                                 uint8_t* dst_ptr,
613                                 int dst_width);
614 void ScaleARGBRowDown2Linear_Any_SSE2(const uint8_t* src_ptr,
615                                       ptrdiff_t src_stride,
616                                       uint8_t* dst_ptr,
617                                       int dst_width);
618 void ScaleARGBRowDown2Box_Any_SSE2(const uint8_t* src_ptr,
619                                    ptrdiff_t src_stride,
620                                    uint8_t* dst_ptr,
621                                    int dst_width);
622 void ScaleARGBRowDown2_Any_NEON(const uint8_t* src_ptr,
623                                 ptrdiff_t src_stride,
624                                 uint8_t* dst_ptr,
625                                 int dst_width);
626 void ScaleARGBRowDown2Linear_Any_NEON(const uint8_t* src_ptr,
627                                       ptrdiff_t src_stride,
628                                       uint8_t* dst_ptr,
629                                       int dst_width);
630 void ScaleARGBRowDown2Box_Any_NEON(const uint8_t* src_ptr,
631                                    ptrdiff_t src_stride,
632                                    uint8_t* dst_ptr,
633                                    int dst_width);
634 void ScaleARGBRowDown2_Any_MSA(const uint8_t* src_ptr,
635                                ptrdiff_t src_stride,
636                                uint8_t* dst_ptr,
637                                int dst_width);
638 void ScaleARGBRowDown2Linear_Any_MSA(const uint8_t* src_ptr,
639                                      ptrdiff_t src_stride,
640                                      uint8_t* dst_ptr,
641                                      int dst_width);
642 void ScaleARGBRowDown2Box_Any_MSA(const uint8_t* src_ptr,
643                                   ptrdiff_t src_stride,
644                                   uint8_t* dst_ptr,
645                                   int dst_width);
646 
647 void ScaleARGBRowDownEven_SSE2(const uint8_t* src_argb,
648                                ptrdiff_t src_stride,
649                                int src_stepx,
650                                uint8_t* dst_argb,
651                                int dst_width);
652 void ScaleARGBRowDownEvenBox_SSE2(const uint8_t* src_argb,
653                                   ptrdiff_t src_stride,
654                                   int src_stepx,
655                                   uint8_t* dst_argb,
656                                   int dst_width);
657 void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb,
658                                ptrdiff_t src_stride,
659                                int src_stepx,
660                                uint8_t* dst_argb,
661                                int dst_width);
662 void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb,
663                                   ptrdiff_t src_stride,
664                                   int src_stepx,
665                                   uint8_t* dst_argb,
666                                   int dst_width);
667 void ScaleARGBRowDownEven_MSA(const uint8_t* src_argb,
668                               ptrdiff_t src_stride,
669                               int32_t src_stepx,
670                               uint8_t* dst_argb,
671                               int dst_width);
672 void ScaleARGBRowDownEvenBox_MSA(const uint8_t* src_argb,
673                                  ptrdiff_t src_stride,
674                                  int src_stepx,
675                                  uint8_t* dst_argb,
676                                  int dst_width);
677 void ScaleARGBRowDownEven_Any_SSE2(const uint8_t* src_ptr,
678                                    ptrdiff_t src_stride,
679                                    int src_stepx,
680                                    uint8_t* dst_ptr,
681                                    int dst_width);
682 void ScaleARGBRowDownEvenBox_Any_SSE2(const uint8_t* src_ptr,
683                                       ptrdiff_t src_stride,
684                                       int src_stepx,
685                                       uint8_t* dst_ptr,
686                                       int dst_width);
687 void ScaleARGBRowDownEven_Any_NEON(const uint8_t* src_ptr,
688                                    ptrdiff_t src_stride,
689                                    int src_stepx,
690                                    uint8_t* dst_ptr,
691                                    int dst_width);
692 void ScaleARGBRowDownEvenBox_Any_NEON(const uint8_t* src_ptr,
693                                       ptrdiff_t src_stride,
694                                       int src_stepx,
695                                       uint8_t* dst_ptr,
696                                       int dst_width);
697 void ScaleARGBRowDownEven_Any_MSA(const uint8_t* src_ptr,
698                                   ptrdiff_t src_stride,
699                                   int32_t src_stepx,
700                                   uint8_t* dst_ptr,
701                                   int dst_width);
702 void ScaleARGBRowDownEvenBox_Any_MSA(const uint8_t* src_ptr,
703                                      ptrdiff_t src_stride,
704                                      int src_stepx,
705                                      uint8_t* dst_ptr,
706                                      int dst_width);
707 
708 // ScaleRowDown2Box also used by planar functions
709 // NEON downscalers with interpolation.
710 
711 // Note - not static due to reuse in convert for 444 to 420.
712 void ScaleRowDown2_NEON(const uint8_t* src_ptr,
713                         ptrdiff_t src_stride,
714                         uint8_t* dst,
715                         int dst_width);
716 void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr,
717                               ptrdiff_t src_stride,
718                               uint8_t* dst,
719                               int dst_width);
720 void ScaleRowDown2Box_NEON(const uint8_t* src_ptr,
721                            ptrdiff_t src_stride,
722                            uint8_t* dst,
723                            int dst_width);
724 
725 void ScaleRowDown4_NEON(const uint8_t* src_ptr,
726                         ptrdiff_t src_stride,
727                         uint8_t* dst_ptr,
728                         int dst_width);
729 void ScaleRowDown4Box_NEON(const uint8_t* src_ptr,
730                            ptrdiff_t src_stride,
731                            uint8_t* dst_ptr,
732                            int dst_width);
733 
734 // Down scale from 4 to 3 pixels. Use the neon multilane read/write
735 //  to load up the every 4th pixel into a 4 different registers.
736 // Point samples 32 pixels to 24 pixels.
737 void ScaleRowDown34_NEON(const uint8_t* src_ptr,
738                          ptrdiff_t src_stride,
739                          uint8_t* dst_ptr,
740                          int dst_width);
741 void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr,
742                                ptrdiff_t src_stride,
743                                uint8_t* dst_ptr,
744                                int dst_width);
745 void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr,
746                                ptrdiff_t src_stride,
747                                uint8_t* dst_ptr,
748                                int dst_width);
749 
750 // 32 -> 12
751 void ScaleRowDown38_NEON(const uint8_t* src_ptr,
752                          ptrdiff_t src_stride,
753                          uint8_t* dst_ptr,
754                          int dst_width);
755 // 32x3 -> 12x1
756 void ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr,
757                                ptrdiff_t src_stride,
758                                uint8_t* dst_ptr,
759                                int dst_width);
760 // 32x2 -> 12x1
761 void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr,
762                                ptrdiff_t src_stride,
763                                uint8_t* dst_ptr,
764                                int dst_width);
765 
766 void ScaleRowDown2_Any_NEON(const uint8_t* src_ptr,
767                             ptrdiff_t src_stride,
768                             uint8_t* dst_ptr,
769                             int dst_width);
770 void ScaleRowDown2Linear_Any_NEON(const uint8_t* src_ptr,
771                                   ptrdiff_t src_stride,
772                                   uint8_t* dst_ptr,
773                                   int dst_width);
774 void ScaleRowDown2Box_Any_NEON(const uint8_t* src_ptr,
775                                ptrdiff_t src_stride,
776                                uint8_t* dst_ptr,
777                                int dst_width);
778 void ScaleRowDown2Box_Odd_NEON(const uint8_t* src_ptr,
779                                ptrdiff_t src_stride,
780                                uint8_t* dst_ptr,
781                                int dst_width);
782 void ScaleRowDown4_Any_NEON(const uint8_t* src_ptr,
783                             ptrdiff_t src_stride,
784                             uint8_t* dst_ptr,
785                             int dst_width);
786 void ScaleRowDown4Box_Any_NEON(const uint8_t* src_ptr,
787                                ptrdiff_t src_stride,
788                                uint8_t* dst_ptr,
789                                int dst_width);
790 void ScaleRowDown34_Any_NEON(const uint8_t* src_ptr,
791                              ptrdiff_t src_stride,
792                              uint8_t* dst_ptr,
793                              int dst_width);
794 void ScaleRowDown34_0_Box_Any_NEON(const uint8_t* src_ptr,
795                                    ptrdiff_t src_stride,
796                                    uint8_t* dst_ptr,
797                                    int dst_width);
798 void ScaleRowDown34_1_Box_Any_NEON(const uint8_t* src_ptr,
799                                    ptrdiff_t src_stride,
800                                    uint8_t* dst_ptr,
801                                    int dst_width);
802 // 32 -> 12
803 void ScaleRowDown38_Any_NEON(const uint8_t* src_ptr,
804                              ptrdiff_t src_stride,
805                              uint8_t* dst_ptr,
806                              int dst_width);
807 // 32x3 -> 12x1
808 void ScaleRowDown38_3_Box_Any_NEON(const uint8_t* src_ptr,
809                                    ptrdiff_t src_stride,
810                                    uint8_t* dst_ptr,
811                                    int dst_width);
812 // 32x2 -> 12x1
813 void ScaleRowDown38_2_Box_Any_NEON(const uint8_t* src_ptr,
814                                    ptrdiff_t src_stride,
815                                    uint8_t* dst_ptr,
816                                    int dst_width);
817 
818 void ScaleAddRow_NEON(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width);
819 void ScaleAddRow_Any_NEON(const uint8_t* src_ptr,
820                           uint16_t* dst_ptr,
821                           int src_width);
822 
823 void ScaleFilterCols_NEON(uint8_t* dst_ptr,
824                           const uint8_t* src_ptr,
825                           int dst_width,
826                           int x,
827                           int dx);
828 
829 void ScaleFilterCols_Any_NEON(uint8_t* dst_ptr,
830                               const uint8_t* src_ptr,
831                               int dst_width,
832                               int x,
833                               int dx);
834 
835 void ScaleRowDown2_MSA(const uint8_t* src_ptr,
836                        ptrdiff_t src_stride,
837                        uint8_t* dst,
838                        int dst_width);
839 void ScaleRowDown2Linear_MSA(const uint8_t* src_ptr,
840                              ptrdiff_t src_stride,
841                              uint8_t* dst,
842                              int dst_width);
843 void ScaleRowDown2Box_MSA(const uint8_t* src_ptr,
844                           ptrdiff_t src_stride,
845                           uint8_t* dst,
846                           int dst_width);
847 void ScaleRowDown4_MSA(const uint8_t* src_ptr,
848                        ptrdiff_t src_stride,
849                        uint8_t* dst,
850                        int dst_width);
851 void ScaleRowDown4Box_MSA(const uint8_t* src_ptr,
852                           ptrdiff_t src_stride,
853                           uint8_t* dst,
854                           int dst_width);
855 void ScaleRowDown38_MSA(const uint8_t* src_ptr,
856                         ptrdiff_t src_stride,
857                         uint8_t* dst,
858                         int dst_width);
859 void ScaleRowDown38_2_Box_MSA(const uint8_t* src_ptr,
860                               ptrdiff_t src_stride,
861                               uint8_t* dst_ptr,
862                               int dst_width);
863 void ScaleRowDown38_3_Box_MSA(const uint8_t* src_ptr,
864                               ptrdiff_t src_stride,
865                               uint8_t* dst_ptr,
866                               int dst_width);
867 void ScaleAddRow_MSA(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width);
868 void ScaleFilterCols_MSA(uint8_t* dst_ptr,
869                          const uint8_t* src_ptr,
870                          int dst_width,
871                          int x,
872                          int dx);
873 void ScaleRowDown34_MSA(const uint8_t* src_ptr,
874                         ptrdiff_t src_stride,
875                         uint8_t* dst,
876                         int dst_width);
877 void ScaleRowDown34_0_Box_MSA(const uint8_t* src_ptr,
878                               ptrdiff_t src_stride,
879                               uint8_t* d,
880                               int dst_width);
881 void ScaleRowDown34_1_Box_MSA(const uint8_t* src_ptr,
882                               ptrdiff_t src_stride,
883                               uint8_t* d,
884                               int dst_width);
885 
886 void ScaleRowDown2_Any_MSA(const uint8_t* src_ptr,
887                            ptrdiff_t src_stride,
888                            uint8_t* dst_ptr,
889                            int dst_width);
890 void ScaleRowDown2Linear_Any_MSA(const uint8_t* src_ptr,
891                                  ptrdiff_t src_stride,
892                                  uint8_t* dst_ptr,
893                                  int dst_width);
894 void ScaleRowDown2Box_Any_MSA(const uint8_t* src_ptr,
895                               ptrdiff_t src_stride,
896                               uint8_t* dst_ptr,
897                               int dst_width);
898 void ScaleRowDown4_Any_MSA(const uint8_t* src_ptr,
899                            ptrdiff_t src_stride,
900                            uint8_t* dst_ptr,
901                            int dst_width);
902 void ScaleRowDown4Box_Any_MSA(const uint8_t* src_ptr,
903                               ptrdiff_t src_stride,
904                               uint8_t* dst_ptr,
905                               int dst_width);
906 void ScaleRowDown38_Any_MSA(const uint8_t* src_ptr,
907                             ptrdiff_t src_stride,
908                             uint8_t* dst_ptr,
909                             int dst_width);
910 void ScaleRowDown38_2_Box_Any_MSA(const uint8_t* src_ptr,
911                                   ptrdiff_t src_stride,
912                                   uint8_t* dst_ptr,
913                                   int dst_width);
914 void ScaleRowDown38_3_Box_Any_MSA(const uint8_t* src_ptr,
915                                   ptrdiff_t src_stride,
916                                   uint8_t* dst_ptr,
917                                   int dst_width);
918 void ScaleAddRow_Any_MSA(const uint8_t* src_ptr,
919                          uint16_t* dst_ptr,
920                          int src_width);
921 void ScaleFilterCols_Any_MSA(uint8_t* dst_ptr,
922                              const uint8_t* src_ptr,
923                              int dst_width,
924                              int x,
925                              int dx);
926 void ScaleRowDown34_Any_MSA(const uint8_t* src_ptr,
927                             ptrdiff_t src_stride,
928                             uint8_t* dst_ptr,
929                             int dst_width);
930 void ScaleRowDown34_0_Box_Any_MSA(const uint8_t* src_ptr,
931                                   ptrdiff_t src_stride,
932                                   uint8_t* dst_ptr,
933                                   int dst_width);
934 void ScaleRowDown34_1_Box_Any_MSA(const uint8_t* src_ptr,
935                                   ptrdiff_t src_stride,
936                                   uint8_t* dst_ptr,
937                                   int dst_width);
938 
939 #ifdef __cplusplus
940 }  // extern "C"
941 }  // namespace libyuv
942 #endif
943 
944 #endif  // INCLUDE_LIBYUV_SCALE_ROW_H_
945