1ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian/*
2ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  Copyright 2013 The LibYuv Project Authors. All rights reserved.
3ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *
4ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  Use of this source code is governed by a BSD-style license
5ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  that can be found in the LICENSE file in the root of the source
6ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  tree. An additional intellectual property rights grant can be found
7ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  in the file PATENTS. All contributing project authors may
8ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian *  be found in the AUTHORS file in the root of the source tree.
9ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian */
10ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
11ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/scale.h"
12ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
13ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include <assert.h>
14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include <string.h>
15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/cpu_id.h"
17ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/planar_functions.h"  // For CopyARGB
18ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/row.h"
19ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/scale_row.h"
20ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
21ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus
22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace libyuv {
23ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianextern "C" {
24ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
26ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int Abs(int v) {
27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return v >= 0 ? v : -v;
28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// CPU agnostic row functions
31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown2_C(const uint8* src_ptr, ptrdiff_t src_stride,
32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* dst, int dst_width) {
33ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
34ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
35ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[1];
36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src_ptr[3];
37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 4;
39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[1];
42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
44ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
45ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown2_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
46ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        uint16* dst, int dst_width) {
47ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[1];
50ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src_ptr[3];
51ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
52ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 4;
53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
55ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[1];
56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown2Linear_C(const uint8* src_ptr, ptrdiff_t src_stride,
60ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           uint8* dst, int dst_width) {
61ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* s = src_ptr;
62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (s[0] + s[1] + 1) >> 1;
65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = (s[2] + s[3] + 1) >> 1;
66ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    s += 4;
68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
69ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (s[0] + s[1] + 1) >> 1;
71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
73ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown2Linear_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                              uint16* dst, int dst_width) {
76ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint16* s = src_ptr;
77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (s[0] + s[1] + 1) >> 1;
80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = (s[2] + s[3] + 1) >> 1;
81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    s += 4;
83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (s[0] + s[1] + 1) >> 1;
86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown2Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        uint8* dst, int dst_width) {
91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* s = src_ptr;
92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* t = src_ptr + src_stride;
93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2;
96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2;
97ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    s += 4;
99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    t += 4;
100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2;
103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1067bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid ScaleRowDown2Box_Odd_C(const uint8* src_ptr, ptrdiff_t src_stride,
1077bc9febe8749e98a3812a0dc4380ceae75c29450Johann                            uint8* dst, int dst_width) {
1087bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const uint8* s = src_ptr;
1097bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const uint8* t = src_ptr + src_stride;
1107bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int x;
1117bc9febe8749e98a3812a0dc4380ceae75c29450Johann  dst_width -= 1;
1127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (x = 0; x < dst_width - 1; x += 2) {
1137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2;
1147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2;
1157bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst += 2;
1167bc9febe8749e98a3812a0dc4380ceae75c29450Johann    s += 4;
1177bc9febe8749e98a3812a0dc4380ceae75c29450Johann    t += 4;
1187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (dst_width & 1) {
1207bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2;
1217bc9febe8749e98a3812a0dc4380ceae75c29450Johann    dst += 1;
1227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    s += 2;
1237bc9febe8749e98a3812a0dc4380ceae75c29450Johann    t += 2;
1247bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1257bc9febe8749e98a3812a0dc4380ceae75c29450Johann  dst[0] = (s[0] + t[0] + 1) >> 1;
1267bc9febe8749e98a3812a0dc4380ceae75c29450Johann}
1277bc9febe8749e98a3812a0dc4380ceae75c29450Johann
128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown2Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           uint16* dst, int dst_width) {
130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint16* s = src_ptr;
131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint16* t = src_ptr + src_stride;
132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2;
135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2;
136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    s += 4;
138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    t += 4;
139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2;
142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown4_C(const uint8* src_ptr, ptrdiff_t src_stride,
146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     uint8* dst, int dst_width) {
147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[2];
150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src_ptr[6];
151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[2];
156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown4_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        uint16* dst, int dst_width) {
161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[2];
164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src_ptr[6];
165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[2];
170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown4Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        uint8* dst, int dst_width) {
175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  intptr_t stride = src_stride;
176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] +
179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 0] + src_ptr[stride + 1] +
180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 2] + src_ptr[stride + 3] +
181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] +
182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] +
183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] +
184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] +
185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             8) >> 4;
186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] +
187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 4] + src_ptr[stride + 5] +
188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 6] + src_ptr[stride + 7] +
189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] +
190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] +
191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] +
192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] +
193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             8) >> 4;
194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] +
199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 0] + src_ptr[stride + 1] +
200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 2] + src_ptr[stride + 3] +
201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] +
202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] +
203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] +
204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] +
205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             8) >> 4;
206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown4Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           uint16* dst, int dst_width) {
211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  intptr_t stride = src_stride;
212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] +
215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 0] + src_ptr[stride + 1] +
216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 2] + src_ptr[stride + 3] +
217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] +
218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] +
219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] +
220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] +
221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             8) >> 4;
222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] +
223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 4] + src_ptr[stride + 5] +
224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 6] + src_ptr[stride + 7] +
225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] +
226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] +
227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] +
228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] +
229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             8) >> 4;
230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] +
235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 0] + src_ptr[stride + 1] +
236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride + 2] + src_ptr[stride + 3] +
237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] +
238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] +
239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] +
240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] +
241ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian             8) >> 4;
242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown34_C(const uint8* src_ptr, ptrdiff_t src_stride,
246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      uint8* dst, int dst_width) {
247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; x += 3) {
250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[0];
251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src_ptr[1];
252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[2] = src_ptr[3];
253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 3;
254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 4;
255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown34_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         uint16* dst, int dst_width) {
260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; x += 3) {
263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[0];
264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src_ptr[1];
265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[2] = src_ptr[3];
266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 3;
267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 4;
268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Filter rows 0 and 1 together, 3 : 1
272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown34_0_Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            uint8* d, int dst_width) {
274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* s = src_ptr;
275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* t = src_ptr + src_stride;
276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; x += 3) {
279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2;
280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1;
281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2;
282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2;
283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1;
284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2;
285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[0] = (a0 * 3 + b0 + 2) >> 2;
286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[1] = (a1 * 3 + b1 + 2) >> 2;
287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[2] = (a2 * 3 + b2 + 2) >> 2;
288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d += 3;
289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    s += 4;
290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    t += 4;
291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown34_0_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               uint16* d, int dst_width) {
296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint16* s = src_ptr;
297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint16* t = src_ptr + src_stride;
298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; x += 3) {
301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2;
302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1;
303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2;
304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2;
305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1;
306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2;
307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[0] = (a0 * 3 + b0 + 2) >> 2;
308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[1] = (a1 * 3 + b1 + 2) >> 2;
309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[2] = (a2 * 3 + b2 + 2) >> 2;
310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d += 3;
311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    s += 4;
312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    t += 4;
313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Filter rows 1 and 2 together, 1 : 1
317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown34_1_Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            uint8* d, int dst_width) {
319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* s = src_ptr;
320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint8* t = src_ptr + src_stride;
321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; x += 3) {
324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2;
325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1;
326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2;
327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2;
328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1;
329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint8 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2;
330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[0] = (a0 + b0 + 1) >> 1;
331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[1] = (a1 + b1 + 1) >> 1;
332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[2] = (a2 + b2 + 1) >> 1;
333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d += 3;
334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    s += 4;
335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    t += 4;
336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown34_1_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               uint16* d, int dst_width) {
341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint16* s = src_ptr;
342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint16* t = src_ptr + src_stride;
343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; x += 3) {
346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2;
347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1;
348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2;
349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2;
350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1;
351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint16 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2;
352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[0] = (a0 + b0 + 1) >> 1;
353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[1] = (a1 + b1 + 1) >> 1;
354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d[2] = (a2 + b2 + 1) >> 1;
355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    d += 3;
356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    s += 4;
357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    t += 4;
358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scales a single row of pixels using point sampling.
362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleCols_C(uint8* dst_ptr, const uint8* src_ptr,
363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                 int dst_width, int x, int dx) {
364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
366ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = src_ptr[x >> 16];
367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = src_ptr[x >> 16];
369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = src_ptr[x >> 16];
374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleCols_16_C(uint16* dst_ptr, const uint16* src_ptr,
378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    int dst_width, int x, int dx) {
379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
380ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = src_ptr[x >> 16];
382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = src_ptr[x >> 16];
384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = src_ptr[x >> 16];
389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scales a single row of pixels up by 2x using point sampling.
393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleColsUp2_C(uint8* dst_ptr, const uint8* src_ptr,
394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                    int dst_width, int x, int dx) {
395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = dst_ptr[0] = src_ptr[0];
398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 1;
399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
402ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = src_ptr[0];
403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleColsUp2_16_C(uint16* dst_ptr, const uint16* src_ptr,
407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       int dst_width, int x, int dx) {
408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = dst_ptr[0] = src_ptr[0];
411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 1;
412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = src_ptr[0];
416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// (1-f)a + fb can be replaced with a + f(b-a)
4207bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(__arm__) || defined(__aarch64__)
4217bc9febe8749e98a3812a0dc4380ceae75c29450Johann#define BLENDER(a, b, f) (uint8)((int)(a) + \
4227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
4237bc9febe8749e98a3812a0dc4380ceae75c29450Johann#else
4247bc9febe8749e98a3812a0dc4380ceae75c29450Johann// inteluses 7 bit math with rounding.
425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define BLENDER(a, b, f) (uint8)((int)(a) + \
4267bc9febe8749e98a3812a0dc4380ceae75c29450Johann    (((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7))
4277bc9febe8749e98a3812a0dc4380ceae75c29450Johann#endif
428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleFilterCols_C(uint8* dst_ptr, const uint8* src_ptr,
430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       int dst_width, int x, int dx) {
431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xi = x >> 16;
434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_ptr[xi];
435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_ptr[xi + 1];
436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = BLENDER(a, b, x & 0xffff);
437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    xi = x >> 16;
439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    a = src_ptr[xi];
440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = src_ptr[xi + 1];
441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = BLENDER(a, b, x & 0xffff);
442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xi = x >> 16;
447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_ptr[xi];
448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_ptr[xi + 1];
449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = BLENDER(a, b, x & 0xffff);
450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleFilterCols64_C(uint8* dst_ptr, const uint8* src_ptr,
454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int dst_width, int x32, int dx) {
455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int64 x = (int64)(x32);
456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int64 xi = x >> 16;
459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_ptr[xi];
460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_ptr[xi + 1];
461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = BLENDER(a, b, x & 0xffff);
462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    xi = x >> 16;
464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    a = src_ptr[xi];
465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = src_ptr[xi + 1];
466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = BLENDER(a, b, x & 0xffff);
467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int64 xi = x >> 16;
472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_ptr[xi];
473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_ptr[xi + 1];
474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = BLENDER(a, b, x & 0xffff);
475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef BLENDER
478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
4797bc9febe8749e98a3812a0dc4380ceae75c29450Johann// Same as 8 bit arm blender but return is cast to uint16
480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define BLENDER(a, b, f) (uint16)((int)(a) + \
4817bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleFilterCols_16_C(uint16* dst_ptr, const uint16* src_ptr,
484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       int dst_width, int x, int dx) {
485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xi = x >> 16;
488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_ptr[xi];
489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_ptr[xi + 1];
490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = BLENDER(a, b, x & 0xffff);
491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    xi = x >> 16;
493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    a = src_ptr[xi];
494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = src_ptr[xi + 1];
495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = BLENDER(a, b, x & 0xffff);
496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xi = x >> 16;
501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_ptr[xi];
502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_ptr[xi + 1];
503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = BLENDER(a, b, x & 0xffff);
504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleFilterCols64_16_C(uint16* dst_ptr, const uint16* src_ptr,
508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         int dst_width, int x32, int dx) {
509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int64 x = (int64)(x32);
510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int64 xi = x >> 16;
513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_ptr[xi];
514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_ptr[xi + 1];
515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = BLENDER(a, b, x & 0xffff);
516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    xi = x >> 16;
518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    a = src_ptr[xi];
519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = src_ptr[xi + 1];
520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = BLENDER(a, b, x & 0xffff);
521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 2;
523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int64 xi = x >> 16;
526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int a = src_ptr[xi];
527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int b = src_ptr[xi + 1];
528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = BLENDER(a, b, x & 0xffff);
529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef BLENDER
532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown38_C(const uint8* src_ptr, ptrdiff_t src_stride,
534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                      uint8* dst, int dst_width) {
535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dst_width % 3 == 0);
537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; x += 3) {
538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[0];
539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src_ptr[3];
540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[2] = src_ptr[6];
541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 3;
542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown38_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         uint16* dst, int dst_width) {
548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dst_width % 3 == 0);
550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; x += 3) {
551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src_ptr[0];
552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src_ptr[3];
553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[2] = src_ptr[6];
554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 3;
555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 8x3 -> 3x1
560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown38_3_Box_C(const uint8* src_ptr,
561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            ptrdiff_t src_stride,
562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            uint8* dst_ptr, int dst_width) {
563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  intptr_t stride = src_stride;
564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < dst_width; i += 3) {
567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] +
568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 0] + src_ptr[stride + 1] +
569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 2] + src_ptr[stride * 2 + 0] +
570ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2]) *
571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (65536 / 9) >> 16;
572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] +
573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 3] + src_ptr[stride + 4] +
574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 5] + src_ptr[stride * 2 + 3] +
575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5]) *
576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (65536 / 9) >> 16;
577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[2] = (src_ptr[6] + src_ptr[7] +
578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 6] + src_ptr[stride + 7] +
579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7]) *
580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (65536 / 6) >> 16;
581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 3;
583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
586ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown38_3_Box_16_C(const uint16* src_ptr,
587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               ptrdiff_t src_stride,
588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               uint16* dst_ptr, int dst_width) {
589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  intptr_t stride = src_stride;
590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < dst_width; i += 3) {
593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] +
594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 0] + src_ptr[stride + 1] +
595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 2] + src_ptr[stride * 2 + 0] +
596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2]) *
597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (65536 / 9) >> 16;
598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] +
599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 3] + src_ptr[stride + 4] +
600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 5] + src_ptr[stride * 2 + 3] +
601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5]) *
602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (65536 / 9) >> 16;
603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[2] = (src_ptr[6] + src_ptr[7] +
604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 6] + src_ptr[stride + 7] +
605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7]) *
606ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (65536 / 6) >> 16;
607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 3;
609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 8x2 -> 3x1
613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown38_2_Box_C(const uint8* src_ptr, ptrdiff_t src_stride,
614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            uint8* dst_ptr, int dst_width) {
615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  intptr_t stride = src_stride;
616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < dst_width; i += 3) {
619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] +
620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 0] + src_ptr[stride + 1] +
621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 2]) * (65536 / 6) >> 16;
622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] +
623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 3] + src_ptr[stride + 4] +
624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 5]) * (65536 / 6) >> 16;
625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[2] = (src_ptr[6] + src_ptr[7] +
626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 6] + src_ptr[stride + 7]) *
627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (65536 / 4) >> 16;
628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 3;
630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleRowDown38_2_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride,
634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               uint16* dst_ptr, int dst_width) {
635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  intptr_t stride = src_stride;
636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int i;
637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert((dst_width % 3 == 0) && (dst_width > 0));
638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (i = 0; i < dst_width; i += 3) {
639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] +
640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 0] + src_ptr[stride + 1] +
641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 2]) * (65536 / 6) >> 16;
642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] +
643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 3] + src_ptr[stride + 4] +
644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 5]) * (65536 / 6) >> 16;
645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr[2] = (src_ptr[6] + src_ptr[7] +
646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        src_ptr[stride + 6] + src_ptr[stride + 7]) *
647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian        (65536 / 4) >> 16;
648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_ptr += 8;
649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_ptr += 3;
650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
653da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid ScaleAddRow_C(const uint8* src_ptr, uint16* dst_ptr, int src_width) {
654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(src_width > 0);
656da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  for (x = 0; x < src_width - 1; x += 2) {
657da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_ptr[0] += src_ptr[0];
658da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_ptr[1] += src_ptr[1];
659da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_ptr += 2;
660da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_ptr += 2;
661da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
662da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (src_width & 1) {
663da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_ptr[0] += src_ptr[0];
664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
667da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid ScaleAddRow_16_C(const uint16* src_ptr, uint32* dst_ptr, int src_width) {
668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(src_width > 0);
670da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  for (x = 0; x < src_width - 1; x += 2) {
671da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_ptr[0] += src_ptr[0];
672da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_ptr[1] += src_ptr[1];
673da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    src_ptr += 2;
674da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_ptr += 2;
675da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  }
676da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (src_width & 1) {
677da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    dst_ptr[0] += src_ptr[0];
678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBRowDown2_C(const uint8* src_argb,
682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         ptrdiff_t src_stride,
683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                         uint8* dst_argb, int dst_width) {
684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32* src = (const uint32*)(src_argb);
685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32* dst = (uint32*)(dst_argb);
686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[1];
690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src[3];
691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src += 4;
692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[1];
696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBRowDown2Linear_C(const uint8* src_argb,
700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               ptrdiff_t src_stride,
701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               uint8* dst_argb, int dst_width) {
702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; ++x) {
704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (src_argb[0] + src_argb[4] + 1) >> 1;
705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (src_argb[1] + src_argb[5] + 1) >> 1;
706ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (src_argb[2] + src_argb[6] + 1) >> 1;
707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = (src_argb[3] + src_argb[7] + 1) >> 1;
708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 8;
709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBRowDown2Box_C(const uint8* src_argb, ptrdiff_t src_stride,
714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            uint8* dst_argb, int dst_width) {
715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; ++x) {
717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (src_argb[0] + src_argb[4] +
718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  src_argb[src_stride] + src_argb[src_stride + 4] + 2) >> 2;
719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (src_argb[1] + src_argb[5] +
720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  src_argb[src_stride + 1] + src_argb[src_stride + 5] + 2) >> 2;
721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (src_argb[2] + src_argb[6] +
722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  src_argb[src_stride + 2] + src_argb[src_stride + 6] + 2) >> 2;
723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = (src_argb[3] + src_argb[7] +
724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  src_argb[src_stride + 3] + src_argb[src_stride + 7] + 2) >> 2;
725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += 8;
726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBRowDownEven_C(const uint8* src_argb, ptrdiff_t src_stride,
731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            int src_stepx,
732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                            uint8* dst_argb, int dst_width) {
733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32* src = (const uint32*)(src_argb);
734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32* dst = (uint32*)(dst_argb);
735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width - 1; x += 2) {
738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[0];
739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src[src_stepx];
740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src += src_stepx * 2;
741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[0];
745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBRowDownEvenBox_C(const uint8* src_argb,
749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               ptrdiff_t src_stride,
750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               int src_stepx,
751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                               uint8* dst_argb, int dst_width) {
752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int x;
753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (x = 0; x < dst_width; ++x) {
754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[0] = (src_argb[0] + src_argb[4] +
755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  src_argb[src_stride] + src_argb[src_stride + 4] + 2) >> 2;
756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[1] = (src_argb[1] + src_argb[5] +
757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  src_argb[src_stride + 1] + src_argb[src_stride + 5] + 2) >> 2;
758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[2] = (src_argb[2] + src_argb[6] +
759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  src_argb[src_stride + 2] + src_argb[src_stride + 6] + 2) >> 2;
760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb[3] = (src_argb[3] + src_argb[7] +
761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                  src_argb[src_stride + 3] + src_argb[src_stride + 7] + 2) >> 2;
762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_argb += src_stepx * 4;
763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += 4;
764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scales a single row of pixels using point sampling.
768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBCols_C(uint8* dst_argb, const uint8* src_argb,
769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                     int dst_width, int x, int dx) {
770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32* src = (const uint32*)(src_argb);
771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32* dst = (uint32*)(dst_argb);
772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[x >> 16];
775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src[x >> 16];
777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
781ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[x >> 16];
782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBCols64_C(uint8* dst_argb, const uint8* src_argb,
786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                       int dst_width, int x32, int dx) {
787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int64 x = (int64)(x32);
788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32* src = (const uint32*)(src_argb);
789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32* dst = (uint32*)(dst_argb);
790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[x >> 16];
793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = src[x >> 16];
795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[x >> 16];
800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scales a single row of pixels up by 2x using point sampling.
804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBColsUp2_C(uint8* dst_argb, const uint8* src_argb,
805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        int dst_width, int x, int dx) {
806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32* src = (const uint32*)(src_argb);
807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32* dst = (uint32*)(dst_argb);
808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = dst[0] = src[0];
811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src += 1;
812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
814ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = src[0];
816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
8197bc9febe8749e98a3812a0dc4380ceae75c29450Johann// TODO(fbarchard): Replace 0x7f ^ f with 128-f.  bug=607.
820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Mimics SSSE3 blender
821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b) * f) >> 7
822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define BLENDERC(a, b, f, s) (uint32)( \
823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    BLENDER1(((a) >> s) & 255, ((b) >> s) & 255, f) << s)
824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define BLENDER(a, b, f) \
825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    BLENDERC(a, b, f, 24) | BLENDERC(a, b, f, 16) | \
826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    BLENDERC(a, b, f, 8) | BLENDERC(a, b, f, 0)
827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBFilterCols_C(uint8* dst_argb, const uint8* src_argb,
829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           int dst_width, int x, int dx) {
830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32* src = (const uint32*)(src_argb);
831ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32* dst = (uint32*)(dst_argb);
832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
834ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xi = x >> 16;
835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xf = (x >> 9) & 0x7f;
836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 a = src[xi];
837ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 b = src[xi + 1];
838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = BLENDER(a, b, xf);
839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    xi = x >> 16;
841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    xf = (x >> 9) & 0x7f;
842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    a = src[xi];
843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = src[xi + 1];
844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = BLENDER(a, b, xf);
845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xi = x >> 16;
850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xf = (x >> 9) & 0x7f;
851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 a = src[xi];
852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 b = src[xi + 1];
853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = BLENDER(a, b, xf);
854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleARGBFilterCols64_C(uint8* dst_argb, const uint8* src_argb,
858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                             int dst_width, int x32, int dx) {
859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int64 x = (int64)(x32);
860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const uint32* src = (const uint32*)(src_argb);
861ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  uint32* dst = (uint32*)(dst_argb);
862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_width - 1; j += 2) {
864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int64 xi = x >> 16;
865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xf = (x >> 9) & 0x7f;
866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 a = src[xi];
867ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 b = src[xi + 1];
868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = BLENDER(a, b, xf);
869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    xi = x >> 16;
871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    xf = (x >> 9) & 0x7f;
872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    a = src[xi];
873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    b = src[xi + 1];
874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[1] = BLENDER(a, b, xf);
875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    x += dx;
876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst += 2;
877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width & 1) {
879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int64 xi = x >> 16;
880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int xf = (x >> 9) & 0x7f;
881ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 a = src[xi];
882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    uint32 b = src[xi + 1];
883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst[0] = BLENDER(a, b, xf);
884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef BLENDER1
887ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef BLENDERC
888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef BLENDER
889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scale plane vertically with bilinear interpolation.
891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScalePlaneVertical(int src_height,
892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        int dst_width, int dst_height,
893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        int src_stride, int dst_stride,
894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        const uint8* src_argb, uint8* dst_argb,
895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        int x, int y, int dy,
896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                        int bpp, enum FilterMode filtering) {
897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // TODO(fbarchard): Allow higher bpp.
898ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int dst_width_bytes = dst_width * bpp;
899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
901ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      InterpolateRow_C;
902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0;
903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(bpp >= 1 && bpp <= 4);
905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(src_height != 0);
906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dst_width > 0);
907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dst_height > 0);
908ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  src_argb += (x >> 16) * bpp;
909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSSE3)
910da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (TestCpuFlag(kCpuHasSSSE3)) {
911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow = InterpolateRow_Any_SSSE3;
912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 16)) {
913da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      InterpolateRow = InterpolateRow_SSSE3;
914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_AVX2)
918da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (TestCpuFlag(kCpuHasAVX2)) {
919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow = InterpolateRow_Any_AVX2;
920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 32)) {
921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      InterpolateRow = InterpolateRow_AVX2;
922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_NEON)
926da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (TestCpuFlag(kCpuHasNEON)) {
927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow = InterpolateRow_Any_NEON;
928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 16)) {
929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      InterpolateRow = InterpolateRow_NEON;
930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
9337bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(HAS_INTERPOLATEROW_DSPR2)
9347bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (TestCpuFlag(kCpuHasDSPR2) &&
935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) &&
936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) {
9377bc9febe8749e98a3812a0dc4380ceae75c29450Johann    InterpolateRow = InterpolateRow_Any_DSPR2;
938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 4)) {
9397bc9febe8749e98a3812a0dc4380ceae75c29450Johann      InterpolateRow = InterpolateRow_DSPR2;
940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
942ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
943ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_height; ++j) {
944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int yi;
945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int yf;
946ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (y > max_y) {
947ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      y = max_y;
948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    yi = y >> 16;
950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    yf = filtering ? ((y >> 8) & 255) : 0;
951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow(dst_argb, src_argb + yi * src_stride,
952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                   src_stride, dst_width_bytes, yf);
953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += dst_stride;
954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    y += dy;
955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScalePlaneVertical_16(int src_height,
958ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           int dst_width, int dst_height,
959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           int src_stride, int dst_stride,
960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           const uint16* src_argb, uint16* dst_argb,
961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           int x, int y, int dy,
962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                           int wpp, enum FilterMode filtering) {
963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // TODO(fbarchard): Allow higher wpp.
964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int dst_width_words = dst_width * wpp;
965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  void (*InterpolateRow)(uint16* dst_argb, const uint16* src_argb,
966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      InterpolateRow_16_C;
968ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0;
969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int j;
970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(wpp >= 1 && wpp <= 2);
971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(src_height != 0);
972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dst_width > 0);
973ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dst_height > 0);
974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  src_argb += (x >> 16) * wpp;
975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_16_SSE2)
976da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (TestCpuFlag(kCpuHasSSE2)) {
977ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow = InterpolateRow_Any_16_SSE2;
978ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 16)) {
979da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      InterpolateRow = InterpolateRow_16_SSE2;
980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
981ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_16_SSSE3)
984da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (TestCpuFlag(kCpuHasSSSE3)) {
985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow = InterpolateRow_Any_16_SSSE3;
986ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 16)) {
987da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      InterpolateRow = InterpolateRow_16_SSSE3;
988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
989ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
990ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
991ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_16_AVX2)
992da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (TestCpuFlag(kCpuHasAVX2)) {
993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow = InterpolateRow_Any_16_AVX2;
994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 32)) {
995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      InterpolateRow = InterpolateRow_16_AVX2;
996ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
997ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_16_NEON)
1000da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  if (TestCpuFlag(kCpuHasNEON)) {
1001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow = InterpolateRow_Any_16_NEON;
1002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 16)) {
1003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      InterpolateRow = InterpolateRow_16_NEON;
1004ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1006ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
10077bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if defined(HAS_INTERPOLATEROW_16_DSPR2)
10087bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (TestCpuFlag(kCpuHasDSPR2) &&
1009ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) &&
1010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) {
10117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    InterpolateRow = InterpolateRow_Any_16_DSPR2;
1012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (IS_ALIGNED(dst_width_bytes, 4)) {
10137bc9febe8749e98a3812a0dc4380ceae75c29450Johann      InterpolateRow = InterpolateRow_16_DSPR2;
1014ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1015ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
1017ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  for (j = 0; j < dst_height; ++j) {
1018ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int yi;
1019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    int yf;
1020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (y > max_y) {
1021ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      y = max_y;
1022ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1023ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    yi = y >> 16;
1024ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    yf = filtering ? ((y >> 8) & 255) : 0;
1025ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    InterpolateRow(dst_argb, src_argb + yi * src_stride,
1026ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                   src_stride, dst_width_words, yf);
1027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_argb += dst_stride;
1028ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    y += dy;
1029ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1030ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1031ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1032ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Simplify the filtering based on scale factors.
1033ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianenum FilterMode ScaleFilterReduce(int src_width, int src_height,
1034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                  int dst_width, int dst_height,
1035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                  enum FilterMode filtering) {
1036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (src_width < 0) {
1037ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_width = -src_width;
1038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (src_height < 0) {
1040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    src_height = -src_height;
1041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (filtering == kFilterBox) {
1043ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // If scaling both axis to 0.5 or larger, switch from Box to Bilinear.
1044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (dst_width * 2 >= src_width && dst_height * 2 >= src_height) {
1045ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      filtering = kFilterBilinear;
1046ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1048ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (filtering == kFilterBilinear) {
1049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (src_height == 1) {
1050ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      filtering = kFilterLinear;
1051ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // TODO(fbarchard): Detect any odd scale factor and reduce to Linear.
1053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (dst_height == src_height || dst_height * 3 == src_height) {
1054ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      filtering = kFilterLinear;
1055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // TODO(fbarchard): Remove 1 pixel wide filter restriction, which is to
1057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // avoid reading 2 pixels horizontally that causes memory exception.
1058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (src_width == 1) {
1059ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      filtering = kFilterNone;
1060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1061ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1062ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (filtering == kFilterLinear) {
1063ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (src_width == 1) {
1064ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      filtering = kFilterNone;
1065ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // TODO(fbarchard): Detect any odd scale factor and reduce to None.
1067ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (dst_width == src_width || dst_width * 3 == src_width) {
1068ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      filtering = kFilterNone;
1069ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1070ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1071ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return filtering;
1072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1073ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1074ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Divide num by div and return as 16.16 fixed point result.
1075ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint FixedDiv_C(int num, int div) {
1076ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (int)(((int64)(num) << 16) / div);
1077ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1079ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Divide num by div and return as 16.16 fixed point result.
1080ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint FixedDiv1_C(int num, int div) {
1081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return (int)((((int64)(num) << 16) - 0x00010001) /
1082ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                          (div - 1));
1083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1084ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1085ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define CENTERSTART(dx, s) (dx < 0) ? -((-dx >> 1) + s) : ((dx >> 1) + s)
1086ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1087ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Compute slope values for stepping.
1088ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid ScaleSlope(int src_width, int src_height,
1089ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                int dst_width, int dst_height,
1090ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                enum FilterMode filtering,
1091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                int* x, int* y, int* dx, int* dy) {
1092ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(x != NULL);
1093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(y != NULL);
1094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dx != NULL);
1095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dy != NULL);
1096ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(src_width != 0);
1097ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(src_height != 0);
1098ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dst_width > 0);
1099ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(dst_height > 0);
1100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Check for 1 pixel and avoid FixedDiv overflow.
1101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_width == 1 && src_width >= 32768) {
1102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_width = src_width;
1103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (dst_height == 1 && src_height >= 32768) {
1105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    dst_height = src_height;
1106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (filtering == kFilterBox) {
1108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // Scale step for point sampling duplicates all pixels equally.
1109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *dx = FixedDiv(Abs(src_width), dst_width);
1110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *dy = FixedDiv(src_height, dst_height);
1111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *x = 0;
1112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *y = 0;
1113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else if (filtering == kFilterBilinear) {
1114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // Scale step for bilinear sampling renders last pixel once for upsample.
1115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (dst_width <= Abs(src_width)) {
1116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *dx = FixedDiv(Abs(src_width), dst_width);
1117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *x = CENTERSTART(*dx, -32768);  // Subtract 0.5 (32768) to center filter.
1118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    } else if (dst_width > 1) {
1119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *dx = FixedDiv1(Abs(src_width), dst_width);
1120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *x = 0;
1121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (dst_height <= src_height) {
1123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *dy = FixedDiv(src_height,  dst_height);
1124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *y = CENTERSTART(*dy, -32768);  // Subtract 0.5 (32768) to center filter.
1125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    } else if (dst_height > 1) {
1126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *dy = FixedDiv1(src_height, dst_height);
1127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *y = 0;
1128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else if (filtering == kFilterLinear) {
1130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // Scale step for bilinear sampling renders last pixel once for upsample.
1131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (dst_width <= Abs(src_width)) {
1132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *dx = FixedDiv(Abs(src_width), dst_width);
1133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *x = CENTERSTART(*dx, -32768);  // Subtract 0.5 (32768) to center filter.
1134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    } else if (dst_width > 1) {
1135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *dx = FixedDiv1(Abs(src_width), dst_width);
1136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      *x = 0;
1137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    }
1138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *dy = FixedDiv(src_height, dst_height);
1139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *y = *dy >> 1;
1140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  } else {
1141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // Scale step for point sampling duplicates all pixels equally.
1142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *dx = FixedDiv(Abs(src_width), dst_width);
1143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *dy = FixedDiv(src_height, dst_height);
1144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *x = CENTERSTART(*dx, 0);
1145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *y = CENTERSTART(*dy, 0);
1146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  // Negative src_width means horizontally mirror.
1148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (src_width < 0) {
1149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *x += (dst_width - 1) * *dx;
1150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *dx = -*dx;
1151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    // src_width = -src_width;   // Caller must do this.
1152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
1153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}
1154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#undef CENTERSTART
1155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus
1157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}  // extern "C"
1158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}  // namespace libyuv
1159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif
1160