190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/*
2f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
4f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Use of this source code is governed by a BSD-style license
5f71323e297a928af368937089d3ed71239786f86Andreas Huber *  that can be found in the LICENSE file in the root of the source
6f71323e297a928af368937089d3ed71239786f86Andreas Huber *  tree. An additional intellectual property rights grant can be found
7f71323e297a928af368937089d3ed71239786f86Andreas Huber *  in the file PATENTS.  All contributing project authors may
8f71323e297a928af368937089d3ed71239786f86Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <float.h>
1390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <math.h>
1490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdio.h>
1590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpx_mem/vpx_mem.h"
1690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpxscale_arbitrary.h"
1790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define FIXED_POINT
1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define MAX_IN_WIDTH        800
2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define MAX_IN_HEIGHT       600
2290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define MAX_OUT_WIDTH       800
2390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define MAX_OUT_HEIGHT      600
2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define MAX_OUT_DIMENSION   ((MAX_OUT_WIDTH > MAX_OUT_HEIGHT) ? \
2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                             MAX_OUT_WIDTH : MAX_OUT_HEIGHT)
2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas HuberBICUBIC_SCALER_STRUCT g_b_scaler;
2890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int g_first_time = 1;
2990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#pragma DATA_SECTION(g_hbuf, "VP6_HEAP")
3190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#pragma DATA_ALIGN (g_hbuf, 32);
3290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberunsigned char g_hbuf[MAX_OUT_DIMENSION];
3390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#pragma DATA_SECTION(g_hbuf_uv, "VP6_HEAP")
3590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#pragma DATA_ALIGN (g_hbuf_uv, 32);
3690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberunsigned char g_hbuf_uv[MAX_OUT_DIMENSION];
3790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef FIXED_POINT
4090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic int a_i = 0.6 * 65536;
4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
4290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberstatic float a = -0.6;
4390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
4490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef FIXED_POINT
4690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//         3     2
4790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// C0 = a*t - a*t
4890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
49f71323e297a928af368937089d3ed71239786f86Andreas Huberstatic short c0_fixed(unsigned int t)
5090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
5190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // put t in Q16 notation
5290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned short v1, v2;
5390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q16
5590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v1 = (a_i * t) >> 16;
5690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v1 = (v1 * t) >> 16;
5790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q16
5990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (a_i * t) >> 16;
6090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
6190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
6290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q12
6490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return -((v1 - v2) >> 4);
6590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
6690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//                     2          3
6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// C1 = a*t + (3-2*a)*t  - (2-a)*t
6990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
70f71323e297a928af368937089d3ed71239786f86Andreas Huberstatic short c1_fixed(unsigned int t)
7190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
7290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned short v1, v2, v3;
7390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned short two, three;
7490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
7590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q16
7690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v1 = (a_i * t) >> 16;
7790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
7890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q13
7990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    two = 2 << 13;
8090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = two - (a_i >> 3);
8190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
8290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q13
8690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    three = 3 << 13;
8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = three - (2 * (a_i >> 3));
8890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = (v3 * t) >> 16;
8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = (v3 * t) >> 16;
9090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q12
9290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return (((v1 >> 3) - v2 + v3) >> 1);
9390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
9590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//                 2          3
9790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// C2 = 1 - (3-a)*t  + (2-a)*t
9890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
99f71323e297a928af368937089d3ed71239786f86Andreas Huberstatic short c2_fixed(unsigned int t)
10090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
10190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned short v1, v2, v3;
10290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned short two, three;
10390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q13
10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v1 = 1 << 13;
10690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q13
10890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    three = 3 << 13;
10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = three - (a_i >> 3);
11090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
11190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
11290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q13
11490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    two = 2 << 13;
11590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = two - (a_i >> 3);
11690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = (v3 * t) >> 16;
11790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = (v3 * t) >> 16;
11890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = (v3 * t) >> 16;
11990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q12
12190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return (v1 - v2 + v3) >> 1;
12290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
12390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//                 2      3
12590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// C3 = a*t - 2*a*t  + a*t
12690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
127f71323e297a928af368937089d3ed71239786f86Andreas Huberstatic short c3_fixed(unsigned int t)
12890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
12990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int v1, v2, v3;
13090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q16
13290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v1 = (a_i * t) >> 16;
13390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q15
13590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = 2 * (a_i >> 1);
13690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
13790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v2 = (v2 * t) >> 16;
13890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q16
14090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = (a_i * t) >> 16;
14190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = (v3 * t) >> 16;
14290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    v3 = (v3 * t) >> 16;
14390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Q12
14590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return ((v2 - (v1 >> 1) - (v3 >> 1)) >> 3);
14690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
14790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//          3     2
14990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// C0 = -a*t + a*t
15090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
15190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberfloat C0(float t)
15290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
15390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return -a * t * t * t + a * t * t;
15490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
15590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
15690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//                      2          3
15790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// C1 = -a*t + (2*a+3)*t  - (a+2)*t
15890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
15990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberfloat C1(float t)
16090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
16190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return -(a + 2.0f) * t * t * t + (2.0f * a + 3.0f) * t * t - a * t;
16290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
16390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
16490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//                 2          3
16590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// C2 = 1 - (a+3)*t  + (a+2)*t
16690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
16790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberfloat C2(float t)
16890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
16990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return (a + 2.0f) * t * t * t - (a + 3.0f) * t * t + 1.0f;
17090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
17190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
17290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//                 2      3
17390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// C3 = a*t - 2*a*t  + a*t
17490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
17590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberfloat C3(float t)
17690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
17790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return a * t * t * t - 2.0f * a * t * t + a * t;
17890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
17990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
18090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
18190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if 0
18290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint compare_real_fixed()
18390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
18490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i, errors = 0;
18590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    float mult = 1.0 / 10000.0;
18690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int fixed_mult = mult * 4294967296;//65536;
18790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int phase_offset_int;
18890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    float phase_offset_real;
18990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
19090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < 10000; i++)
19190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
19290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int fixed0, fixed1, fixed2, fixed3, fixed_total;
19390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        int real0, real1, real2, real3, real_total;
19490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
19590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset_real = (float)i * mult;
19690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset_int = (fixed_mult * i) >> 16;
19790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//      phase_offset_int = phase_offset_real * 65536;
19890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
19990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        fixed0 = c0_fixed(phase_offset_int);
20090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        real0 = C0(phase_offset_real) * 4096.0;
20190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
20290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((abs(fixed0) > (abs(real0) + 1)) || (abs(fixed0) < (abs(real0) - 1)))
20390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            errors++;
20490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
20590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        fixed1 = c1_fixed(phase_offset_int);
20690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        real1 = C1(phase_offset_real) * 4096.0;
20790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
20890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((abs(fixed1) > (abs(real1) + 1)) || (abs(fixed1) < (abs(real1) - 1)))
20990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            errors++;
21090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
21190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        fixed2 = c2_fixed(phase_offset_int);
21290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        real2 = C2(phase_offset_real) * 4096.0;
21390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
21490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((abs(fixed2) > (abs(real2) + 1)) || (abs(fixed2) < (abs(real2) - 1)))
21590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            errors++;
21690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
21790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        fixed3 = c3_fixed(phase_offset_int);
21890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        real3 = C3(phase_offset_real) * 4096.0;
21990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
22090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((abs(fixed3) > (abs(real3) + 1)) || (abs(fixed3) < (abs(real3) - 1)))
22190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            errors++;
22290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
22390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        fixed_total = fixed0 + fixed1 + fixed2 + fixed3;
22490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        real_total = real0 + real1 + real2 + real3;
22590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
22690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((fixed_total > 4097) || (fixed_total < 4094))
22790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            errors ++;
22890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
22990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((real_total > 4097) || (real_total < 4095))
23090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            errors ++;
23190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
23290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
23390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return errors;
23490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
23590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
23690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
23790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Find greatest common denominator between two integers.  Method used here is
23890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//  slow compared to Euclid's algorithm, but does not require any division.
23990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint gcd(int a, int b)
24090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
24190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Problem with this algorithm is that if a or b = 0 this function
24290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  will never exit.  Don't want to return 0 because any computation
24390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  that was based on a common denoninator and tried to reduce by
24490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  dividing by 0 would fail.  Best solution that could be thought of
24590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  would to be fail by returing a 1;
24690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (a <= 0 || b <= 0)
24790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return 1;
24890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
24990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    while (a != b)
25090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
25190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (b > a)
25290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            b = b - a;
25390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        else
25490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
25590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            int tmp = a;//swap large and
25690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            a = b; //small
25790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            b = tmp;
25890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
25990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
26090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
26190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return b;
26290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
26390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
26490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid bicubic_coefficient_init()
26590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
26690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    vpx_memset(&g_b_scaler, 0, sizeof(BICUBIC_SCALER_STRUCT));
26790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_first_time = 0;
26890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
26990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
27090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid bicubic_coefficient_destroy()
27190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
27290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (!g_first_time)
27390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
27479f15823c34ae1e423108295e416213200bb280fAndreas Huber        vpx_free(g_b_scaler.l_w);
27590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
27679f15823c34ae1e423108295e416213200bb280fAndreas Huber        vpx_free(g_b_scaler.l_h);
27790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
27879f15823c34ae1e423108295e416213200bb280fAndreas Huber        vpx_free(g_b_scaler.l_h_uv);
27990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28079f15823c34ae1e423108295e416213200bb280fAndreas Huber        vpx_free(g_b_scaler.c_w);
28190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28279f15823c34ae1e423108295e416213200bb280fAndreas Huber        vpx_free(g_b_scaler.c_h);
28390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28479f15823c34ae1e423108295e416213200bb280fAndreas Huber        vpx_free(g_b_scaler.c_h_uv);
28590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vpx_memset(&g_b_scaler, 0, sizeof(BICUBIC_SCALER_STRUCT));
28790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
28890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
28990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
29090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Create the coeffients that will be used for the cubic interpolation.
29190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//  Because scaling does not have to be equal in the vertical and horizontal
29290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//  regimes the phase offsets will be different.  There are 4 coefficents
29390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//  for each point, two on each side.  The layout is that there are the
29490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//  4 coefficents for each phase in the array and then the next phase.
29590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint bicubic_coefficient_setup(int in_width, int in_height, int out_width, int out_height)
29690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
29790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
29890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef FIXED_POINT
29990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int phase_offset_int;
30090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned int fixed_mult;
30190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int product_val = 0;
30290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
30390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    float phase_offset;
30490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
30590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int gcd_w, gcd_h, gcd_h_uv, d_w, d_h, d_h_uv;
30690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
30790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (g_first_time)
30890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        bicubic_coefficient_init();
30990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
31090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
31190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // check to see if the coefficents have already been set up correctly
31290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if ((in_width == g_b_scaler.in_width) && (in_height == g_b_scaler.in_height)
31390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        && (out_width == g_b_scaler.out_width) && (out_height == g_b_scaler.out_height))
31490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return 0;
31590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
31690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.in_width = in_width;
31790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.in_height = in_height;
31890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.out_width = out_width;
31990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.out_height = out_height;
32090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
32190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Don't want to allow crazy scaling, just try and prevent a catastrophic
32290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  failure here.  Want to fail after setting the member functions so if
32390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  if the scaler is called the member functions will not scale.
32490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (out_width <= 0 || out_height <= 0)
32590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return -1;
32690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
32790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // reduce in/out width and height ratios using the gcd
32890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    gcd_w = gcd(out_width, in_width);
32990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    gcd_h = gcd(out_height, in_height);
33090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    gcd_h_uv = gcd(out_height, in_height / 2);
33190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
33290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // the numerator width and height are to be saved in
33390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  globals so they can be used during the scaling process
33490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  without having to be recalculated.
33590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.nw = out_width / gcd_w;
33690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    d_w = in_width / gcd_w;
33790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
33890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.nh = out_height / gcd_h;
33990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    d_h = in_height / gcd_h;
34090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
34190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.nh_uv = out_height / gcd_h_uv;
34290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    d_h_uv = (in_height / 2) / gcd_h_uv;
34390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
34490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // allocate memory for the coefficents
34579f15823c34ae1e423108295e416213200bb280fAndreas Huber    vpx_free(g_b_scaler.l_w);
34690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
34779f15823c34ae1e423108295e416213200bb280fAndreas Huber    vpx_free(g_b_scaler.l_h);
34890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
34979f15823c34ae1e423108295e416213200bb280fAndreas Huber    vpx_free(g_b_scaler.l_h_uv);
35090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
35190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.l_w = (short *)vpx_memalign(32, out_width * 2);
35290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.l_h = (short *)vpx_memalign(32, out_height * 2);
35390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.l_h_uv = (short *)vpx_memalign(32, out_height * 2);
35490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
35579f15823c34ae1e423108295e416213200bb280fAndreas Huber    vpx_free(g_b_scaler.c_w);
35690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
35779f15823c34ae1e423108295e416213200bb280fAndreas Huber    vpx_free(g_b_scaler.c_h);
35890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
35979f15823c34ae1e423108295e416213200bb280fAndreas Huber    vpx_free(g_b_scaler.c_h_uv);
36090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
36190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.c_w = (short *)vpx_memalign(32, g_b_scaler.nw * 4 * 2);
36290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.c_h = (short *)vpx_memalign(32, g_b_scaler.nh * 4 * 2);
36390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.c_h_uv = (short *)vpx_memalign(32, g_b_scaler.nh_uv * 4 * 2);
36490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
36590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.hbuf = g_hbuf;
36690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.hbuf_uv = g_hbuf_uv;
36790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
36890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Set up polyphase filter taps.  This needs to be done before
36990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  the scaling because of the floating point math required.  The
37090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  coefficients are multiplied by 2^12 so that fixed point math
37190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  can be used in the main scaling loop.
37290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef FIXED_POINT
37390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    fixed_mult = (1.0 / (float)g_b_scaler.nw) * 4294967296;
37490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    product_val = 0;
37690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < g_b_scaler.nw; i++)
37890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
37990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (product_val > g_b_scaler.nw)
38090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            product_val -= g_b_scaler.nw;
38190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
38290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset_int = (fixed_mult * product_val) >> 16;
38390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
38490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_w[i*4]   = c3_fixed(phase_offset_int);
38590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_w[i*4+1] = c2_fixed(phase_offset_int);
38690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_w[i*4+2] = c1_fixed(phase_offset_int);
38790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_w[i*4+3] = c0_fixed(phase_offset_int);
38890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
38990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        product_val += d_w;
39090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
39190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
39290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
39390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    fixed_mult = (1.0 / (float)g_b_scaler.nh) * 4294967296;
39490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
39590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    product_val = 0;
39690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
39790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < g_b_scaler.nh; i++)
39890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
39990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (product_val > g_b_scaler.nh)
40090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            product_val -= g_b_scaler.nh;
40190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
40290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset_int = (fixed_mult * product_val) >> 16;
40390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
40490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_h[i*4]   = c0_fixed(phase_offset_int);
40590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_h[i*4+1] = c1_fixed(phase_offset_int);
40690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_h[i*4+2] = c2_fixed(phase_offset_int);
40790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_h[i*4+3] = c3_fixed(phase_offset_int);
40890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
40990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        product_val += d_h;
41090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
41190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
41290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    fixed_mult = (1.0 / (float)g_b_scaler.nh_uv) * 4294967296;
41390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
41490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    product_val = 0;
41590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
41690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < g_b_scaler.nh_uv; i++)
41790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
41890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (product_val > g_b_scaler.nh_uv)
41990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            product_val -= g_b_scaler.nh_uv;
42090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
42190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset_int = (fixed_mult * product_val) >> 16;
42290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
42390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_h_uv[i*4]   = c0_fixed(phase_offset_int);
42490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_h_uv[i*4+1] = c1_fixed(phase_offset_int);
42590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_h_uv[i*4+2] = c2_fixed(phase_offset_int);
42690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.c_h_uv[i*4+3] = c3_fixed(phase_offset_int);
42790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
42890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        product_val += d_h_uv;
42990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
43090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
43190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
43290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
43390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < g_nw; i++)
43490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
43590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset = (float)((i * d_w) % g_nw) / (float)g_nw;
43690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_w[i*4]   = (C3(phase_offset) * 4096.0);
43790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_w[i*4+1] = (C2(phase_offset) * 4096.0);
43890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_w[i*4+2] = (C1(phase_offset) * 4096.0);
43990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_w[i*4+3] = (C0(phase_offset) * 4096.0);
44090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
44190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
44290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < g_nh; i++)
44390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
44490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset = (float)((i * d_h) % g_nh) / (float)g_nh;
44590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_h[i*4]   = (C0(phase_offset) * 4096.0);
44690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_h[i*4+1] = (C1(phase_offset) * 4096.0);
44790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_h[i*4+2] = (C2(phase_offset) * 4096.0);
44890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_h[i*4+3] = (C3(phase_offset) * 4096.0);
44990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
45090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
45190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < g_nh_uv; i++)
45290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
45390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset = (float)((i * d_h_uv) % g_nh_uv) / (float)g_nh_uv;
45490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_h_uv[i*4]   = (C0(phase_offset) * 4096.0);
45590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_h_uv[i*4+1] = (C1(phase_offset) * 4096.0);
45690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_h_uv[i*4+2] = (C2(phase_offset) * 4096.0);
45790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_c_h_uv[i*4+3] = (C3(phase_offset) * 4096.0);
45890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
45990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
46090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
46190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
46290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // Create an array that corresponds input lines to output lines.
46390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  This doesn't require floating point math, but it does require
46490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  a division and because hardware division is not present that
46590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    //  is a call.
46690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < out_width; i++)
46790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
46890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.l_w[i] = (i * d_w) / g_b_scaler.nw;
46990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
47090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((g_b_scaler.l_w[i] + 2) <= in_width)
47190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            g_b_scaler.max_usable_out_width = i;
47290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
47390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
47490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
47590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < out_height + 1; i++)
47690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
47790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.l_h[i] = (i * d_h) / g_b_scaler.nh;
47890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        g_b_scaler.l_h_uv[i] = (i * d_h_uv) / g_b_scaler.nh_uv;
47990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
48090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
48190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return 0;
48290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
48390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
48490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberint bicubic_scale(int in_width, int in_height, int in_stride,
48590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  int out_width, int out_height, int out_stride,
48690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  unsigned char *input_image, unsigned char *output_image)
48790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
48890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    short *RESTRICT l_w, * RESTRICT l_h;
48990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    short *RESTRICT c_w, * RESTRICT c_h;
49090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *RESTRICT ip, * RESTRICT op;
49190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *RESTRICT hbuf;
49290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int h, w, lw, lh;
49390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int temp_sum;
49490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int phase_offset_w, phase_offset_h;
49590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
49690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    c_w = g_b_scaler.c_w;
49790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    c_h = g_b_scaler.c_h;
49890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
49990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    op = output_image;
50090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
50190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    l_w = g_b_scaler.l_w;
50290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    l_h = g_b_scaler.l_h;
50390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
50490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    phase_offset_h = 0;
50590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
50690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (h = 0; h < out_height; h++)
50790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
50890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // select the row to work on
50990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        lh = l_h[h];
51090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        ip = input_image + (in_stride * lh);
51190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
51290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // vp8_filter the row vertically into an temporary buffer.
51390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //  If the phase offset == 0 then all the multiplication
51490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //  is going to result in the output equalling the input.
51590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //  So instead point the temporary buffer to the input.
51690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //  Also handle the boundry condition of not being able to
51790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //  filter that last lines.
51890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (phase_offset_h && (lh < in_height - 2))
51990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
52090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            hbuf = g_b_scaler.hbuf;
52190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
52290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            for (w = 0; w < in_width; w++)
52390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
52490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                temp_sum =  c_h[phase_offset_h*4+3] * ip[w - in_stride];
52590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                temp_sum += c_h[phase_offset_h*4+2] * ip[w];
52690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                temp_sum += c_h[phase_offset_h*4+1] * ip[w + in_stride];
52790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                temp_sum += c_h[phase_offset_h*4]   * ip[w + 2*in_stride];
52890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
52990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                hbuf[w] = temp_sum >> 12;
53090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
53190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
53290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        else
53390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            hbuf = ip;
53490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
53590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // increase the phase offset for the next time around.
53690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (++phase_offset_h >= g_b_scaler.nh)
53790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            phase_offset_h = 0;
53890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
53990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // now filter and expand it horizontally into the final
54090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //  output buffer
54190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        phase_offset_w = 0;
54290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
54390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (w = 0; w < out_width; w++)
54490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
54590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // get the index to use to expand the image
54690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            lw = l_w[w];
54790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
54890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            temp_sum =  c_w[phase_offset_w*4]   * hbuf[lw - 1];
54990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            temp_sum += c_w[phase_offset_w*4+1] * hbuf[lw];
55090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            temp_sum += c_w[phase_offset_w*4+2] * hbuf[lw + 1];
55190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            temp_sum += c_w[phase_offset_w*4+3] * hbuf[lw + 2];
55290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            temp_sum = temp_sum >> 12;
55390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
55490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (++phase_offset_w >= g_b_scaler.nw)
55590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                phase_offset_w = 0;
55690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
55790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // boundry conditions
55890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ((lw + 2) >= in_width)
55990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                temp_sum = hbuf[lw];
56090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
56190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (lw == 0)
56290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                temp_sum = hbuf[0];
56390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
56490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            op[w] = temp_sum;
56590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
56690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
56790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        op += out_stride;
56890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
56990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
57090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    return 0;
57190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
57290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
57390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid bicubic_scale_frame_reset()
57490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
57590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.out_width = 0;
57690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    g_b_scaler.out_height = 0;
57790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
57890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
57990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid bicubic_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
58090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         int new_width, int new_height)
58190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
58290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
58390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst->y_width = new_width;
58490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst->y_height = new_height;
58590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst->uv_width = new_width / 2;
58690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst->uv_height = new_height / 2;
58790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
58890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst->y_stride = dst->y_width;
58990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    dst->uv_stride = dst->uv_width;
59090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
59190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    bicubic_scale(src->y_width, src->y_height, src->y_stride,
59290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  new_width, new_height, dst->y_stride,
59390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  src->y_buffer, dst->y_buffer);
59490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
59590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    bicubic_scale(src->uv_width, src->uv_height, src->uv_stride,
59690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  new_width / 2, new_height / 2, dst->uv_stride,
59790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  src->u_buffer, dst->u_buffer);
59890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
59990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    bicubic_scale(src->uv_width, src->uv_height, src->uv_stride,
60090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  new_width / 2, new_height / 2, dst->uv_stride,
60190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  src->v_buffer, dst->v_buffer);
60290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
603