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_  // NOLINT
12#define INCLUDE_LIBYUV_SCALE_ROW_H_
13
14#include "libyuv/basic_types.h"
15
16#ifdef __cplusplus
17namespace libyuv {
18extern "C" {
19#endif
20
21#if defined(__pnacl__) || defined(__CLR_VER) || defined(COVERAGE_ENABLED) || \
22    defined(TARGET_IPHONE_SIMULATOR)
23#define LIBYUV_DISABLE_X86
24#endif
25
26// The following are available on all x86 platforms:
27#if !defined(LIBYUV_DISABLE_X86) && \
28    (defined(_M_IX86) || defined(__x86_64__) || defined(__i386__))
29#define HAS_SCALEROWDOWN2_SSE2
30#define HAS_SCALEROWDOWN4_SSE2
31#define HAS_SCALEROWDOWN34_SSSE3
32#define HAS_SCALEROWDOWN38_SSSE3
33#define HAS_SCALEADDROWS_SSE2
34#define HAS_SCALEFILTERCOLS_SSSE3
35#define HAS_SCALECOLSUP2_SSE2
36#define HAS_SCALEARGBROWDOWN2_SSE2
37#define HAS_SCALEARGBROWDOWNEVEN_SSE2
38#define HAS_SCALEARGBCOLS_SSE2
39#define HAS_SCALEARGBFILTERCOLS_SSSE3
40#define HAS_SCALEARGBCOLSUP2_SSE2
41#define HAS_FIXEDDIV_X86
42#define HAS_FIXEDDIV1_X86
43#endif
44
45// The following are available on Neon platforms:
46#if !defined(LIBYUV_DISABLE_NEON) && !defined(__native_client__) && \
47    (defined(__ARM_NEON__) || defined(LIBYUV_NEON))
48#define HAS_SCALEROWDOWN2_NEON
49#define HAS_SCALEROWDOWN4_NEON
50#define HAS_SCALEROWDOWN34_NEON
51#define HAS_SCALEROWDOWN38_NEON
52#define HAS_SCALEARGBROWDOWNEVEN_NEON
53#define HAS_SCALEARGBROWDOWN2_NEON
54#endif
55
56// The following are available on Mips platforms:
57#if !defined(LIBYUV_DISABLE_MIPS) && !defined(__native_client__) && \
58    defined(__mips__) && defined(__mips_dsp) && (__mips_dsp_rev >= 2)
59#define HAS_SCALEROWDOWN2_MIPS_DSPR2
60#define HAS_SCALEROWDOWN4_MIPS_DSPR2
61#define HAS_SCALEROWDOWN34_MIPS_DSPR2
62#define HAS_SCALEROWDOWN38_MIPS_DSPR2
63#endif
64
65// Scale ARGB vertically with bilinear interpolation.
66void ScalePlaneVertical(int src_height,
67                        int dst_width, int dst_height,
68                        int src_stride, int dst_stride,
69                        const uint8* src_argb, uint8* dst_argb,
70                        int x, int y, int dy,
71                        int bpp, enum FilterMode filtering);
72
73void ScalePlaneVertical_16(int src_height,
74                           int dst_width, int dst_height,
75                           int src_stride, int dst_stride,
76                           const uint16* src_argb, uint16* dst_argb,
77                           int x, int y, int dy,
78                           int wpp, enum FilterMode filtering);
79
80// Simplify the filtering based on scale factors.
81enum FilterMode ScaleFilterReduce(int src_width, int src_height,
82                                  int dst_width, int dst_height,
83                                  enum FilterMode filtering);
84
85// Divide num by div and return as 16.16 fixed point result.
86int FixedDiv_C(int num, int div);
87int FixedDiv_X86(int num, int div);
88// Divide num - 1 by div - 1 and return as 16.16 fixed point result.
89int FixedDiv1_C(int num, int div);
90int FixedDiv1_X86(int num, int div);
91#ifdef HAS_FIXEDDIV_X86
92#define FixedDiv FixedDiv_X86
93#define FixedDiv1 FixedDiv1_X86
94#else
95#define FixedDiv FixedDiv_C
96#define FixedDiv1 FixedDiv1_C
97#endif
98
99// Compute slope values for stepping.
100void ScaleSlope(int src_width, int src_height,
101                int dst_width, int dst_height,
102                enum FilterMode filtering,
103                int* x, int* y, int* dx, int* dy);
104
105void ScaleRowDown2_C(const uint8* src_ptr, ptrdiff_t src_stride,
106                     uint8* dst, int dst_width);
107void ScaleRowDown2_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
108                        uint16* dst, int dst_width);
109void ScaleRowDown2Linear_C(const uint8* src_ptr, ptrdiff_t src_stride,
110                           uint8* dst, int dst_width);
111void ScaleRowDown2Linear_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
112                              uint16* dst, int dst_width);
113void ScaleRowDown2Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
114                        uint8* dst, int dst_width);
115void ScaleRowDown2Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
116                           uint16* dst, int dst_width);
117void ScaleRowDown4_C(const uint8* src_ptr, ptrdiff_t src_stride,
118                     uint8* dst, int dst_width);
119void ScaleRowDown4_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
120                        uint16* dst, int dst_width);
121void ScaleRowDown4Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
122                        uint8* dst, int dst_width);
123void ScaleRowDown4Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
124                           uint16* dst, int dst_width);
125void ScaleRowDown34_C(const uint8* src_ptr, ptrdiff_t src_stride,
126                      uint8* dst, int dst_width);
127void ScaleRowDown34_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
128                         uint16* dst, int dst_width);
129void ScaleRowDown34_0_Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
130                            uint8* d, int dst_width);
131void ScaleRowDown34_0_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
132                               uint16* d, int dst_width);
133void ScaleRowDown34_1_Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
134                            uint8* d, int dst_width);
135void ScaleRowDown34_1_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
136                               uint16* d, int dst_width);
137void ScaleCols_C(uint8* dst_ptr, const uint8* src_ptr,
138                 int dst_width, int x, int dx);
139void ScaleCols_16_C(uint16* dst_ptr, const uint16* src_ptr,
140                    int dst_width, int x, int dx);
141void ScaleColsUp2_C(uint8* dst_ptr, const uint8* src_ptr,
142                    int dst_width, int, int);
143void ScaleColsUp2_16_C(uint16* dst_ptr, const uint16* src_ptr,
144                       int dst_width, int, int);
145void ScaleFilterCols_C(uint8* dst_ptr, const uint8* src_ptr,
146                       int dst_width, int x, int dx);
147void ScaleFilterCols_16_C(uint16* dst_ptr, const uint16* src_ptr,
148                          int dst_width, int x, int dx);
149void ScaleFilterCols64_C(uint8* dst_ptr, const uint8* src_ptr,
150                         int dst_width, int x, int dx);
151void ScaleFilterCols64_16_C(uint16* dst_ptr, const uint16* src_ptr,
152                            int dst_width, int x, int dx);
153void ScaleRowDown38_C(const uint8* src_ptr, ptrdiff_t src_stride,
154                      uint8* dst, int dst_width);
155void ScaleRowDown38_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
156                         uint16* dst, int dst_width);
157void ScaleRowDown38_3_Box_C(const uint8* src_ptr,
158                            ptrdiff_t src_stride,
159                            uint8* dst_ptr, int dst_width);
160void ScaleRowDown38_3_Box_16_C(const uint16* src_ptr,
161                               ptrdiff_t src_stride,
162                               uint16* dst_ptr, int dst_width);
163void ScaleRowDown38_2_Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
164                            uint8* dst_ptr, int dst_width);
165void ScaleRowDown38_2_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
166                               uint16* dst_ptr, int dst_width);
167void ScaleAddRows_C(const uint8* src_ptr, ptrdiff_t src_stride,
168                    uint16* dst_ptr, int src_width, int src_height);
169void ScaleAddRows_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
170                       uint32* dst_ptr, int src_width, int src_height);
171void ScaleARGBRowDown2_C(const uint8* src_argb,
172                         ptrdiff_t src_stride,
173                         uint8* dst_argb, int dst_width);
174void ScaleARGBRowDown2Linear_C(const uint8* src_argb,
175                               ptrdiff_t src_stride,
176                               uint8* dst_argb, int dst_width);
177void ScaleARGBRowDown2Box_C(const uint8* src_argb, ptrdiff_t src_stride,
178                            uint8* dst_argb, int dst_width);
179void ScaleARGBRowDownEven_C(const uint8* src_argb, ptrdiff_t src_stride,
180                            int src_stepx,
181                            uint8* dst_argb, int dst_width);
182void ScaleARGBRowDownEvenBox_C(const uint8* src_argb,
183                               ptrdiff_t src_stride,
184                               int src_stepx,
185                               uint8* dst_argb, int dst_width);
186void ScaleARGBCols_C(uint8* dst_argb, const uint8* src_argb,
187                     int dst_width, int x, int dx);
188void ScaleARGBCols64_C(uint8* dst_argb, const uint8* src_argb,
189                       int dst_width, int x, int dx);
190void ScaleARGBColsUp2_C(uint8* dst_argb, const uint8* src_argb,
191                        int dst_width, int, int);
192void ScaleARGBFilterCols_C(uint8* dst_argb, const uint8* src_argb,
193                           int dst_width, int x, int dx);
194void ScaleARGBFilterCols64_C(uint8* dst_argb, const uint8* src_argb,
195                             int dst_width, int x, int dx);
196
197void ScaleRowDown2_SSE2(const uint8* src_ptr, ptrdiff_t src_stride,
198                        uint8* dst_ptr, int dst_width);
199void ScaleRowDown2Linear_SSE2(const uint8* src_ptr, ptrdiff_t src_stride,
200                              uint8* dst_ptr, int dst_width);
201void ScaleRowDown2Box_SSE2(const uint8* src_ptr, ptrdiff_t src_stride,
202                           uint8* dst_ptr, int dst_width);
203void ScaleRowDown2_Unaligned_SSE2(const uint8* src_ptr,
204                                  ptrdiff_t src_stride,
205                                  uint8* dst_ptr, int dst_width);
206void ScaleRowDown2Linear_Unaligned_SSE2(const uint8* src_ptr,
207                                        ptrdiff_t src_stride,
208                                        uint8* dst_ptr, int dst_width);
209void ScaleRowDown2Box_Unaligned_SSE2(const uint8* src_ptr,
210                                     ptrdiff_t src_stride,
211                                     uint8* dst_ptr, int dst_width);
212void ScaleRowDown4_SSE2(const uint8* src_ptr, ptrdiff_t src_stride,
213                        uint8* dst_ptr, int dst_width);
214void ScaleRowDown4Box_SSE2(const uint8* src_ptr, ptrdiff_t src_stride,
215                           uint8* dst_ptr, int dst_width);
216void ScaleRowDown34_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
217                          uint8* dst_ptr, int dst_width);
218void ScaleRowDown34_1_Box_SSSE3(const uint8* src_ptr,
219                                ptrdiff_t src_stride,
220                                uint8* dst_ptr, int dst_width);
221void ScaleRowDown34_0_Box_SSSE3(const uint8* src_ptr,
222                                ptrdiff_t src_stride,
223                                uint8* dst_ptr, int dst_width);
224void ScaleRowDown38_SSSE3(const uint8* src_ptr, ptrdiff_t src_stride,
225                          uint8* dst_ptr, int dst_width);
226void ScaleRowDown38_3_Box_SSSE3(const uint8* src_ptr,
227                                ptrdiff_t src_stride,
228                                uint8* dst_ptr, int dst_width);
229void ScaleRowDown38_2_Box_SSSE3(const uint8* src_ptr,
230                                ptrdiff_t src_stride,
231                                uint8* dst_ptr, int dst_width);
232void ScaleAddRows_SSE2(const uint8* src_ptr, ptrdiff_t src_stride,
233                       uint16* dst_ptr, int src_width,
234                       int src_height);
235void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
236                           int dst_width, int x, int dx);
237void ScaleColsUp2_SSE2(uint8* dst_ptr, const uint8* src_ptr,
238                       int dst_width, int x, int dx);
239void ScaleARGBRowDown2_SSE2(const uint8* src_argb,
240                            ptrdiff_t src_stride,
241                            uint8* dst_argb, int dst_width);
242void ScaleARGBRowDown2Linear_SSE2(const uint8* src_argb,
243                                  ptrdiff_t src_stride,
244                                  uint8* dst_argb, int dst_width);
245void ScaleARGBRowDown2Box_SSE2(const uint8* src_argb,
246                               ptrdiff_t src_stride,
247                               uint8* dst_argb, int dst_width);
248void ScaleARGBRowDownEven_SSE2(const uint8* src_argb, ptrdiff_t src_stride,
249                               int src_stepx,
250                               uint8* dst_argb, int dst_width);
251void ScaleARGBRowDownEvenBox_SSE2(const uint8* src_argb,
252                                  ptrdiff_t src_stride,
253                                  int src_stepx,
254                                  uint8* dst_argb, int dst_width);
255void ScaleARGBCols_SSE2(uint8* dst_argb, const uint8* src_argb,
256                        int dst_width, int x, int dx);
257void ScaleARGBFilterCols_SSSE3(uint8* dst_argb, const uint8* src_argb,
258                               int dst_width, int x, int dx);
259void ScaleARGBColsUp2_SSE2(uint8* dst_argb, const uint8* src_argb,
260                           int dst_width, int x, int dx);
261// Row functions.
262void ScaleARGBRowDownEven_NEON(const uint8* src_argb, int src_stride,
263                               int src_stepx,
264                               uint8* dst_argb, int dst_width);
265void ScaleARGBRowDownEvenBox_NEON(const uint8* src_argb, int src_stride,
266                                  int src_stepx,
267                                  uint8* dst_argb, int dst_width);
268void ScaleARGBRowDown2_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
269                            uint8* dst, int dst_width);
270void ScaleARGBRowDown2Box_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
271                               uint8* dst, int dst_width);
272
273// ScaleRowDown2Box also used by planar functions
274// NEON downscalers with interpolation.
275
276// Note - not static due to reuse in convert for 444 to 420.
277void ScaleRowDown2_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
278                        uint8* dst, int dst_width);
279
280void ScaleRowDown2Box_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
281                           uint8* dst, int dst_width);
282
283void ScaleRowDown4_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
284                        uint8* dst_ptr, int dst_width);
285void ScaleRowDown4Box_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
286                           uint8* dst_ptr, int dst_width);
287
288// Down scale from 4 to 3 pixels. Use the neon multilane read/write
289//  to load up the every 4th pixel into a 4 different registers.
290// Point samples 32 pixels to 24 pixels.
291void ScaleRowDown34_NEON(const uint8* src_ptr,
292                         ptrdiff_t src_stride,
293                         uint8* dst_ptr, int dst_width);
294void ScaleRowDown34_0_Box_NEON(const uint8* src_ptr,
295                               ptrdiff_t src_stride,
296                               uint8* dst_ptr, int dst_width);
297void ScaleRowDown34_1_Box_NEON(const uint8* src_ptr,
298                               ptrdiff_t src_stride,
299                               uint8* dst_ptr, int dst_width);
300
301// 32 -> 12
302void ScaleRowDown38_NEON(const uint8* src_ptr,
303                         ptrdiff_t src_stride,
304                         uint8* dst_ptr, int dst_width);
305// 32x3 -> 12x1
306void ScaleRowDown38_3_Box_NEON(const uint8* src_ptr,
307                               ptrdiff_t src_stride,
308                               uint8* dst_ptr, int dst_width);
309// 32x2 -> 12x1
310void ScaleRowDown38_2_Box_NEON(const uint8* src_ptr,
311                               ptrdiff_t src_stride,
312                               uint8* dst_ptr, int dst_width);
313
314void ScaleRowDown2_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
315                              uint8* dst, int dst_width);
316void ScaleRowDown2Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
317                                 uint8* dst, int dst_width);
318void ScaleRowDown4_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
319                              uint8* dst, int dst_width);
320void ScaleRowDown4Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
321                                 uint8* dst, int dst_width);
322void ScaleRowDown34_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
323                               uint8* dst, int dst_width);
324void ScaleRowDown34_0_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
325                                     uint8* d, int dst_width);
326void ScaleRowDown34_1_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
327                                     uint8* d, int dst_width);
328void ScaleRowDown38_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
329                               uint8* dst, int dst_width);
330void ScaleRowDown38_2_Box_MIPS_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
331                                     uint8* dst_ptr, int dst_width);
332void ScaleRowDown38_3_Box_MIPS_DSPR2(const uint8* src_ptr,
333                                     ptrdiff_t src_stride,
334                                     uint8* dst_ptr, int dst_width);
335
336#ifdef __cplusplus
337}  // extern "C"
338}  // namespace libyuv
339#endif
340
341#endif  // INCLUDE_LIBYUV_SCALE_ROW_H_  NOLINT
342